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:
authorYimingWu <xp8110@outlook.com>2019-05-16 04:48:45 +0300
committerYimingWu <xp8110@outlook.com>2019-05-16 04:48:45 +0300
commit54804117e89931a1e7bfa67b2aaf4fe237881ab6 (patch)
tree72f60f4ee18426243c986e973029508ab706569a /source/blender
parent2753611c4e2482885021416f1b2af46250fd09dd (diff)
parent2384564149b54374572ea28f91b5f64dc61143e2 (diff)
Merge branch 'master' into soc-2018-npr
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/alembic/intern/abc_transform.cc2
-rw-r--r--source/blender/blenkernel/BKE_appdir.h1
-rw-r--r--source/blender/blenkernel/BKE_armature.h4
-rw-r--r--source/blender/blenkernel/BKE_blender_version.h2
-rw-r--r--source/blender/blenkernel/BKE_blendfile.h2
-rw-r--r--source/blender/blenkernel/BKE_collection.h2
-rw-r--r--source/blender/blenkernel/BKE_curve.h11
-rw-r--r--source/blender/blenkernel/BKE_displist.h9
-rw-r--r--source/blender/blenkernel/BKE_global.h4
-rw-r--r--source/blender/blenkernel/BKE_image.h5
-rw-r--r--source/blender/blenkernel/BKE_material.h2
-rw-r--r--source/blender/blenkernel/BKE_mesh.h2
-rw-r--r--source/blender/blenkernel/BKE_movieclip.h3
-rw-r--r--source/blender/blenkernel/BKE_object.h2
-rw-r--r--source/blender/blenkernel/BKE_pbvh.h2
-rw-r--r--source/blender/blenkernel/BKE_scene.h8
-rw-r--r--source/blender/blenkernel/BKE_sound.h25
-rw-r--r--source/blender/blenkernel/BKE_workspace.h2
-rw-r--r--source/blender/blenkernel/BKE_writeavi.h3
-rw-r--r--source/blender/blenkernel/intern/action.c1
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c12
-rw-r--r--source/blender/blenkernel/intern/appdir.c20
-rw-r--r--source/blender/blenkernel/intern/armature.c51
-rw-r--r--source/blender/blenkernel/intern/armature_update.c60
-rw-r--r--source/blender/blenkernel/intern/blendfile.c122
-rw-r--r--source/blender/blenkernel/intern/collection.c9
-rw-r--r--source/blender/blenkernel/intern/constraint.c33
-rw-r--r--source/blender/blenkernel/intern/curve.c234
-rw-r--r--source/blender/blenkernel/intern/displist.c207
-rw-r--r--source/blender/blenkernel/intern/dynamicpaint.c2
-rw-r--r--source/blender/blenkernel/intern/fcurve.c5
-rw-r--r--source/blender/blenkernel/intern/image.c6
-rw-r--r--source/blender/blenkernel/intern/layer.c38
-rw-r--r--source/blender/blenkernel/intern/library.c2
-rw-r--r--source/blender/blenkernel/intern/light.c1
-rw-r--r--source/blender/blenkernel/intern/mesh_convert.c2
-rw-r--r--source/blender/blenkernel/intern/object.c11
-rw-r--r--source/blender/blenkernel/intern/object_dupli.c2
-rw-r--r--source/blender/blenkernel/intern/object_update.c6
-rw-r--r--source/blender/blenkernel/intern/paint.c3
-rw-r--r--source/blender/blenkernel/intern/scene.c47
-rw-r--r--source/blender/blenkernel/intern/screen.c13
-rw-r--r--source/blender/blenkernel/intern/sequencer.c31
-rw-r--r--source/blender/blenkernel/intern/sound.c331
-rw-r--r--source/blender/blenkernel/intern/workspace.c51
-rw-r--r--source/blender/blenkernel/intern/writeavi.c1
-rw-r--r--source/blender/blenlib/BLI_math_matrix.h5
-rw-r--r--source/blender/blenlib/BLI_memblock.h57
-rw-r--r--source/blender/blenlib/BLI_rand.h8
-rw-r--r--source/blender/blenlib/CMakeLists.txt2
-rw-r--r--source/blender/blenlib/intern/BLI_memblock.c174
-rw-r--r--source/blender/blenlib/intern/math_matrix.c127
-rw-r--r--source/blender/blenloader/intern/readfile.c117
-rw-r--r--source/blender/blenloader/intern/versioning_250.c12
-rw-r--r--source/blender/blenloader/intern/versioning_280.c104
-rw-r--r--source/blender/blenloader/intern/versioning_cycles.c132
-rw-r--r--source/blender/blenloader/intern/versioning_defaults.c40
-rw-r--r--source/blender/blenloader/intern/versioning_userdef.c69
-rw-r--r--source/blender/blenloader/intern/writefile.c2
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh.c4
-rw-r--r--source/blender/bmesh/tools/bmesh_bevel.c9
-rw-r--r--source/blender/collada/ImageExporter.cpp2
-rw-r--r--source/blender/depsgraph/DEG_depsgraph_query.h9
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder.cc7
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder.h2
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.cc39
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.h4
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc9
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.cc37
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.h9
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc8
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc13
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_rna.cc29
-rw-r--r--source/blender/depsgraph/intern/depsgraph_build.cc2
-rw-r--r--source/blender/depsgraph/intern/depsgraph_query_iter.cc7
-rw-r--r--source/blender/depsgraph/intern/depsgraph_tag.cc26
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc244
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_operation.cc3
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_operation.h6
-rw-r--r--source/blender/draw/CMakeLists.txt1
-rw-r--r--source/blender/draw/DRW_engine.h11
-rw-r--r--source/blender/draw/engines/basic/basic_engine.c6
-rw-r--r--source/blender/draw/engines/eevee/eevee_bloom.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_depth_of_field.c9
-rw-r--r--source/blender/draw/engines/eevee/eevee_effects.c24
-rw-r--r--source/blender/draw/engines/eevee/eevee_lightprobes.c61
-rw-r--r--source/blender/draw/engines/eevee/eevee_lights.c31
-rw-r--r--source/blender/draw/engines/eevee/eevee_lookdev.c40
-rw-r--r--source/blender/draw/engines/eevee/eevee_materials.c67
-rw-r--r--source/blender/draw/engines/eevee/eevee_mist.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_motion_blur.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_occlusion.c8
-rw-r--r--source/blender/draw/engines/eevee/eevee_private.h5
-rw-r--r--source/blender/draw/engines/eevee/eevee_screen_raytrace.c4
-rw-r--r--source/blender/draw/engines/eevee/eevee_subsurface.c6
-rw-r--r--source/blender/draw/engines/eevee/eevee_temporal_sampling.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_volumes.c33
-rw-r--r--source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl18
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_planar_downsample_vert.glsl9
-rw-r--r--source/blender/draw/engines/eevee/shaders/lit_surface_vert.glsl27
-rw-r--r--source/blender/draw/engines/eevee/shaders/prepass_vert.glsl16
-rw-r--r--source/blender/draw/engines/eevee/shaders/shadow_vert.glsl23
-rw-r--r--source/blender/draw/engines/external/external_engine.c2
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c43
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_draw_utils.c91
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_engine.c48
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_engine.h11
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_shader_fx.c32
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_geom.glsl1
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_vert.glsl3
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_fill_frag.glsl25
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_fill_vert.glsl4
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_paper_frag.glsl2
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_point_frag.glsl27
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_point_geom.glsl8
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_point_vert.glsl6
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_stroke_frag.glsl25
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_stroke_geom.glsl1
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_stroke_vert.glsl4
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl30
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_deferred_composite_frag.glsl3
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl5
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl3
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_prepass_vert.glsl41
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_shadow_vert.glsl6
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl12
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_volume_vert.glsl3
-rw-r--r--source/blender/draw/engines/workbench/workbench_deferred.c130
-rw-r--r--source/blender/draw/engines/workbench/workbench_effect_dof.c18
-rw-r--r--source/blender/draw/engines/workbench/workbench_effect_fxaa.c2
-rw-r--r--source/blender/draw/engines/workbench/workbench_effect_taa.c24
-rw-r--r--source/blender/draw/engines/workbench/workbench_forward.c37
-rw-r--r--source/blender/draw/engines/workbench/workbench_materials.c9
-rw-r--r--source/blender/draw/engines/workbench/workbench_private.h23
-rw-r--r--source/blender/draw/engines/workbench/workbench_volume.c12
-rw-r--r--source/blender/draw/intern/DRW_render.h135
-rw-r--r--source/blender/draw/intern/draw_anim_viz.c4
-rw-r--r--source/blender/draw/intern/draw_armature.c222
-rw-r--r--source/blender/draw/intern/draw_cache.c131
-rw-r--r--source/blender/draw/intern/draw_cache_impl.h30
-rw-r--r--source/blender/draw/intern/draw_cache_impl_curve.c8
-rw-r--r--source/blender/draw/intern/draw_cache_impl_displist.c3
-rw-r--r--source/blender/draw/intern/draw_cache_impl_lattice.c6
-rw-r--r--source/blender/draw/intern/draw_cache_impl_mesh.c336
-rw-r--r--source/blender/draw/intern/draw_cache_impl_metaball.c6
-rw-r--r--source/blender/draw/intern/draw_cache_inline.h110
-rw-r--r--source/blender/draw/intern/draw_common.c372
-rw-r--r--source/blender/draw/intern/draw_common.h120
-rw-r--r--source/blender/draw/intern/draw_hair.c4
-rw-r--r--source/blender/draw/intern/draw_instance_data.c343
-rw-r--r--source/blender/draw/intern/draw_instance_data.h23
-rw-r--r--source/blender/draw/intern/draw_manager.c445
-rw-r--r--source/blender/draw/intern/draw_manager.h148
-rw-r--r--source/blender/draw/intern/draw_manager_data.c671
-rw-r--r--source/blender/draw/intern/draw_manager_exec.c351
-rw-r--r--source/blender/draw/intern/draw_manager_shader.c2
-rw-r--r--source/blender/draw/modes/edit_curve_mode.c27
-rw-r--r--source/blender/draw/modes/edit_lattice_mode.c6
-rw-r--r--source/blender/draw/modes/edit_mesh_mode.c55
-rw-r--r--source/blender/draw/modes/edit_metaball_mode.c15
-rw-r--r--source/blender/draw/modes/edit_text_mode.c34
-rw-r--r--source/blender/draw/modes/object_mode.c1152
-rw-r--r--source/blender/draw/modes/overlay_mode.c55
-rw-r--r--source/blender/draw/modes/paint_texture_mode.c45
-rw-r--r--source/blender/draw/modes/paint_vertex_mode.c23
-rw-r--r--source/blender/draw/modes/particle_mode.c23
-rw-r--r--source/blender/draw/modes/pose_mode.c4
-rw-r--r--source/blender/draw/modes/sculpt_mode.c10
-rw-r--r--source/blender/draw/modes/shaders/armature_axes_vert.glsl6
-rw-r--r--source/blender/draw/modes/shaders/armature_envelope_outline_vert.glsl5
-rw-r--r--source/blender/draw/modes/shaders/armature_envelope_solid_vert.glsl5
-rw-r--r--source/blender/draw/modes/shaders/armature_shape_outline_geom.glsl1
-rw-r--r--source/blender/draw/modes/shaders/armature_shape_outline_vert.glsl13
-rw-r--r--source/blender/draw/modes/shaders/armature_shape_solid_vert.glsl13
-rw-r--r--source/blender/draw/modes/shaders/armature_stick_vert.glsl5
-rw-r--r--source/blender/draw/modes/shaders/common_view_lib.glsl35
-rw-r--r--source/blender/draw/modes/shaders/edit_curve_overlay_handle_vert.glsl8
-rw-r--r--source/blender/draw/modes/shaders/edit_curve_overlay_loosevert_vert.glsl9
-rw-r--r--source/blender/draw/modes/shaders/edit_curve_overlay_normals_vert.glsl9
-rw-r--r--source/blender/draw/modes/shaders/edit_lattice_overlay_loosevert_vert.glsl8
-rw-r--r--source/blender/draw/modes/shaders/edit_mesh_overlay_facefill_vert.glsl7
-rw-r--r--source/blender/draw/modes/shaders/edit_mesh_overlay_mesh_analysis_vert.glsl7
-rw-r--r--source/blender/draw/modes/shaders/edit_mesh_overlay_vert.glsl21
-rw-r--r--source/blender/draw/modes/shaders/edit_normals_vert.glsl16
-rw-r--r--source/blender/draw/modes/shaders/object_empty_axes_vert.glsl5
-rw-r--r--source/blender/draw/modes/shaders/object_empty_image_frag.glsl23
-rw-r--r--source/blender/draw/modes/shaders/object_empty_image_vert.glsl13
-rw-r--r--source/blender/draw/modes/shaders/object_grid_frag.glsl7
-rw-r--r--source/blender/draw/modes/shaders/object_grid_vert.glsl5
-rw-r--r--source/blender/draw/modes/shaders/object_mball_handles_vert.glsl3
-rw-r--r--source/blender/draw/modes/shaders/object_outline_prepass_geom.glsl2
-rw-r--r--source/blender/draw/modes/shaders/object_outline_prepass_vert.glsl11
-rw-r--r--source/blender/draw/modes/shaders/object_particle_dot_vert.glsl13
-rw-r--r--source/blender/draw/modes/shaders/object_particle_prim_vert.glsl21
-rw-r--r--source/blender/draw/modes/shaders/overlay_face_orientation_vert.glsl7
-rw-r--r--source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl49
-rw-r--r--source/blender/draw/modes/shaders/paint_face_vert.glsl9
-rw-r--r--source/blender/draw/modes/shaders/paint_texture_frag.glsl23
-rw-r--r--source/blender/draw/modes/shaders/paint_texture_vert.glsl8
-rw-r--r--source/blender/draw/modes/shaders/paint_vertex_vert.glsl8
-rw-r--r--source/blender/draw/modes/shaders/paint_weight_vert.glsl8
-rw-r--r--source/blender/draw/modes/shaders/paint_wire_vert.glsl8
-rw-r--r--source/blender/draw/modes/shaders/particle_strand_frag.glsl1
-rw-r--r--source/blender/draw/modes/shaders/particle_strand_vert.glsl5
-rw-r--r--source/blender/draw/modes/shaders/sculpt_mask_vert.glsl4
-rw-r--r--source/blender/draw/modes/shaders/volume_velocity_vert.glsl5
-rw-r--r--source/blender/editors/animation/CMakeLists.txt1
-rw-r--r--source/blender/editors/animation/anim_channels_defines.c10
-rw-r--r--source/blender/editors/animation/anim_channels_edit.c5
-rw-r--r--source/blender/editors/animation/anim_filter.c4
-rw-r--r--source/blender/editors/animation/anim_markers.c4
-rw-r--r--source/blender/editors/animation/anim_ops.c6
-rw-r--r--source/blender/editors/animation/drivers.c3
-rw-r--r--source/blender/editors/animation/keyframing.c8
-rw-r--r--source/blender/editors/animation/time_scrub_ui.c214
-rw-r--r--source/blender/editors/armature/armature_intern.h2
-rw-r--r--source/blender/editors/armature/armature_naming.c10
-rw-r--r--source/blender/editors/armature/armature_ops.c2
-rw-r--r--source/blender/editors/armature/armature_relations.c37
-rw-r--r--source/blender/editors/armature/armature_select.c8
-rw-r--r--source/blender/editors/armature/armature_utils.c3
-rw-r--r--source/blender/editors/armature/pose_slide.c255
-rw-r--r--source/blender/editors/armature/pose_transform.c337
-rw-r--r--source/blender/editors/curve/editcurve.c2
-rw-r--r--source/blender/editors/gpencil/gpencil_edit.c2
-rw-r--r--source/blender/editors/gpencil/gpencil_merge.c2
-rw-r--r--source/blender/editors/gpencil/gpencil_paint.c2
-rw-r--r--source/blender/editors/gpencil/gpencil_primitive.c2
-rw-r--r--source/blender/editors/gpencil/gpencil_utils.c2
-rw-r--r--source/blender/editors/include/ED_anim_api.h10
-rw-r--r--source/blender/editors/include/ED_mesh.h16
-rw-r--r--source/blender/editors/include/ED_screen.h10
-rw-r--r--source/blender/editors/include/ED_time_scrub_ui.h43
-rw-r--r--source/blender/editors/include/ED_view3d.h5
-rw-r--r--source/blender/editors/include/UI_icons.h36
-rw-r--r--source/blender/editors/include/UI_interface.h15
-rw-r--r--source/blender/editors/include/UI_interface_icons.h25
-rw-r--r--source/blender/editors/include/UI_resources.h6
-rw-r--r--source/blender/editors/include/UI_view2d.h8
-rw-r--r--source/blender/editors/interface/interface.c5
-rw-r--r--source/blender/editors/interface/interface_anim.c5
-rw-r--r--source/blender/editors/interface/interface_context_menu.c160
-rw-r--r--source/blender/editors/interface/interface_handlers.c42
-rw-r--r--source/blender/editors/interface/interface_icons.c543
-rw-r--r--source/blender/editors/interface/interface_intern.h6
-rw-r--r--source/blender/editors/interface/interface_layout.c3
-rw-r--r--source/blender/editors/interface/interface_panel.c151
-rw-r--r--source/blender/editors/interface/interface_region_menu_pie.c2
-rw-r--r--source/blender/editors/interface/interface_region_menu_popup.c25
-rw-r--r--source/blender/editors/interface/interface_region_popover.c10
-rw-r--r--source/blender/editors/interface/interface_region_popup.c8
-rw-r--r--source/blender/editors/interface/interface_region_tooltip.c4
-rw-r--r--source/blender/editors/interface/interface_templates.c36
-rw-r--r--source/blender/editors/interface/interface_widgets.c50
-rw-r--r--source/blender/editors/interface/resources.c26
-rw-r--r--source/blender/editors/interface/view2d.c24
-rw-r--r--source/blender/editors/interface/view2d_ops.c4
-rw-r--r--source/blender/editors/mask/mask_ops.c8
-rw-r--r--source/blender/editors/mesh/CMakeLists.txt1
-rw-r--r--source/blender/editors/mesh/editface.c6
-rw-r--r--source/blender/editors/mesh/editmesh_bevel.c3
-rw-r--r--source/blender/editors/mesh/editmesh_extrude.c4
-rw-r--r--source/blender/editors/mesh/editmesh_knife.c1
-rw-r--r--source/blender/editors/mesh/editmesh_loopcut.c69
-rw-r--r--source/blender/editors/mesh/editmesh_select.c368
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c21
-rw-r--r--source/blender/editors/mesh/meshtools.c8
-rw-r--r--source/blender/editors/metaball/mball_edit.c2
-rw-r--r--source/blender/editors/object/object_add.c72
-rw-r--r--source/blender/editors/object/object_bake_api.c3
-rw-r--r--source/blender/editors/object/object_constraint.c4
-rw-r--r--source/blender/editors/object/object_edit.c4
-rw-r--r--source/blender/editors/render/render_internal.c49
-rw-r--r--source/blender/editors/render/render_preview.c11
-rw-r--r--source/blender/editors/screen/area.c127
-rw-r--r--source/blender/editors/screen/screen_ops.c200
-rw-r--r--source/blender/editors/screen/workspace_edit.c12
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c3
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_proj.c18
-rw-r--r--source/blender/editors/sculpt_paint/paint_utils.c1
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c4
-rw-r--r--source/blender/editors/sound/CMakeLists.txt1
-rw-r--r--source/blender/editors/sound/sound_ops.c55
-rw-r--r--source/blender/editors/space_action/action_draw.c2
-rw-r--r--source/blender/editors/space_action/action_select.c1
-rw-r--r--source/blender/editors/space_action/space_action.c26
-rw-r--r--source/blender/editors/space_buttons/buttons_context.c7
-rw-r--r--source/blender/editors/space_buttons/buttons_ops.c5
-rw-r--r--source/blender/editors/space_buttons/space_buttons.c108
-rw-r--r--source/blender/editors/space_clip/clip_intern.h2
-rw-r--r--source/blender/editors/space_clip/clip_ops.c8
-rw-r--r--source/blender/editors/space_clip/space_clip.c44
-rw-r--r--source/blender/editors/space_clip/tracking_ops.c10
-rw-r--r--source/blender/editors/space_file/file_draw.c2
-rw-r--r--source/blender/editors/space_file/file_ops.c5
-rw-r--r--source/blender/editors/space_file/fsmenu.c161
-rw-r--r--source/blender/editors/space_file/fsmenu.h2
-rw-r--r--source/blender/editors/space_file/space_file.c13
-rw-r--r--source/blender/editors/space_graph/graph_edit.c1
-rw-r--r--source/blender/editors/space_graph/graph_ops.c2
-rw-r--r--source/blender/editors/space_graph/graph_select.c2
-rw-r--r--source/blender/editors/space_graph/space_graph.c45
-rw-r--r--source/blender/editors/space_image/image_ops.c5
-rw-r--r--source/blender/editors/space_image/space_image.c18
-rw-r--r--source/blender/editors/space_info/info_ops.c12
-rw-r--r--source/blender/editors/space_nla/nla_channels.c4
-rw-r--r--source/blender/editors/space_nla/nla_draw.c10
-rw-r--r--source/blender/editors/space_nla/nla_edit.c3
-rw-r--r--source/blender/editors/space_nla/nla_select.c3
-rw-r--r--source/blender/editors/space_nla/space_nla.c24
-rw-r--r--source/blender/editors/space_node/drawnode.c12
-rw-r--r--source/blender/editors/space_node/node_edit.c9
-rw-r--r--source/blender/editors/space_node/node_select.c186
-rw-r--r--source/blender/editors/space_node/space_node.c2
-rw-r--r--source/blender/editors/space_outliner/outliner_collections.c24
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.c1350
-rw-r--r--source/blender/editors/space_outliner/outliner_edit.c4
-rw-r--r--source/blender/editors/space_outliner/outliner_intern.h9
-rw-r--r--source/blender/editors/space_outliner/outliner_select.c3
-rw-r--r--source/blender/editors/space_outliner/outliner_tree.c12
-rw-r--r--source/blender/editors/space_outliner/outliner_utils.c39
-rw-r--r--source/blender/editors/space_outliner/space_outliner.c1
-rw-r--r--source/blender/editors/space_sequencer/CMakeLists.txt1
-rw-r--r--source/blender/editors/space_sequencer/sequencer_add.c8
-rw-r--r--source/blender/editors/space_sequencer/sequencer_draw.c43
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c3
-rw-r--r--source/blender/editors/space_sequencer/sequencer_preview.c4
-rw-r--r--source/blender/editors/space_sequencer/space_sequencer.c8
-rw-r--r--source/blender/editors/space_text/text_draw.c6
-rw-r--r--source/blender/editors/space_text/text_ops.c2
-rw-r--r--source/blender/editors/space_topbar/space_topbar.c7
-rw-r--r--source/blender/editors/space_userpref/space_userpref.c2
-rw-r--r--source/blender/editors/space_view3d/drawobject.c231
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c109
-rw-r--r--source/blender/editors/space_view3d/view3d_draw_legacy.c16
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c17
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h7
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c33
-rw-r--r--source/blender/editors/transform/transform.c3
-rw-r--r--source/blender/editors/transform/transform.h33
-rw-r--r--source/blender/editors/transform/transform_conversions.c183
-rw-r--r--source/blender/editors/transform/transform_generics.c83
-rw-r--r--source/blender/editors/transform/transform_gizmo_3d.c9
-rw-r--r--source/blender/editors/util/CMakeLists.txt1
-rw-r--r--source/blender/editors/uvedit/uvedit_draw.c3
-rw-r--r--source/blender/editors/uvedit/uvedit_unwrap_ops.c4
-rw-r--r--source/blender/freestyle/intern/geometry/Noise.cpp18
-rw-r--r--source/blender/gpu/CMakeLists.txt9
-rw-r--r--source/blender/gpu/GPU_batch.h1
-rw-r--r--source/blender/gpu/GPU_buffers.h2
-rw-r--r--source/blender/gpu/GPU_draw.h2
-rw-r--r--source/blender/gpu/GPU_material.h7
-rw-r--r--source/blender/gpu/GPU_matrix.h5
-rw-r--r--source/blender/gpu/GPU_shader.h9
-rw-r--r--source/blender/gpu/GPU_shader_interface.h3
-rw-r--r--source/blender/gpu/GPU_texture.h5
-rw-r--r--source/blender/gpu/GPU_vertex_buffer.h16
-rw-r--r--source/blender/gpu/GPU_vertex_format.h62
-rw-r--r--source/blender/gpu/GPU_viewport.h14
-rw-r--r--source/blender/gpu/intern/gpu_attr_binding.c3
-rw-r--r--source/blender/gpu/intern/gpu_batch.c4
-rw-r--r--source/blender/gpu/intern/gpu_codegen.c95
-rw-r--r--source/blender/gpu/intern/gpu_codegen.h2
-rw-r--r--source/blender/gpu/intern/gpu_draw.c472
-rw-r--r--source/blender/gpu/intern/gpu_material.c17
-rw-r--r--source/blender/gpu/intern/gpu_matrix.c32
-rw-r--r--source/blender/gpu/intern/gpu_select_sample_query.c7
-rw-r--r--source/blender/gpu/intern/gpu_shader.c119
-rw-r--r--source/blender/gpu/intern/gpu_shader_interface.c3
-rw-r--r--source/blender/gpu/intern/gpu_texture.c2
-rw-r--r--source/blender/gpu/intern/gpu_vertex_buffer.c11
-rw-r--r--source/blender/gpu/intern/gpu_vertex_format.c90
-rw-r--r--source/blender/gpu/intern/gpu_viewport.c98
-rw-r--r--source/blender/gpu/shaders/gpu_shader_edges_front_back_ortho_vert.glsl54
-rw-r--r--source/blender/gpu/shaders/gpu_shader_edges_front_back_persp_geom.glsl60
-rw-r--r--source/blender/gpu/shaders/gpu_shader_edges_front_back_persp_legacy_vert.glsl68
-rw-r--r--source/blender/gpu/shaders/gpu_shader_edges_front_back_persp_vert.glsl44
-rw-r--r--source/blender/gpu/shaders/gpu_shader_edges_overlay_frag.glsl21
-rw-r--r--source/blender/gpu/shaders/gpu_shader_edges_overlay_geom.glsl72
-rw-r--r--source/blender/gpu/shaders/gpu_shader_edges_overlay_simple_geom.glsl56
-rw-r--r--source/blender/gpu/shaders/gpu_shader_edges_overlay_vert.glsl14
-rw-r--r--source/blender/gpu/shaders/gpu_shader_instance_edges_variying_color_vert.glsl14
-rw-r--r--source/blender/gpu/shaders/gpu_shader_instance_objectspace_variying_color_vert.glsl13
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material.glsl135
-rw-r--r--source/blender/imbuf/IMB_colormanagement.h13
-rw-r--r--source/blender/imbuf/intern/IMB_colormanagement_intern.h7
-rw-r--r--source/blender/imbuf/intern/colormanagement.c91
-rw-r--r--source/blender/makesdna/DNA_ID.h8
-rw-r--r--source/blender/makesdna/DNA_action_types.h6
-rw-r--r--source/blender/makesdna/DNA_anim_types.h3
-rw-r--r--source/blender/makesdna/DNA_armature_types.h10
-rw-r--r--source/blender/makesdna/DNA_collection_types.h4
-rw-r--r--source/blender/makesdna/DNA_constraint_types.h25
-rw-r--r--source/blender/makesdna/DNA_image_types.h2
-rw-r--r--source/blender/makesdna/DNA_layer_types.h2
-rw-r--r--source/blender/makesdna/DNA_light_types.h3
-rw-r--r--source/blender/makesdna/DNA_material_types.h13
-rw-r--r--source/blender/makesdna/DNA_node_types.h8
-rw-r--r--source/blender/makesdna/DNA_object_types.h10
-rw-r--r--source/blender/makesdna/DNA_screen_types.h4
-rw-r--r--source/blender/makesdna/DNA_sequence_types.h3
-rw-r--r--source/blender/makesdna/DNA_space_types.h15
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h45
-rw-r--r--source/blender/makesdna/DNA_view2d_types.h8
-rw-r--r--source/blender/makesdna/intern/dna_rename_defs.h9
-rw-r--r--source/blender/makesrna/RNA_enum_types.h1
-rw-r--r--source/blender/makesrna/intern/makesrna.c6
-rw-r--r--source/blender/makesrna/intern/rna_animation.c40
-rw-r--r--source/blender/makesrna/intern/rna_animation_api.c27
-rw-r--r--source/blender/makesrna/intern/rna_armature.c37
-rw-r--r--source/blender/makesrna/intern/rna_collection.c8
-rw-r--r--source/blender/makesrna/intern/rna_color.c28
-rw-r--r--source/blender/makesrna/intern/rna_constraint.c48
-rw-r--r--source/blender/makesrna/intern/rna_define.c2
-rw-r--r--source/blender/makesrna/intern/rna_fcurve.c2
-rw-r--r--source/blender/makesrna/intern/rna_image.c3
-rw-r--r--source/blender/makesrna/intern/rna_image_api.c95
-rw-r--r--source/blender/makesrna/intern/rna_internal.h1
-rw-r--r--source/blender/makesrna/intern/rna_layer.c50
-rw-r--r--source/blender/makesrna/intern/rna_light.c8
-rw-r--r--source/blender/makesrna/intern/rna_lightprobe.c2
-rw-r--r--source/blender/makesrna/intern/rna_material.c27
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c100
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c27
-rw-r--r--source/blender/makesrna/intern/rna_object.c8
-rw-r--r--source/blender/makesrna/intern/rna_object_api.c2
-rw-r--r--source/blender/makesrna/intern/rna_object_force.c2
-rw-r--r--source/blender/makesrna/intern/rna_pose.c43
-rw-r--r--source/blender/makesrna/intern/rna_scene.c12
-rw-r--r--source/blender/makesrna/intern/rna_smoke.c2
-rw-r--r--source/blender/makesrna/intern/rna_space.c71
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c134
-rw-r--r--source/blender/makesrna/intern/rna_wm.c3
-rw-r--r--source/blender/makesrna/intern/rna_wm_gizmo.c7
-rw-r--r--source/blender/modifiers/intern/MOD_multires.c9
-rw-r--r--source/blender/nodes/shader/node_shader_util.h1
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c21
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_normal_map.c31
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_object_info.c6
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tangent.c13
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_coord.c7
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_environment.c23
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_image.c59
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_vector_displacement.c2
-rw-r--r--source/blender/python/intern/bpy_rna_anim.c12
-rw-r--r--source/blender/render/extern/include/RE_pipeline.h25
-rw-r--r--source/blender/render/intern/source/multires_bake.c3
-rw-r--r--source/blender/render/intern/source/pipeline.c110
-rw-r--r--source/blender/windowmanager/WM_api.h4
-rw-r--r--source/blender/windowmanager/WM_types.h2
-rw-r--r--source/blender/windowmanager/gizmo/WM_gizmo_types.h4
-rw-r--r--source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c63
-rw-r--r--source/blender/windowmanager/intern/wm_dragdrop.c2
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c6
-rw-r--r--source/blender/windowmanager/intern/wm_files.c392
-rw-r--r--source/blender/windowmanager/intern/wm_init_exit.c43
-rw-r--r--source/blender/windowmanager/intern/wm_keymap.c7
-rw-r--r--source/blender/windowmanager/intern/wm_operator_props.c20
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c26
-rw-r--r--source/blender/windowmanager/intern/wm_toolsystem.c14
-rw-r--r--source/blender/windowmanager/intern/wm_window.c3
-rw-r--r--source/blender/windowmanager/wm_files.h3
462 files changed, 10791 insertions, 8243 deletions
diff --git a/source/blender/alembic/intern/abc_transform.cc b/source/blender/alembic/intern/abc_transform.cc
index 8b8ed6c5c4b..08f8eb8bd8f 100644
--- a/source/blender/alembic/intern/abc_transform.cc
+++ b/source/blender/alembic/intern/abc_transform.cc
@@ -86,7 +86,7 @@ void AbcTransformWriter::do_write()
m_xform, m_xform.getSchema().getTimeSampling());
}
- m_visibility.set(!(ob_eval->restrictflag & OB_RESTRICT_VIEW));
+ m_visibility.set(!(ob_eval->restrictflag & OB_RESTRICT_VIEWPORT));
if (!m_first_frame && !m_is_animated) {
return;
diff --git a/source/blender/blenkernel/BKE_appdir.h b/source/blender/blenkernel/BKE_appdir.h
index 7ff8514f675..e956aeb769a 100644
--- a/source/blender/blenkernel/BKE_appdir.h
+++ b/source/blender/blenkernel/BKE_appdir.h
@@ -36,6 +36,7 @@ const char *BKE_appdir_folder_id_version(const int folder_id, const int ver, con
bool BKE_appdir_app_is_portable_install(void);
bool BKE_appdir_app_template_any(void);
bool BKE_appdir_app_template_id_search(const char *app_template, char *path, size_t path_len);
+bool BKE_appdir_app_template_has_userpref(const char *app_template);
void BKE_appdir_app_templates(struct ListBase *templates);
/* Initialize path to program executable */
diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h
index b5da30e725d..6839e13ffe1 100644
--- a/source/blender/blenkernel/BKE_armature.h
+++ b/source/blender/blenkernel/BKE_armature.h
@@ -84,7 +84,9 @@ bool BKE_pose_minmax(
int bone_autoside_name(char name[64], int strip_number, short axis, float head, float tail);
struct Bone *BKE_armature_find_bone_name(struct bArmature *arm, const char *name);
-struct GHash *BKE_armature_bone_from_name_map(struct bArmature *arm);
+
+void BKE_armature_bone_hash_make(struct bArmature *arm);
+void BKE_armature_bone_hash_free(struct bArmature *arm);
bool BKE_armature_bone_flag_test_recursive(const struct Bone *bone, int flag);
diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h
index e01f6a6b751..a36ead4630e 100644
--- a/source/blender/blenkernel/BKE_blender_version.h
+++ b/source/blender/blenkernel/BKE_blender_version.h
@@ -27,7 +27,7 @@
* \note Use #STRINGIFY() rather than defining with quotes.
*/
#define BLENDER_VERSION 280
-#define BLENDER_SUBVERSION 60
+#define BLENDER_SUBVERSION 64
/** Several breakages with 280, e.g. collections vs layers. */
#define BLENDER_MINVERSION 280
#define BLENDER_MINSUBVERSION 0
diff --git a/source/blender/blenkernel/BKE_blendfile.h b/source/blender/blenkernel/BKE_blendfile.h
index 216bef0d1e3..76c05b0411a 100644
--- a/source/blender/blenkernel/BKE_blendfile.h
+++ b/source/blender/blenkernel/BKE_blendfile.h
@@ -62,6 +62,8 @@ struct UserDef *BKE_blendfile_userdef_read_from_memory(const void *filebuf,
bool BKE_blendfile_userdef_write(const char *filepath, struct ReportList *reports);
bool BKE_blendfile_userdef_write_app_template(const char *filepath, struct ReportList *reports);
+bool BKE_blendfile_userdef_write_all(struct ReportList *reports);
+
struct WorkspaceConfigFileData *BKE_blendfile_workspace_config_read(const char *filepath,
const void *filebuf,
int filelength,
diff --git a/source/blender/blenkernel/BKE_collection.h b/source/blender/blenkernel/BKE_collection.h
index 47786629aed..0e093bb086b 100644
--- a/source/blender/blenkernel/BKE_collection.h
+++ b/source/blender/blenkernel/BKE_collection.h
@@ -161,6 +161,8 @@ bool BKE_collection_move(struct Main *bmain,
bool BKE_collection_find_cycle(struct Collection *new_ancestor, struct Collection *collection);
+bool BKE_collection_has_collection(struct Collection *parent, struct Collection *collection);
+
/* Iteration callbacks. */
typedef void (*BKE_scene_objects_Cb)(struct Object *ob, void *data);
diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h
index 4eaa0fbe057..4356d39be36 100644
--- a/source/blender/blenkernel/BKE_curve.h
+++ b/source/blender/blenkernel/BKE_curve.h
@@ -134,10 +134,6 @@ void BKE_curve_editNurb_keyIndex_free(struct GHash **keyindex);
void BKE_curve_editNurb_free(struct Curve *cu);
struct ListBase *BKE_curve_editNurbs_get(struct Curve *cu);
-float *BKE_curve_make_orco(struct Depsgraph *depsgraph,
- struct Scene *scene,
- struct Object *ob,
- int *r_numVerts);
float *BKE_curve_surf_make_orco(struct Object *ob);
void BKE_curve_bevelList_free(struct ListBase *bev);
@@ -147,7 +143,6 @@ void BKE_curve_bevel_make(struct Depsgraph *depsgraph,
struct Object *ob,
struct ListBase *disp,
const bool for_render,
- const bool use_render_resolution,
struct LinkNode *ob_cyclic_list);
void BKE_curve_forward_diff_bezier(
@@ -212,9 +207,9 @@ void BKE_nurb_knot_calc_u(struct Nurb *nu);
void BKE_nurb_knot_calc_v(struct Nurb *nu);
/* nurb checks if they can be drawn, also clamp order func */
-bool BKE_nurb_check_valid_u(struct Nurb *nu);
-bool BKE_nurb_check_valid_v(struct Nurb *nu);
-bool BKE_nurb_check_valid_uv(struct Nurb *nu);
+bool BKE_nurb_check_valid_u(const struct Nurb *nu);
+bool BKE_nurb_check_valid_v(const struct Nurb *nu);
+bool BKE_nurb_check_valid_uv(const struct Nurb *nu);
bool BKE_nurb_order_clamp_u(struct Nurb *nu);
bool BKE_nurb_order_clamp_v(struct Nurb *nu);
diff --git a/source/blender/blenkernel/BKE_displist.h b/source/blender/blenkernel/BKE_displist.h
index 9bf5a2f9971..db57df42d02 100644
--- a/source/blender/blenkernel/BKE_displist.h
+++ b/source/blender/blenkernel/BKE_displist.h
@@ -85,8 +85,7 @@ void BKE_displist_make_surf(struct Depsgraph *depsgraph,
struct ListBase *dispbase,
struct Mesh **r_final,
const bool for_render,
- const bool for_orco,
- const bool use_render_resolution);
+ const bool for_orco);
void BKE_displist_make_curveTypes(struct Depsgraph *depsgraph,
struct Scene *scene,
struct Object *ob,
@@ -99,13 +98,7 @@ void BKE_displist_make_curveTypes_forRender(struct Depsgraph *depsgraph,
struct ListBase *dispbase,
struct Mesh **r_final,
const bool for_orco,
- const bool use_render_resolution,
struct LinkNode *ob_cyclic_list);
-void BKE_displist_make_curveTypes_forOrco(struct Depsgraph *depsgraph,
- struct Scene *scene,
- struct Object *ob,
- struct ListBase *dispbase,
- struct LinkNode *ob_cyclic_list);
void BKE_displist_make_mball(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob);
void BKE_displist_make_mball_forRender(struct Depsgraph *depsgraph,
struct Scene *scene,
diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h
index 2c19c1e2006..387e7f2182b 100644
--- a/source/blender/blenkernel/BKE_global.h
+++ b/source/blender/blenkernel/BKE_global.h
@@ -111,6 +111,7 @@ enum {
G_FLAG_PICKSEL = (1 << 2),
/** Support simulating events (for testing). */
G_FLAG_EVENT_SIMULATE = (1 << 3),
+ G_FLAG_USERPREF_NO_SAVE_ON_EXIT = (1 << 4),
G_FLAG_SCRIPT_AUTOEXEC = (1 << 13),
/** When this flag is set ignore the prefs #USER_SCRIPT_AUTOEXEC_DISABLE. */
@@ -121,7 +122,8 @@ enum {
/** Don't overwrite these flags when reading a file. */
#define G_FLAG_ALL_RUNTIME \
- (G_FLAG_SCRIPT_AUTOEXEC | G_FLAG_SCRIPT_OVERRIDE_PREF | G_FLAG_EVENT_SIMULATE)
+ (G_FLAG_SCRIPT_AUTOEXEC | G_FLAG_SCRIPT_OVERRIDE_PREF | G_FLAG_EVENT_SIMULATE | \
+ G_FLAG_USERPREF_NO_SAVE_ON_EXIT)
/** Flags to read from blend file. */
#define G_FLAG_ALL_READFILE 0
diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h
index 28886a5a195..d5304ec5434 100644
--- a/source/blender/blenkernel/BKE_image.h
+++ b/source/blender/blenkernel/BKE_image.h
@@ -340,12 +340,15 @@ void BKE_image_buf_fill_checker_color(unsigned char *rect,
unsigned char *BKE_image_get_pixels_for_frame(struct Image *image, int frame);
float *BKE_image_get_float_pixels_for_frame(struct Image *image, int frame);
+/* Image modifications */
+bool BKE_image_is_dirty(struct Image *image);
+void BKE_image_mark_dirty(struct Image *image, struct ImBuf *ibuf);
+
/* Guess offset for the first frame in the sequence */
int BKE_image_sequence_guess_offset(struct Image *image);
bool BKE_image_has_anim(struct Image *image);
bool BKE_image_has_packedfile(struct Image *image);
bool BKE_image_is_animated(struct Image *image);
-bool BKE_image_is_dirty(struct Image *image);
void BKE_image_file_format_set(struct Image *image,
int ftype,
const struct ImbFormatOptions *options);
diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h
index 9d8b9218a79..37c502b3b0c 100644
--- a/source/blender/blenkernel/BKE_material.h
+++ b/source/blender/blenkernel/BKE_material.h
@@ -113,7 +113,7 @@ void free_matcopybuf(void);
void copy_matcopybuf(struct Main *bmain, struct Material *ma);
void paste_matcopybuf(struct Main *bmain, struct Material *ma);
-/* Dependency graph evaluation. */
+/* Evaluation. */
struct Depsgraph;
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index ecee00b1b3f..b094dc5f400 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -671,11 +671,9 @@ void BKE_mesh_eval_geometry(struct Depsgraph *depsgraph, struct Mesh *mesh);
/* Draw Cache */
enum {
BKE_MESH_BATCH_DIRTY_ALL = 0,
- BKE_MESH_BATCH_DIRTY_MAYBE_ALL,
BKE_MESH_BATCH_DIRTY_SELECT,
BKE_MESH_BATCH_DIRTY_SELECT_PAINT,
BKE_MESH_BATCH_DIRTY_SHADING,
- BKE_MESH_BATCH_DIRTY_SCULPT_COORDS,
BKE_MESH_BATCH_DIRTY_UVEDIT_ALL,
BKE_MESH_BATCH_DIRTY_UVEDIT_SELECT,
};
diff --git a/source/blender/blenkernel/BKE_movieclip.h b/source/blender/blenkernel/BKE_movieclip.h
index 9425f396bc5..43ee284a201 100644
--- a/source/blender/blenkernel/BKE_movieclip.h
+++ b/source/blender/blenkernel/BKE_movieclip.h
@@ -116,8 +116,7 @@ bool BKE_movieclip_put_frame_if_possible(struct MovieClip *clip,
struct MovieClipUser *user,
struct ImBuf *ibuf);
-/* Dependency graph evaluation. */
-
+/* Evaluation. */
void BKE_movieclip_eval_update(struct Depsgraph *depsgraph, struct MovieClip *clip);
void BKE_movieclip_eval_selection_update(struct Depsgraph *depsgraph, struct MovieClip *clip);
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index 49b35bfccc1..c373fbfe478 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -100,6 +100,8 @@ bool BKE_object_is_mode_compat(const struct Object *ob, eObjectMode object_mode)
bool BKE_object_data_is_in_editmode(const struct ID *id);
+void BKE_object_update_select_id(struct Main *bmain);
+
typedef enum eObjectVisibilityResult {
OB_VISIBLE_SELF = 1,
OB_VISIBLE_PARTICLES = 2,
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index 9b15462de6b..315c0224b11 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -34,13 +34,13 @@ struct CCGKey;
struct CustomData;
struct DMFlagMat;
struct GPUBatch;
+struct GPU_PBVH_Buffers;
struct MLoop;
struct MLoopTri;
struct MPoly;
struct MVert;
struct PBVH;
struct PBVHNode;
-struct GPU_PBVH_Buffers;
typedef struct PBVH PBVH;
typedef struct PBVHNode PBVHNode;
diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h
index 3b5db883cf3..75ff5eace3c 100644
--- a/source/blender/blenkernel/BKE_scene.h
+++ b/source/blender/blenkernel/BKE_scene.h
@@ -240,14 +240,6 @@ void BKE_scene_cursor_quat_to_rot(struct View3DCursor *cursor,
const float quat[4],
bool use_compat);
-/* Dependency graph evaluation. */
-
-/* Evaluate parts of sequences which needs to be done as a part of a dependency graph evaluation.
- * This does NOT include actual rendering of the strips, but rather makes them up-to-date for
- * animation playback and makes them ready for the sequencer's rendering pipeline to render them.
- */
-void BKE_scene_eval_sequencer_sequences(struct Depsgraph *depsgraph, struct Scene *scene);
-
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/BKE_sound.h b/source/blender/blenkernel/BKE_sound.h
index f526dd579ce..91e23d35f0e 100644
--- a/source/blender/blenkernel/BKE_sound.h
+++ b/source/blender/blenkernel/BKE_sound.h
@@ -32,7 +32,6 @@
struct Main;
struct Sequence;
struct bSound;
-struct Depsgraph;
typedef struct SoundWaveform {
int length;
@@ -72,17 +71,10 @@ void BKE_sound_cache(struct bSound *sound);
void BKE_sound_delete_cache(struct bSound *sound);
-void BKE_sound_reset_runtime(struct bSound *sound);
void BKE_sound_load(struct Main *main, struct bSound *sound);
-void BKE_sound_ensure_loaded(struct Main *bmain, struct bSound *sound);
void BKE_sound_free(struct bSound *sound);
-/* Is used by sequencer to temporarily load audio to access information about channels and
- * duration. */
-void BKE_sound_load_audio(struct Main *main, struct bSound *sound);
-void BKE_sound_free_audio(struct bSound *sound);
-
void BKE_sound_copy_data(struct Main *bmain,
struct bSound *sound_dst,
const struct bSound *sound_src,
@@ -94,9 +86,7 @@ void BKE_sound_make_local(struct Main *bmain, struct bSound *sound, const bool l
AUD_Device *BKE_sound_mixdown(struct Scene *scene, AUD_DeviceSpecs specs, int start, float volume);
#endif
-void BKE_sound_reset_scene_runtime(struct Scene *scene);
void BKE_sound_create_scene(struct Scene *scene);
-void BKE_sound_ensure_scene(struct Scene *scene);
void BKE_sound_destroy_scene(struct Scene *scene);
@@ -144,10 +134,6 @@ void BKE_sound_stop_scene(struct Scene *scene);
void BKE_sound_seek_scene(struct Main *bmain, struct Scene *scene);
-/* Use this after original scene's frame has been changed. It will take care of doing all the
- * updates required for BKE_sound_seek_scene(). */
-void BKE_sound_update_and_seek(struct Main *bmain, struct Depsgraph *depsgraph);
-
float BKE_sound_sync_scene(struct Scene *scene);
int BKE_sound_scene_playing(struct Scene *scene);
@@ -164,15 +150,4 @@ float BKE_sound_get_length(struct bSound *sound);
char **BKE_sound_get_device_names(void);
-typedef void (*SoundJackSyncCallback)(struct Main *bmain, int mode, float time);
-
-void BKE_sound_jack_sync_callback_set(SoundJackSyncCallback callback);
-void BKE_sound_jack_scene_update(struct Scene *scene, int mode, float time);
-
-/* Dependency graph evaluation. */
-
-struct Depsgraph;
-
-void BKE_sound_evaluate(struct Depsgraph *depsgraph, struct Main *bmain, struct bSound *sound);
-
#endif /* __BKE_SOUND_H__ */
diff --git a/source/blender/blenkernel/BKE_workspace.h b/source/blender/blenkernel/BKE_workspace.h
index 0a4ad4cd994..133cf2d6cf5 100644
--- a/source/blender/blenkernel/BKE_workspace.h
+++ b/source/blender/blenkernel/BKE_workspace.h
@@ -110,6 +110,8 @@ void BKE_workspace_hook_layout_for_workspace_set(struct WorkSpaceInstanceHook *h
bool BKE_workspace_owner_id_check(const struct WorkSpace *workspace, const char *owner_id)
ATTR_NONNULL();
+void BKE_workspace_id_tag_all_visible(struct Main *bmain, int tag) ATTR_NONNULL();
+
#undef GETTER_ATTRS
#undef SETTER_ATTRS
diff --git a/source/blender/blenkernel/BKE_writeavi.h b/source/blender/blenkernel/BKE_writeavi.h
index 72817217a0a..3212bad75cb 100644
--- a/source/blender/blenkernel/BKE_writeavi.h
+++ b/source/blender/blenkernel/BKE_writeavi.h
@@ -53,9 +53,6 @@ typedef struct bMovieHandle {
const char *suffix,
struct ReportList *reports);
void (*end_movie)(void *context_v);
- int (*get_next_frame)(void *context_v,
- struct RenderData *rd,
- struct ReportList *reports); /* optional */
void (*get_movie_path)(char *string,
struct RenderData *rd,
bool preview,
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index 9b321ff4e44..34c50865073 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -978,6 +978,7 @@ void BKE_pose_channel_copy_data(bPoseChannel *pchan, const bPoseChannel *pchan_f
}
pchan->custom_scale = pchan_from->custom_scale;
+ pchan->drawflag = pchan_from->drawflag;
}
/* checks for IK constraint, Spline IK, and also for Follow-Path constraint.
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index cc5cd3b03ae..663eb4027f6 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -1893,6 +1893,10 @@ static void animsys_evaluate_fcurves(Depsgraph *depsgraph,
if ((fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED))) {
continue;
}
+ /* Skip empty curves, as if muted. */
+ if (fcu->totvert == 0) {
+ continue;
+ }
PathResolvedRNA anim_rna;
if (animsys_store_rna_setting(ptr, fcu->rna_path, fcu->array_index, &anim_rna)) {
const float curval = calculate_fcurve(&anim_rna, fcu, ctime);
@@ -2005,7 +2009,7 @@ void animsys_evaluate_action_group(PointerRNA *ptr, bAction *act, bActionGroup *
/* calculate then execute each curve */
for (fcu = agrp->channels.first; (fcu) && (fcu->grp == agrp); fcu = fcu->next) {
/* check if this curve should be skipped */
- if ((fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED)) == 0) {
+ if ((fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED)) == 0 && fcu->totvert != 0) {
PathResolvedRNA anim_rna;
if (animsys_store_rna_setting(ptr, fcu->rna_path, fcu->array_index, &anim_rna)) {
const float curval = calculate_fcurve(&anim_rna, fcu, ctime);
@@ -3101,6 +3105,9 @@ static void nlastrip_evaluate_actionclip(PointerRNA *ptr,
if ((fcu->grp) && (fcu->grp->flag & AGRP_MUTED)) {
continue;
}
+ if (fcu->totvert == 0) {
+ continue;
+ }
/* evaluate the F-Curve's value for the time given in the strip
* NOTE: we use the modified time here, since strip's F-Curve Modifiers
@@ -3327,6 +3334,9 @@ static void nla_eval_domain_action(PointerRNA *ptr,
if ((fcu->grp) && (fcu->grp->flag & AGRP_MUTED)) {
continue;
}
+ if (fcu->totvert == 0) {
+ continue;
+ }
NlaEvalChannel *nec = nlaevalchan_verify(ptr, channels, fcu->rna_path);
diff --git a/source/blender/blenkernel/intern/appdir.c b/source/blender/blenkernel/intern/appdir.c
index 2b4123c74e2..c1ea57c5fcc 100644
--- a/source/blender/blenkernel/intern/appdir.c
+++ b/source/blender/blenkernel/intern/appdir.c
@@ -838,6 +838,26 @@ bool BKE_appdir_app_template_id_search(const char *app_template, char *path, siz
return false;
}
+bool BKE_appdir_app_template_has_userpref(const char *app_template)
+{
+ /* Test if app template provides a userpref.blend.
+ * If not, we will share user preferences with the rest of Blender. */
+ if (!app_template && app_template[0]) {
+ return false;
+ }
+
+ char app_template_path[FILE_MAX];
+ if (!BKE_appdir_app_template_id_search(
+ app_template, app_template_path, sizeof(app_template_path))) {
+ return false;
+ }
+
+ char userpref_path[FILE_MAX];
+ BLI_path_join(
+ userpref_path, sizeof(userpref_path), app_template_path, BLENDER_USERPREF_FILE, NULL);
+ return BLI_exists(userpref_path);
+}
+
void BKE_appdir_app_templates(ListBase *templates)
{
BLI_listbase_clear(templates);
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 60446bf60b6..bd9907acb24 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -125,6 +125,7 @@ void BKE_armature_free(bArmature *arm)
{
BKE_animdata_free(&arm->id, false);
+ BKE_armature_bone_hash_free(arm);
BKE_armature_bonelist_free(&arm->bonebase);
/* free editmode data */
@@ -169,25 +170,20 @@ static void copy_bonechildren(Bone *bone_dst,
}
}
-static void copy_bonechildren_custom_handles(Bone *bone_dst, bArmature *arm_dst, GHash **bone_hash)
+static void copy_bonechildren_custom_handles(Bone *bone_dst, bArmature *arm_dst)
{
Bone *bone_dst_child;
- /* Lazily create the name -> bone hashtable. */
- if ((bone_dst->bbone_prev || bone_dst->bbone_next) && *bone_hash == NULL) {
- *bone_hash = BKE_armature_bone_from_name_map(arm_dst);
- }
-
if (bone_dst->bbone_prev) {
- bone_dst->bbone_prev = BLI_ghash_lookup(*bone_hash, bone_dst->bbone_prev->name);
+ bone_dst->bbone_prev = BKE_armature_find_bone_name(arm_dst, bone_dst->bbone_prev->name);
}
if (bone_dst->bbone_next) {
- bone_dst->bbone_next = BLI_ghash_lookup(*bone_hash, bone_dst->bbone_next->name);
+ bone_dst->bbone_next = BKE_armature_find_bone_name(arm_dst, bone_dst->bbone_next->name);
}
for (bone_dst_child = bone_dst->childbase.first; bone_dst_child;
bone_dst_child = bone_dst_child->next) {
- copy_bonechildren_custom_handles(bone_dst_child, arm_dst, bone_hash);
+ copy_bonechildren_custom_handles(bone_dst_child, arm_dst);
}
}
@@ -212,6 +208,8 @@ void BKE_armature_copy_data(Main *UNUSED(bmain),
/* We never handle usercount here for own data. */
const int flag_subdata = flag | LIB_ID_CREATE_NO_USER_REFCOUNT;
+ arm_dst->bonehash = NULL;
+
BLI_duplicatelist(&arm_dst->bonebase, &arm_src->bonebase);
/* Duplicate the childrens' lists */
@@ -224,15 +222,11 @@ void BKE_armature_copy_data(Main *UNUSED(bmain),
arm_dst->act_bone = bone_dst_act;
- /* Fix custom handle references. */
- GHash *bone_hash = NULL; /* lazily created */
+ BKE_armature_bone_hash_make(arm_dst);
+ /* Fix custom handle references. */
for (bone_dst = arm_dst->bonebase.first; bone_dst; bone_dst = bone_dst->next) {
- copy_bonechildren_custom_handles(bone_dst, arm_dst, &bone_hash);
- }
-
- if (bone_hash) {
- BLI_ghash_free(bone_hash, NULL, NULL);
+ copy_bonechildren_custom_handles(bone_dst, arm_dst);
}
arm_dst->edbo = NULL;
@@ -274,6 +268,10 @@ Bone *BKE_armature_find_bone_name(bArmature *arm, const char *name)
return NULL;
}
+ if (arm->bonehash) {
+ return BLI_ghash_lookup(arm->bonehash, name);
+ }
+
return get_named_bone_bonechildren(&arm->bonebase, name);
}
@@ -291,7 +289,7 @@ static void armature_bone_from_name_insert_recursive(GHash *bone_hash, ListBase
* \note typically #bPose.chanhash us used via #BKE_pose_channel_find_name
* this is for the cases we can't use pose channels.
*/
-GHash *BKE_armature_bone_from_name_map(bArmature *arm)
+static GHash *armature_bone_from_name_map(bArmature *arm)
{
const int bones_count = BKE_armature_bonelist_count(&arm->bonebase);
GHash *bone_hash = BLI_ghash_str_new_ex(__func__, bones_count);
@@ -299,6 +297,21 @@ GHash *BKE_armature_bone_from_name_map(bArmature *arm)
return bone_hash;
}
+void BKE_armature_bone_hash_make(bArmature *arm)
+{
+ if (!arm->bonehash) {
+ arm->bonehash = armature_bone_from_name_map(arm);
+ }
+}
+
+void BKE_armature_bone_hash_free(bArmature *arm)
+{
+ if (arm->bonehash) {
+ BLI_ghash_free(arm->bonehash, NULL, NULL);
+ arm->bonehash = NULL;
+ }
+}
+
bool BKE_armature_bone_flag_test_recursive(const Bone *bone, int flag)
{
if (bone->flag & flag) {
@@ -2458,11 +2471,9 @@ void BKE_pose_clear_pointers(bPose *pose)
void BKE_pose_remap_bone_pointers(bArmature *armature, bPose *pose)
{
- GHash *bone_hash = BKE_armature_bone_from_name_map(armature);
for (bPoseChannel *pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
- pchan->bone = BLI_ghash_lookup(bone_hash, pchan->name);
+ pchan->bone = BKE_armature_find_bone_name(armature, pchan->name);
}
- BLI_ghash_free(bone_hash, NULL, NULL);
}
/** Find the matching pose channel using the bone name, if not NULL. */
diff --git a/source/blender/blenkernel/intern/armature_update.c b/source/blender/blenkernel/intern/armature_update.c
index c71c2dc86cf..bf7d81e5d63 100644
--- a/source/blender/blenkernel/intern/armature_update.c
+++ b/source/blender/blenkernel/intern/armature_update.c
@@ -273,11 +273,12 @@ static void splineik_evaluate_bone(
/* first, adjust the point positions on the curve */
float curveLen = tree->points[index] - tree->points[index + 1];
float pointStart = state->curve_position;
+ float poseScale = len_v3v3(poseHead, poseTail) / pchan->bone->length;
float baseScale = 1.0f;
if (ikData->yScaleMode == CONSTRAINT_SPLINEIK_YS_ORIGINAL) {
/* Carry over the bone Y scale to the curve range. */
- baseScale = len_v3v3(poseHead, poseTail) / pchan->bone->length;
+ baseScale = poseScale;
}
float pointEnd = pointStart + curveLen * baseScale * state->curve_scale;
@@ -339,8 +340,8 @@ static void splineik_evaluate_bone(
sub_v3_v3v3(splineVec, poseTail, poseHead);
scaleFac = len_v3(splineVec) / pchan->bone->length;
- /* Adjust the scale factor towards the neutral state when rolling off the curve end. */
- scaleFac = interpf(scaleFac, baseScale, tailBlendFac);
+ /* Extrapolate the full length of the bone as it rolls off the end of the curve. */
+ scaleFac = (tailBlendFac < 1e-5f) ? baseScale : scaleFac / tailBlendFac;
/* Step 3: compute the shortest rotation needed
* to map from the bone rotation to the current axis.
@@ -394,24 +395,31 @@ static void splineik_evaluate_bone(
}
/* step 4: set the scaling factors for the axes */
- {
- /* only multiply the y-axis by the scaling factor to get nice volume-preservation */
- mul_v3_fl(poseMat[1], scaleFac);
- /* set the scaling factors of the x and z axes from... */
- switch (ikData->xzScaleMode) {
- case CONSTRAINT_SPLINEIK_XZS_ORIGINAL: {
- /* original scales get used */
- float scale;
+ /* Always multiply the y-axis by the scaling factor to get the correct length. */
+ mul_v3_fl(poseMat[1], scaleFac);
+
+ /* After that, apply x/z scaling modes. */
+ if (ikData->xzScaleMode != CONSTRAINT_SPLINEIK_XZS_NONE) {
+ /* First, apply the original scale if enabled. */
+ if (ikData->xzScaleMode == CONSTRAINT_SPLINEIK_XZS_ORIGINAL ||
+ (ikData->flag & CONSTRAINT_SPLINEIK_USE_ORIGINAL_SCALE) != 0) {
+ float scale;
+
+ /* x-axis scale */
+ scale = len_v3(pchan->pose_mat[0]);
+ mul_v3_fl(poseMat[0], scale);
+ /* z-axis scale */
+ scale = len_v3(pchan->pose_mat[2]);
+ mul_v3_fl(poseMat[2], scale);
+
+ /* Adjust the scale factor used for volume preservation
+ * to consider the pre-IK scaling as the initial volume. */
+ scaleFac /= poseScale;
+ }
- /* x-axis scale */
- scale = len_v3(pchan->pose_mat[0]);
- mul_v3_fl(poseMat[0], scale);
- /* z-axis scale */
- scale = len_v3(pchan->pose_mat[2]);
- mul_v3_fl(poseMat[2], scale);
- break;
- }
+ /* Apply volume preservation. */
+ switch (ikData->xzScaleMode) {
case CONSTRAINT_SPLINEIK_XZS_INVERSE: {
/* old 'volume preservation' method using the inverse scale */
float scale;
@@ -483,14 +491,14 @@ static void splineik_evaluate_bone(
break;
}
}
+ }
- /* finally, multiply the x and z scaling by the radius of the curve too,
- * to allow automatic scales to get tweaked still
- */
- if ((ikData->flag & CONSTRAINT_SPLINEIK_NO_CURVERAD) == 0) {
- mul_v3_fl(poseMat[0], radius);
- mul_v3_fl(poseMat[2], radius);
- }
+ /* Finally, multiply the x and z scaling by the radius of the curve too,
+ * to allow automatic scales to get tweaked still.
+ */
+ if ((ikData->flag & CONSTRAINT_SPLINEIK_NO_CURVERAD) == 0) {
+ mul_v3_fl(poseMat[0], radius);
+ mul_v3_fl(poseMat[2], radius);
}
/* Blend the scaling of the matrix according to the influence. */
diff --git a/source/blender/blenkernel/intern/blendfile.c b/source/blender/blenkernel/intern/blendfile.c
index d1a3045a829..570c1b9bd4c 100644
--- a/source/blender/blenkernel/intern/blendfile.c
+++ b/source/blender/blenkernel/intern/blendfile.c
@@ -98,6 +98,25 @@ static bool wm_scene_is_visible(wmWindowManager *wm, Scene *scene)
return false;
}
+static void setup_app_userdef(BlendFileData *bfd)
+{
+ if (bfd->user) {
+ /* only here free userdef themes... */
+ BKE_blender_userdef_data_set_and_free(bfd->user);
+ bfd->user = NULL;
+
+ /* Security issue: any blend file could include a USER block.
+ *
+ * Currently we load prefs from BLENDER_STARTUP_FILE and later on load BLENDER_USERPREF_FILE,
+ * to load the preferences defined in the users home dir.
+ *
+ * This means we will never accidentally (or maliciously)
+ * enable scripts auto-execution by loading a '.blend' file.
+ */
+ U.flag |= USER_SCRIPT_AUTOEXEC_DISABLE;
+ }
+}
+
/**
* Context matching, handle no-ui case
*
@@ -235,26 +254,10 @@ static void setup_app_data(bContext *C,
RNA_property_update_cache_free();
bmain = G_MAIN = bfd->main;
+ bfd->main = NULL;
CTX_data_main_set(C, bmain);
- if (bfd->user) {
-
- /* only here free userdef themes... */
- BKE_blender_userdef_data_set_and_free(bfd->user);
- bfd->user = NULL;
-
- /* Security issue: any blend file could include a USER block.
- *
- * Currently we load prefs from BLENDER_STARTUP_FILE and later on load BLENDER_USERPREF_FILE,
- * to load the preferences defined in the users home dir.
- *
- * This means we will never accidentally (or maliciously)
- * enable scripts auto-execution by loading a '.blend' file.
- */
- U.flag |= USER_SCRIPT_AUTOEXEC_DISABLE;
- }
-
/* case G_FILE_NO_UI or no screens in file */
if (mode != LOAD_UI) {
/* leave entire context further unaltered? */
@@ -356,8 +359,20 @@ static void setup_app_data(bContext *C,
/* TODO(sergey): Can this be also move above? */
RE_FreeAllPersistentData();
}
+}
- MEM_freeN(bfd);
+static void setup_app_blend_file_data(bContext *C,
+ BlendFileData *bfd,
+ const char *filepath,
+ const struct BlendFileReadParams *params,
+ ReportList *reports)
+{
+ if ((params->skip_flags & BLO_READ_SKIP_USERDEF) == 0) {
+ setup_app_userdef(bfd);
+ }
+ if ((params->skip_flags & BLO_READ_SKIP_DATA) == 0) {
+ setup_app_data(C, bfd, filepath, params->is_startup, reports);
+ }
}
static int handle_subversion_warning(Main *main, ReportList *reports)
@@ -400,7 +415,8 @@ int BKE_blendfile_read(bContext *C,
retval = BKE_BLENDFILE_READ_FAIL;
}
else {
- setup_app_data(C, bfd, filepath, params->is_startup, reports);
+ setup_app_blend_file_data(C, bfd, filepath, params, reports);
+ BLO_blendfiledata_free(bfd);
}
}
else {
@@ -422,9 +438,13 @@ bool BKE_blendfile_read_from_memory(bContext *C,
bfd = BLO_read_from_memory(filebuf, filelength, params->skip_flags, reports);
if (bfd) {
if (update_defaults) {
- BLO_update_defaults_startup_blend(bfd->main, NULL);
+ if ((params->skip_flags & BLO_READ_SKIP_DATA) == 0) {
+ BLO_update_defaults_startup_blend(bfd->main, NULL);
+ }
}
- setup_app_data(C, bfd, "<memory2>", params->is_startup, reports);
+
+ setup_app_blend_file_data(C, bfd, "<memory2>", params, reports);
+ BLO_blendfiledata_free(bfd);
}
else {
BKE_reports_prepend(reports, "Loading failed: ");
@@ -453,7 +473,8 @@ bool BKE_blendfile_read_from_memfile(bContext *C,
BKE_id_free(bfd->main, bfd->main->screens.first);
}
- setup_app_data(C, bfd, "<memory1>", params->is_startup, reports);
+ setup_app_blend_file_data(C, bfd, "<memory1>", params, reports);
+ BLO_blendfiledata_free(bfd);
}
else {
BKE_reports_prepend(reports, "Loading failed: ");
@@ -566,6 +587,63 @@ bool BKE_blendfile_userdef_write_app_template(const char *filepath, ReportList *
return ok;
}
+bool BKE_blendfile_userdef_write_all(ReportList *reports)
+{
+ char filepath[FILE_MAX];
+ const char *cfgdir;
+ bool ok = true;
+ const bool use_template_userpref = BKE_appdir_app_template_has_userpref(U.app_template);
+
+ if ((cfgdir = BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL))) {
+ bool ok_write;
+ BLI_path_join(filepath, sizeof(filepath), cfgdir, BLENDER_USERPREF_FILE, NULL);
+
+ printf("Writing userprefs: '%s' ", filepath);
+ if (use_template_userpref) {
+ ok_write = BKE_blendfile_userdef_write_app_template(filepath, reports);
+ }
+ else {
+ ok_write = BKE_blendfile_userdef_write(filepath, reports);
+ }
+
+ if (ok_write) {
+ printf("ok\n");
+ }
+ else {
+ printf("fail\n");
+ ok = false;
+ }
+ }
+ else {
+ BKE_report(reports, RPT_ERROR, "Unable to create userpref path");
+ }
+
+ if (use_template_userpref) {
+ if ((cfgdir = BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, U.app_template))) {
+ /* Also save app-template prefs */
+ BLI_path_join(filepath, sizeof(filepath), cfgdir, BLENDER_USERPREF_FILE, NULL);
+
+ printf("Writing userprefs app-template: '%s' ", filepath);
+ if (BKE_blendfile_userdef_write(filepath, reports) != 0) {
+ printf("ok\n");
+ }
+ else {
+ printf("fail\n");
+ ok = false;
+ }
+ }
+ else {
+ BKE_report(reports, RPT_ERROR, "Unable to create app-template userpref path");
+ ok = false;
+ }
+ }
+
+ if (ok) {
+ U.runtime.is_dirty = false;
+ }
+ return ok;
+}
+
WorkspaceConfigFileData *BKE_blendfile_workspace_config_read(const char *filepath,
const void *filebuf,
int filelength,
diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c
index d33d4e344b5..87f448d8d57 100644
--- a/source/blender/blenkernel/intern/collection.c
+++ b/source/blender/blenkernel/intern/collection.c
@@ -434,8 +434,8 @@ static void collection_object_cache_fill(ListBase *lb, Collection *collection, i
int object_restrict = base->object->restrictflag;
- if (((child_restrict & COLLECTION_RESTRICT_VIEW) == 0) &&
- ((object_restrict & OB_RESTRICT_VIEW) == 0)) {
+ if (((child_restrict & COLLECTION_RESTRICT_VIEWPORT) == 0) &&
+ ((object_restrict & OB_RESTRICT_VIEWPORT) == 0)) {
base->flag |= BASE_ENABLED_VIEWPORT;
}
@@ -966,6 +966,11 @@ static bool collection_find_child_recursive(Collection *parent, Collection *coll
return false;
}
+bool BKE_collection_has_collection(Collection *parent, Collection *collection)
+{
+ return collection_find_child_recursive(parent, collection);
+}
+
static CollectionParent *collection_find_parent(Collection *child, Collection *collection)
{
return BLI_findptr(&child->parents, collection, offsetof(CollectionParent, collection));
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 0e29f165992..c680e15763d 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -1882,6 +1882,7 @@ static void sizelike_new_data(void *cdata)
bSizeLikeConstraint *data = (bSizeLikeConstraint *)cdata;
data->flag = SIZELIKE_X | SIZELIKE_Y | SIZELIKE_Z | SIZELIKE_MULTIPLY;
+ data->power = 1.0f;
}
static void sizelike_id_looper(bConstraint *con, ConstraintIDFunc func, void *userdata)
@@ -1929,6 +1930,10 @@ static void sizelike_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *ta
mat4_to_size(size, ct->matrix);
mat4_to_size(obsize, cob->matrix);
+ for (int i = 0; i < 3; i++) {
+ size[i] = powf(size[i], data->power);
+ }
+
if (data->flag & SIZELIKE_OFFSET) {
/* Scale is a multiplicative quantity, so adding it makes no sense.
* However, the additive mode has to stay for backward compatibility. */
@@ -2037,7 +2042,7 @@ static void samevolume_new_data(void *cdata)
{
bSameVolumeConstraint *data = (bSameVolumeConstraint *)cdata;
- data->flag = SAMEVOL_Y;
+ data->free_axis = SAMEVOL_Y;
data->volume = 1.0f;
}
@@ -2046,19 +2051,30 @@ static void samevolume_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *
bSameVolumeConstraint *data = con->data;
float volume = data->volume;
- float fac = 1.0f, total_scale;
+ float fac = 1.0f, total_scale = 1.0f;
float obsize[3];
mat4_to_size(obsize, cob->matrix);
/* calculate normalizing scale factor for non-essential values */
- total_scale = obsize[0] * obsize[1] * obsize[2];
+ switch (data->mode) {
+ case SAMEVOL_STRICT:
+ total_scale = obsize[0] * obsize[1] * obsize[2];
+ break;
+ case SAMEVOL_UNIFORM:
+ total_scale = pow3f(obsize[data->free_axis]);
+ break;
+ case SAMEVOL_SINGLE_AXIS:
+ total_scale = obsize[data->free_axis];
+ break;
+ }
+
if (total_scale != 0) {
fac = sqrtf(volume / total_scale);
}
/* apply scaling factor to the channels not being kept */
- switch (data->flag) {
+ switch (data->free_axis) {
case SAMEVOL_X:
mul_v3_fl(cob->matrix[1], fac);
mul_v3_fl(cob->matrix[2], fac);
@@ -2406,7 +2422,8 @@ static void armdef_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *targ
copy_v3_v3(input_co, cob->matrix[3]);
}
- /* Process all targets. */
+ /* Process all targets. This can't use ct->matrix, as armdef_get_tarmat is not
+ * called in solve for efficiency because the constraint needs bone data anyway. */
for (bConstraintTarget *ct = targets->first; ct; ct = ct->next) {
if (ct->weight <= 0.0f) {
continue;
@@ -4224,6 +4241,7 @@ static void splineik_new_data(void *cdata)
data->bulge_min = 1.0f;
data->yScaleMode = CONSTRAINT_SPLINEIK_YS_FIT_CURVE;
+ data->flag = CONSTRAINT_SPLINEIK_USE_ORIGINAL_SCALE;
}
static void splineik_id_looper(bConstraint *con, ConstraintIDFunc func, void *userdata)
@@ -5600,6 +5618,11 @@ void BKE_constraint_targets_for_solving_get(struct Depsgraph *depsgraph,
*/
cti->get_constraint_targets(con, targets);
+ /* The Armature constraint doesn't need ct->matrix for evaluate at all. */
+ if (ELEM(cti->type, CONSTRAINT_TYPE_ARMATURE)) {
+ return;
+ }
+
/* set matrices
* - calculate if possible, otherwise just initialize as identity matrix
*/
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index dc677449a4c..2775cf9691f 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -1737,232 +1737,6 @@ static void forward_diff_bezier_cotangent(const float p0[3],
}
}
-/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-
-float *BKE_curve_surf_make_orco(Object *ob)
-{
- /* Note: this function is used in convertblender only atm, so
- * suppose nonzero curve's render resolution should always be used */
- Curve *cu = ob->data;
- Nurb *nu;
- int a, b, tot = 0;
- int sizeu, sizev;
- int resolu, resolv;
- float *fp, *coord_array;
-
- /* first calculate the size of the datablock */
- nu = cu->nurb.first;
- while (nu) {
- /* as we want to avoid the seam in a cyclic nurbs
- * texture wrapping, reserve extra orco data space to save these extra needed
- * vertex based UV coordinates for the meridian vertices.
- * Vertices on the 0/2pi boundary are not duplicated inside the displist but later in
- * the renderface/vert construction.
- *
- * See also convertblender.c: init_render_surf()
- */
-
- resolu = cu->resolu_ren ? cu->resolu_ren : nu->resolu;
- resolv = cu->resolv_ren ? cu->resolv_ren : nu->resolv;
-
- sizeu = nu->pntsu * resolu;
- sizev = nu->pntsv * resolv;
- if (nu->flagu & CU_NURB_CYCLIC) {
- sizeu++;
- }
- if (nu->flagv & CU_NURB_CYCLIC) {
- sizev++;
- }
- if (nu->pntsv > 1) {
- tot += sizeu * sizev;
- }
-
- nu = nu->next;
- }
- /* makeNurbfaces wants zeros */
- fp = coord_array = MEM_calloc_arrayN(tot, 3 * sizeof(float), "make_orco");
-
- nu = cu->nurb.first;
- while (nu) {
- resolu = cu->resolu_ren ? cu->resolu_ren : nu->resolu;
- resolv = cu->resolv_ren ? cu->resolv_ren : nu->resolv;
-
- if (nu->pntsv > 1) {
- sizeu = nu->pntsu * resolu;
- sizev = nu->pntsv * resolv;
-
- if (nu->flagu & CU_NURB_CYCLIC) {
- sizeu++;
- }
- if (nu->flagv & CU_NURB_CYCLIC) {
- sizev++;
- }
-
- if (cu->flag & CU_UV_ORCO) {
- for (b = 0; b < sizeu; b++) {
- for (a = 0; a < sizev; a++) {
-
- if (sizev < 2) {
- fp[0] = 0.0f;
- }
- else {
- fp[0] = -1.0f + 2.0f * ((float)a) / (sizev - 1);
- }
-
- if (sizeu < 2) {
- fp[1] = 0.0f;
- }
- else {
- fp[1] = -1.0f + 2.0f * ((float)b) / (sizeu - 1);
- }
-
- fp[2] = 0.0;
-
- fp += 3;
- }
- }
- }
- else {
- int size = (nu->pntsu * resolu) * (nu->pntsv * resolv) * 3 * sizeof(float);
- float *_tdata = MEM_mallocN(size, "temp data");
- float *tdata = _tdata;
-
- BKE_nurb_makeFaces(nu, tdata, 0, resolu, resolv);
-
- for (b = 0; b < sizeu; b++) {
- int use_b = b;
- if (b == sizeu - 1 && (nu->flagu & CU_NURB_CYCLIC)) {
- use_b = false;
- }
-
- for (a = 0; a < sizev; a++) {
- int use_a = a;
- if (a == sizev - 1 && (nu->flagv & CU_NURB_CYCLIC)) {
- use_a = false;
- }
-
- tdata = _tdata + 3 * (use_b * (nu->pntsv * resolv) + use_a);
-
- fp[0] = (tdata[0] - cu->loc[0]) / cu->size[0];
- fp[1] = (tdata[1] - cu->loc[1]) / cu->size[1];
- fp[2] = (tdata[2] - cu->loc[2]) / cu->size[2];
- fp += 3;
- }
- }
-
- MEM_freeN(_tdata);
- }
- }
- nu = nu->next;
- }
-
- return coord_array;
-}
-
-/* NOTE: This routine is tied to the order of vertex
- * built by displist and as passed to the renderer.
- */
-float *BKE_curve_make_orco(Depsgraph *depsgraph, Scene *scene, Object *ob, int *r_numVerts)
-{
- Curve *cu = ob->data;
- DispList *dl;
- int u, v, numVerts;
- float *fp, *coord_array;
- ListBase disp = {NULL, NULL};
-
- BKE_displist_make_curveTypes_forOrco(depsgraph, scene, ob, &disp, NULL);
-
- numVerts = 0;
- for (dl = disp.first; dl; dl = dl->next) {
- if (dl->type == DL_INDEX3) {
- numVerts += dl->nr;
- }
- else if (dl->type == DL_SURF) {
- /* convertblender.c uses the Surface code for creating renderfaces when cyclic U only
- * (closed circle beveling)
- */
- if (dl->flag & DL_CYCL_U) {
- if (dl->flag & DL_CYCL_V) {
- numVerts += (dl->parts + 1) * (dl->nr + 1);
- }
- else {
- numVerts += dl->parts * (dl->nr + 1);
- }
- }
- else if (dl->flag & DL_CYCL_V) {
- numVerts += (dl->parts + 1) * dl->nr;
- }
- else {
- numVerts += dl->parts * dl->nr;
- }
- }
- }
-
- if (r_numVerts) {
- *r_numVerts = numVerts;
- }
-
- fp = coord_array = MEM_malloc_arrayN(numVerts, 3 * sizeof(float), "cu_orco");
- for (dl = disp.first; dl; dl = dl->next) {
- if (dl->type == DL_INDEX3) {
- for (u = 0; u < dl->nr; u++, fp += 3) {
- if (cu->flag & CU_UV_ORCO) {
- fp[0] = 2.0f * u / (dl->nr - 1) - 1.0f;
- fp[1] = 0.0;
- fp[2] = 0.0;
- }
- else {
- copy_v3_v3(fp, &dl->verts[u * 3]);
-
- fp[0] = (fp[0] - cu->loc[0]) / cu->size[0];
- fp[1] = (fp[1] - cu->loc[1]) / cu->size[1];
- fp[2] = (fp[2] - cu->loc[2]) / cu->size[2];
- }
- }
- }
- else if (dl->type == DL_SURF) {
- int sizeu = dl->nr, sizev = dl->parts;
-
- /* exception as handled in convertblender.c too */
- if (dl->flag & DL_CYCL_U) {
- sizeu++;
- if (dl->flag & DL_CYCL_V) {
- sizev++;
- }
- }
- else if (dl->flag & DL_CYCL_V) {
- sizev++;
- }
-
- for (u = 0; u < sizev; u++) {
- for (v = 0; v < sizeu; v++, fp += 3) {
- if (cu->flag & CU_UV_ORCO) {
- fp[0] = 2.0f * u / (sizev - 1) - 1.0f;
- fp[1] = 2.0f * v / (sizeu - 1) - 1.0f;
- fp[2] = 0.0;
- }
- else {
- const float *vert;
- int realv = v % dl->nr;
- int realu = u % dl->parts;
-
- vert = dl->verts + 3 * (dl->nr * realu + realv);
- copy_v3_v3(fp, vert);
-
- fp[0] = (fp[0] - cu->loc[0]) / cu->size[0];
- fp[1] = (fp[1] - cu->loc[1]) / cu->size[1];
- fp[2] = (fp[2] - cu->loc[2]) / cu->size[2];
- }
- }
- }
- }
- }
-
- BKE_displist_free(&disp);
-
- return coord_array;
-}
-
/* ***************** BEVEL ****************** */
void BKE_curve_bevel_make(Depsgraph *depsgraph,
@@ -1970,7 +1744,6 @@ void BKE_curve_bevel_make(Depsgraph *depsgraph,
Object *ob,
ListBase *disp,
const bool for_render,
- const bool use_render_resolution,
LinkNode *ob_cyclic_list)
{
DispList *dl, *dlnew;
@@ -2003,7 +1776,6 @@ void BKE_curve_bevel_make(Depsgraph *depsgraph,
&bevdisp,
NULL,
false,
- use_render_resolution,
&(LinkNode){
.link = ob,
.next = ob_cyclic_list,
@@ -4980,7 +4752,7 @@ void BKE_curve_nurbs_keyVertexTilts_apply(ListBase *lb, float *key)
}
}
-bool BKE_nurb_check_valid_u(struct Nurb *nu)
+bool BKE_nurb_check_valid_u(const Nurb *nu)
{
if (nu->pntsu <= 1) {
return false;
@@ -5007,7 +4779,7 @@ bool BKE_nurb_check_valid_u(struct Nurb *nu)
}
return true;
}
-bool BKE_nurb_check_valid_v(struct Nurb *nu)
+bool BKE_nurb_check_valid_v(const Nurb *nu)
{
if (nu->pntsv <= 1) {
return false;
@@ -5035,7 +4807,7 @@ bool BKE_nurb_check_valid_v(struct Nurb *nu)
return true;
}
-bool BKE_nurb_check_valid_uv(struct Nurb *nu)
+bool BKE_nurb_check_valid_uv(const Nurb *nu)
{
if (!BKE_nurb_check_valid_u(nu)) {
return false;
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index c228595b6e8..cc1c73b1e68 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -315,8 +315,7 @@ bool BKE_displist_surfindex_get(DispList *dl, int a, int *b, int *p1, int *p2, i
static void curve_to_displist(Curve *cu,
ListBase *nubase,
ListBase *dispbase,
- const bool for_render,
- const bool use_render_resolution)
+ const bool for_render)
{
Nurb *nu;
DispList *dl;
@@ -329,7 +328,7 @@ static void curve_to_displist(Curve *cu,
nu = nubase->first;
while (nu) {
if (nu->hide == 0 || editmode == false) {
- if (use_render_resolution && cu->resolu_ren != 0) {
+ if (for_render && cu->resolu_ren != 0) {
resolu = cu->resolu_ren;
}
else {
@@ -801,7 +800,7 @@ void BKE_displist_make_mball_forRender(Depsgraph *depsgraph,
static ModifierData *curve_get_tessellate_point(Scene *scene,
Object *ob,
- const bool use_render_resolution,
+ const bool for_render,
const bool editmode)
{
VirtualModifierData virtualModifierData;
@@ -809,7 +808,7 @@ static ModifierData *curve_get_tessellate_point(Scene *scene,
ModifierData *pretessellatePoint;
int required_mode;
- if (use_render_resolution) {
+ if (for_render) {
required_mode = eModifierMode_Render;
}
else {
@@ -848,12 +847,8 @@ static ModifierData *curve_get_tessellate_point(Scene *scene,
return pretessellatePoint;
}
-static void curve_calc_modifiers_pre(Depsgraph *depsgraph,
- Scene *scene,
- Object *ob,
- ListBase *nurb,
- const bool for_render,
- const bool use_render_resolution)
+static void curve_calc_modifiers_pre(
+ Depsgraph *depsgraph, Scene *scene, Object *ob, ListBase *nurb, const bool for_render)
{
VirtualModifierData virtualModifierData;
ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
@@ -871,7 +866,7 @@ static void curve_calc_modifiers_pre(Depsgraph *depsgraph,
if (editmode) {
app_flag |= MOD_APPLY_USECACHE;
}
- if (use_render_resolution) {
+ if (for_render) {
app_flag |= MOD_APPLY_RENDER;
required_mode = eModifierMode_Render;
}
@@ -881,7 +876,7 @@ static void curve_calc_modifiers_pre(Depsgraph *depsgraph,
const ModifierEvalContext mectx = {depsgraph, ob, app_flag};
- pretessellatePoint = curve_get_tessellate_point(scene, ob, use_render_resolution, editmode);
+ pretessellatePoint = curve_get_tessellate_point(scene, ob, for_render, editmode);
if (editmode) {
required_mode |= eModifierMode_Editmode;
@@ -979,8 +974,7 @@ static void curve_calc_modifiers_post(Depsgraph *depsgraph,
ListBase *nurb,
ListBase *dispbase,
Mesh **r_final,
- const bool for_render,
- const bool use_render_resolution)
+ const bool for_render)
{
VirtualModifierData virtualModifierData;
ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
@@ -993,7 +987,7 @@ static void curve_calc_modifiers_post(Depsgraph *depsgraph,
int useCache = !for_render;
ModifierApplyFlag app_flag = 0;
- if (use_render_resolution) {
+ if (for_render) {
app_flag |= MOD_APPLY_RENDER;
required_mode = eModifierMode_Render;
}
@@ -1006,7 +1000,7 @@ static void curve_calc_modifiers_post(Depsgraph *depsgraph,
const ModifierEvalContext mectx_apply = {
depsgraph, ob, useCache ? app_flag | MOD_APPLY_USECACHE : app_flag};
- pretessellatePoint = curve_get_tessellate_point(scene, ob, use_render_resolution, editmode);
+ pretessellatePoint = curve_get_tessellate_point(scene, ob, for_render, editmode);
if (editmode) {
required_mode |= eModifierMode_Editmode;
@@ -1199,144 +1193,13 @@ static void displist_surf_indices(DispList *dl)
}
}
-/* XXX2.8(Sybren): unused function; impossible to test after porting to Mesh */
-#ifdef WITH_DERIVEDMESH_DEPRECATED_FUNCS
-static DerivedMesh *create_orco_dm(Depsgraph *depsgraph, Scene *scene, Object *ob)
-{
- DerivedMesh *dm;
- ListBase disp = {NULL, NULL};
-
- /* OrcoDM should be created from underformed disp lists */
- BKE_displist_make_curveTypes_forOrco(depsgraph, scene, ob, &disp);
- dm = CDDM_from_curve_displist(ob, &disp);
-
- BKE_displist_free(&disp);
-
- return dm;
-}
-
-static void add_orco_dm(Object *ob, DerivedMesh *dm, DerivedMesh *orcodm)
-{
- float(*orco)[3], (*layerorco)[3];
- int totvert, a;
- Curve *cu = ob->data;
-
- totvert = dm->getNumVerts(dm);
-
- orco = MEM_callocN(sizeof(float) * 3 * totvert, "dm orco");
-
- if (orcodm->getNumVerts(orcodm) == totvert) {
- orcodm->getVertCos(orcodm, orco);
- }
- else {
- dm->getVertCos(dm, orco);
- }
-
- for (a = 0; a < totvert; a++) {
- float *co = orco[a];
- co[0] = (co[0] - cu->loc[0]) / cu->size[0];
- co[1] = (co[1] - cu->loc[1]) / cu->size[1];
- co[2] = (co[2] - cu->loc[2]) / cu->size[2];
- }
-
- if ((layerorco = DM_get_vert_data_layer(dm, CD_ORCO))) {
- memcpy(layerorco, orco, sizeof(float) * totvert);
- MEM_freeN(orco);
- }
- else {
- DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, orco);
- }
-}
-#endif
-
-/* XXX2.8(Sybren): unused function; impossible to test after porting to Mesh */
-#ifdef WITH_DERIVEDMESH_DEPRECATED_FUNCS
-static void curve_calc_orcodm(Depsgraph *depsgraph,
- Scene *scene,
- Object *ob,
- DerivedMesh *dm_final,
- const bool for_render,
- const bool use_render_resolution)
-{
- /* this function represents logic of mesh's orcodm calculation
- * for displist-based objects
- */
- VirtualModifierData virtualModifierData;
- ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
- ModifierData *pretessellatePoint;
- Curve *cu = ob->data;
- int required_mode;
- const bool editmode = (!for_render && (cu->editnurb || cu->editfont));
- DerivedMesh *ndm, *orcodm = NULL;
- ModifierApplyFlag app_flag = MOD_APPLY_ORCO;
-
- if (use_render_resolution) {
- app_flag |= MOD_APPLY_RENDER;
- required_mode = eModifierMode_Render;
- }
- else {
- required_mode = eModifierMode_Realtime;
- }
-
- const ModifierEvalContext mectx = {depsgraph, ob, app_flag};
-
- pretessellatePoint = curve_get_tessellate_point(scene, ob, use_render_resolution, editmode);
-
- if (editmode) {
- required_mode |= eModifierMode_Editmode;
- }
-
- if (pretessellatePoint) {
- md = pretessellatePoint->next;
- }
-
- /* If modifiers are disabled, we wouldn't be here because
- * this function is only called if there're enabled constructive
- * modifiers applied on the curve.
- *
- * This means we can create ORCO DM in advance and assume it's
- * never NULL.
- */
- orcodm = create_orco_dm(depsgraph, scene, ob);
-
- for (; md; md = md->next) {
- const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
-
- md->scene = scene;
-
- if (!modifier_isEnabled(scene, md, required_mode)) {
- continue;
- }
- if (mti->type != eModifierTypeType_Constructive) {
- continue;
- }
-
- ndm = modwrap_applyModifier(md, &mectx, orcodm);
-
- if (ndm) {
- /* if the modifier returned a new dm, release the old one */
- if (orcodm && orcodm != ndm) {
- orcodm->release(orcodm);
- }
- orcodm = ndm;
- }
- }
-
- /* add an orco layer if needed */
- add_orco_dm(ob, dm_final, orcodm);
-
- orcodm->release(orcodm);
-}
-#endif
-
void BKE_displist_make_surf(Depsgraph *depsgraph,
Scene *scene,
Object *ob,
ListBase *dispbase,
Mesh **r_final,
const bool for_render,
- const bool for_orco,
- const bool use_render_resolution)
+ const bool for_orco)
{
ListBase nubase = {NULL, NULL};
Nurb *nu;
@@ -1353,14 +1216,14 @@ void BKE_displist_make_surf(Depsgraph *depsgraph,
}
if (!for_orco) {
- curve_calc_modifiers_pre(depsgraph, scene, ob, &nubase, for_render, use_render_resolution);
+ curve_calc_modifiers_pre(depsgraph, scene, ob, &nubase, for_render);
}
for (nu = nubase.first; nu; nu = nu->next) {
if ((for_render || nu->hide == 0) && BKE_nurb_check_valid_uv(nu)) {
int resolu = nu->resolu, resolv = nu->resolv;
- if (use_render_resolution) {
+ if (for_render) {
if (cu->resolu_ren) {
resolu = cu->resolu_ren;
}
@@ -1431,8 +1294,7 @@ void BKE_displist_make_surf(Depsgraph *depsgraph,
if (!for_orco) {
BKE_nurbList_duplicate(&ob->runtime.curve_cache->deformed_nurbs, &nubase);
- curve_calc_modifiers_post(
- depsgraph, scene, ob, &nubase, dispbase, r_final, for_render, use_render_resolution);
+ curve_calc_modifiers_post(depsgraph, scene, ob, &nubase, dispbase, r_final, for_render);
}
BKE_nurbList_free(&nubase);
@@ -1665,7 +1527,6 @@ static void do_makeDispListCurveTypes(Depsgraph *depsgraph,
ListBase *dispbase,
const bool for_render,
const bool for_orco,
- const bool use_render_resolution,
LinkNode *ob_cyclic_list,
Mesh **r_final)
{
@@ -1677,8 +1538,7 @@ static void do_makeDispListCurveTypes(Depsgraph *depsgraph,
}
if (ob->type == OB_SURF) {
- BKE_displist_make_surf(
- depsgraph, scene, ob, dispbase, r_final, for_render, for_orco, use_render_resolution);
+ BKE_displist_make_surf(depsgraph, scene, ob, dispbase, r_final, for_render, for_orco);
}
else if (ELEM(ob->type, OB_CURVE, OB_FONT)) {
ListBase dlbev;
@@ -1705,18 +1565,17 @@ static void do_makeDispListCurveTypes(Depsgraph *depsgraph,
}
if (!for_orco) {
- curve_calc_modifiers_pre(depsgraph, scene, ob, &nubase, for_render, use_render_resolution);
+ curve_calc_modifiers_pre(depsgraph, scene, ob, &nubase, for_render);
}
- BKE_curve_bevelList_make(ob, &nubase, use_render_resolution);
+ BKE_curve_bevelList_make(ob, &nubase, for_render);
/* If curve has no bevel will return nothing */
- BKE_curve_bevel_make(
- depsgraph, scene, ob, &dlbev, for_render, use_render_resolution, ob_cyclic_list);
+ BKE_curve_bevel_make(depsgraph, scene, ob, &dlbev, for_render, ob_cyclic_list);
/* no bevel or extrude, and no width correction? */
if (!dlbev.first && cu->width == 1.0f) {
- curve_to_displist(cu, &nubase, dispbase, for_render, use_render_resolution);
+ curve_to_displist(cu, &nubase, dispbase, for_render);
}
else {
float widfac = cu->width - 1.0f;
@@ -1916,8 +1775,7 @@ static void do_makeDispListCurveTypes(Depsgraph *depsgraph,
if (!for_orco) {
BKE_nurbList_duplicate(&ob->runtime.curve_cache->deformed_nurbs, &nubase);
- curve_calc_modifiers_post(
- depsgraph, scene, ob, &nubase, dispbase, r_final, for_render, use_render_resolution);
+ curve_calc_modifiers_post(depsgraph, scene, ob, &nubase, dispbase, r_final, for_render);
}
if (cu->flag & CU_DEFORM_FILL && !ob->runtime.mesh_eval) {
@@ -1958,7 +1816,6 @@ void BKE_displist_make_curveTypes(Depsgraph *depsgraph,
dispbase,
for_render,
for_orco,
- false,
ob_cyclic_list,
&ob->runtime.mesh_eval);
@@ -1971,32 +1828,14 @@ void BKE_displist_make_curveTypes_forRender(Depsgraph *depsgraph,
ListBase *dispbase,
Mesh **r_final,
const bool for_orco,
- const bool use_render_resolution,
LinkNode *ob_cyclic_list)
{
if (ob->runtime.curve_cache == NULL) {
ob->runtime.curve_cache = MEM_callocN(sizeof(CurveCache), "CurveCache for Curve");
}
- do_makeDispListCurveTypes(depsgraph,
- scene,
- ob,
- dispbase,
- true,
- for_orco,
- use_render_resolution,
- ob_cyclic_list,
- r_final);
-}
-
-void BKE_displist_make_curveTypes_forOrco(
- Depsgraph *depsgraph, Scene *scene, Object *ob, ListBase *dispbase, LinkNode *ob_cyclic_list)
-{
- if (ob->runtime.curve_cache == NULL) {
- ob->runtime.curve_cache = MEM_callocN(sizeof(CurveCache), "CurveCache for Curve");
- }
-
- do_makeDispListCurveTypes(depsgraph, scene, ob, dispbase, 1, 1, 1, ob_cyclic_list, NULL);
+ do_makeDispListCurveTypes(
+ depsgraph, scene, ob, dispbase, true, for_orco, ob_cyclic_list, r_final);
}
void BKE_displist_minmax(ListBase *dispbase, float min[3], float max[3])
diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c
index 93b6fd34a8f..b5242d00ee0 100644
--- a/source/blender/blenkernel/intern/dynamicpaint.c
+++ b/source/blender/blenkernel/intern/dynamicpaint.c
@@ -2066,7 +2066,7 @@ static Mesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object *
}
if (update_normals) {
- // result->dirty |= DM_DIRTY_NORMALS;
+ result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
}
}
/* make a copy of mesh to use as brush data */
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index 8c95e4c7ff3..e2d0a479792 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -1707,6 +1707,11 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
/* not valid channel */
return 0.0f;
}
+ else 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 (dtar->transChan >= DTAR_TRANSCHAN_SCALEX) {
/* Extract scale, and choose the right axis,
* inline 'mat4_to_size'. */
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index f23c58befdf..18c42da0bd4 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -5087,6 +5087,7 @@ bool BKE_image_is_animated(Image *image)
return ELEM(image->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE);
}
+/* Image modifications */
bool BKE_image_is_dirty(Image *image)
{
bool is_dirty = false;
@@ -5110,6 +5111,11 @@ bool BKE_image_is_dirty(Image *image)
return is_dirty;
}
+void BKE_image_mark_dirty(Image *UNUSED(image), ImBuf *ibuf)
+{
+ ibuf->userflags |= IB_BITMAPDIRTY;
+}
+
void BKE_image_file_format_set(Image *image, int ftype, const ImbFormatOptions *options)
{
BLI_spin_lock(&image_spin);
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index fc349e62809..99e6c99ec0c 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -693,8 +693,8 @@ static short layer_collection_sync(ViewLayer *view_layer,
lc->runtime_flag = child_runtime_flag;
}
- if (((child_restrict & COLLECTION_RESTRICT_VIEW) == 0) &&
- ((child_layer_restrict & LAYER_COLLECTION_RESTRICT_VIEW) == 0)) {
+ if (((child_restrict & COLLECTION_RESTRICT_VIEWPORT) == 0) &&
+ ((child_layer_restrict & LAYER_COLLECTION_HIDE) == 0)) {
lc->runtime_flag |= LAYER_COLLECTION_VISIBLE;
}
@@ -723,9 +723,9 @@ static short layer_collection_sync(ViewLayer *view_layer,
BLI_addtail(new_object_bases, base);
}
- if ((child_restrict & COLLECTION_RESTRICT_VIEW) == 0) {
+ if ((child_restrict & COLLECTION_RESTRICT_VIEWPORT) == 0) {
base->flag_from_collection |= BASE_ENABLED_VIEWPORT;
- if ((child_layer_restrict & LAYER_COLLECTION_RESTRICT_VIEW) == 0) {
+ if ((child_layer_restrict & LAYER_COLLECTION_HIDE) == 0) {
base->flag_from_collection |= BASE_VISIBLE;
if (((child_restrict & COLLECTION_RESTRICT_SELECT) == 0)) {
base->flag_from_collection |= BASE_SELECTABLE;
@@ -1014,8 +1014,8 @@ bool BKE_layer_collection_isolate(Scene *scene,
bool hide_it = extend && (lc->runtime_flag & LAYER_COLLECTION_VISIBLE);
if ((!ID_IS_LINKED(lc->collection) && !hide_it)) {
- if (lc->collection->flag & COLLECTION_RESTRICT_VIEW) {
- lc->collection->flag &= ~COLLECTION_RESTRICT_VIEW;
+ if (lc->collection->flag & COLLECTION_RESTRICT_VIEWPORT) {
+ lc->collection->flag &= ~COLLECTION_RESTRICT_VIEWPORT;
depsgraph_need_update = true;
}
}
@@ -1024,13 +1024,13 @@ bool BKE_layer_collection_isolate(Scene *scene,
/* Hide all collections . */
for (LayerCollection *lc_iter = lc_master->layer_collections.first; lc_iter;
lc_iter = lc_iter->next) {
- layer_collection_flag_set_recursive(lc_iter, LAYER_COLLECTION_RESTRICT_VIEW);
+ layer_collection_flag_set_recursive(lc_iter, LAYER_COLLECTION_HIDE);
}
}
/* Make all the direct parents visible. */
if (hide_it) {
- lc->flag |= LAYER_COLLECTION_RESTRICT_VIEW;
+ lc->flag |= LAYER_COLLECTION_HIDE;
}
else {
LayerCollection *lc_parent = lc;
@@ -1044,13 +1044,13 @@ bool BKE_layer_collection_isolate(Scene *scene,
while (lc_parent != lc) {
if (!ID_IS_LINKED(lc_parent->collection)) {
- if (lc_parent->collection->flag & COLLECTION_RESTRICT_VIEW) {
- lc_parent->collection->flag &= ~COLLECTION_RESTRICT_VIEW;
+ if (lc_parent->collection->flag & COLLECTION_RESTRICT_VIEWPORT) {
+ lc_parent->collection->flag &= ~COLLECTION_RESTRICT_VIEWPORT;
depsgraph_need_update = true;
}
}
- lc_parent->flag &= ~LAYER_COLLECTION_RESTRICT_VIEW;
+ lc_parent->flag &= ~LAYER_COLLECTION_HIDE;
for (LayerCollection *lc_iter = lc_parent->layer_collections.first; lc_iter;
lc_iter = lc_iter->next) {
@@ -1062,7 +1062,7 @@ bool BKE_layer_collection_isolate(Scene *scene,
}
/* Make all the children visible, but respect their disable state. */
- layer_collection_flag_unset_recursive(lc, LAYER_COLLECTION_RESTRICT_VIEW);
+ layer_collection_flag_unset_recursive(lc, LAYER_COLLECTION_HIDE);
BKE_layer_collection_activate(view_layer, lc);
}
@@ -1109,27 +1109,27 @@ bool BKE_layer_collection_set_visible(ViewLayer *view_layer,
bool depsgraph_changed = false;
if (visible && (!ID_IS_LINKED(lc->collection)) &&
- ((lc->collection->flag & COLLECTION_RESTRICT_VIEW) != 0)) {
- lc->collection->flag &= ~COLLECTION_RESTRICT_VIEW;
+ ((lc->collection->flag & COLLECTION_RESTRICT_VIEWPORT) != 0)) {
+ lc->collection->flag &= ~COLLECTION_RESTRICT_VIEWPORT;
depsgraph_changed = true;
}
if (hierarchy) {
if (visible) {
- layer_collection_flag_unset_recursive(lc, LAYER_COLLECTION_RESTRICT_VIEW);
+ layer_collection_flag_unset_recursive(lc, LAYER_COLLECTION_HIDE);
layer_collection_bases_show_recursive(view_layer, lc);
}
else {
- layer_collection_flag_set_recursive(lc, LAYER_COLLECTION_RESTRICT_VIEW);
+ layer_collection_flag_set_recursive(lc, LAYER_COLLECTION_HIDE);
layer_collection_bases_hide_recursive(view_layer, lc);
}
}
else {
if (visible) {
- lc->flag &= ~LAYER_COLLECTION_RESTRICT_VIEW;
+ lc->flag &= ~LAYER_COLLECTION_HIDE;
}
else {
- lc->flag |= LAYER_COLLECTION_RESTRICT_VIEW;
+ lc->flag |= LAYER_COLLECTION_HIDE;
}
}
return depsgraph_changed;
@@ -1491,7 +1491,7 @@ void BKE_base_eval_flags(Base *base)
/* Apply object restrictions. */
const int object_restrict = base->object->restrictflag;
- if (object_restrict & OB_RESTRICT_VIEW) {
+ if (object_restrict & OB_RESTRICT_VIEWPORT) {
base->flag &= ~BASE_ENABLED_VIEWPORT;
}
if (object_restrict & OB_RESTRICT_RENDER) {
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index ad0c405ab28..3e6f93d1323 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -1860,7 +1860,7 @@ static void library_make_local_copying_check(ID *id,
* (except group and objects ones).
*/
/* Note: Old (2.77) version was simply making (tagging) data-blocks as local,
- * without actually making any check whether * they were also indirectly used or not...
+ * without actually making any check whether they were also indirectly used or not...
*
* Current version uses regular id_make_local callback, with advanced pre-processing step to detect
* all cases of IDs currently indirectly used, but which will be used by local data only once this
diff --git a/source/blender/blenkernel/intern/light.c b/source/blender/blenkernel/intern/light.c
index 05b2eb82daf..1c3acb6a73a 100644
--- a/source/blender/blenkernel/intern/light.c
+++ b/source/blender/blenkernel/intern/light.c
@@ -80,6 +80,7 @@ void BKE_light_init(Light *la)
la->contact_thickness = 0.2f;
la->spec_fac = 1.0f;
la->att_dist = 40.0f;
+ la->sun_angle = DEG2RADF(0.526f);
curvemapping_initialize(la->curfalloff);
}
diff --git a/source/blender/blenkernel/intern/mesh_convert.c b/source/blender/blenkernel/intern/mesh_convert.c
index 3f4e504867c..fe8d053c1df 100644
--- a/source/blender/blenkernel/intern/mesh_convert.c
+++ b/source/blender/blenkernel/intern/mesh_convert.c
@@ -1007,7 +1007,7 @@ Mesh *BKE_mesh_new_from_object(Depsgraph *depsgraph,
/* get updated display list, and convert to a mesh */
BKE_displist_make_curveTypes_forRender(
- depsgraph, sce, tmpobj, &dispbase, &me_eval_final, false, render, NULL);
+ depsgraph, sce, tmpobj, &dispbase, &me_eval_final, false, NULL);
copycu->editfont = NULL;
copycu->editnurb = NULL;
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 38a8ad2769a..6c2bd5e6127 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -4487,3 +4487,14 @@ void BKE_object_type_set_empty_for_versioning(Object *ob)
}
ob->mode = OB_MODE_OBJECT;
}
+
+/* Updates select_id of all objects in the given bmain. */
+void BKE_object_update_select_id(struct Main *bmain)
+{
+ Object *ob = bmain->objects.first;
+ int select_id = 1;
+ while (ob) {
+ ob->runtime.select_id = select_id++;
+ ob = ob->id.next;
+ }
+} \ No newline at end of file
diff --git a/source/blender/blenkernel/intern/object_dupli.c b/source/blender/blenkernel/intern/object_dupli.c
index 8080834a53a..0dedbb7e934 100644
--- a/source/blender/blenkernel/intern/object_dupli.c
+++ b/source/blender/blenkernel/intern/object_dupli.c
@@ -1082,7 +1082,7 @@ static const DupliGenerator *get_dupli_generator(const DupliContext *ctx)
/* Should the dupli's be generated for this object? - Respect restrict flags */
if (DEG_get_mode(ctx->depsgraph) == DAG_EVAL_RENDER ? (restrictflag & OB_RESTRICT_RENDER) :
- (restrictflag & OB_RESTRICT_VIEW)) {
+ (restrictflag & OB_RESTRICT_VIEWPORT)) {
return NULL;
}
diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c
index 183bc968897..77941e7d607 100644
--- a/source/blender/blenkernel/intern/object_update.c
+++ b/source/blender/blenkernel/intern/object_update.c
@@ -202,9 +202,11 @@ void BKE_object_handle_data_update(Depsgraph *depsgraph, Scene *scene, Object *o
case OB_CURVE:
case OB_SURF:
- case OB_FONT:
- BKE_displist_make_curveTypes(depsgraph, scene, ob, false, false, NULL);
+ case OB_FONT: {
+ bool for_render = (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
+ BKE_displist_make_curveTypes(depsgraph, scene, ob, for_render, false, NULL);
break;
+ }
case OB_LATTICE:
BKE_lattice_modifiers_calc(depsgraph, scene, ob);
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index b594232193d..bd06e2fe7e0 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -1276,9 +1276,6 @@ void BKE_sculpt_update_mesh_elements(
}
}
}
-
- /* 2.8x - avoid full mesh update! */
- BKE_mesh_batch_cache_dirty_tag(me, BKE_MESH_BATCH_DIRTY_SCULPT_COORDS);
}
int BKE_sculpt_mask_layers_ensure(Object *ob, MultiresModifierData *mmd)
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 8a70db8704f..3d6b7390057 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -37,7 +37,6 @@
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_sequence_types.h"
-#include "DNA_sound_types.h"
#include "DNA_space_types.h"
#include "DNA_view3d_types.h"
#include "DNA_windowmanager_types.h"
@@ -309,7 +308,8 @@ void BKE_scene_copy_data(Main *bmain, Scene *sce_dst, const Scene *sce_src, cons
flag_subdata);
}
- BKE_sound_reset_scene_runtime(sce_dst);
+ /* before scene copy */
+ BKE_sound_create_scene(sce_dst);
/* Copy sequencer, this is local data! */
if (sce_src->ed) {
@@ -399,7 +399,8 @@ Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type)
sce_copy->r.ffcodecdata.properties = IDP_CopyProperty(sce->r.ffcodecdata.properties);
}
- BKE_sound_reset_scene_runtime(sce_copy);
+ /* before scene copy */
+ BKE_sound_create_scene(sce_copy);
/* grease pencil */
sce_copy->gpd = NULL;
@@ -779,7 +780,7 @@ void BKE_scene_init(Scene *sce)
srv = sce->r.views.last;
BLI_strncpy(srv->suffix, STEREO_RIGHT_SUFFIX, sizeof(srv->suffix));
- BKE_sound_reset_scene_runtime(sce);
+ BKE_sound_create_scene(sce);
/* color management */
colorspace_name = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_DEFAULT_SEQUENCER);
@@ -1530,13 +1531,6 @@ static void prepare_mesh_for_viewport_render(Main *bmain, const ViewLayer *view_
}
}
-static void scene_update_sound(Depsgraph *depsgraph, Main *bmain)
-{
- Scene *scene = DEG_get_evaluated_scene(depsgraph);
- BKE_sound_ensure_scene(scene);
- BKE_sound_update_scene(bmain, scene);
-}
-
/* TODO(sergey): This actually should become view_layer_graph or so.
* Same applies to update_for_newframe.
*/
@@ -1565,9 +1559,10 @@ void BKE_scene_graph_update_tagged(Depsgraph *depsgraph, Main *bmain)
* by depgraph or manual, no layer check here, gets correct flushed.
*/
DEG_evaluate_on_refresh(depsgraph);
- /* Update sound system. */
- scene_update_sound(depsgraph, bmain);
- /* Notify python about depsgraph update. */
+ /* Update sound system animation (TODO, move to depsgraph). */
+ BKE_sound_update_scene(bmain, scene);
+
+ /* Notify python about depsgraph update */
if (run_callbacks) {
BLI_callback_exec(bmain, &scene->id, BLI_CB_EVT_DEPSGRAPH_UPDATE_POST);
}
@@ -1602,8 +1597,8 @@ void BKE_scene_graph_update_for_newframe(Depsgraph *depsgraph, Main *bmain)
* by depgraph or manual, no layer check here, gets correct flushed.
*/
DEG_evaluate_on_framechange(bmain, depsgraph, ctime);
- /* Update sound system animation. */
- scene_update_sound(depsgraph, bmain);
+ /* Update sound system animation (TODO, move to depsgraph). */
+ BKE_sound_update_scene(bmain, scene);
/* Notify editors and python about recalc. */
BLI_callback_exec(bmain, &scene->id, BLI_CB_EVT_FRAME_CHANGE_POST);
/* Inform editors about possible changes. */
@@ -2415,23 +2410,3 @@ void BKE_scene_cursor_quat_to_rot(View3DCursor *cursor, const float quat[4], boo
}
/** \} */
-
-/* Dependency graph evaluation. */
-
-void BKE_scene_eval_sequencer_sequences(Depsgraph *depsgraph, Scene *scene)
-{
- DEG_debug_print_eval(depsgraph, __func__, scene->id.name, scene);
- if (scene->ed == NULL) {
- return;
- }
- BKE_sound_ensure_scene(scene);
- Sequence *seq;
- SEQ_BEGIN (scene->ed, seq) {
- if (seq->sound != NULL && seq->scene_sound == NULL) {
- seq->scene_sound = BKE_sound_add_scene_sound_defaults(scene, seq);
- }
- }
- SEQ_END;
- BKE_sequencer_update_muting(scene->ed);
- BKE_sequencer_update_sound_bounds_all(scene);
-}
diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c
index 9799f7c2943..5c41048be83 100644
--- a/source/blender/blenkernel/intern/screen.c
+++ b/source/blender/blenkernel/intern/screen.c
@@ -193,18 +193,6 @@ static void panel_list_copy(ListBase *newlb, const ListBase *lb)
Panel *pa = lb->first;
for (; newpa; newpa = newpa->next, pa = pa->next) {
newpa->activedata = NULL;
-
- Panel *newpatab = newlb->first;
- Panel *patab = lb->first;
- while (newpatab) {
- if (newpa->paneltab == patab) {
- newpa->paneltab = newpatab;
- break;
- }
- newpatab = newpatab->next;
- patab = patab->next;
- }
-
panel_list_copy(&newpa->children, &pa->children);
}
}
@@ -859,6 +847,7 @@ void BKE_screen_view3d_shading_init(View3DShading *shading)
shading->xray_alpha_wire = 0.5f;
shading->cavity_valley_factor = 1.0f;
shading->cavity_ridge_factor = 1.0f;
+ shading->cavity_type = V3D_SHADING_CAVITY_CURVATURE;
shading->curvature_ridge_factor = 1.0f;
shading->curvature_valley_factor = 1.0f;
copy_v3_fl(shading->single_color, 0.8f);
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index 74541c13c4f..7f738ff4e4f 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -808,7 +808,10 @@ void BKE_sequence_calc_disp(Scene *scene, Sequence *seq)
seq->handsize = (float)((seq->enddisp - seq->startdisp) / 25);
}
- if (seq->type == SEQ_TYPE_META) {
+ if (ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SCENE)) {
+ BKE_sequencer_update_sound_bounds(scene, seq);
+ }
+ else if (seq->type == SEQ_TYPE_META) {
seq_update_sound_bounds_recursive(scene, seq);
}
}
@@ -3572,9 +3575,9 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context,
re = RE_NewSceneRender(scene);
}
- RE_BlenderFrame(re, context->bmain, scene, view_layer, camera, frame, false);
+ RE_RenderFrame(re, context->bmain, scene, view_layer, camera, frame, false);
- /* restore previous state after it was toggled on & off by RE_BlenderFrame */
+ /* restore previous state after it was toggled on & off by RE_RenderFrame */
G.is_rendering = is_rendering;
}
@@ -5488,18 +5491,17 @@ Sequence *BKE_sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoad
Strip *strip;
StripElem *se;
+ AUD_SoundInfo info;
+
sound = BKE_sound_new_file(bmain, seq_load->path); /* handles relative paths */
- /* Load the original sound, so we can access number of channels and length information.
- * We free the sound handle on the original bSound datablock before existing this function, it is
- * to be allocated on an evaluated version after this. */
- BKE_sound_load_audio(bmain, sound);
- AUD_SoundInfo info = AUD_getInfo(sound->playback_handle);
if (sound->playback_handle == NULL) {
BKE_id_free(bmain, sound);
return NULL;
}
+ info = AUD_getInfo(sound->playback_handle);
+
if (info.specs.channels == AUD_CHANNELS_INVALID) {
BKE_id_free(bmain, sound);
return NULL;
@@ -5524,7 +5526,8 @@ Sequence *BKE_sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoad
BLI_split_dirfile(seq_load->path, strip->dir, se->name, sizeof(strip->dir), sizeof(se->name));
- seq->scene_sound = NULL;
+ seq->scene_sound = BKE_sound_add_scene_sound(
+ scene, seq, seq_load->start_frame, seq_load->start_frame + seq->len, 0);
BKE_sequence_calc_disp(scene, seq);
@@ -5533,11 +5536,6 @@ Sequence *BKE_sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoad
seq_load_apply(bmain, scene, seq, seq_load);
- BKE_sound_free_audio(sound);
-
- /* TODO(sergey): Shall we tag here or in the oeprator? */
- DEG_relations_tag_update(bmain);
-
return seq;
}
#else // WITH_AUDASPACE
@@ -5749,7 +5747,10 @@ static Sequence *seq_dupli(const Scene *scene_src,
}
else if (seq->type == SEQ_TYPE_SOUND_RAM) {
seqn->strip->stripdata = MEM_dupallocN(seq->strip->stripdata);
- seqn->scene_sound = NULL;
+ if (seq->scene_sound) {
+ seqn->scene_sound = BKE_sound_add_scene_sound_defaults(scene_dst, seqn);
+ }
+
if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
id_us_plus((ID *)seqn->sound);
}
diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c
index 9ccb90b5cdc..c97baf8f7dd 100644
--- a/source/blender/blenkernel/intern/sound.c
+++ b/source/blender/blenkernel/intern/sound.c
@@ -38,7 +38,6 @@
#include "DNA_screen_types.h"
#include "DNA_sound_types.h"
#include "DNA_speaker_types.h"
-#include "DNA_windowmanager_types.h"
#ifdef WITH_AUDASPACE
# include <AUD_Sound.h>
@@ -56,37 +55,12 @@
#include "BKE_sequencer.h"
#include "BKE_scene.h"
-#include "DEG_depsgraph.h"
-#include "DEG_depsgraph_query.h"
-
#ifdef WITH_AUDASPACE
/* evil globals ;-) */
static int sound_cfra;
static char **audio_device_names = NULL;
#endif
-BLI_INLINE void sound_verify_evaluated_id(ID *id)
-{
- UNUSED_VARS_NDEBUG(id);
- /* This is a bit tricky and not quite reliable, but good enough check.
- *
- * We don't want audio system handles to be allocated on amn original datablocks, and only want
- * them to be allocated on a datablocks which are result of dependency graph evaluation.
- *
- * Datablocks which are covered by a copy-on-write system of dependency graph will have
- * LIB_TAG_COPIED_ON_WRITE tag set on them. But if some of datablocks during its evaluation
- * decides to re-allocate it's nested one (for example, object evaluation could re-allocate mesh
- * when evaluating modifier stack). Such datablocks will have LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT
- * tag set on them.
- *
- * Additionally, we also allow datablocks outside of main database. Those can not be "original"
- * and could be used as a temporary evaluated result during operations like baking.
- *
- * NOTE: We conder ID evaluated if ANY of those flags is set. We do NOT require ALL of them. */
- BLI_assert(id->tag &
- (LIB_TAG_COPIED_ON_WRITE | LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT | LIB_TAG_NO_MAIN));
-}
-
bSound *BKE_sound_new_file(Main *bmain, const char *filepath)
{
bSound *sound;
@@ -103,10 +77,7 @@ bSound *BKE_sound_new_file(Main *bmain, const char *filepath)
BLI_strncpy(sound->name, filepath, FILE_MAX);
/* sound->type = SOUND_TYPE_FILE; */ /* XXX unused currently */
- sound->spinlock = MEM_mallocN(sizeof(SpinLock), "sound_spinlock");
- BLI_spin_init(sound->spinlock);
-
- BKE_sound_reset_runtime(sound);
+ BKE_sound_load(bmain, sound);
return sound;
}
@@ -154,18 +125,6 @@ void BKE_sound_free(bSound *sound)
sound->packedfile = NULL;
}
- BKE_sound_free_audio(sound);
- BKE_sound_free_waveform(sound);
-
- if (sound->spinlock) {
- BLI_spin_end(sound->spinlock);
- MEM_freeN(sound->spinlock);
- sound->spinlock = NULL;
- }
-}
-
-void BKE_sound_free_audio(bSound *sound)
-{
#ifdef WITH_AUDASPACE
if (sound->handle) {
AUD_Sound_free(sound->handle);
@@ -177,9 +136,15 @@ void BKE_sound_free_audio(bSound *sound)
AUD_Sound_free(sound->cache);
sound->cache = NULL;
}
-#else
- UNUSED_VARS(sound);
+
+ BKE_sound_free_waveform(sound);
+
#endif /* WITH_AUDASPACE */
+ if (sound->spinlock) {
+ BLI_spin_end(sound->spinlock);
+ MEM_freeN(sound->spinlock);
+ sound->spinlock = NULL;
+ }
}
/**
@@ -192,7 +157,7 @@ void BKE_sound_free_audio(bSound *sound)
*
* \param flag: Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
*/
-void BKE_sound_copy_data(Main *UNUSED(bmain),
+void BKE_sound_copy_data(Main *bmain,
bSound *sound_dst,
const bSound *UNUSED(sound_src),
const int UNUSED(flag))
@@ -201,8 +166,8 @@ void BKE_sound_copy_data(Main *UNUSED(bmain),
sound_dst->cache = NULL;
sound_dst->waveform = NULL;
sound_dst->playback_handle = NULL;
- sound_dst->spinlock = MEM_mallocN(sizeof(SpinLock), "sound_spinlock");
- BLI_spin_init(sound_dst->spinlock);
+ sound_dst->spinlock =
+ NULL; /* Think this is OK? Otherwise, easy to create new spinlock here... */
/* Just to be sure, should not have any value actually after reading time. */
sound_dst->ipo = NULL;
@@ -212,7 +177,8 @@ void BKE_sound_copy_data(Main *UNUSED(bmain),
sound_dst->packedfile = dupPackedFile(sound_dst->packedfile);
}
- BKE_sound_reset_runtime(sound_dst);
+ /* Initialize whole runtime (audaspace) stuff. */
+ BKE_sound_load(bmain, sound_dst);
}
void BKE_sound_make_local(Main *bmain, bSound *sound, const bool lib_local)
@@ -225,15 +191,31 @@ void BKE_sound_make_local(Main *bmain, bSound *sound, const bool lib_local)
static const char *force_device = NULL;
# ifdef WITH_JACK
-static SoundJackSyncCallback sound_jack_sync_callback = NULL;
-
static void sound_sync_callback(void *data, int mode, float time)
{
- if (sound_jack_sync_callback == NULL) {
+ // Ugly: Blender doesn't like it when the animation is played back during rendering
+ if (G.is_rendering) {
return;
}
+
Main *bmain = (Main *)data;
- sound_jack_sync_callback(bmain, mode, time);
+ Scene *scene;
+
+ scene = bmain->scenes.first;
+ while (scene) {
+ if (scene->audio.flag & AUDIO_SYNC) {
+ if (mode) {
+ BKE_sound_play_scene(scene);
+ }
+ else {
+ BKE_sound_stop_scene(scene);
+ }
+ if (scene->playback_handle) {
+ AUD_Handle_setPosition(scene->playback_handle, time);
+ }
+ }
+ scene = scene->id.next;
+ }
}
# endif
@@ -316,7 +298,7 @@ void BKE_sound_init_main(Main *bmain)
AUD_setSynchronizerCallback(sound_sync_callback, bmain);
}
# else
- UNUSED_VARS(bmain);
+ (void)bmain; /* unused */
# endif
}
@@ -385,8 +367,6 @@ bSound *BKE_sound_new_limiter(Main *bmain, bSound *source, float start, float en
void BKE_sound_cache(bSound *sound)
{
- sound_verify_evaluated_id(&sound->id);
-
sound->flags |= SOUND_FLAGS_CACHING;
if (sound->cache) {
AUD_Sound_free(sound->cache);
@@ -413,50 +393,44 @@ void BKE_sound_delete_cache(bSound *sound)
void BKE_sound_load(Main *bmain, bSound *sound)
{
- sound_verify_evaluated_id(&sound->id);
- BKE_sound_load_audio(bmain, sound);
-}
-
-void BKE_sound_load_audio(Main *bmain, bSound *sound)
-{
-
- if (sound->cache) {
- AUD_Sound_free(sound->cache);
- sound->cache = NULL;
- }
+ if (sound) {
+ if (sound->cache) {
+ AUD_Sound_free(sound->cache);
+ sound->cache = NULL;
+ }
- if (sound->handle) {
- AUD_Sound_free(sound->handle);
- sound->handle = NULL;
- sound->playback_handle = NULL;
- }
+ if (sound->handle) {
+ AUD_Sound_free(sound->handle);
+ sound->handle = NULL;
+ sound->playback_handle = NULL;
+ }
- BKE_sound_free_waveform(sound);
+ BKE_sound_free_waveform(sound);
/* XXX unused currently */
# if 0
switch (sound->type) {
case SOUND_TYPE_FILE:
# endif
- {
- char fullpath[FILE_MAX];
+ {
+ char fullpath[FILE_MAX];
- /* load sound */
- PackedFile *pf = sound->packedfile;
+ /* load sound */
+ PackedFile *pf = sound->packedfile;
- /* don't modify soundact->sound->name, only change a copy */
- BLI_strncpy(fullpath, sound->name, sizeof(fullpath));
- BLI_path_abs(fullpath, ID_BLEND_PATH(bmain, &sound->id));
+ /* don't modify soundact->sound->name, only change a copy */
+ BLI_strncpy(fullpath, sound->name, sizeof(fullpath));
+ BLI_path_abs(fullpath, ID_BLEND_PATH(bmain, &sound->id));
- /* but we need a packed file then */
- if (pf) {
- sound->handle = AUD_Sound_bufferFile((unsigned char *)pf->data, pf->size);
- }
- else {
- /* or else load it from disk */
- sound->handle = AUD_Sound_file(fullpath);
+ /* but we need a packed file then */
+ if (pf) {
+ sound->handle = AUD_Sound_bufferFile((unsigned char *)pf->data, pf->size);
+ }
+ else {
+ /* or else load it from disk */
+ sound->handle = AUD_Sound_file(fullpath);
+ }
}
- }
/* XXX unused currently */
# if 0
break;
@@ -473,34 +447,34 @@ void BKE_sound_load_audio(Main *bmain, bSound *sound)
break;
}
# endif
- if (sound->flags & SOUND_FLAGS_MONO) {
- void *handle = AUD_Sound_rechannel(sound->handle, AUD_CHANNELS_MONO);
- AUD_Sound_free(sound->handle);
- sound->handle = handle;
- }
+ if (sound->flags & SOUND_FLAGS_MONO) {
+ void *handle = AUD_Sound_rechannel(sound->handle, AUD_CHANNELS_MONO);
+ AUD_Sound_free(sound->handle);
+ sound->handle = handle;
+ }
- if (sound->flags & SOUND_FLAGS_CACHING) {
- sound->cache = AUD_Sound_cache(sound->handle);
- }
+ if (sound->flags & SOUND_FLAGS_CACHING) {
+ sound->cache = AUD_Sound_cache(sound->handle);
+ }
- if (sound->cache) {
- sound->playback_handle = sound->cache;
- }
- else {
- sound->playback_handle = sound->handle;
+ if (sound->cache) {
+ sound->playback_handle = sound->cache;
+ }
+ else {
+ sound->playback_handle = sound->handle;
+ }
+
+ BKE_sound_update_sequencer(bmain, sound);
}
}
AUD_Device *BKE_sound_mixdown(Scene *scene, AUD_DeviceSpecs specs, int start, float volume)
{
- sound_verify_evaluated_id(&scene->id);
return AUD_openMixdownDevice(specs, scene->sound_scene, volume, start / FPS);
}
void BKE_sound_create_scene(Scene *scene)
{
- sound_verify_evaluated_id(&scene->id);
-
/* should be done in version patch, but this gets called before */
if (scene->r.frs_sec_base == 0) {
scene->r.frs_sec_base = 1;
@@ -533,21 +507,16 @@ void BKE_sound_destroy_scene(Scene *scene)
void BKE_sound_reset_scene_specs(Scene *scene)
{
- sound_verify_evaluated_id(&scene->id);
+ AUD_Specs specs;
- if (scene->sound_scene) {
- AUD_Specs specs;
+ specs.channels = AUD_Device_getChannels(sound_device);
+ specs.rate = AUD_Device_getRate(sound_device);
- specs.channels = AUD_Device_getChannels(sound_device);
- specs.rate = AUD_Device_getRate(sound_device);
-
- AUD_Sequence_setSpecs(scene->sound_scene, specs);
- }
+ AUD_Sequence_setSpecs(scene->sound_scene, specs);
}
void BKE_sound_mute_scene(Scene *scene, int muted)
{
- sound_verify_evaluated_id(&scene->id);
if (scene->sound_scene) {
AUD_Sequence_setMuted(scene->sound_scene, muted);
}
@@ -555,8 +524,6 @@ void BKE_sound_mute_scene(Scene *scene, int muted)
void BKE_sound_update_fps(Scene *scene)
{
- sound_verify_evaluated_id(&scene->id);
-
if (scene->sound_scene) {
AUD_Sequence_setFPS(scene->sound_scene, FPS);
}
@@ -566,8 +533,6 @@ void BKE_sound_update_fps(Scene *scene)
void BKE_sound_update_scene_listener(Scene *scene)
{
- sound_verify_evaluated_id(&scene->id);
-
AUD_Sequence_setSpeedOfSound(scene->sound_scene, scene->audio.speed_of_sound);
AUD_Sequence_setDopplerFactor(scene->sound_scene, scene->audio.doppler_factor);
AUD_Sequence_setDistanceModel(scene->sound_scene, scene->audio.distance_model);
@@ -576,7 +541,6 @@ void BKE_sound_update_scene_listener(Scene *scene)
void *BKE_sound_scene_add_scene_sound(
Scene *scene, Sequence *sequence, int startframe, int endframe, int frameskip)
{
- sound_verify_evaluated_id(&scene->id);
if (sequence->scene && scene != sequence->scene) {
const double fps = FPS;
return AUD_Sequence_add(scene->sound_scene,
@@ -600,7 +564,6 @@ void *BKE_sound_scene_add_scene_sound_defaults(Scene *scene, Sequence *sequence)
void *BKE_sound_add_scene_sound(
Scene *scene, Sequence *sequence, int startframe, int endframe, int frameskip)
{
- sound_verify_evaluated_id(&scene->id);
/* Happens when sequence's sound datablock was removed. */
if (sequence->sound == NULL) {
return NULL;
@@ -640,14 +603,12 @@ void BKE_sound_mute_scene_sound(void *handle, char mute)
void BKE_sound_move_scene_sound(
Scene *scene, void *handle, int startframe, int endframe, int frameskip)
{
- sound_verify_evaluated_id(&scene->id);
const double fps = FPS;
AUD_SequenceEntry_move(handle, startframe / fps, endframe / fps, frameskip / fps);
}
void BKE_sound_move_scene_sound_defaults(Scene *scene, Sequence *sequence)
{
- sound_verify_evaluated_id(&scene->id);
if (sequence->scene_sound) {
BKE_sound_move_scene_sound(scene,
sequence->scene_sound,
@@ -669,7 +630,6 @@ void BKE_sound_set_cfra(int cfra)
void BKE_sound_set_scene_volume(Scene *scene, float volume)
{
- sound_verify_evaluated_id(&scene->id);
AUD_Sequence_setAnimationData(scene->sound_scene,
AUD_AP_VOLUME,
CFRA,
@@ -695,8 +655,6 @@ void BKE_sound_set_scene_sound_pan(void *handle, float pan, char animated)
void BKE_sound_update_sequencer(Main *main, bSound *sound)
{
- BLI_assert(!"is not supposed to be used, is weird function.");
-
Scene *scene;
for (scene = main->scenes.first; scene; scene = scene->id.next) {
@@ -706,8 +664,6 @@ void BKE_sound_update_sequencer(Main *main, bSound *sound)
static void sound_start_play_scene(Scene *scene)
{
- sound_verify_evaluated_id(&scene->id);
-
if (scene->playback_handle) {
AUD_Handle_stop(scene->playback_handle);
}
@@ -721,8 +677,6 @@ static void sound_start_play_scene(Scene *scene)
void BKE_sound_play_scene(Scene *scene)
{
- sound_verify_evaluated_id(&scene->id);
-
AUD_Status status;
const float cur_time = (float)((double)CFRA / FPS);
@@ -765,8 +719,6 @@ void BKE_sound_stop_scene(Scene *scene)
void BKE_sound_seek_scene(Main *bmain, Scene *scene)
{
- sound_verify_evaluated_id(&scene->id);
-
AUD_Status status;
bScreen *screen;
int animation_playing;
@@ -798,10 +750,9 @@ void BKE_sound_seek_scene(Main *bmain, Scene *scene)
}
}
- Scene *scene_orig = (Scene *)DEG_get_original_id(&scene->id);
- if (scene_orig->audio.flag & AUDIO_SCRUB && !animation_playing) {
+ if (scene->audio.flag & AUDIO_SCRUB && !animation_playing) {
AUD_Handle_setPosition(scene->playback_handle, cur_time);
- if (scene_orig->audio.flag & AUDIO_SYNC) {
+ if (scene->audio.flag & AUDIO_SYNC) {
AUD_seekSynchronizer(scene->playback_handle, cur_time);
}
AUD_Handle_resume(scene->playback_handle);
@@ -817,7 +768,7 @@ void BKE_sound_seek_scene(Main *bmain, Scene *scene)
}
}
else {
- if (scene_orig->audio.flag & AUDIO_SYNC) {
+ if (scene->audio.flag & AUDIO_SYNC) {
AUD_seekSynchronizer(scene->playback_handle, cur_time);
}
else {
@@ -832,8 +783,6 @@ void BKE_sound_seek_scene(Main *bmain, Scene *scene)
float BKE_sound_sync_scene(Scene *scene)
{
- sound_verify_evaluated_id(&scene->id);
-
// Ugly: Blender doesn't like it when the animation is played back during rendering
if (G.is_rendering) {
return NAN_FLT;
@@ -852,8 +801,6 @@ float BKE_sound_sync_scene(Scene *scene)
int BKE_sound_scene_playing(Scene *scene)
{
- sound_verify_evaluated_id(&scene->id);
-
// Ugly: Blender doesn't like it when the animation is played back during rendering
if (G.is_rendering) {
return -1;
@@ -884,9 +831,6 @@ void BKE_sound_free_waveform(bSound *sound)
sound->tags &= ~SOUND_TAGS_WAVEFORM_NO_RELOAD;
}
-/* TODO(sergey): Consider mamakinging this function fully autonomous, as in, not require having
- * an existing playback handle. That would make it easy to read waveforms, which doesn't seem to
- * be affected by evaluated scene (waveworm comes from file). */
void BKE_sound_read_waveform(bSound *sound, short *stop)
{
AUD_SoundInfo info = AUD_getInfo(sound->playback_handle);
@@ -935,14 +879,11 @@ static void sound_update_base(Scene *scene, Base *base, void *new_set)
Speaker *speaker;
float quat[4];
- sound_verify_evaluated_id(&scene->id);
- sound_verify_evaluated_id(&ob->id);
+ if ((ob->id.tag & LIB_TAG_DOIT) == 0) {
+ return;
+ }
- // TODO(sergey): Bring the test back, or make it a part of dependency graph update.
- // if ((ob->id.tag & LIB_TAG_DOIT) == 0) {
- // return;
- // }
- // ob->id.tag &= ~LIB_TAG_DOIT;
+ ob->id.tag &= ~LIB_TAG_DOIT;
if ((ob->type != OB_SPEAKER) || !ob->adt) {
return;
@@ -1005,8 +946,6 @@ static void sound_update_base(Scene *scene, Base *base, void *new_set)
void BKE_sound_update_scene(Main *bmain, Scene *scene)
{
- sound_verify_evaluated_id(&scene->id);
-
Base *base;
Scene *sce_it;
@@ -1016,8 +955,7 @@ void BKE_sound_update_scene(Main *bmain, Scene *scene)
/* cheap test to skip looping over all objects (no speakers is a common case) */
if (!BLI_listbase_is_empty(&bmain->speakers)) {
- // TODO(sergey): Bring the test back, or make it a part of dependency graph update.
- // BKE_main_id_tag_listbase(&bmain->objects, LIB_TAG_DOIT, true);
+ BKE_main_id_tag_listbase(&bmain->objects, LIB_TAG_DOIT, true);
for (ViewLayer *view_layer = scene->view_layers.first; view_layer;
view_layer = view_layer->next) {
@@ -1054,7 +992,6 @@ void *BKE_sound_get_factory(void *sound)
/* stupid wrapper because AUD_C-API.h includes Python.h which makesrna doesn't like */
float BKE_sound_get_length(bSound *sound)
{
- sound_verify_evaluated_id(&sound->id);
AUD_SoundInfo info = AUD_getInfo(sound->playback_handle);
return info.length;
@@ -1217,94 +1154,4 @@ char **BKE_sound_get_device_names(void)
return names;
}
-void BKE_sound_free_waveform(bSound *UNUSED(sound))
-{
-}
-
-void BKE_sound_load_audio(Main *UNUSED(bmain), bSound *UNUSED(sound))
-{
-}
-
#endif /* WITH_AUDASPACE */
-
-void BKE_sound_update_and_seek(Main *bmain, Depsgraph *depsgraph)
-{
- Scene *scene_orig = DEG_get_input_scene(depsgraph);
- Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
- /* NOTE: We don't do copy-on-write or anything like that here because we need to know scene's
- * flags like "scrubbing" in the BKE_sound_seek_scene(). So we simply update frame to which
- * seek needs to happen.
- *
- * TODO(sergey): Might change API so the frame is passes explicitly. */
- scene_eval->r.cfra = scene_orig->r.cfra;
- BKE_sound_seek_scene(bmain, scene_eval);
-}
-
-void BKE_sound_reset_scene_runtime(Scene *scene)
-{
- scene->sound_scene = NULL;
- scene->playback_handle = NULL;
- scene->sound_scrub_handle = NULL;
- scene->speaker_handles = NULL;
-}
-
-void BKE_sound_ensure_scene(struct Scene *scene)
-{
- if (scene->sound_scene != NULL) {
- return;
- }
- BKE_sound_create_scene(scene);
-}
-
-void BKE_sound_reset_runtime(bSound *sound)
-{
- sound->cache = NULL;
- sound->playback_handle = NULL;
-}
-
-void BKE_sound_ensure_loaded(Main *bmain, bSound *sound)
-{
- if (sound->cache != NULL) {
- return;
- }
- BKE_sound_load(bmain, sound);
-}
-
-void BKE_sound_jack_sync_callback_set(SoundJackSyncCallback callback)
-{
-#if defined(WITH_AUDASPACE) && defined(WITH_JACK)
- sound_jack_sync_callback = callback;
-#else
- UNUSED_VARS(callback);
-#endif
-}
-
-void BKE_sound_jack_scene_update(Scene *scene, int mode, float time)
-{
- sound_verify_evaluated_id(&scene->id);
-
- /* Ugly: Blender doesn't like it when the animation is played back during rendering. */
- if (G.is_rendering) {
- return;
- }
-
- if (mode) {
- BKE_sound_play_scene(scene);
- }
- else {
- BKE_sound_stop_scene(scene);
- }
-#ifdef WITH_AUDASPACE
- if (scene->playback_handle != NULL) {
- AUD_Handle_setPosition(scene->playback_handle, time);
- }
-#else
- UNUSED_VARS(time);
-#endif
-}
-
-void BKE_sound_evaluate(Depsgraph *depsgraph, Main *bmain, bSound *sound)
-{
- DEG_debug_print_eval(depsgraph, __func__, sound->id.name, sound);
- BKE_sound_ensure_loaded(bmain, sound);
-}
diff --git a/source/blender/blenkernel/intern/workspace.c b/source/blender/blenkernel/intern/workspace.c
index f9584adc6e0..669eb5c42dc 100644
--- a/source/blender/blenkernel/intern/workspace.c
+++ b/source/blender/blenkernel/intern/workspace.c
@@ -36,6 +36,7 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
+#include "DNA_windowmanager_types.h"
#include "DNA_workspace_types.h"
#include "DEG_depsgraph.h"
@@ -43,7 +44,8 @@
#include "MEM_guardedalloc.h"
/* -------------------------------------------------------------------- */
-/* Internal utils */
+/** \name Internal Utils
+ * \{ */
static void workspace_layout_name_set(WorkSpace *workspace,
WorkSpaceLayout *layout,
@@ -134,8 +136,11 @@ static bool UNUSED_FUNCTION(workspaces_is_screen_used)
return false;
}
+/** \} */
+
/* -------------------------------------------------------------------- */
-/* Create, delete, init */
+/** \name Create, Delete, Init
+ * \{ */
WorkSpace *BKE_workspace_add(Main *bmain, const char *name)
{
@@ -253,8 +258,11 @@ void BKE_workspace_relations_free(ListBase *relation_list)
}
}
+/** \} */
+
/* -------------------------------------------------------------------- */
-/* General Utils */
+/** \name General Utils
+ * \{ */
WorkSpaceLayout *BKE_workspace_layout_find(const WorkSpace *workspace, const bScreen *screen)
{
@@ -354,8 +362,32 @@ void BKE_workspace_tool_remove(struct WorkSpace *workspace, struct bToolRef *tre
MEM_freeN(tref);
}
+bool BKE_workspace_owner_id_check(const WorkSpace *workspace, const char *owner_id)
+{
+ 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;
+ }
+}
+
+void BKE_workspace_id_tag_all_visible(Main *bmain, int tag)
+{
+ BKE_main_id_tag_listbase(&bmain->workspaces, tag, false);
+ wmWindowManager *wm = bmain->wm.first;
+ for (wmWindow *win = wm->windows.first; win; win = win->next) {
+ WorkSpace *workspace = BKE_workspace_active_get(win->workspace_hook);
+ workspace->id.tag |= tag;
+ }
+}
+
+/** \} */
+
/* -------------------------------------------------------------------- */
-/* Getters/Setters */
+/** \name Getters/Setters
+ * \{ */
WorkSpace *BKE_workspace_active_get(WorkSpaceInstanceHook *hook)
{
@@ -433,13 +465,4 @@ void BKE_workspace_hook_layout_for_workspace_set(WorkSpaceInstanceHook *hook,
workspace_relation_ensure_updated(&workspace->hook_layout_relations, hook, layout);
}
-bool BKE_workspace_owner_id_check(const WorkSpace *workspace, const char *owner_id)
-{
- 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 under < ~16 items. */
- return BLI_findstring(&workspace->owner_ids, owner_id, offsetof(wmOwnerID, name)) != NULL;
- }
-}
+/** \} */
diff --git a/source/blender/blenkernel/intern/writeavi.c b/source/blender/blenkernel/intern/writeavi.c
index b72b99e514d..19425a0d80b 100644
--- a/source/blender/blenkernel/intern/writeavi.c
+++ b/source/blender/blenkernel/intern/writeavi.c
@@ -118,7 +118,6 @@ bMovieHandle *BKE_movie_handle_get(const char imtype)
mh.start_movie = start_stub;
mh.append_movie = append_stub;
mh.end_movie = end_stub;
- mh.get_next_frame = NULL;
mh.get_movie_path = NULL;
mh.context_create = context_create_stub;
mh.context_free = context_free_stub;
diff --git a/source/blender/blenlib/BLI_math_matrix.h b/source/blender/blenlib/BLI_math_matrix.h
index 652f096f32d..52d976daa2d 100644
--- a/source/blender/blenlib/BLI_math_matrix.h
+++ b/source/blender/blenlib/BLI_math_matrix.h
@@ -209,6 +209,7 @@ bool invert_m3(float R[3][3]);
bool invert_m3_m3(float R[3][3], const float A[3][3]);
bool invert_m4(float R[4][4]);
bool invert_m4_m4(float R[4][4], const float A[4][4]);
+bool invert_m4_m4_fallback(float R[4][4], const float A[4][4]);
/* double arithmetic (mixed float/double) */
void mul_m4_v4d(const float M[4][4], double r[4]);
@@ -260,6 +261,7 @@ float determinant_m2(float a, float b, float c, float d);
float determinant_m3(
float a, float b, float c, float d, float e, float f, float g, float h, float i);
float determinant_m3_array(const float m[3][3]);
+float determinant_m4_mat3_array(const float m[4][4]);
float determinant_m4(const float A[4][4]);
#define PSEUDOINVERSE_EPSILON 1e-8f
@@ -277,6 +279,9 @@ void invert_m4_m4_safe(float Ainv[4][4], const float A[4][4]);
void scale_m3_fl(float R[3][3], float scale);
void scale_m4_fl(float R[4][4], float scale);
+float mat3_to_volume_scale(const float M[3][3]);
+float mat4_to_volume_scale(const float M[4][4]);
+
float mat3_to_scale(const float M[3][3]);
float mat4_to_scale(const float M[4][4]);
float mat4_to_xy_scale(const float M[4][4]);
diff --git a/source/blender/blenlib/BLI_memblock.h b/source/blender/blenlib/BLI_memblock.h
new file mode 100644
index 00000000000..81dd2100362
--- /dev/null
+++ b/source/blender/blenlib/BLI_memblock.h
@@ -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.
+ *
+ * The Original Code is Copyright (C) 2008 Blender Foundation.
+ * All rights reserved.
+ */
+
+#ifndef __BLI_MEMBLOCK_H__
+#define __BLI_MEMBLOCK_H__
+
+/** \file
+ * \ingroup bli
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "BLI_compiler_attrs.h"
+
+struct BLI_memblock;
+
+typedef struct BLI_memblock BLI_memblock;
+typedef void (*MemblockValFreeFP)(void *val);
+
+BLI_memblock *BLI_memblock_create(uint elem_size,
+ const bool clear_alloc) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
+void *BLI_memblock_alloc(BLI_memblock *mblk) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1);
+void BLI_memblock_clear(BLI_memblock *mblk, MemblockValFreeFP valfreefp) ATTR_NONNULL(1);
+void BLI_memblock_destroy(BLI_memblock *mblk, MemblockValFreeFP free_callback) ATTR_NONNULL(1);
+
+typedef struct BLI_memblock_iter {
+ BLI_memblock *mblk;
+ int current_index;
+ int elem_per_chunk;
+} BLI_memblock_iter;
+
+void BLI_memblock_iternew(BLI_memblock *pool, BLI_memblock_iter *iter) ATTR_NONNULL();
+void *BLI_memblock_iterstep(BLI_memblock_iter *iter) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __BLI_MEMBLOCK_H__ */
diff --git a/source/blender/blenlib/BLI_rand.h b/source/blender/blenlib/BLI_rand.h
index 151b02a33aa..eec4e885493 100644
--- a/source/blender/blenlib/BLI_rand.h
+++ b/source/blender/blenlib/BLI_rand.h
@@ -25,6 +25,10 @@
* \brief Random number functions.
*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* RNG is an abstract random number generator type that avoids using globals.
* Always use this instead of the global RNG unless you have a good reason,
* the global RNG is not thread safe and will not give repeatable results.
@@ -106,4 +110,8 @@ void BLI_hammersley_1d(unsigned int n, double *r);
void BLI_halton_2d_sequence(unsigned int prime[2], double offset[2], int n, double *r);
void BLI_hammersley_2d_sequence(unsigned int n, double *r);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* __BLI_RAND_H__ */
diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt
index dbc72ff1213..0ec6e7ee4fc 100644
--- a/source/blender/blenlib/CMakeLists.txt
+++ b/source/blender/blenlib/CMakeLists.txt
@@ -48,6 +48,7 @@ set(SRC
intern/BLI_linklist.c
intern/BLI_linklist_lockfree.c
intern/BLI_memarena.c
+ intern/BLI_memblock.c
intern/BLI_memiter.c
intern/BLI_mempool.c
intern/BLI_timer.c
@@ -194,6 +195,7 @@ set(SRC
BLI_math_statistics.h
BLI_math_vector.h
BLI_memarena.h
+ BLI_memblock.h
BLI_memiter.h
BLI_memory_utils.h
BLI_mempool.h
diff --git a/source/blender/blenlib/intern/BLI_memblock.c b/source/blender/blenlib/intern/BLI_memblock.c
new file mode 100644
index 00000000000..50b1e14757c
--- /dev/null
+++ b/source/blender/blenlib/intern/BLI_memblock.c
@@ -0,0 +1,174 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2008 by Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup bli
+ *
+ * Dead simple, fast memory allocator for allocating many elements of the same size.
+ *
+ */
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "atomic_ops.h"
+
+#include "BLI_utildefines.h"
+
+#include "BLI_memblock.h" /* own include */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_strict_flags.h" /* keep last */
+
+#define BLI_MEM_BLOCK_CHUNK_SIZE (1 << 15) /* 32KiB */
+#define CHUNK_LIST_SIZE 16
+
+struct BLI_memblock {
+ void **chunk_list;
+
+ /** Element size in bytes. */
+ int elem_size;
+ /** First unused element index. */
+ int elem_next;
+ /** Last "touched" element. */
+ int elem_last;
+ /** Chunck size in bytes. */
+ int chunk_size;
+ /** Number of allocated chunck. */
+ int chunk_len;
+ /** Clear newly allocated chuncks. */
+ bool clear_alloc;
+};
+
+/**
+ * /clear_alloc will clear the memory the first time a chunck is allocated.
+ */
+BLI_memblock *BLI_memblock_create(uint elem_size, const bool clear_alloc)
+{
+ BLI_assert(elem_size < BLI_MEM_BLOCK_CHUNK_SIZE);
+
+ BLI_memblock *mblk = MEM_mallocN(sizeof(BLI_memblock), "BLI_memblock");
+ mblk->elem_size = (int)elem_size;
+ mblk->elem_next = 0;
+ mblk->elem_last = -1;
+ mblk->chunk_size = BLI_MEM_BLOCK_CHUNK_SIZE;
+ mblk->chunk_len = CHUNK_LIST_SIZE;
+ mblk->chunk_list = MEM_callocN(sizeof(void *) * (uint)mblk->chunk_len, "chunk list");
+ mblk->clear_alloc = clear_alloc;
+ return mblk;
+}
+
+void BLI_memblock_destroy(BLI_memblock *mblk, MemblockValFreeFP free_callback)
+{
+ if (free_callback) {
+ int elem_per_chunk = mblk->chunk_size / mblk->elem_size;
+
+ for (int i = mblk->elem_last; i >= 0; i--) {
+ int chunk_idx = i / elem_per_chunk;
+ int elem_idx = i - elem_per_chunk * chunk_idx;
+ void *val = (char *)(mblk->chunk_list[chunk_idx]) + mblk->elem_size * elem_idx;
+ free_callback(val);
+ }
+ }
+
+ for (int i = 0; i < mblk->chunk_len; i++) {
+ MEM_SAFE_FREE(mblk->chunk_list[i]);
+ }
+ MEM_SAFE_FREE(mblk->chunk_list);
+ MEM_freeN(mblk);
+}
+
+/* Reset elem count to 0 but keep as much memory allocated needed for at least the previous elem
+ * count. */
+void BLI_memblock_clear(BLI_memblock *mblk, MemblockValFreeFP free_callback)
+{
+ int elem_per_chunk = mblk->chunk_size / mblk->elem_size;
+ int last_used_chunk = (mblk->elem_next - 1) / elem_per_chunk;
+
+ if (free_callback) {
+ for (int i = mblk->elem_last; i >= mblk->elem_next; i--) {
+ int chunk_idx = i / elem_per_chunk;
+ int elem_idx = i - elem_per_chunk * chunk_idx;
+ void *val = (char *)(mblk->chunk_list[chunk_idx]) + mblk->elem_size * elem_idx;
+ free_callback(val);
+ }
+ }
+
+ for (int i = last_used_chunk + 1; i < mblk->chunk_len; i++) {
+ MEM_SAFE_FREE(mblk->chunk_list[i]);
+ }
+
+ if (UNLIKELY(last_used_chunk + 1 < mblk->chunk_len - CHUNK_LIST_SIZE)) {
+ mblk->chunk_len -= CHUNK_LIST_SIZE;
+ mblk->chunk_list = MEM_recallocN(mblk->chunk_list, sizeof(void *) * (uint)mblk->chunk_len);
+ }
+
+ mblk->elem_last = mblk->elem_next - 1;
+ mblk->elem_next = 0;
+}
+
+void *BLI_memblock_alloc(BLI_memblock *mblk)
+{
+ int elem_per_chunk = mblk->chunk_size / mblk->elem_size;
+ int chunk_idx = mblk->elem_next / elem_per_chunk;
+ int elem_idx = mblk->elem_next - elem_per_chunk * chunk_idx;
+
+ if (mblk->elem_last < mblk->elem_next) {
+ mblk->elem_last = mblk->elem_next;
+ }
+
+ mblk->elem_next++;
+
+ if (UNLIKELY(chunk_idx >= mblk->chunk_len)) {
+ mblk->chunk_len += CHUNK_LIST_SIZE;
+ mblk->chunk_list = MEM_recallocN(mblk->chunk_list, sizeof(void *) * (uint)mblk->chunk_len);
+ }
+
+ if (UNLIKELY(mblk->chunk_list[chunk_idx] == NULL)) {
+ if (mblk->clear_alloc) {
+ mblk->chunk_list[chunk_idx] = MEM_callocN((uint)mblk->chunk_size, "BLI_memblock chunk");
+ }
+ else {
+ mblk->chunk_list[chunk_idx] = MEM_mallocN((uint)mblk->chunk_size, "BLI_memblock chunk");
+ }
+ }
+
+ return (char *)(mblk->chunk_list[chunk_idx]) + mblk->elem_size * elem_idx;
+}
+
+void BLI_memblock_iternew(BLI_memblock *mblk, BLI_memblock_iter *iter)
+{
+ iter->mblk = mblk;
+ iter->current_index = 0;
+ iter->elem_per_chunk = mblk->chunk_size / mblk->elem_size;
+}
+
+void *BLI_memblock_iterstep(BLI_memblock_iter *iter)
+{
+ if (iter->current_index >= iter->mblk->elem_next) {
+ return NULL;
+ }
+
+ int chunk_idx = iter->current_index / iter->elem_per_chunk;
+ int elem_idx = iter->current_index - iter->elem_per_chunk * chunk_idx;
+ iter->current_index++;
+
+ return (char *)(iter->mblk->chunk_list[chunk_idx]) + iter->mblk->elem_size * elem_idx;
+}
diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c
index e09fae7d140..6ac1ac776b3 100644
--- a/source/blender/blenlib/intern/math_matrix.c
+++ b/source/blender/blenlib/intern/math_matrix.c
@@ -931,6 +931,13 @@ float determinant_m3_array(const float m[3][3])
m[2][0] * (m[0][1] * m[1][2] - m[0][2] * m[1][1]));
}
+float determinant_m4_mat3_array(const float m[4][4])
+{
+ return (m[0][0] * (m[1][1] * m[2][2] - m[1][2] * m[2][1]) -
+ m[1][0] * (m[0][1] * m[2][2] - m[0][2] * m[2][1]) +
+ m[2][0] * (m[0][1] * m[1][2] - m[0][2] * m[1][1]));
+}
+
bool invert_m3_ex(float m[3][3], const float epsilon)
{
float tmp[3][3];
@@ -1011,6 +1018,81 @@ bool invert_m4(float m[4][4])
return success;
}
+/**
+ * Computes the inverse of mat and puts it in inverse.
+ * Uses Gaussian Elimination with partial (maximal column) pivoting.
+ * \return true on success (i.e. can always find a pivot) and false on failure.
+ * Mark Segal - 1992.
+ *
+ * \note this is less performant than #EIG_invert_m4_m4 (Eigen), but e.g.
+ * for non-invertible scale matrices, findinging a partial solution can
+ * be useful to have a valid local transform center, see T57767.
+ */
+bool invert_m4_m4_fallback(float inverse[4][4], const float mat[4][4])
+{
+ if (EIG_invert_m4_m4(inverse, mat)) {
+ return true;
+ }
+
+ int i, j, k;
+ double temp;
+ float tempmat[4][4];
+ float max;
+ int maxj;
+
+ BLI_assert(inverse != mat);
+
+ /* Set inverse to identity */
+ for (i = 0; i < 4; i++)
+ for (j = 0; j < 4; j++)
+ inverse[i][j] = 0;
+ for (i = 0; i < 4; i++)
+ inverse[i][i] = 1;
+
+ /* Copy original matrix so we don't mess it up */
+ for (i = 0; i < 4; i++)
+ for (j = 0; j < 4; j++)
+ tempmat[i][j] = mat[i][j];
+
+ for (i = 0; i < 4; i++) {
+ /* Look for row with max pivot */
+ max = fabsf(tempmat[i][i]);
+ maxj = i;
+ for (j = i + 1; j < 4; j++) {
+ if (fabsf(tempmat[j][i]) > max) {
+ max = fabsf(tempmat[j][i]);
+ maxj = j;
+ }
+ }
+ /* Swap rows if necessary */
+ if (maxj != i) {
+ for (k = 0; k < 4; k++) {
+ SWAP(float, tempmat[i][k], tempmat[maxj][k]);
+ SWAP(float, inverse[i][k], inverse[maxj][k]);
+ }
+ }
+
+ if (UNLIKELY(tempmat[i][i] == 0.0f)) {
+ return false; /* No non-zero pivot */
+ }
+ temp = (double)tempmat[i][i];
+ for (k = 0; k < 4; k++) {
+ tempmat[i][k] = (float)((double)tempmat[i][k] / temp);
+ inverse[i][k] = (float)((double)inverse[i][k] / temp);
+ }
+ for (j = 0; j < 4; j++) {
+ if (j != i) {
+ temp = tempmat[j][i];
+ for (k = 0; k < 4; k++) {
+ tempmat[j][k] -= (float)((double)tempmat[i][k] * temp);
+ inverse[j][k] -= (float)((double)inverse[i][k] * temp);
+ }
+ }
+ }
+ }
+ return true;
+}
+
bool invert_m4_m4(float inverse[4][4], const float mat[4][4])
{
/* Use optimized matrix inverse from Eigen, since performance
@@ -1641,9 +1723,26 @@ void mat4_to_size(float size[3], const float mat[4][4])
size[2] = len_v3(mat[2]);
}
-/* this gets the average scale of a matrix, only use when your scaling
+/**
+ * This computes the overall volume scale factor of a transformation matrix.
+ * For an orthogonal matrix, it is the product of all three scale values.
+ * Returns a negative value if the transform is flipped by negative scale.
+ */
+float mat3_to_volume_scale(const float mat[3][3])
+{
+ return determinant_m3_array(mat);
+}
+
+float mat4_to_volume_scale(const float mat[4][4])
+{
+ return determinant_m4_mat3_array(mat);
+}
+
+/**
+ * This gets the average scale of a matrix, only use when your scaling
* data that has no idea of scale axis, examples are bone-envelope-radius
- * and curve radius */
+ * and curve radius.
+ */
float mat3_to_scale(const float mat[3][3])
{
/* unit length vector */
@@ -2003,10 +2102,12 @@ bool equals_m4m4(const float mat1[4][4], const float mat2[4][4])
equals_v4v4(mat1[2], mat2[2]) && equals_v4v4(mat1[3], mat2[3]));
}
-/* make a 4x4 matrix out of 3 transform components */
-/* matrices are made in the order: scale * rot * loc */
-/* TODO: need to have a version that allows for rotation order... */
-
+/**
+ * Make a 4x4 matrix out of 3 transform components.
+ * Matrices are made in the order: `scale * rot * loc`
+ *
+ * TODO: need to have a version that allows for rotation order...
+ */
void loc_eul_size_to_mat4(float mat[4][4],
const float loc[3],
const float eul[3],
@@ -2031,9 +2132,10 @@ void loc_eul_size_to_mat4(float mat[4][4],
mat[3][2] = loc[2];
}
-/* make a 4x4 matrix out of 3 transform components */
-
-/* matrices are made in the order: scale * rot * loc */
+/**
+ * Make a 4x4 matrix out of 3 transform components.
+ * Matrices are made in the order: `scale * rot * loc`
+ */
void loc_eulO_size_to_mat4(float mat[4][4],
const float loc[3],
const float eul[3],
@@ -2059,9 +2161,10 @@ void loc_eulO_size_to_mat4(float mat[4][4],
mat[3][2] = loc[2];
}
-/* make a 4x4 matrix out of 3 transform components */
-
-/* matrices are made in the order: scale * rot * loc */
+/**
+ * Make a 4x4 matrix out of 3 transform components.
+ * Matrices are made in the order: `scale * rot * loc`
+ */
void loc_quat_size_to_mat4(float mat[4][4],
const float loc[3],
const float quat[4],
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 28412bf6f34..e060c0f68d2 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -3764,9 +3764,6 @@ static void lib_link_pose(FileData *fd, Main *bmain, Object *ob, bPose *pose)
}
}
- /* avoid string */
- GHash *bone_hash = BKE_armature_bone_from_name_map(arm);
-
if (ob->proxy) {
/* sync proxy layer */
if (pose->proxy_layer) {
@@ -3775,7 +3772,7 @@ static void lib_link_pose(FileData *fd, Main *bmain, Object *ob, bPose *pose)
/* sync proxy active bone */
if (pose->proxy_act_bone[0]) {
- Bone *bone = BLI_ghash_lookup(bone_hash, pose->proxy_act_bone);
+ Bone *bone = BKE_armature_find_bone_name(arm, pose->proxy_act_bone);
if (bone) {
arm->act_bone = bone;
}
@@ -3785,7 +3782,7 @@ static void lib_link_pose(FileData *fd, Main *bmain, Object *ob, bPose *pose)
for (bPoseChannel *pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
lib_link_constraints(fd, (ID *)ob, &pchan->constraints);
- pchan->bone = BLI_ghash_lookup(bone_hash, pchan->name);
+ pchan->bone = BKE_armature_find_bone_name(arm, pchan->name);
IDP_LibLinkProperty(pchan->prop, fd);
@@ -3800,8 +3797,6 @@ static void lib_link_pose(FileData *fd, Main *bmain, Object *ob, bPose *pose)
}
}
- BLI_ghash_free(bone_hash, NULL, NULL);
-
if (rebuild) {
DEG_id_tag_update_ex(
bmain, &ob->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION);
@@ -3859,6 +3854,7 @@ static void direct_link_armature(FileData *fd, bArmature *arm)
Bone *bone;
link_list(fd, &arm->bonebase);
+ arm->bonehash = NULL;
arm->edbo = NULL;
arm->adt = newdataadr(fd, arm->adt);
@@ -3870,6 +3866,8 @@ static void direct_link_armature(FileData *fd, bArmature *arm)
arm->act_bone = newdataadr(fd, arm->act_bone);
arm->act_edbone = NULL;
+
+ BKE_armature_bone_hash_make(arm);
}
/** \} */
@@ -6466,7 +6464,9 @@ static void lib_link_scene(FileData *fd, Main *main)
seq->scene_sound = NULL;
if (seq->scene) {
seq->scene = newlibadr(fd, sce->id.lib, seq->scene);
- seq->scene_sound = NULL;
+ if (seq->scene) {
+ seq->scene_sound = BKE_sound_scene_add_scene_sound_defaults(sce, seq);
+ }
}
if (seq->clip) {
seq->clip = newlibadr_us(fd, sce->id.lib, seq->clip);
@@ -6487,7 +6487,7 @@ static void lib_link_scene(FileData *fd, Main *main)
}
if (seq->sound) {
id_us_plus_no_lib((ID *)seq->sound);
- seq->scene_sound = NULL;
+ seq->scene_sound = BKE_sound_add_scene_sound_defaults(sce, seq);
}
}
if (seq->type == SEQ_TYPE_TEXT) {
@@ -6506,6 +6506,9 @@ static void lib_link_scene(FileData *fd, Main *main)
}
}
+ BKE_sequencer_update_muting(sce->ed);
+ BKE_sequencer_update_sound_bounds_all(sce);
+
/* rigidbody world relies on it's linked collections */
if (sce->rigidbody_world) {
RigidBodyWorld *rbw = sce->rigidbody_world;
@@ -6635,6 +6638,13 @@ static void direct_link_paint(FileData *fd, const Scene *scene, Paint *p)
p->tool_slots = newdataadr(fd, p->tool_slots);
+ /* Workaround for invalid data written in older versions. */
+ const size_t expected_size = sizeof(PaintToolSlot) * p->tool_slots_len;
+ if (p->tool_slots && MEM_allocN_len(p->tool_slots) < expected_size) {
+ MEM_freeN(p->tool_slots);
+ p->tool_slots = MEM_callocN(expected_size, "PaintToolSlot");
+ }
+
BKE_paint_runtime_init(scene->toolsettings, p);
}
@@ -6687,7 +6697,7 @@ static void direct_link_scene(FileData *fd, Scene *sce)
memset(&sce->customdata_mask, 0, sizeof(sce->customdata_mask));
memset(&sce->customdata_mask_modal, 0, sizeof(sce->customdata_mask_modal));
- BKE_sound_reset_scene_runtime(sce);
+ BKE_sound_create_scene(sce);
/* set users to one by default, not in lib-link, this will increase it for compo nodes */
id_us_ensure_real(&sce->id);
@@ -7123,7 +7133,6 @@ static void direct_link_panel_list(FileData *fd, ListBase *lb)
link_list(fd, lb);
for (Panel *pa = lb->first; pa; pa = pa->next) {
- pa->paneltab = newdataadr(fd, pa->paneltab);
pa->runtime_flag = 0;
pa->activedata = NULL;
pa->type = NULL;
@@ -8428,9 +8437,10 @@ static void direct_link_sound(FileData *fd, bSound *sound)
sound->waveform = NULL;
}
- sound->spinlock = MEM_mallocN(sizeof(SpinLock), "sound_spinlock");
- BLI_spin_init(sound->spinlock);
-
+ if (sound->spinlock) {
+ sound->spinlock = MEM_mallocN(sizeof(SpinLock), "sound_spinlock");
+ BLI_spin_init(sound->spinlock);
+ }
/* clear waveform loading flag */
sound->tags &= ~SOUND_TAGS_WAVEFORM_LOADING;
@@ -8447,7 +8457,7 @@ static void lib_link_sound(FileData *fd, Main *main)
sound->ipo = newlibadr_us(
fd, sound->id.lib, sound->ipo); // XXX deprecated - old animation system
- BKE_sound_reset_runtime(sound);
+ BKE_sound_load(main, sound);
sound->id.tag &= ~LIB_TAG_NEED_LINK;
}
@@ -9623,6 +9633,9 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
/* Don't read the active app template, use the default one. */
user->app_template[0] = '\0';
+ /* Clear runtime data. */
+ user->runtime.is_dirty = false;
+
/* free fd->datamap again */
oldnewmap_free_unused(fd->datamap);
oldnewmap_clear(fd->datamap);
@@ -9643,14 +9656,17 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath)
ListBase mainlist = {NULL, NULL};
bfd = MEM_callocN(sizeof(BlendFileData), "blendfiledata");
- bfd->main = BKE_main_new();
- BLI_addtail(&mainlist, bfd->main);
- fd->mainlist = &mainlist;
+ bfd->main = BKE_main_new();
bfd->main->versionfile = fd->fileversion;
bfd->type = BLENFILETYPE_BLEND;
- BLI_strncpy(bfd->main->name, filepath, sizeof(bfd->main->name));
+
+ if ((fd->skip_flags & BLO_READ_SKIP_DATA) == 0) {
+ BLI_addtail(&mainlist, bfd->main);
+ fd->mainlist = &mainlist;
+ BLI_strncpy(bfd->main->name, filepath, sizeof(bfd->main->name));
+ }
if (G.background) {
/* We only read & store .blend thumbnail in background mode
@@ -9728,45 +9744,52 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath)
/* do before read_libraries, but skip undo case */
if (fd->memfile == NULL) {
- do_versions(fd, NULL, bfd->main);
- do_versions_userdef(fd, bfd);
+ if ((fd->skip_flags & BLO_READ_SKIP_DATA) == 0) {
+ do_versions(fd, NULL, bfd->main);
+ }
+
+ if ((fd->skip_flags & BLO_READ_SKIP_USERDEF) == 0) {
+ do_versions_userdef(fd, bfd);
+ }
}
- read_libraries(fd, &mainlist);
+ if ((fd->skip_flags & BLO_READ_SKIP_DATA) == 0) {
+ read_libraries(fd, &mainlist);
- blo_join_main(&mainlist);
+ blo_join_main(&mainlist);
- lib_link_all(fd, bfd->main);
+ lib_link_all(fd, bfd->main);
- /* Skip in undo case. */
- if (fd->memfile == NULL) {
- /* Yep, second splitting... but this is a very cheap operation, so no big deal. */
- blo_split_main(&mainlist, bfd->main);
- for (Main *mainvar = mainlist.first; mainvar; mainvar = mainvar->next) {
- BLI_assert(mainvar->versionfile != 0);
- do_versions_after_linking(mainvar);
- }
- blo_join_main(&mainlist);
+ /* Skip in undo case. */
+ if (fd->memfile == NULL) {
+ /* Yep, second splitting... but this is a very cheap operation, so no big deal. */
+ blo_split_main(&mainlist, bfd->main);
+ for (Main *mainvar = mainlist.first; mainvar; mainvar = mainvar->next) {
+ BLI_assert(mainvar->versionfile != 0);
+ do_versions_after_linking(mainvar);
+ }
+ blo_join_main(&mainlist);
- /* After all data has been read and versioned, uses LIB_TAG_NEW. */
- ntreeUpdateAllNew(bfd->main);
- }
+ /* After all data has been read and versioned, uses LIB_TAG_NEW. */
+ ntreeUpdateAllNew(bfd->main);
+ }
- BKE_main_id_tag_all(bfd->main, LIB_TAG_NEW, false);
+ BKE_main_id_tag_all(bfd->main, LIB_TAG_NEW, false);
- /* Now that all our data-blocks are loaded,
- * we can re-generate overrides from their references. */
- if (fd->memfile == NULL) {
- /* Do not apply in undo case! */
- BKE_main_override_static_update(bfd->main);
- }
+ /* Now that all our data-blocks are loaded,
+ * we can re-generate overrides from their references. */
+ if (fd->memfile == NULL) {
+ /* Do not apply in undo case! */
+ BKE_main_override_static_update(bfd->main);
+ }
- BKE_collections_after_lib_link(bfd->main);
+ BKE_collections_after_lib_link(bfd->main);
- fix_relpaths_library(fd->relabase,
- bfd->main); /* make all relative paths, relative to the open blend file */
+ /* Make all relative paths, relative to the open blend file. */
+ fix_relpaths_library(fd->relabase, bfd->main);
- link_global(fd, bfd); /* as last */
+ link_global(fd, bfd); /* as last */
+ }
fd->mainlist = NULL; /* Safety, this is local variable, shall not be used afterward. */
diff --git a/source/blender/blenloader/intern/versioning_250.c b/source/blender/blenloader/intern/versioning_250.c
index face4b61d1e..7b239105251 100644
--- a/source/blender/blenloader/intern/versioning_250.c
+++ b/source/blender/blenloader/intern/versioning_250.c
@@ -285,8 +285,8 @@ static void area_add_window_regions(ScrArea *sa, SpaceLink *sl, ListBase *lb)
memcpy(&ar->v2d, &sipo->v2d, sizeof(View2D));
/* init mainarea view2d */
- ar->v2d.scroll |= (V2D_SCROLL_BOTTOM | V2D_SCROLL_SCALE_HORIZONTAL);
- ar->v2d.scroll |= (V2D_SCROLL_LEFT | V2D_SCROLL_SCALE_VERTICAL);
+ ar->v2d.scroll |= (V2D_SCROLL_BOTTOM | V2D_SCROLL_HORIZONTAL_HANDLES);
+ ar->v2d.scroll |= (V2D_SCROLL_LEFT | V2D_SCROLL_VERTICAL_HANDLES);
ar->v2d.min[0] = FLT_MIN;
ar->v2d.min[1] = FLT_MIN;
@@ -304,7 +304,7 @@ static void area_add_window_regions(ScrArea *sa, SpaceLink *sl, ListBase *lb)
ar->v2d.tot.ymin = (float)(-sa->winy) / 3.0f;
ar->v2d.tot.ymax = 0.0f;
- ar->v2d.scroll |= (V2D_SCROLL_BOTTOM | V2D_SCROLL_SCALE_HORIZONTAL);
+ ar->v2d.scroll |= (V2D_SCROLL_BOTTOM | V2D_SCROLL_HORIZONTAL_HANDLES);
ar->v2d.scroll |= (V2D_SCROLL_RIGHT);
ar->v2d.align = V2D_ALIGN_NO_POS_Y;
ar->v2d.flag |= V2D_VIEWSYNC_AREA_VERTICAL;
@@ -330,7 +330,7 @@ static void area_add_window_regions(ScrArea *sa, SpaceLink *sl, ListBase *lb)
ar->v2d.minzoom = 0.01f;
ar->v2d.maxzoom = 50;
- ar->v2d.scroll = (V2D_SCROLL_BOTTOM | V2D_SCROLL_SCALE_HORIZONTAL);
+ ar->v2d.scroll = (V2D_SCROLL_BOTTOM | V2D_SCROLL_HORIZONTAL_HANDLES);
ar->v2d.scroll |= (V2D_SCROLL_RIGHT);
ar->v2d.keepzoom = V2D_LOCKZOOM_Y;
ar->v2d.align = V2D_ALIGN_NO_POS_Y;
@@ -349,8 +349,8 @@ static void area_add_window_regions(ScrArea *sa, SpaceLink *sl, ListBase *lb)
SpaceSeq *sseq = (SpaceSeq *)sl;
memcpy(&ar->v2d, &sseq->v2d, sizeof(View2D));
- ar->v2d.scroll |= (V2D_SCROLL_BOTTOM | V2D_SCROLL_SCALE_HORIZONTAL);
- ar->v2d.scroll |= (V2D_SCROLL_LEFT | V2D_SCROLL_SCALE_VERTICAL);
+ ar->v2d.scroll |= (V2D_SCROLL_BOTTOM | V2D_SCROLL_HORIZONTAL_HANDLES);
+ ar->v2d.scroll |= (V2D_SCROLL_LEFT | V2D_SCROLL_VERTICAL_HANDLES);
ar->v2d.align = V2D_ALIGN_NO_NEG_Y;
ar->v2d.flag |= V2D_IS_INITIALISED;
break;
diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c
index 3a16389dfda..c7bcbf3d864 100644
--- a/source/blender/blenloader/intern/versioning_280.c
+++ b/source/blender/blenloader/intern/versioning_280.c
@@ -421,10 +421,13 @@ static void do_version_layers_to_collections(Main *bmain, Scene *scene)
Collection *collection = BKE_collection_add(bmain, collection_master, name);
collection->id.lib = scene->id.lib;
+ if (collection->id.lib != NULL) {
+ collection->id.tag |= LIB_TAG_INDIRECT;
+ }
collections[layer] = collection;
if (!(scene->lay & (1 << layer))) {
- collection->flag |= COLLECTION_RESTRICT_VIEW | COLLECTION_RESTRICT_RENDER;
+ collection->flag |= COLLECTION_RESTRICT_VIEWPORT | COLLECTION_RESTRICT_RENDER;
}
}
@@ -692,6 +695,26 @@ static void do_version_bbone_scale_animdata_cb(ID *UNUSED(id),
}
}
+static void do_version_constraints_maintain_volume_mode_uniform(ListBase *lb)
+{
+ for (bConstraint *con = lb->first; con; con = con->next) {
+ if (con->type == CONSTRAINT_TYPE_SAMEVOL) {
+ bSameVolumeConstraint *data = (bSameVolumeConstraint *)con->data;
+ data->mode = SAMEVOL_UNIFORM;
+ }
+ }
+}
+
+static void do_version_constraints_copy_scale_power(ListBase *lb)
+{
+ for (bConstraint *con = lb->first; con; con = con->next) {
+ if (con->type == CONSTRAINT_TYPE_SIZELIKE) {
+ bSizeLikeConstraint *data = (bSizeLikeConstraint *)con->data;
+ data->power = 1.0f;
+ }
+ }
+}
+
void do_versions_after_linking_280(Main *bmain)
{
bool use_collection_compat_28 = true;
@@ -705,7 +728,7 @@ void do_versions_after_linking_280(Main *bmain)
/* Add fake user for all existing groups. */
id_fake_user_set(&collection->id);
- if (collection->flag & (COLLECTION_RESTRICT_VIEW | COLLECTION_RESTRICT_RENDER)) {
+ if (collection->flag & (COLLECTION_RESTRICT_VIEWPORT | COLLECTION_RESTRICT_RENDER)) {
continue;
}
@@ -731,7 +754,8 @@ void do_versions_after_linking_280(Main *bmain)
char name[MAX_ID_NAME];
BLI_snprintf(name, sizeof(name), DATA_("Hidden %d"), coll_idx + 1);
*collection_hidden = BKE_collection_add(bmain, collection, name);
- (*collection_hidden)->flag |= COLLECTION_RESTRICT_VIEW | COLLECTION_RESTRICT_RENDER;
+ (*collection_hidden)->flag |= COLLECTION_RESTRICT_VIEWPORT |
+ COLLECTION_RESTRICT_RENDER;
}
BKE_collection_object_add(bmain, *collection_hidden, ob);
@@ -1290,6 +1314,16 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
}
+
+ /* 2.79 style Maintain Volume mode. */
+ LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
+ do_version_constraints_maintain_volume_mode_uniform(&ob->constraints);
+ if (ob->pose) {
+ LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) {
+ do_version_constraints_maintain_volume_mode_uniform(&pchan->constraints);
+ }
+ }
+ }
}
#ifdef USE_COLLECTION_COMPAT_28
@@ -2842,7 +2876,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
for (Material *mat = bmain->materials.first; mat; mat = mat->id.next) {
- mat->blend_flag &= ~(MA_BL_FLAG_UNUSED_2);
+ mat->blend_flag &= ~(1 << 2); /* UNUSED */
}
}
@@ -3353,7 +3387,69 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
+ if (!MAIN_VERSION_ATLEAST(bmain, 280, 61)) {
+ /* Added a power option to Copy Scale. */
+ if (!DNA_struct_elem_find(fd->filesdna, "bSizeLikeConstraint", "float", "power")) {
+ LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
+ do_version_constraints_copy_scale_power(&ob->constraints);
+ if (ob->pose) {
+ LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) {
+ do_version_constraints_copy_scale_power(&pchan->constraints);
+ }
+ }
+ }
+ }
+
+ for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
+ for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
+ for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) {
+ if (ELEM(sl->spacetype, SPACE_CLIP, SPACE_GRAPH, SPACE_SEQ)) {
+ ListBase *regionbase = (sl == sa->spacedata.first) ? &sa->regionbase : &sl->regionbase;
+
+ ARegion *ar = NULL;
+ if (sl->spacetype == SPACE_CLIP) {
+ if (((SpaceClip *)sl)->view == SC_VIEW_GRAPH) {
+ ar = do_versions_find_region(regionbase, RGN_TYPE_PREVIEW);
+ }
+ }
+ else {
+ ar = do_versions_find_region(regionbase, RGN_TYPE_WINDOW);
+ }
+
+ if (ar != NULL) {
+ ar->v2d.scroll &= ~V2D_SCROLL_LEFT;
+ ar->v2d.scroll |= V2D_SCROLL_RIGHT;
+ }
+ }
+ }
+ }
+ }
+
+ for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
+ for (ScrArea *area = screen->areabase.first; area; area = area->next) {
+ for (SpaceLink *sl = area->spacedata.first; sl; sl = sl->next) {
+ if (sl->spacetype != SPACE_OUTLINER) {
+ continue;
+ }
+ SpaceOutliner *so = (SpaceOutliner *)sl;
+ so->filter &= ~SO_FLAG_UNUSED_1;
+ so->show_restrict_flags = SO_RESTRICT_ENABLE | SO_RESTRICT_SELECT | SO_RESTRICT_HIDE;
+ }
+ }
+ }
+ }
+
{
/* Versioning code until next subversion bump goes here. */
+ LISTBASE_FOREACH (bArmature *, arm, &bmain->armatures) {
+ arm->flag &= ~(ARM_FLAG_UNUSED_7 | ARM_FLAG_UNUSED_9);
+ }
+
+ /* Initializes sun lights with the new angular diameter property */
+ if (!DNA_struct_elem_find(fd->filesdna, "Light", "float", "sun_angle")) {
+ LISTBASE_FOREACH (Light *, light, &bmain->lights) {
+ light->sun_angle = 2.0f * atanf(light->area_size);
+ }
+ }
}
}
diff --git a/source/blender/blenloader/intern/versioning_cycles.c b/source/blender/blenloader/intern/versioning_cycles.c
index 023bd685352..7616e62af9f 100644
--- a/source/blender/blenloader/intern/versioning_cycles.c
+++ b/source/blender/blenloader/intern/versioning_cycles.c
@@ -38,6 +38,8 @@
#include "BKE_main.h"
#include "BKE_node.h"
+#include "IMB_colormanagement.h"
+
#include "BLO_readfile.h"
#include "readfile.h"
@@ -47,6 +49,12 @@ static float *cycles_node_socket_float_value(bNodeSocket *socket)
return &socket_data->value;
}
+static float *cycles_node_socket_rgba_value(bNodeSocket *socket)
+{
+ bNodeSocketValueRGBA *socket_data = socket->default_value;
+ return socket_data->value;
+}
+
static IDProperty *cycles_properties_from_ID(ID *id)
{
IDProperty *idprop = IDP_GetProperties(id, false);
@@ -262,6 +270,114 @@ static void ambient_occlusion_node_relink(bNodeTree *ntree)
}
}
+static void image_node_colorspace(bNode *node)
+{
+ if (node->id == NULL) {
+ return;
+ }
+
+ int color_space;
+ if (node->type == SH_NODE_TEX_IMAGE) {
+ NodeTexImage *tex = node->storage;
+ color_space = tex->color_space;
+ }
+ else if (node->type == SH_NODE_TEX_ENVIRONMENT) {
+ NodeTexEnvironment *tex = node->storage;
+ color_space = tex->color_space;
+ }
+ else {
+ return;
+ }
+
+ const int SHD_COLORSPACE_NONE = 0;
+ Image *image = (Image *)node->id;
+ if (color_space == SHD_COLORSPACE_NONE) {
+ STRNCPY(image->colorspace_settings.name,
+ IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_DATA));
+ }
+}
+
+static void light_emission_node_to_energy(Light *light, float *energy, float color[3])
+{
+ *energy = 1.0;
+ copy_v3_fl(color, 1.0f);
+
+ /* If nodetree has animation or drivers, don't try to convert. */
+ bNodeTree *ntree = light->nodetree;
+ if (ntree == NULL || ntree->adt) {
+ return;
+ }
+
+ /* Find emission node */
+ bNode *output_node = ntreeShaderOutputNode(ntree, SHD_OUTPUT_CYCLES);
+ if (output_node == NULL) {
+ return;
+ }
+
+ bNode *emission_node = NULL;
+ for (bNodeLink *link = ntree->links.first; link; link = link->next) {
+ if (link->tonode == output_node && link->fromnode->type == SH_NODE_EMISSION) {
+ emission_node = link->fromnode;
+ break;
+ }
+ }
+
+ if (emission_node == NULL) {
+ return;
+ }
+
+ /* Don't convert if anything is linked */
+ bNodeSocket *strength_socket = nodeFindSocket(emission_node, SOCK_IN, "Strength");
+ bNodeSocket *color_socket = nodeFindSocket(emission_node, SOCK_IN, "Color");
+
+ if ((strength_socket->flag & SOCK_IN_USE) || (color_socket->flag & SOCK_IN_USE)) {
+ return;
+ }
+
+ float *strength_value = cycles_node_socket_float_value(strength_socket);
+ float *color_value = cycles_node_socket_rgba_value(color_socket);
+
+ *energy = *strength_value;
+ copy_v3_v3(color, color_value);
+
+ *strength_value = 1.0f;
+ copy_v4_fl(color_value, 1.0f);
+ light->use_nodes = false;
+}
+
+static void light_emission_unify(Light *light, const char *engine)
+{
+ if (light->type != LA_SUN) {
+ light->energy *= 100.0f;
+ }
+
+ /* Attempt to extract constant energy and color from nodes. */
+ bool use_nodes = light->use_nodes;
+ float energy, color[3];
+ light_emission_node_to_energy(light, &energy, color);
+
+ if (STREQ(engine, "CYCLES")) {
+ if (use_nodes) {
+ /* Energy extracted from nodes */
+ light->energy = energy;
+ copy_v3_v3(&light->r, color);
+ }
+ else {
+ /* Default cycles multipliers if there are no nodes */
+ if (light->type == LA_SUN) {
+ light->energy = 1.0f;
+ }
+ else {
+ light->energy = 100.0f;
+ }
+ }
+ }
+ else {
+ /* Disable nodes if scene was configured for Eevee */
+ light->use_nodes = false;
+ }
+}
+
void blo_do_versions_cycles(FileData *UNUSED(fd), Library *UNUSED(lib), Main *bmain)
{
/* Particle shape shared with Eevee. */
@@ -326,7 +442,23 @@ void do_versions_after_linking_cycles(Main *bmain)
if (!MAIN_VERSION_ATLEAST(bmain, 279, 5)) {
ambient_occlusion_node_relink(ntree);
}
+
+ if (!MAIN_VERSION_ATLEAST(bmain, 280, 63)) {
+ for (bNode *node = ntree->nodes.first; node; node = node->next) {
+ image_node_colorspace(node);
+ }
+ }
}
FOREACH_NODETREE_END;
}
+
+ if (!MAIN_VERSION_ATLEAST(bmain, 280, 64)) {
+ /* Unfiy Cycles and Eevee settings. */
+ Scene *scene = bmain->scenes.first;
+ const char *engine = (scene) ? scene->r.engine : "CYCLES";
+
+ for (Light *light = bmain->lights.first; light; light = light->id.next) {
+ light_emission_unify(light, engine);
+ }
+ }
}
diff --git a/source/blender/blenloader/intern/versioning_defaults.c b/source/blender/blenloader/intern/versioning_defaults.c
index 1da9d692440..2d6f0015634 100644
--- a/source/blender/blenloader/intern/versioning_defaults.c
+++ b/source/blender/blenloader/intern/versioning_defaults.c
@@ -281,17 +281,45 @@ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)
}
for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
- /* Hide channels in timelines. */
for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
- SpaceAction *saction = (sa->spacetype == SPACE_ACTION) ? sa->spacedata.first : NULL;
+ if (sa->spacetype == SPACE_ACTION) {
+ /* Show marker lines, hide channels and collapse summary in timelines. */
+ SpaceAction *saction = sa->spacedata.first;
+ saction->flag |= SACTION_SHOW_MARKER_LINES;
- if (saction && saction->mode == SACTCONT_TIMELINE) {
- for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) {
- if (ar->regiontype == RGN_TYPE_CHANNELS) {
- ar->flag |= RGN_FLAG_HIDDEN;
+ if (saction->mode == SACTCONT_TIMELINE) {
+ saction->ads.flag |= ADS_FLAG_SUMMARY_COLLAPSED;
+
+ for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) {
+ if (ar->regiontype == RGN_TYPE_CHANNELS) {
+ ar->flag |= RGN_FLAG_HIDDEN;
+ }
}
}
}
+ else if (sa->spacetype == SPACE_GRAPH) {
+ SpaceGraph *sipo = sa->spacedata.first;
+ sipo->flag |= SIPO_MARKER_LINES;
+ }
+ else if (sa->spacetype == SPACE_NLA) {
+ SpaceNla *snla = sa->spacedata.first;
+ snla->flag |= SNLA_SHOW_MARKER_LINES;
+ }
+ else if (sa->spacetype == SPACE_TEXT) {
+ /* Show syntax and line numbers in Script workspace text editor. */
+ SpaceText *stext = sa->spacedata.first;
+ stext->showsyntax = true;
+ stext->showlinenrs = true;
+ }
+ else if (sa->spacetype == SPACE_VIEW3D) {
+ /* Screen space cavity by default for faster performance. */
+ View3D *v3d = sa->spacedata.first;
+ v3d->shading.cavity_type = V3D_SHADING_CAVITY_CURVATURE;
+ }
+ else if (sa->spacetype == SPACE_CLIP) {
+ SpaceClip *sclip = sa->spacedata.first;
+ sclip->around = V3D_AROUND_CENTER_MEDIAN;
+ }
}
}
diff --git a/source/blender/blenloader/intern/versioning_userdef.c b/source/blender/blenloader/intern/versioning_userdef.c
index 46fd58e59c1..909334ae26f 100644
--- a/source/blender/blenloader/intern/versioning_userdef.c
+++ b/source/blender/blenloader/intern/versioning_userdef.c
@@ -19,7 +19,7 @@
*
* Version patch user preferences.
*/
-
+#define DNA_DEPRECATED_ALLOW
#include <string.h>
#include "BLI_math.h"
@@ -28,6 +28,7 @@
#include "DNA_userdef_types.h"
#include "DNA_curve_types.h"
#include "DNA_windowmanager_types.h"
+#include "DNA_scene_types.h"
#include "BKE_addon.h"
#include "BKE_colorband.h"
@@ -42,7 +43,7 @@
/* Disallow access to global userdef. */
#define U (_error_)
-static void do_versions_theme(UserDef *userdef, bTheme *btheme)
+static void do_versions_theme(const UserDef *userdef, bTheme *btheme)
{
#define USER_VERSION_ATLEAST(ver, subver) MAIN_VERSION_ATLEAST(userdef, ver, subver)
@@ -113,13 +114,30 @@ static void do_versions_theme(UserDef *userdef, bTheme *btheme)
FROM_DEFAULT_V4_UCHAR(space_info.info_info);
}
+ if (!USER_VERSION_ATLEAST(280, 64)) {
+ FROM_DEFAULT_V4_UCHAR(tui.icon_scene);
+
+ if (btheme->space_view3d.obcenter_dia == 0) {
+ btheme->space_view3d.obcenter_dia = U_theme_default.space_view3d.obcenter_dia;
+ }
+
+ FROM_DEFAULT_V4_UCHAR(space_graph.text);
+ FROM_DEFAULT_V4_UCHAR(space_action.text);
+ FROM_DEFAULT_V4_UCHAR(space_nla.text);
+ FROM_DEFAULT_V4_UCHAR(space_sequencer.text);
+ FROM_DEFAULT_V4_UCHAR(space_clip.text);
+
+ FROM_DEFAULT_V4_UCHAR(space_graph.scrubbing_background);
+ FROM_DEFAULT_V4_UCHAR(space_action.scrubbing_background);
+ FROM_DEFAULT_V4_UCHAR(space_nla.scrubbing_background);
+ FROM_DEFAULT_V4_UCHAR(space_sequencer.scrubbing_background);
+ FROM_DEFAULT_V4_UCHAR(space_clip.scrubbing_background);
+ }
+
/**
* Include next version bump.
*/
{
- if (btheme->space_view3d.obcenter_dia == 0) {
- btheme->space_view3d.obcenter_dia = U_theme_default.space_view3d.obcenter_dia;
- }
}
#undef FROM_DEFAULT_V4_UCHAR
@@ -542,19 +560,48 @@ void BLO_version_defaults_userpref_blend(Main *bmain, UserDef *userdef)
userdef->dupflag |= USER_DUP_GPENCIL;
}
- /**
- * Include next version bump.
- */
- {
+ if (!USER_VERSION_ATLEAST(280, 60)) {
+ const float GPU_VIEWPORT_QUALITY_FXAA = 0.10f;
+ const float GPU_VIEWPORT_QUALITY_TAA8 = 0.25f;
+ const float GPU_VIEWPORT_QUALITY_TAA16 = 0.6f;
+ const float GPU_VIEWPORT_QUALITY_TAA32 = 0.8f;
+
+ if (userdef->gpu_viewport_quality <= GPU_VIEWPORT_QUALITY_FXAA) {
+ userdef->viewport_aa = SCE_DISPLAY_AA_OFF;
+ }
+ else if (userdef->gpu_viewport_quality <= GPU_VIEWPORT_QUALITY_TAA8) {
+ userdef->viewport_aa = SCE_DISPLAY_AA_FXAA;
+ }
+ else if (userdef->gpu_viewport_quality <= GPU_VIEWPORT_QUALITY_TAA16) {
+ userdef->viewport_aa = SCE_DISPLAY_AA_SAMPLES_8;
+ }
+ else if (userdef->gpu_viewport_quality <= GPU_VIEWPORT_QUALITY_TAA32) {
+ userdef->viewport_aa = SCE_DISPLAY_AA_SAMPLES_16;
+ }
+ else {
+ userdef->viewport_aa = SCE_DISPLAY_AA_SAMPLES_32;
+ }
+ }
+
+ if (!USER_VERSION_ATLEAST(280, 62)) {
/* (keep this block even if it becomes empty). */
if (userdef->vbotimeout == 0) {
userdef->vbocollectrate = 60;
userdef->vbotimeout = 120;
}
- if (userdef->lookdev_ball_size == 0) {
- userdef->lookdev_ball_size = 150;
+ if (userdef->lookdev_sphere_size == 0) {
+ userdef->lookdev_sphere_size = 150;
}
+
+ userdef->pref_flag |= USER_PREF_FLAG_SAVE;
+ }
+
+ /**
+ * Include next version bump.
+ */
+ {
+ /* pass */
}
if (userdef->pixelsize == 0.0f) {
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 1e2bbc138a3..5a1ce7177c2 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -2417,7 +2417,7 @@ static void write_paint(WriteData *wd, Paint *p)
if (p->cavity_curve) {
write_curvemapping(wd, p->cavity_curve);
}
- writedata(wd, DATA, sizeof(PaintToolSlot) * p->tool_slots_len, p->tool_slots);
+ writestruct(wd, DATA, PaintToolSlot, p->tool_slots_len, p->tool_slots);
}
static void write_layer_collections(WriteData *wd, ListBase *lb)
diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c
index cb10ec9d701..a35d10db697 100644
--- a/source/blender/bmesh/intern/bmesh_mesh.c
+++ b/source/blender/bmesh/intern/bmesh_mesh.c
@@ -1440,7 +1440,6 @@ static int bm_loop_normal_mark_indiv(BMesh *bm, BLI_bitmap *loops)
* Note that this is On² piece of code,
* but it is not designed to be used with huge selection sets,
* rather with only a few items selected at most.*/
- printf("using face history selection\n");
/* Goes from last selected to the first selected element. */
for (ese = bm->selected.last; ese; ese = ese->prev) {
if (ese->htype == BM_FACE) {
@@ -1473,7 +1472,6 @@ static int bm_loop_normal_mark_indiv(BMesh *bm, BLI_bitmap *loops)
else {
if (sel_faces) {
/* Only select all loops of selected faces. */
- printf("using face selection\n");
BMLoop *l;
BMFace *f;
BMIter liter, fiter;
@@ -1487,7 +1485,6 @@ static int bm_loop_normal_mark_indiv(BMesh *bm, BLI_bitmap *loops)
}
if (sel_edges) {
/* Only select all loops of selected edges. */
- printf("using edge selection\n");
BMLoop *l;
BMEdge *e;
BMIter liter, eiter;
@@ -1510,7 +1507,6 @@ static int bm_loop_normal_mark_indiv(BMesh *bm, BLI_bitmap *loops)
}
if (sel_verts) {
/* Select all loops of selected verts. */
- printf("using vert selection\n");
BMLoop *l;
BMVert *v;
BMIter liter, viter;
diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c
index af5ce4ed9ac..a559d13fc70 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.c
+++ b/source/blender/bmesh/tools/bmesh_bevel.c
@@ -5222,7 +5222,7 @@ static BevVert *bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
BMIter iter;
EdgeHalf *e;
float weight, z;
- float vert_axis[3];
+ float vert_axis[3] = {0, 0, 0};
int i, ccw_test_sum;
int nsel = 0;
int ntot = 0;
@@ -5357,7 +5357,6 @@ static BevVert *bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
normalize_v3(edge_dir);
add_v3_v3v3(vert_axis, vert_axis, edge_dir);
}
- mul_v3_fl(vert_axis, 1 / ntot);
}
}
@@ -5430,8 +5429,7 @@ static BevVert *bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
case BEVEL_AMT_WIDTH: {
v2 = BM_edge_other_vert(e->e, bv->v);
sub_v3_v3v3(edge_dir, bv->v->co, v2->co);
- normalize_v3(edge_dir);
- z = fabsf(2.0f * sinf(angle_normalized_v3v3(vert_axis, edge_dir)));
+ z = fabsf(2.0f * sinf(angle_v3v3(vert_axis, edge_dir)));
if (z < BEVEL_EPSILON) {
e->offset_l_spec = 0.01f * bp->offset; /* undefined behavior, so tiny bevel. */
}
@@ -5443,8 +5441,7 @@ static BevVert *bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
case BEVEL_AMT_DEPTH: {
v2 = BM_edge_other_vert(e->e, bv->v);
sub_v3_v3v3(edge_dir, bv->v->co, v2->co);
- normalize_v3(edge_dir);
- z = fabsf(cosf(angle_normalized_v3v3(vert_axis, edge_dir)));
+ z = fabsf(cosf(angle_v3v3(vert_axis, edge_dir)));
if (z < BEVEL_EPSILON) {
e->offset_l_spec = 0.01f * bp->offset; /* undefined behavior, so tiny bevel. */
}
diff --git a/source/blender/collada/ImageExporter.cpp b/source/blender/collada/ImageExporter.cpp
index 650e1bfcd57..b606799efde 100644
--- a/source/blender/collada/ImageExporter.cpp
+++ b/source/blender/collada/ImageExporter.cpp
@@ -61,7 +61,7 @@ void ImagesExporter::export_UV_Image(Image *image, bool use_copies)
return;
}
- bool is_dirty = (imbuf->userflags & IB_BITMAPDIRTY) != 0;
+ bool is_dirty = BKE_image_is_dirty(image);
ImageFormatData imageFormat;
BKE_imbuf_to_image_format(&imageFormat, imbuf);
diff --git a/source/blender/depsgraph/DEG_depsgraph_query.h b/source/blender/depsgraph/DEG_depsgraph_query.h
index 78434411a22..3030bfb28b3 100644
--- a/source/blender/depsgraph/DEG_depsgraph_query.h
+++ b/source/blender/depsgraph/DEG_depsgraph_query.h
@@ -72,10 +72,15 @@ void DEG_get_customdata_mask_for_object(const struct Depsgraph *graph,
struct Object *object,
struct CustomData_MeshMasks *r_mask);
-/* Get scene the despgraph is created for. */
+/* Get scene at its evaluated state.
+ *
+ * Technically, this is a copied-on-written and fully evaluated version of the input scene.
+ * This function will check that the datablock has been expanded (and copied) from the original
+ * one. Assert will happen if it's not. */
struct Scene *DEG_get_evaluated_scene(const struct Depsgraph *graph);
-/* Get scene layer the despgraph is created for. */
+/* Get view layer at its evaluated state.
+ * This is a shortcut for accessing active view layer from evaluated scene. */
struct ViewLayer *DEG_get_evaluated_view_layer(const struct Depsgraph *graph);
/* Get evaluated version of object for given original one. */
diff --git a/source/blender/depsgraph/intern/builder/deg_builder.cc b/source/blender/depsgraph/intern/builder/deg_builder.cc
index b8e0ba51019..36c6d246097 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder.cc
@@ -103,7 +103,7 @@ bool DepsgraphBuilder::need_pull_base_into_graph(Base *base)
bool DepsgraphBuilder::check_pchan_has_bbone(Object *object, const bPoseChannel *pchan)
{
BLI_assert(object->type == OB_ARMATURE);
- if (pchan->bone == NULL) {
+ if (pchan == NULL || pchan->bone == NULL) {
return false;
}
/* We don't really care whether segments are higher than 1 due to static user input (as in,
@@ -114,7 +114,10 @@ bool DepsgraphBuilder::check_pchan_has_bbone(Object *object, const bPoseChannel
}
bArmature *armature = static_cast<bArmature *>(object->data);
AnimatedPropertyID property_id(&armature->id, &RNA_Bone, pchan->bone, "bbone_segments");
- return cache_->isPropertyAnimated(&armature->id, property_id);
+ /* Check both Object and Armature animation data, because drivers modifying Armature
+ * state could easily be created in the Object AnimData. */
+ return cache_->isPropertyAnimated(&object->id, property_id) ||
+ cache_->isPropertyAnimated(&armature->id, property_id);
}
bool DepsgraphBuilder::check_pchan_has_bbone_segments(Object *object, const bPoseChannel *pchan)
diff --git a/source/blender/depsgraph/intern/builder/deg_builder.h b/source/blender/depsgraph/intern/builder/deg_builder.h
index 224e3212d57..040bb6cfeea 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder.h
@@ -23,10 +23,10 @@
#pragma once
-struct bPoseChannel;
struct Base;
struct Main;
struct Object;
+struct bPoseChannel;
namespace DEG {
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
index 64ca5902136..0d10bd1d3dc 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
@@ -58,7 +58,6 @@ extern "C" {
#include "DNA_lightprobe_types.h"
#include "DNA_rigidbody_types.h"
#include "DNA_scene_types.h"
-#include "DNA_sequence_types.h"
#include "DNA_sound_types.h"
#include "DNA_speaker_types.h"
#include "DNA_texture_types.h"
@@ -90,8 +89,6 @@ extern "C" {
#include "BKE_particle.h"
#include "BKE_pointcache.h"
#include "BKE_rigidbody.h"
-#include "BKE_scene.h"
-#include "BKE_sequencer.h"
#include "BKE_shader_fx.h"
#include "BKE_sound.h"
#include "BKE_tracking.h"
@@ -466,7 +463,7 @@ void DepsgraphNodeBuilder::build_id(ID *id)
void DepsgraphNodeBuilder::build_collection(LayerCollection *from_layer_collection,
Collection *collection)
{
- const int restrict_flag = (graph_->mode == DAG_EVAL_VIEWPORT) ? COLLECTION_RESTRICT_VIEW :
+ const int restrict_flag = (graph_->mode == DAG_EVAL_VIEWPORT) ? COLLECTION_RESTRICT_VIEWPORT :
COLLECTION_RESTRICT_RENDER;
const bool is_collection_restricted = (collection->flag & restrict_flag);
const bool is_collection_visible = !is_collection_restricted && is_parent_collection_visible_;
@@ -1563,42 +1560,12 @@ void DepsgraphNodeBuilder::build_sound(bSound *sound)
if (built_map_.checkIsBuiltAndTag(sound)) {
return;
}
- add_id_node(&sound->id);
- bSound *sound_cow = get_cow_datablock(sound);
- add_operation_node(&sound->id,
- NodeType::AUDIO,
- OperationCode::SOUND_EVAL,
- function_bind(BKE_sound_evaluate, _1, bmain_, sound_cow));
+ /* Placeholder so we can add relations and tag ID node for update. */
+ add_operation_node(&sound->id, NodeType::AUDIO, OperationCode::SOUND_EVAL);
build_animdata(&sound->id);
build_parameters(&sound->id);
}
-void DepsgraphNodeBuilder::build_sequencer(Scene *scene)
-{
- if (scene->ed == NULL) {
- return;
- }
- Scene *scene_cow = get_cow_datablock(scene_);
- add_operation_node(&scene->id,
- NodeType::SEQUENCER,
- OperationCode::SEQUENCES_EVAL,
- function_bind(BKE_scene_eval_sequencer_sequences, _1, scene_cow));
- /* Make sure data for sequences is in the graph. */
- Sequence *seq;
- SEQ_BEGIN (scene->ed, seq) {
- if (seq->sound != NULL) {
- build_sound(seq->sound);
- }
- /* TODO(sergey): Movie clip, scene, camera, mask. */
- }
- SEQ_END;
-}
-
-void DepsgraphNodeBuilder::build_scene_audio(Scene *scene)
-{
- add_operation_node(&scene->id, NodeType::AUDIO, OperationCode::SOUND_EVAL);
-}
-
/* **** ID traversal callbacks functions **** */
void DepsgraphNodeBuilder::modifier_walk(void *user_data,
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
index 9074efefe50..41314380b23 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
@@ -32,7 +32,6 @@
#include "DEG_depsgraph.h"
struct Base;
-struct bSound;
struct CacheFile;
struct Camera;
struct Collection;
@@ -63,6 +62,7 @@ struct bConstraint;
struct bGPdata;
struct bNodeTree;
struct bPoseChannel;
+struct bSound;
struct PropertyRNA;
@@ -208,8 +208,6 @@ class DepsgraphNodeBuilder : public DepsgraphBuilder {
void build_lightprobe(LightProbe *probe);
void build_speaker(Speaker *speaker);
void build_sound(bSound *sound);
- void build_sequencer(Scene *scene);
- void build_scene_audio(Scene *scene);
/* Per-ID information about what was already in the dependency graph.
* Allows to re-use certain values, to speed up following evaluation. */
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc
index 1b9524e5832..b898b3d3519 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc
@@ -60,7 +60,7 @@ namespace DEG {
void DepsgraphNodeBuilder::build_layer_collections(ListBase *lb)
{
- const int restrict_flag = (graph_->mode == DAG_EVAL_VIEWPORT) ? COLLECTION_RESTRICT_VIEW :
+ const int restrict_flag = (graph_->mode == DAG_EVAL_VIEWPORT) ? COLLECTION_RESTRICT_VIEWPORT :
COLLECTION_RESTRICT_RENDER;
for (LayerCollection *lc = (LayerCollection *)lb->first; lc; lc = lc->next) {
@@ -92,7 +92,6 @@ void DepsgraphNodeBuilder::build_view_layer(Scene *scene,
/* Get pointer to a CoW version of scene ID. */
Scene *scene_cow = get_cow_datablock(scene);
/* Scene objects. */
- int select_id = 1;
/* NOTE: Base is used for function bindings as-is, so need to pass CoW base,
* but object is expected to be an original one. Hence we go into some
* tricks here iterating over the view layer. */
@@ -108,7 +107,6 @@ void DepsgraphNodeBuilder::build_view_layer(Scene *scene,
build_object(base_index, base->object, linked_state, true);
++base_index;
}
- base->object->select_id = select_id++;
}
build_layer_collections(&view_layer->layer_collections);
if (scene->camera != NULL) {
@@ -152,11 +150,6 @@ void DepsgraphNodeBuilder::build_view_layer(Scene *scene,
build_collection(NULL, fls->group);
}
}
- /* Sequencer. */
- if (linked_state == DEG_ID_LINKED_DIRECTLY) {
- build_scene_audio(scene);
- build_sequencer(scene);
- }
/* Collections. */
add_operation_node(
&scene->id,
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index 4c4bc01a3dd..c7a728fd0d7 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -58,7 +58,6 @@ extern "C" {
#include "DNA_object_types.h"
#include "DNA_rigidbody_types.h"
#include "DNA_scene_types.h"
-#include "DNA_sequence_types.h"
#include "DNA_sound_types.h"
#include "DNA_speaker_types.h"
#include "DNA_texture_types.h"
@@ -85,7 +84,6 @@ extern "C" {
#include "BKE_particle.h"
#include "BKE_pointcache.h"
#include "BKE_rigidbody.h"
-#include "BKE_sequencer.h"
#include "BKE_shader_fx.h"
#include "BKE_shrinkwrap.h"
#include "BKE_sound.h"
@@ -2069,6 +2067,7 @@ void DepsgraphRelationBuilder::build_camera(Camera *camera)
if (built_map_.checkIsBuiltAndTag(camera)) {
return;
}
+ build_animdata(&camera->id);
build_parameters(&camera->id);
if (camera->dof_ob != NULL) {
ComponentKey camera_parameters_key(&camera->id, NodeType::PARAMETERS);
@@ -2083,6 +2082,7 @@ void DepsgraphRelationBuilder::build_light(Light *lamp)
if (built_map_.checkIsBuiltAndTag(lamp)) {
return;
}
+ build_animdata(&lamp->id);
build_parameters(&lamp->id);
/* light's nodetree */
if (lamp->nodetree != NULL) {
@@ -2316,35 +2316,6 @@ void DepsgraphRelationBuilder::build_sound(bSound *sound)
build_parameters(&sound->id);
}
-void DepsgraphRelationBuilder::build_sequencer(Scene *scene)
-{
- if (scene->ed == NULL) {
- return;
- }
- /* Make sure dependencies from sequences data goes to the sequencer evaluation. */
- ComponentKey sequencer_key(&scene->id, NodeType::SEQUENCER);
- Sequence *seq;
- bool has_audio_strips = false;
- SEQ_BEGIN (scene->ed, seq) {
- if (seq->sound != NULL) {
- build_sound(seq->sound);
- ComponentKey sound_key(&seq->sound->id, NodeType::AUDIO);
- add_relation(sound_key, sequencer_key, "Sound -> Sequencer");
- has_audio_strips = true;
- }
- /* TODO(sergey): Movie clip, scene, camera, mask. */
- }
- SEQ_END;
- if (has_audio_strips) {
- ComponentKey scene_audio_key(&scene->id, NodeType::AUDIO);
- add_relation(sequencer_key, scene_audio_key, "Sequencer -> Audio");
- }
-}
-
-void DepsgraphRelationBuilder::build_scene_audio(Scene * /*scene*/)
-{
-}
-
void DepsgraphRelationBuilder::build_copy_on_write_relations()
{
for (IDNode *id_node : graph_->id_nodes) {
@@ -2408,10 +2379,6 @@ void DepsgraphRelationBuilder::build_copy_on_write_relations(IDNode *id_node)
(id_type == ID_CF && comp_node->type == NodeType::CACHE)) {
rel_flag &= ~RELATION_FLAG_NO_FLUSH;
}
- /* TODO(sergey): Needs better solution for this. */
- if (id_type == ID_SO) {
- rel_flag &= ~RELATION_FLAG_NO_FLUSH;
- }
/* Notes on exceptions:
* - Parameters component is where drivers are living. Changing any
* of the (custom) properties in the original datablock (even the
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h
index 30fbe5bcf6b..1cf0b48128f 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h
@@ -41,12 +41,10 @@
#include "intern/builder/deg_builder_rna.h"
#include "intern/depsgraph.h"
#include "intern/node/deg_node.h"
-#include "intern/node/deg_node_id.h"
#include "intern/node/deg_node_component.h"
#include "intern/node/deg_node_operation.h"
struct Base;
-struct bSound;
struct CacheFile;
struct Camera;
struct Collection;
@@ -80,6 +78,7 @@ struct bConstraint;
struct bGPdata;
struct bNodeTree;
struct bPoseChannel;
+struct bSound;
struct PropertyRNA;
@@ -196,9 +195,7 @@ class DepsgraphRelationBuilder : public DepsgraphBuilder {
void build_id(ID *id);
void build_layer_collections(ListBase *lb);
- void build_view_layer(Scene *scene,
- ViewLayer *view_layer,
- eDepsNode_LinkedState_Type linked_state);
+ void build_view_layer(Scene *scene, ViewLayer *view_layer);
void build_collection(LayerCollection *from_layer_collection,
Object *object,
Collection *collection);
@@ -269,8 +266,6 @@ class DepsgraphRelationBuilder : public DepsgraphBuilder {
void build_lightprobe(LightProbe *probe);
void build_speaker(Speaker *speaker);
void build_sound(bSound *sound);
- void build_sequencer(Scene *scene);
- void build_scene_audio(Scene *scene);
void build_nested_datablock(ID *owner, ID *id);
void build_nested_nodetree(ID *owner, bNodeTree *ntree);
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc
index fadce685d31..f8313dc854b 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc
@@ -383,7 +383,13 @@ void DepsgraphRelationBuilder::build_rig(Object *object)
bPoseChannel *prev, *next;
BKE_pchan_bbone_handles_get(pchan, &prev, &next);
if (prev) {
- OperationKey prev_key(&object->id, NodeType::BONE, prev->name, OperationCode::BONE_DONE);
+ OperationCode opcode = OperationCode::BONE_DONE;
+ /* Inheriting parent roll requires access to prev handle's B-Bone properties. */
+ if ((pchan->bone->flag & BONE_ADD_PARENT_END_ROLL) != 0 &&
+ check_pchan_has_bbone_segments(object, prev)) {
+ opcode = OperationCode::BONE_SEGMENTS;
+ }
+ OperationKey prev_key(&object->id, NodeType::BONE, prev->name, opcode);
add_relation(prev_key, bone_segments_key, "Prev Handle -> B-Bone Segments");
}
if (next) {
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc
index cadb4ab3611..b5a926ad597 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc
@@ -61,7 +61,7 @@ namespace DEG {
void DepsgraphRelationBuilder::build_layer_collections(ListBase *lb)
{
- const int restrict_flag = (graph_->mode == DAG_EVAL_VIEWPORT) ? COLLECTION_RESTRICT_VIEW :
+ const int restrict_flag = (graph_->mode == DAG_EVAL_VIEWPORT) ? COLLECTION_RESTRICT_VIEWPORT :
COLLECTION_RESTRICT_RENDER;
for (LayerCollection *lc = (LayerCollection *)lb->first; lc; lc = lc->next) {
@@ -75,9 +75,7 @@ void DepsgraphRelationBuilder::build_layer_collections(ListBase *lb)
}
}
-void DepsgraphRelationBuilder::build_view_layer(Scene *scene,
- ViewLayer *view_layer,
- eDepsNode_LinkedState_Type linked_state)
+void DepsgraphRelationBuilder::build_view_layer(Scene *scene, ViewLayer *view_layer)
{
/* Setup currently building context. */
scene_ = scene;
@@ -130,15 +128,10 @@ void DepsgraphRelationBuilder::build_view_layer(Scene *scene,
build_collection(NULL, NULL, fls->group);
}
}
- /* Sequencer. */
- if (linked_state == DEG_ID_LINKED_DIRECTLY) {
- build_scene_audio(scene);
- build_sequencer(scene);
- }
/* Build all set scenes. */
if (scene->set != NULL) {
ViewLayer *set_view_layer = BKE_view_layer_default_render(scene->set);
- build_view_layer(scene->set, set_view_layer, DEG_ID_LINKED_VIA_SET);
+ build_view_layer(scene->set, set_view_layer);
}
}
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc
index ea5f86a31a8..fa38dce1a9f 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc
@@ -196,11 +196,30 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr,
/* Bone - generally, we just want the bone component. */
node_identifier.type = NodeType::BONE;
node_identifier.component_name = pchan->name;
- /* But B-Bone properties should connect to the actual operation. */
- Object *object = reinterpret_cast<Object *>(node_identifier.id);
- if (!ELEM(NULL, pchan->bone, prop) && STRPREFIX(RNA_property_identifier(prop), "bbone_") &&
- builder_->check_pchan_has_bbone_segments(object, pchan)) {
- node_identifier.operation_code = OperationCode::BONE_SEGMENTS;
+ /* However check property name for special handling. */
+ if (prop != NULL) {
+ Object *object = reinterpret_cast<Object *>(node_identifier.id);
+ const char *prop_name = RNA_property_identifier(prop);
+ /* B-Bone properties should connect to the final operation. */
+ if (STRPREFIX(prop_name, "bbone_")) {
+ if (builder_->check_pchan_has_bbone_segments(object, pchan)) {
+ node_identifier.operation_code = OperationCode::BONE_SEGMENTS;
+ }
+ else {
+ node_identifier.operation_code = OperationCode::BONE_DONE;
+ }
+ }
+ /* Final transform properties go to the Done node for the exit. */
+ else if (STREQ(prop_name, "head") || STREQ(prop_name, "tail") ||
+ STRPREFIX(prop_name, "matrix")) {
+ if (source == RNAPointerSource::EXIT) {
+ node_identifier.operation_code = OperationCode::BONE_DONE;
+ }
+ }
+ /* And other properties can always go to the entry operation. */
+ else {
+ node_identifier.operation_code = OperationCode::BONE_LOCAL;
+ }
}
}
return node_identifier;
diff --git a/source/blender/depsgraph/intern/depsgraph_build.cc b/source/blender/depsgraph/intern/depsgraph_build.cc
index a4082c24dec..dd2979160cd 100644
--- a/source/blender/depsgraph/intern/depsgraph_build.cc
+++ b/source/blender/depsgraph/intern/depsgraph_build.cc
@@ -249,7 +249,7 @@ void DEG_graph_build_from_view_layer(Depsgraph *graph,
* 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_view_layer(scene, view_layer);
relation_builder.build_copy_on_write_relations();
/* Detect and solve cycles. */
DEG::deg_graph_detect_cycles(deg_graph);
diff --git a/source/blender/depsgraph/intern/depsgraph_query_iter.cc b/source/blender/depsgraph/intern/depsgraph_query_iter.cc
index d3bf27747c0..4bc2ab557ec 100644
--- a/source/blender/depsgraph/intern/depsgraph_query_iter.cc
+++ b/source/blender/depsgraph/intern/depsgraph_query_iter.cc
@@ -145,7 +145,6 @@ bool deg_objects_dupli_iterator_next(BLI_Iterator *iter)
Object *dupli_parent = data->dupli_parent;
Object *temp_dupli_object = &data->temp_dupli_object;
*temp_dupli_object = *dob->ob;
- temp_dupli_object->select_id = dupli_parent->select_id;
temp_dupli_object->base_flag = dupli_parent->base_flag | BASE_FROM_DUPLI;
temp_dupli_object->base_local_view_bits = dupli_parent->base_local_view_bits;
temp_dupli_object->dt = MIN2(temp_dupli_object->dt, dupli_parent->dt);
@@ -159,7 +158,13 @@ bool deg_objects_dupli_iterator_next(BLI_Iterator *iter)
continue;
}
+ /* This could be avoided by refactoring make_dupli() in order to track all negative scaling
+ * recursively. */
+ bool is_neg_scale = is_negative_m4(dob->mat);
+ SET_FLAG_FROM_TEST(data->temp_dupli_object.transflag, is_neg_scale, OB_NEG_SCALE);
+
copy_m4_m4(data->temp_dupli_object.obmat, dob->mat);
+ invert_m4_m4(data->temp_dupli_object.imat, data->temp_dupli_object.obmat);
iter->current = &data->temp_dupli_object;
BLI_assert(DEG::deg_validate_copy_on_write_datablock(&data->temp_dupli_object.id));
return true;
diff --git a/source/blender/depsgraph/intern/depsgraph_tag.cc b/source/blender/depsgraph/intern/depsgraph_tag.cc
index f7d7b76cb69..7dcba8b7655 100644
--- a/source/blender/depsgraph/intern/depsgraph_tag.cc
+++ b/source/blender/depsgraph/intern/depsgraph_tag.cc
@@ -215,9 +215,6 @@ void depsgraph_tag_to_component_opcode(const ID *id,
/* There is no such node in depsgraph, this tag is to be handled
* separately. */
break;
- case ID_RECALC_SEQUENCER:
- *component_type = NodeType::SEQUENCER;
- break;
case ID_RECALC_ALL:
case ID_RECALC_PSYS_ALL:
BLI_assert(!"Should not happen");
@@ -248,6 +245,13 @@ void depsgraph_update_editors_tag(Main *bmain, Depsgraph *graph, ID *id)
deg_editors_id_update(&update_ctx, id);
}
+void depsgraph_id_tag_copy_on_write(Depsgraph *graph, IDNode *id_node, eUpdateSource update_source)
+{
+ ComponentNode *cow_comp = id_node->find_component(NodeType::COPY_ON_WRITE);
+ cow_comp->tag_update(graph, update_source);
+ id_node->id_orig->recalc |= ID_RECALC_COPY_ON_WRITE;
+}
+
void depsgraph_tag_component(Depsgraph *graph,
IDNode *id_node,
NodeType component_type,
@@ -255,7 +259,13 @@ void depsgraph_tag_component(Depsgraph *graph,
eUpdateSource update_source)
{
ComponentNode *component_node = id_node->find_component(component_type);
+ /* NOTE: Animation component might not be existing yet (which happens when adding new driver or
+ * adding a new keyframe), so the required copy-on-write tag needs to be taken care explicitly
+ * here. */
if (component_node == NULL) {
+ if (component_type == NodeType::ANIMATION) {
+ depsgraph_id_tag_copy_on_write(graph, id_node, update_source);
+ }
return;
}
if (operation_code == OperationCode::OPERATION) {
@@ -269,9 +279,7 @@ void depsgraph_tag_component(Depsgraph *graph,
}
/* If component depends on copy-on-write, tag it as well. */
if (component_node->need_tag_cow_before_update()) {
- ComponentNode *cow_comp = id_node->find_component(NodeType::COPY_ON_WRITE);
- cow_comp->tag_update(graph, update_source);
- id_node->id_orig->recalc |= ID_RECALC_COPY_ON_WRITE;
+ depsgraph_id_tag_copy_on_write(graph, id_node, update_source);
}
}
@@ -465,7 +473,9 @@ void deg_graph_on_visible_update(Main *bmain, Depsgraph *graph)
* Need to solve those issues carefully, for until then we evaluate
* animation for datablocks which appears in the graph for the first
* time. */
- flag |= ID_RECALC_ANIMATION;
+ if (BKE_animdata_from_id(id_node->id_orig) != NULL) {
+ flag |= ID_RECALC_ANIMATION;
+ }
}
/* We only tag components which needs an update. Tagging everything is
* not a good idea because that might reset particles cache (or any
@@ -618,8 +628,6 @@ const char *DEG_update_tag_as_string(IDRecalcFlag flag)
return "POINT_CACHE";
case ID_RECALC_EDITORS:
return "EDITORS";
- case ID_RECALC_SEQUENCER:
- return "SEQUENCER";
case ID_RECALC_ALL:
return "ALL";
}
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 bb4300e5330..2a76d5cd362 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
@@ -59,8 +59,6 @@ extern "C" {
#include "DNA_mesh_types.h"
#include "DNA_modifier_types.h"
#include "DNA_scene_types.h"
-#include "DNA_sequence_types.h"
-#include "DNA_sound_types.h"
#include "DNA_object_types.h"
#include "DNA_particle_types.h"
@@ -86,8 +84,6 @@ extern "C" {
#include "BKE_library_query.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
-#include "BKE_sequencer.h"
-#include "BKE_sound.h"
}
#include "intern/depsgraph.h"
@@ -428,25 +424,6 @@ void scene_setup_view_layers_after_remap(const Depsgraph *depsgraph,
* Still not an excuse to have those. */
}
-void update_sequence_orig_pointers(const ListBase *sequences_orig, ListBase *sequences_cow)
-{
- Sequence *sequence_orig = reinterpret_cast<Sequence *>(sequences_orig->first);
- Sequence *sequence_cow = reinterpret_cast<Sequence *>(sequences_cow->first);
- while (sequence_orig != NULL) {
- update_sequence_orig_pointers(&sequence_orig->seqbase, &sequence_cow->seqbase);
- sequence_cow->orig_sequence = sequence_orig;
- sequence_cow = sequence_cow->next;
- sequence_orig = sequence_orig->next;
- }
-}
-
-void update_scene_orig_pointers(const Scene *scene_orig, Scene *scene_cow)
-{
- if (scene_orig->ed != NULL) {
- update_sequence_orig_pointers(&scene_orig->ed->seqbase, &scene_cow->ed->seqbase);
- }
-}
-
/* Check whether given ID is expanded or still a shallow copy. */
BLI_INLINE bool check_datablock_expanded(const ID *id_cow)
{
@@ -731,7 +708,6 @@ void update_id_after_copy(const Depsgraph *depsgraph,
scene_cow->toolsettings = scene_orig->toolsettings;
scene_cow->eevee.light_cache = scene_orig->eevee.light_cache;
scene_setup_view_layers_after_remap(depsgraph, id_node, reinterpret_cast<Scene *>(id_cow));
- update_scene_orig_pointers(scene_orig, scene_cow);
break;
}
default:
@@ -862,205 +838,6 @@ ID *deg_expand_copy_on_write_datablock(const Depsgraph *depsgraph,
namespace {
-/* Backup of sequencer strips runtime data. */
-
-/* Backup of a single strip. */
-class SequenceBackup {
- public:
- SequenceBackup()
- {
- reset();
- }
-
- inline void reset()
- {
- scene_sound = NULL;
- }
-
- void init_from_sequence(Sequence *sequence)
- {
- scene_sound = sequence->scene_sound;
-
- sequence->scene_sound = NULL;
- }
-
- void restore_to_sequence(Sequence *sequence)
- {
- sequence->scene_sound = scene_sound;
- reset();
- }
-
- inline bool isEmpty() const
- {
- return (scene_sound == NULL);
- }
-
- void *scene_sound;
-};
-
-class SequencerBackup {
- public:
- SequencerBackup();
-
- void init_from_scene(Scene *scene);
- void restore_to_scene(Scene *scene);
-
- typedef map<Sequence *, SequenceBackup> SequencesBackupMap;
- SequencesBackupMap sequences_backup;
-};
-
-SequencerBackup::SequencerBackup()
-{
-}
-
-void SequencerBackup::init_from_scene(Scene *scene)
-{
- Sequence *sequence;
- SEQ_BEGIN (scene->ed, sequence) {
- SequenceBackup sequence_backup;
- sequence_backup.init_from_sequence(sequence);
- if (!sequence_backup.isEmpty()) {
- sequences_backup.insert(make_pair(sequence->orig_sequence, sequence_backup));
- }
- }
- SEQ_END;
-}
-
-void SequencerBackup::restore_to_scene(Scene *scene)
-{
- Sequence *sequence;
- SEQ_BEGIN (scene->ed, sequence) {
- SequencesBackupMap::iterator it = sequences_backup.find(sequence->orig_sequence);
- if (it == sequences_backup.end()) {
- continue;
- }
- SequenceBackup &sequence_backup = it->second;
- sequence_backup.restore_to_sequence(sequence);
- }
- SEQ_END;
- /* Cleanup audio while the scene is still known. */
- for (SequencesBackupMap::value_type &it : sequences_backup) {
- SequenceBackup &sequence_backup = it.second;
- if (sequence_backup.scene_sound != NULL) {
- BKE_sound_remove_scene_sound(scene, sequence_backup.scene_sound);
- }
- }
-}
-
-/* Backup of scene runtime data. */
-
-class SceneBackup {
- public:
- SceneBackup();
-
- void reset();
-
- void init_from_scene(Scene *scene);
- void restore_to_scene(Scene *scene);
-
- /* Sound/audio related pointers of the scene itself.
- *
- * NOTE: Scene can not disappear after relations update, because otherwise the entire dependency
- * graph will be gone. This means we don't need to compare original scene pointer, or worry about
- * freeing those if they cant' be restorted: we just copy them over to a new scene. */
- void *sound_scene;
- void *playback_handle;
- void *sound_scrub_handle;
- void *speaker_handles;
-
- SequencerBackup sequencer_backup;
-};
-
-SceneBackup::SceneBackup()
-{
- reset();
-}
-
-void SceneBackup::reset()
-{
- sound_scene = NULL;
- playback_handle = NULL;
- sound_scrub_handle = NULL;
- speaker_handles = NULL;
-}
-
-void SceneBackup::init_from_scene(Scene *scene)
-{
- sound_scene = scene->sound_scene;
- playback_handle = scene->playback_handle;
- sound_scrub_handle = scene->sound_scrub_handle;
- speaker_handles = scene->speaker_handles;
-
- /* Clear pointers stored in the scene, so they are not freed when copied-on-written datablock
- * is freed for re-allocation. */
- scene->sound_scene = NULL;
- scene->playback_handle = NULL;
- scene->sound_scrub_handle = NULL;
- scene->speaker_handles = NULL;
-
- sequencer_backup.init_from_scene(scene);
-}
-
-void SceneBackup::restore_to_scene(Scene *scene)
-{
- scene->sound_scene = sound_scene;
- scene->playback_handle = playback_handle;
- scene->sound_scrub_handle = sound_scrub_handle;
- scene->speaker_handles = speaker_handles;
-
- sequencer_backup.restore_to_scene(scene);
-
- reset();
-}
-
-/* Backup of sound datablocks runtime data. */
-
-class SoundBackup {
- public:
- SoundBackup();
-
- void reset();
-
- void init_from_sound(bSound *sound);
- void restore_to_sound(bSound *sound);
-
- void *cache;
- void *waveform;
- void *playback_handle;
-};
-
-SoundBackup::SoundBackup()
-{
- reset();
-}
-
-void SoundBackup::reset()
-{
- cache = NULL;
- waveform = NULL;
- playback_handle = NULL;
-}
-
-void SoundBackup::init_from_sound(bSound *sound)
-{
- cache = sound->cache;
- waveform = sound->waveform;
- playback_handle = sound->playback_handle;
-
- sound->cache = NULL;
- sound->waveform = NULL;
- sound->playback_handle = NULL;
-}
-
-void SoundBackup::restore_to_sound(bSound *sound)
-{
- sound->cache = cache;
- sound->waveform = waveform;
- sound->playback_handle = playback_handle;
-
- reset();
-}
-
/* Identifier used to match modifiers to backup/restore their runtime data.
* Identification is happening using original modifier data pointer and the
* modifier type.
@@ -1101,8 +878,7 @@ typedef map<ModifierDataBackupID, void *> ModifierRuntimeDataBackup;
/* Storage for backed up pose channel runtime data. */
typedef map<bPoseChannel *, bPoseChannel_Runtime> PoseChannelRuntimeDataBackup;
-class ObjectRuntimeBackup {
- public:
+struct ObjectRuntimeBackup {
ObjectRuntimeBackup() : base_flag(0), base_local_view_bits(0)
{
/* TODO(sergey): Use something like BKE_object_runtime_reset(). */
@@ -1280,8 +1056,6 @@ class RuntimeBackup {
/* Restore fields to the given ID. */
void restore_to_id(ID *id);
- SceneBackup scene_backup;
- SoundBackup sound_backup;
ObjectRuntimeBackup object_backup;
DrawDataList drawdata_backup;
DrawDataList *drawdata_ptr;
@@ -1297,12 +1071,6 @@ void RuntimeBackup::init_from_id(ID *id)
case ID_OB:
object_backup.init_from_object(reinterpret_cast<Object *>(id));
break;
- case ID_SCE:
- scene_backup.init_from_scene(reinterpret_cast<Scene *>(id));
- break;
- case ID_SO:
- sound_backup.init_from_sound(reinterpret_cast<bSound *>(id));
- break;
default:
break;
}
@@ -1322,12 +1090,6 @@ void RuntimeBackup::restore_to_id(ID *id)
case ID_OB:
object_backup.restore_to_object(reinterpret_cast<Object *>(id));
break;
- case ID_SCE:
- scene_backup.restore_to_scene(reinterpret_cast<Scene *>(id));
- break;
- case ID_SO:
- sound_backup.restore_to_sound(reinterpret_cast<bSound *>(id));
- break;
default:
break;
}
@@ -1516,7 +1278,9 @@ bool deg_copy_on_write_is_expanded(const ID *id_cow)
bool deg_copy_on_write_is_needed(const ID *id_orig)
{
const ID_Type id_type = GS(id_orig->name);
- return !ELEM(id_type, ID_IM);
+ /* TODO(sergey): Make Sound copyable. It is here only because the code for dependency graph is
+ * being work in progress. */
+ return !ELEM(id_type, ID_IM, ID_SO);
}
} // namespace DEG
diff --git a/source/blender/depsgraph/intern/node/deg_node_operation.cc b/source/blender/depsgraph/intern/node/deg_node_operation.cc
index 09a761d282f..62a61675bcc 100644
--- a/source/blender/depsgraph/intern/node/deg_node_operation.cc
+++ b/source/blender/depsgraph/intern/node/deg_node_operation.cc
@@ -185,9 +185,6 @@ const char *operationCodeAsString(OperationCode opcode)
/* Generic datablock. */
case OperationCode::GENERIC_DATABLOCK_UPDATE:
return "GENERIC_DATABLOCK_UPDATE";
- /* Sequencer. */
- case OperationCode::SEQUENCES_EVAL:
- return "SEQUENCES_EVAL";
/* instancing/duplication. */
case OperationCode::DUPLI:
return "DUPLI";
diff --git a/source/blender/depsgraph/intern/node/deg_node_operation.h b/source/blender/depsgraph/intern/node/deg_node_operation.h
index 8fc565cfa77..ab6242a6196 100644
--- a/source/blender/depsgraph/intern/node/deg_node_operation.h
+++ b/source/blender/depsgraph/intern/node/deg_node_operation.h
@@ -185,16 +185,12 @@ enum class OperationCode {
/* Images. -------------------------------------------------------------- */
IMAGE_ANIMATION,
- /* Synchronization. ----------------------------------------------------- */
+ /* Synchronization clips. ----------------------------------------------- */
SYNCHRONIZE_TO_ORIGINAL,
/* Generic datablock ---------------------------------------------------- */
GENERIC_DATABLOCK_UPDATE,
- /* Sequencer. ----------------------------------------------------------- */
-
- SEQUENCES_EVAL,
-
/* Duplication/instancing system. --------------------------------------- */
DUPLI,
};
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index f07568965bb..3cdf07fd7ff 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -138,6 +138,7 @@ set(SRC
intern/DRW_render.h
intern/draw_cache.h
intern/draw_cache_impl.h
+ intern/draw_cache_inline.h
intern/draw_common.h
intern/draw_debug.h
intern/draw_hair_private.h
diff --git a/source/blender/draw/DRW_engine.h b/source/blender/draw/DRW_engine.h
index da1f5c7863a..5919e100ddd 100644
--- a/source/blender/draw/DRW_engine.h
+++ b/source/blender/draw/DRW_engine.h
@@ -38,6 +38,7 @@ struct IDProperty;
struct Main;
struct Material;
struct Object;
+struct RegionView3D;
struct RenderEngine;
struct RenderEngineType;
struct Scene;
@@ -135,6 +136,15 @@ void DRW_draw_depth_loop_gpencil(struct Depsgraph *depsgraph,
void DRW_draw_depth_object(struct ARegion *ar,
struct GPUViewport *viewport,
struct Object *object);
+void DRW_draw_select_id_object(struct Scene *scene,
+ struct RegionView3D *rv3d,
+ struct Object *ob,
+ short select_mode,
+ bool draw_facedot,
+ uint initial_offset,
+ uint *r_vert_offset,
+ uint *r_edge_offset,
+ uint *r_face_offset);
void DRW_framebuffer_select_id_setup(struct ARegion *ar, const bool clear);
void DRW_framebuffer_select_id_release(struct ARegion *ar);
@@ -146,7 +156,6 @@ void DRW_render_gpencil(struct RenderEngine *engine, struct Depsgraph *depsgraph
void DRW_gpencil_freecache(struct Object *ob);
/* This is here because GPUViewport needs it */
-void DRW_pass_free(struct DRWPass *pass);
struct DRWInstanceDataList *DRW_instance_data_list_create(void);
void DRW_instance_data_list_free(struct DRWInstanceDataList *idatalist);
diff --git a/source/blender/draw/engines/basic/basic_engine.c b/source/blender/draw/engines/basic/basic_engine.c
index 05ee485e053..360d1d30736 100644
--- a/source/blender/draw/engines/basic/basic_engine.c
+++ b/source/blender/draw/engines/basic/basic_engine.c
@@ -143,7 +143,7 @@ static void basic_cache_populate(void *vedata, Object *ob)
const int draw_as = (part->draw_as == PART_DRAW_REND) ? part->ren_as : part->draw_as;
if (draw_as == PART_DRAW_PATH) {
struct GPUBatch *hairs = DRW_cache_particles_get_hair(ob, psys, NULL);
- DRW_shgroup_call_add(stl->g_data->depth_shgrp, hairs, NULL);
+ DRW_shgroup_call(stl->g_data->depth_shgrp, hairs, NULL);
}
}
}
@@ -159,7 +159,7 @@ static void basic_cache_populate(void *vedata, Object *ob)
if (is_flat_object_viewed_from_side) {
/* Avoid losing flat objects when in ortho views (see T56549) */
struct GPUBatch *geom = DRW_cache_object_all_edges_get(ob);
- DRW_shgroup_call_object_add(stl->g_data->depth_shgrp, geom, ob);
+ DRW_shgroup_call_object(stl->g_data->depth_shgrp, geom, ob);
return;
}
}
@@ -169,7 +169,7 @@ static void basic_cache_populate(void *vedata, Object *ob)
const bool do_cull = (draw_ctx->v3d &&
(draw_ctx->v3d->shading.flag & V3D_SHADING_BACKFACE_CULLING));
/* Depth Prepass */
- DRW_shgroup_call_object_add(
+ DRW_shgroup_call_object(
(do_cull) ? stl->g_data->depth_shgrp_cull : stl->g_data->depth_shgrp, geom, ob);
}
}
diff --git a/source/blender/draw/engines/eevee/eevee_bloom.c b/source/blender/draw/engines/eevee/eevee_bloom.c
index b0013151a70..e0165ea020a 100644
--- a/source/blender/draw/engines/eevee/eevee_bloom.c
+++ b/source/blender/draw/engines/eevee/eevee_bloom.c
@@ -186,7 +186,7 @@ static DRWShadingGroup *eevee_create_bloom_pass(const char *name,
*pass = DRW_pass_create(name, DRW_STATE_WRITE_COLOR);
DRWShadingGroup *grp = DRW_shgroup_create(sh, *pass);
- DRW_shgroup_call_add(grp, quad, NULL);
+ DRW_shgroup_call(grp, quad, NULL);
DRW_shgroup_uniform_texture_ref(grp, "sourceBuffer", &effects->unf_source_buffer);
DRW_shgroup_uniform_vec2(grp, "sourceBufferTexelSize", effects->unf_source_texel_size, 1);
if (upsample) {
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 8fb73bd605f..3d058f7e46e 100644
--- a/source/blender/draw/engines/eevee/eevee_depth_of_field.c
+++ b/source/blender/draw/engines/eevee/eevee_depth_of_field.c
@@ -212,7 +212,7 @@ void EEVEE_depth_of_field_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
DRW_shgroup_uniform_vec2(grp, "nearFar", effects->dof_near_far, 1);
DRW_shgroup_uniform_vec2(grp, "dofParams", effects->dof_params, 1);
- DRW_shgroup_call_add(grp, quad, NULL);
+ DRW_shgroup_call(grp, quad, NULL);
psl->dof_scatter = DRW_pass_create("DoF Scatter",
DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE_FULL);
@@ -222,13 +222,14 @@ void EEVEE_depth_of_field_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_
const float *viewport_size = DRW_viewport_size_get();
const int sprite_len = ((int)viewport_size[0] / 2) *
((int)viewport_size[1] / 2); /* brackets matters */
- grp = DRW_shgroup_empty_tri_batch_create(
- e_data.dof_scatter_sh[use_alpha], psl->dof_scatter, sprite_len);
+ grp = DRW_shgroup_create(e_data.dof_scatter_sh[use_alpha], psl->dof_scatter);
DRW_shgroup_uniform_texture_ref(grp, "nearBuffer", &effects->dof_down_near);
DRW_shgroup_uniform_texture_ref(grp, "farBuffer", &effects->dof_down_far);
DRW_shgroup_uniform_texture_ref(grp, "cocBuffer", &effects->dof_coc);
DRW_shgroup_uniform_vec4(grp, "bokehParams", effects->dof_bokeh, 2);
+ DRW_shgroup_call_procedural_triangles(grp, sprite_len, NULL);
+
psl->dof_resolve = DRW_pass_create("DoF Resolve", DRW_STATE_WRITE_COLOR);
grp = DRW_shgroup_create(e_data.dof_resolve_sh[use_alpha], psl->dof_resolve);
@@ -237,7 +238,7 @@ void EEVEE_depth_of_field_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
DRW_shgroup_uniform_vec2(grp, "nearFar", effects->dof_near_far, 1);
DRW_shgroup_uniform_vec2(grp, "dofParams", effects->dof_params, 1);
- DRW_shgroup_call_add(grp, quad, NULL);
+ DRW_shgroup_call(grp, quad, NULL);
if (use_alpha) {
DRW_shgroup_uniform_texture_ref(grp, "scatterAlphaBuffer", &effects->dof_blur_alpha);
diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c
index a8b4159e030..c4075fc2bef 100644
--- a/source/blender/draw/engines/eevee/eevee_effects.c
+++ b/source/blender/draw/engines/eevee/eevee_effects.c
@@ -301,19 +301,17 @@ void EEVEE_effects_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRWShadingGroup *grp = DRW_shgroup_create(e_data.downsample_sh, psl->color_downsample_ps);
DRW_shgroup_uniform_texture_ref(grp, "source", &e_data.color_src);
DRW_shgroup_uniform_float(grp, "fireflyFactor", &sldata->common_data.ssr_firefly_fac, 1);
- DRW_shgroup_call_add(grp, quad, NULL);
+ DRW_shgroup_call(grp, quad, NULL);
}
{
- static int zero = 0;
- static uint six = 6;
psl->color_downsample_cube_ps = DRW_pass_create("Downsample Cube", DRW_STATE_WRITE_COLOR);
DRWShadingGroup *grp = DRW_shgroup_create(e_data.downsample_cube_sh,
psl->color_downsample_cube_ps);
DRW_shgroup_uniform_texture_ref(grp, "source", &e_data.color_src);
DRW_shgroup_uniform_float(grp, "texelSize", &e_data.cube_texel_size, 1);
- DRW_shgroup_uniform_int(grp, "Layer", &zero, 1);
- DRW_shgroup_call_instances_add(grp, quad, NULL, &six);
+ DRW_shgroup_uniform_int_copy(grp, "Layer", 0);
+ DRW_shgroup_call_instances(grp, quad, NULL, 6);
}
{
@@ -324,7 +322,7 @@ void EEVEE_effects_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
downsample_write | DRW_STATE_DEPTH_ALWAYS);
grp = DRW_shgroup_create(e_data.maxz_downlevel_sh, psl->maxz_downlevel_ps);
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &txl->maxzbuffer);
- DRW_shgroup_call_add(grp, quad, NULL);
+ DRW_shgroup_call(grp, quad, NULL);
/* Copy depth buffer to halfres top level of HiZ */
@@ -332,27 +330,27 @@ void EEVEE_effects_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
downsample_write | DRW_STATE_DEPTH_ALWAYS);
grp = DRW_shgroup_create(e_data.maxz_downdepth_sh, psl->maxz_downdepth_ps);
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &e_data.depth_src);
- DRW_shgroup_call_add(grp, quad, NULL);
+ DRW_shgroup_call(grp, quad, NULL);
psl->maxz_downdepth_layer_ps = DRW_pass_create("HiZ Max Copy DepthLayer Halfres",
downsample_write | DRW_STATE_DEPTH_ALWAYS);
grp = DRW_shgroup_create(e_data.maxz_downdepth_layer_sh, psl->maxz_downdepth_layer_ps);
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &e_data.depth_src);
DRW_shgroup_uniform_int(grp, "depthLayer", &e_data.depth_src_layer, 1);
- DRW_shgroup_call_add(grp, quad, NULL);
+ DRW_shgroup_call(grp, quad, NULL);
psl->maxz_copydepth_ps = DRW_pass_create("HiZ Max Copy Depth Fullres",
downsample_write | DRW_STATE_DEPTH_ALWAYS);
grp = DRW_shgroup_create(e_data.maxz_copydepth_sh, psl->maxz_copydepth_ps);
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &e_data.depth_src);
- DRW_shgroup_call_add(grp, quad, NULL);
+ DRW_shgroup_call(grp, quad, NULL);
psl->maxz_copydepth_layer_ps = DRW_pass_create("HiZ Max Copy DepthLayer Halfres",
downsample_write | DRW_STATE_DEPTH_ALWAYS);
grp = DRW_shgroup_create(e_data.maxz_copydepth_layer_sh, psl->maxz_copydepth_layer_ps);
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &e_data.depth_src);
DRW_shgroup_uniform_int(grp, "depthLayer", &e_data.depth_src_layer, 1);
- DRW_shgroup_call_add(grp, quad, NULL);
+ DRW_shgroup_call(grp, quad, NULL);
}
if ((effects->enabled_effects & EFFECT_VELOCITY_BUFFER) != 0) {
@@ -364,7 +362,7 @@ void EEVEE_effects_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_mat4(grp, "currPersinv", effects->velocity_curr_persinv);
DRW_shgroup_uniform_mat4(grp, "pastPersmat", effects->velocity_past_persmat);
- DRW_shgroup_call_add(grp, quad, NULL);
+ DRW_shgroup_call(grp, quad, NULL);
}
if ((effects->enabled_effects & EFFECT_ALPHA_CHECKER) != 0) {
@@ -381,7 +379,7 @@ void EEVEE_effects_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_uniform_vec4(grp, "color1", effects->color_checker_dark, 1);
DRW_shgroup_uniform_vec4(grp, "color2", effects->color_checker_light, 1);
DRW_shgroup_uniform_int_copy(grp, "size", 8);
- DRW_shgroup_call_add(grp, quad, NULL);
+ DRW_shgroup_call(grp, quad, NULL);
}
}
@@ -572,7 +570,7 @@ void EEVEE_draw_effects(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
/* NOTE: Lookdev drawing happens before TAA but after
* motion blur and dof to avoid distortions.
* Velocity resolve use a hack to exclude lookdev
- * balls from creating shimering reprojection vectors. */
+ * spheres from creating shimering reprojection vectors. */
EEVEE_lookdev_draw(vedata);
EEVEE_velocity_resolve(vedata);
diff --git a/source/blender/draw/engines/eevee/eevee_lightprobes.c b/source/blender/draw/engines/eevee/eevee_lightprobes.c
index a4a17de7a57..2dd5debfb83 100644
--- a/source/blender/draw/engines/eevee/eevee_lightprobes.c
+++ b/source/blender/draw/engines/eevee/eevee_lightprobes.c
@@ -249,7 +249,7 @@ void EEVEE_lightbake_cache_init(EEVEE_ViewLayerData *sldata,
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
struct GPUBatch *geom = DRW_cache_fullscreen_quad_get();
- DRW_shgroup_call_add(grp, geom, NULL);
+ DRW_shgroup_call(grp, geom, NULL);
}
{
@@ -272,7 +272,7 @@ void EEVEE_lightbake_cache_init(EEVEE_ViewLayerData *sldata,
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
struct GPUBatch *geom = DRW_cache_fullscreen_quad_get();
- DRW_shgroup_call_add(grp, geom, NULL);
+ DRW_shgroup_call(grp, geom, NULL);
}
{
@@ -294,7 +294,7 @@ void EEVEE_lightbake_cache_init(EEVEE_ViewLayerData *sldata,
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
struct GPUBatch *geom = DRW_cache_fullscreen_quad_get();
- DRW_shgroup_call_add(grp, geom, NULL);
+ DRW_shgroup_call(grp, geom, NULL);
}
{
@@ -306,7 +306,7 @@ void EEVEE_lightbake_cache_init(EEVEE_ViewLayerData *sldata,
DRW_shgroup_uniform_texture_ref(grp, "irradianceGrid", &light_cache->grid_tx.tex);
struct GPUBatch *geom = DRW_cache_fullscreen_quad_get();
- DRW_shgroup_call_add(grp, geom, NULL);
+ DRW_shgroup_call(grp, geom, NULL);
}
}
@@ -360,7 +360,7 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
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_call_add(grp, geom, NULL);
+ DRW_shgroup_call(grp, geom, NULL);
break;
default:
col = error_col;
@@ -374,7 +374,7 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
grp = DRW_shgroup_create(EEVEE_shaders_probe_default_sh_get(), psl->probe_background);
DRW_shgroup_uniform_vec3(grp, "color", col, 1);
DRW_shgroup_uniform_float_copy(grp, "backgroundAlpha", 1.0f);
- DRW_shgroup_call_add(grp, geom, NULL);
+ DRW_shgroup_call(grp, geom, NULL);
}
}
@@ -386,8 +386,8 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
/* Cube Display */
if (scene_eval->eevee.flag & SCE_EEVEE_SHOW_CUBEMAPS && lcache->cube_len > 1) {
int cube_len = lcache->cube_len - 1; /* don't count the world. */
- DRWShadingGroup *grp = DRW_shgroup_empty_tri_batch_create(
- EEVEE_shaders_probe_cube_display_sh_get(), psl->probe_display, cube_len * 2);
+ DRWShadingGroup *grp = DRW_shgroup_create(EEVEE_shaders_probe_cube_display_sh_get(),
+ psl->probe_display);
DRW_shgroup_uniform_texture_ref(grp, "probeCubes", &lcache->cube_tx.tex);
DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
@@ -398,6 +398,8 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
/* TODO (fclem) get rid of those UBO. */
DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo);
+
+ DRW_shgroup_call_procedural_triangles(grp, cube_len * 2, NULL);
}
/* Grid Display */
@@ -423,7 +425,7 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
DRW_shgroup_uniform_block(shgrp, "grid_block", sldata->grid_ubo);
DRW_shgroup_uniform_block(shgrp, "common_block", sldata->common_ubo);
int tri_count = egrid->resolution[0] * egrid->resolution[1] * egrid->resolution[2] * 2;
- DRW_shgroup_call_procedural_triangles_add(shgrp, tri_count, NULL);
+ DRW_shgroup_call_procedural_triangles(shgrp, tri_count, NULL);
}
}
@@ -434,29 +436,16 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
{"probe_mat", DRW_ATTR_FLOAT, 16},
});
- DRWShadingGroup *grp = DRW_shgroup_instance_create(EEVEE_shaders_probe_planar_display_sh_get(),
- psl->probe_display,
- DRW_cache_quad_get(),
- e_data.format_probe_display_planar);
- stl->g_data->planar_display_shgrp = grp;
+ DRWShadingGroup *grp = DRW_shgroup_create(EEVEE_shaders_probe_planar_display_sh_get(),
+ psl->probe_display);
DRW_shgroup_uniform_texture_ref(grp, "probePlanars", &txl->planar_pool);
+
+ stl->g_data->planar_display_shgrp = DRW_shgroup_call_buffer_instance(
+ grp, e_data.format_probe_display_planar, DRW_cache_quad_get());
}
else {
stl->g_data->planar_display_shgrp = NULL;
}
-
- {
- psl->probe_planar_downsample_ps = DRW_pass_create("LightProbe Planar Downsample",
- DRW_STATE_WRITE_COLOR);
-
- DRWShadingGroup *grp = DRW_shgroup_create(EEVEE_shaders_probe_planar_downsample_sh_get(),
- psl->probe_planar_downsample_ps);
-
- DRW_shgroup_uniform_texture_ref(grp, "source", &txl->planar_pool);
- DRW_shgroup_uniform_float(grp, "fireflyFactor", &sldata->common_data.ssr_firefly_fac, 1);
- DRW_shgroup_call_instances_add(
- grp, DRW_cache_fullscreen_quad_get(), NULL, (uint *)&pinfo->num_planar);
- }
}
static bool eevee_lightprobes_culling_test(Object *ob)
@@ -510,9 +499,9 @@ void EEVEE_lightprobes_cache_add(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata
EEVEE_lightprobes_planar_data_from_object(
ob, &pinfo->planar_data[pinfo->num_planar], &pinfo->planar_vis_tests[pinfo->num_planar]);
/* Debug Display */
- DRWShadingGroup *grp = vedata->stl->g_data->planar_display_shgrp;
+ DRWCallBuffer *grp = vedata->stl->g_data->planar_display_shgrp;
if (grp && (probe->flag & LIGHTPROBE_FLAG_SHOW_DATA)) {
- DRW_shgroup_call_dynamic_add(grp, &pinfo->num_planar, ob->obmat);
+ DRW_buffer_add_entry(grp, &pinfo->num_planar, ob->obmat);
}
pinfo->num_planar++;
@@ -772,6 +761,20 @@ void EEVEE_lightprobes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *ved
}
}
}
+
+ if (pinfo->num_planar) {
+ EEVEE_PassList *psl = vedata->psl;
+ EEVEE_TextureList *txl = vedata->txl;
+ psl->probe_planar_downsample_ps = DRW_pass_create("LightProbe Planar Downsample",
+ DRW_STATE_WRITE_COLOR);
+
+ DRWShadingGroup *grp = DRW_shgroup_create(EEVEE_shaders_probe_planar_downsample_sh_get(),
+ psl->probe_planar_downsample_ps);
+
+ DRW_shgroup_uniform_texture_ref(grp, "source", &txl->planar_pool);
+ DRW_shgroup_uniform_float(grp, "fireflyFactor", &sldata->common_data.ssr_firefly_fac, 1);
+ DRW_shgroup_call_procedural_triangles(grp, pinfo->num_planar, NULL);
+ }
}
/* -------------------------------------------------------------------- */
diff --git a/source/blender/draw/engines/eevee/eevee_lights.c b/source/blender/draw/engines/eevee/eevee_lights.c
index 270defb039b..f64cd340ab2 100644
--- a/source/blender/draw/engines/eevee/eevee_lights.c
+++ b/source/blender/draw/engines/eevee/eevee_lights.c
@@ -53,6 +53,8 @@ extern char datatoc_shadow_store_frag_glsl[];
extern char datatoc_shadow_copy_frag_glsl[];
extern char datatoc_concentric_samples_lib_glsl[];
+extern char datatoc_common_view_lib_glsl[];
+
/* Prototypes */
static void eevee_light_setup(Object *ob, EEVEE_Light *evli);
static float light_attenuation_radius_get(Light *la, float light_threshold);
@@ -111,8 +113,11 @@ void EEVEE_lights_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(
- datatoc_shadow_vert_glsl, NULL, datatoc_shadow_frag_glsl, NULL);
+ e_data.shadow_sh = DRW_shader_create_with_lib(datatoc_shadow_vert_glsl,
+ NULL,
+ datatoc_shadow_frag_glsl,
+ datatoc_common_view_lib_glsl,
+ NULL);
}
if (!sldata->lights) {
@@ -258,7 +263,7 @@ static DRWPass *eevee_lights_cube_store_pass_get(EEVEE_PassList *psl,
DRW_shgroup_uniform_texture_ref(grp, "shadowTexture", &sldata->shadow_cube_blur);
DRW_shgroup_uniform_block(grp, "shadow_render_block", sldata->shadow_render_ubo);
DRW_shgroup_uniform_float(grp, "shadowFilterSize", &linfo->filter_size, 1);
- DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
+ DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
}
return *pass;
}
@@ -280,7 +285,7 @@ static DRWPass *eevee_lights_cascade_store_pass_get(EEVEE_PassList *psl,
DRW_shgroup_uniform_block(grp, "shadow_render_block", sldata->shadow_render_ubo);
DRW_shgroup_uniform_int(grp, "cascadeId", &linfo->current_shadow_cascade, 1);
DRW_shgroup_uniform_float(grp, "shadowFilterSize", &linfo->filter_size, 1);
- DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
+ DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
}
return *pass;
}
@@ -322,7 +327,7 @@ void EEVEE_lights_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_uniform_block(grp, "shadow_render_block", sldata->shadow_render_ubo);
DRW_shgroup_uniform_float(grp, "shadowFilterSize", &linfo->filter_size, 1);
DRW_shgroup_uniform_int(grp, "faceId", &linfo->current_shadow_face, 1);
- DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
+ DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
}
{
@@ -335,7 +340,7 @@ void EEVEE_lights_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_uniform_block(grp, "shadow_render_block", sldata->shadow_render_ubo);
DRW_shgroup_uniform_float(grp, "shadowFilterSize", &linfo->filter_size, 1);
DRW_shgroup_uniform_int(grp, "cascadeId", &linfo->current_shadow_cascade, 1);
- DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
+ DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
}
{
@@ -449,7 +454,7 @@ void EEVEE_lights_cache_shcaster_add(EEVEE_ViewLayerData *UNUSED(sldata),
struct GPUBatch *geom,
Object *ob)
{
- DRW_shgroup_call_object_add(stl->g_data->shadow_shgrp, geom, ob);
+ DRW_shgroup_call_object(stl->g_data->shadow_shgrp, geom, ob);
}
void EEVEE_lights_cache_shcaster_material_add(EEVEE_ViewLayerData *sldata,
@@ -479,7 +484,7 @@ void EEVEE_lights_cache_shcaster_material_add(EEVEE_ViewLayerData *sldata,
DRW_shgroup_uniform_float(grp, "alphaThreshold", alpha_threshold, 1);
}
- DRW_shgroup_call_object_add(grp, geom, ob);
+ DRW_shgroup_call_object(grp, geom, ob);
}
/* Make that object update shadow casting lights inside its influence bounding box. */
@@ -640,7 +645,7 @@ float light_attenuation_radius_get(Light *la, float light_threshold)
/* Compute max light power. */
float power = max_fff(la->r, la->g, la->b);
- power *= fabsf(la->energy);
+ power *= fabsf(la->energy / 100.0f);
power *= max_ff(1.0f, la->spec_fac);
/* Compute the distance (using the inverse square law)
* at which the light power reaches the light_threshold. */
@@ -667,6 +672,9 @@ static void light_shape_parameters_set(EEVEE_Light *evli, const Light *la, float
evli->sizey = max_ff(0.003f, la->area_size * scale[1] * 0.5f);
}
}
+ else if (la->type == LA_SUN) {
+ evli->radius = max_ff(0.001f, tanf(la->sun_angle / 2.0f));
+ }
else {
evli->radius = max_ff(0.001f, la->area_size);
}
@@ -678,7 +686,7 @@ static float light_shape_power_get(const Light *la, const EEVEE_Light *evli)
/* Make illumination power constant */
if (la->type == LA_AREA) {
power = 1.0f / (evli->sizex * evli->sizey * 4.0f * M_PI) * /* 1/(w*h*Pi) */
- 80.0f; /* XXX : Empirical, Fit cycles power */
+ 0.8f; /* XXX : Empirical, Fit cycles power */
if (ELEM(la->area_shape, LA_AREA_DISK, LA_AREA_ELLIPSE)) {
/* Scale power to account for the lower area of the ellipse compared to the surrounding
* rectangle. */
@@ -686,8 +694,7 @@ static float light_shape_power_get(const Light *la, const EEVEE_Light *evli)
}
}
else if (la->type == LA_SPOT || la->type == LA_LOCAL) {
- power = 1.0f / (4.0f * evli->radius * evli->radius * M_PI * M_PI) * /* 1/(4*r²*Pi²) */
- M_PI * M_PI * 10.0; /* XXX : Empirical, Fit cycles power */
+ power = 1.0f / (4.0f * evli->radius * evli->radius * M_PI * M_PI); /* 1/(4*r²*Pi²) */
/* for point lights (a.k.a radius == 0.0) */
// power = M_PI * M_PI * 0.78; /* XXX : Empirical, Fit cycles power */
diff --git a/source/blender/draw/engines/eevee/eevee_lookdev.c b/source/blender/draw/engines/eevee/eevee_lookdev.c
index 13f7ab1c562..bd786c06e69 100644
--- a/source/blender/draw/engines/eevee/eevee_lookdev.c
+++ b/source/blender/draw/engines/eevee/eevee_lookdev.c
@@ -72,21 +72,21 @@ void EEVEE_lookdev_cache_init(EEVEE_Data *vedata,
Scene *scene = draw_ctx->scene;
if (LOOK_DEV_OVERLAY_ENABLED(v3d)) {
- /* Viewport / Ball size. */
+ /* Viewport / Spheres size. */
rcti rect;
ED_region_visible_rect(draw_ctx->ar, &rect);
- /* Make the viewport width scale the lookdev balls a bit.
+ /* Make the viewport width scale the lookdev spheres a bit.
* Scale between 1000px and 2000px. */
const float viewport_scale = clamp_f(
BLI_rcti_size_x(&rect) / (2000.0f * U.dpi_fac), 0.5f, 1.0f);
- const int ball_size = U.lookdev_ball_size * U.dpi_fac * viewport_scale;
+ const int sphere_size = U.lookdev_sphere_size * U.dpi_fac * viewport_scale;
- if (ball_size != effects->ball_size || rect.xmax != effects->anchor[0] ||
+ if (sphere_size != effects->sphere_size || rect.xmax != effects->anchor[0] ||
rect.ymin != effects->anchor[1]) {
- /* If ball size or anchor point moves, reset TAA to avoid ghosting issue.
+ /* If sphere size or anchor point moves, reset TAA to avoid ghosting issue.
* This needs to happen early because we are changing taa_current_sample. */
- effects->ball_size = ball_size;
+ effects->sphere_size = sphere_size;
effects->anchor[0] = rect.xmax;
effects->anchor[1] = rect.ymin;
EEVEE_temporal_sampling_reset(vedata);
@@ -151,7 +151,7 @@ void EEVEE_lookdev_cache_init(EEVEE_Data *vedata,
DRW_shgroup_uniform_mat3(*grp, "StudioLightMatrix", stl->g_data->studiolight_matrix);
DRW_shgroup_uniform_float_copy(*grp, "backgroundAlpha", background_alpha);
DRW_shgroup_uniform_vec3(*grp, "color", background_color, 1);
- DRW_shgroup_call_add(*grp, geom, NULL);
+ DRW_shgroup_call(*grp, geom, NULL);
if (!pinfo) {
/* Do not fadeout when doing probe rendering, only when drawing the background */
DRW_shgroup_uniform_float(
@@ -184,7 +184,7 @@ void EEVEE_lookdev_cache_init(EEVEE_Data *vedata,
}
static void eevee_lookdev_apply_taa(const EEVEE_EffectsInfo *effects,
- int ball_size,
+ int sphere_size,
float winmat[4][4])
{
if (DRW_state_is_image_render() || ((effects->enabled_effects & EFFECT_TAA) != 0)) {
@@ -195,8 +195,8 @@ static void eevee_lookdev_apply_taa(const EEVEE_EffectsInfo *effects,
BLI_halton_2d(ht_primes, ht_offset, effects->taa_current_sample, ht_point);
EEVEE_temporal_sampling_offset_calc(ht_point, 1.5f, ofs);
- winmat[3][0] += ofs[0] / ball_size;
- winmat[3][1] += ofs[1] / ball_size;
+ winmat[3][0] += ofs[0] / sphere_size;
+ winmat[3][1] += ofs[1] / sphere_size;
}
}
@@ -226,7 +226,7 @@ void EEVEE_lookdev_draw(EEVEE_Data *vedata)
DRWMatrixState matstate;
unit_m4(matstate.winmat);
- eevee_lookdev_apply_taa(effects, effects->ball_size, matstate.winmat);
+ eevee_lookdev_apply_taa(effects, effects->sphere_size, matstate.winmat);
/* "Remove" view matrix location. Leaving only rotation. */
DRW_viewport_matrix_get(matstate.viewmat, DRW_MAT_VIEW);
@@ -246,25 +246,25 @@ void EEVEE_lookdev_draw(EEVEE_Data *vedata)
GPU_framebuffer_bind(fb);
- const int ball_margin = effects->ball_size / 6.0f;
- float offset[2] = {0.0f, ball_margin};
+ const int sphere_margin = effects->sphere_size / 6.0f;
+ float offset[2] = {0.0f, sphere_margin};
- offset[0] = effects->ball_size + ball_margin;
+ offset[0] = effects->sphere_size + sphere_margin;
GPU_framebuffer_viewport_set(fb,
effects->anchor[0] - offset[0],
effects->anchor[1] + offset[1],
- effects->ball_size,
- effects->ball_size);
+ effects->sphere_size,
+ effects->sphere_size);
DRW_draw_pass(psl->lookdev_diffuse_pass);
- offset[0] = (effects->ball_size + ball_margin) +
- (ball_margin + effects->ball_size + ball_margin);
+ offset[0] = (effects->sphere_size + sphere_margin) +
+ (sphere_margin + effects->sphere_size + sphere_margin);
GPU_framebuffer_viewport_set(fb,
effects->anchor[0] - offset[0],
effects->anchor[1] + offset[1],
- effects->ball_size,
- effects->ball_size);
+ effects->sphere_size,
+ effects->sphere_size);
DRW_draw_pass(psl->lookdev_glossy_pass);
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c
index c55f3f0150c..c6b228c29d3 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -48,6 +48,7 @@
static struct {
char *frag_shader_lib;
char *vert_shader_str;
+ char *vert_shadow_shader_str;
char *volume_shader_lib;
struct GPUShader *default_prepass_sh;
@@ -133,7 +134,7 @@ static struct GPUTexture *create_ggx_lut_texture(int UNUSED(w), int UNUSED(h))
DRW_shgroup_uniform_texture(grp, "texJitter", e_data.jitter);
struct GPUBatch *geom = DRW_cache_fullscreen_quad_get();
- DRW_shgroup_call_add(grp, geom, NULL);
+ DRW_shgroup_call(grp, geom, NULL);
float *texels = MEM_mallocN(sizeof(float[2]) * w * h, "lut");
@@ -196,7 +197,7 @@ static struct GPUTexture *create_ggx_refraction_lut_texture(int w, int h)
DRW_shgroup_uniform_texture(grp, "utilTex", e_data.util_tex);
struct GPUBatch *geom = DRW_cache_fullscreen_quad_get();
- DRW_shgroup_call_add(grp, geom, NULL);
+ DRW_shgroup_call(grp, geom, NULL);
float *texels = MEM_mallocN(sizeof(float[2]) * w * h, "lut");
@@ -609,18 +610,20 @@ void EEVEE_materials_init(EEVEE_ViewLayerData *sldata,
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.default_background = DRW_shader_create(
datatoc_background_vert_glsl, NULL, datatoc_default_world_frag_glsl, NULL);
- e_data.default_prepass_sh = DRW_shader_create(
- datatoc_prepass_vert_glsl, NULL, datatoc_prepass_frag_glsl, NULL);
-
- e_data.default_prepass_clip_sh = DRW_shader_create(
- datatoc_prepass_vert_glsl, NULL, datatoc_prepass_frag_glsl, "#define CLIP_PLANES\n");
-
char *vert_str = BLI_string_joinN(
datatoc_common_view_lib_glsl, datatoc_common_hair_lib_glsl, datatoc_prepass_vert_glsl);
+ e_data.default_prepass_sh = DRW_shader_create(vert_str, NULL, datatoc_prepass_frag_glsl, NULL);
+
+ e_data.default_prepass_clip_sh = DRW_shader_create(
+ vert_str, NULL, datatoc_prepass_frag_glsl, "#define CLIP_PLANES\n");
+
e_data.default_hair_prepass_sh = DRW_shader_create(
vert_str, NULL, datatoc_prepass_frag_glsl, "#define HAIR_SHADER\n");
@@ -853,7 +856,7 @@ struct GPUMaterial *EEVEE_material_mesh_depth_get(struct Scene *scene,
ma,
engine,
options,
- (is_shadow) ? datatoc_shadow_vert_glsl :
+ (is_shadow) ? e_data.vert_shadow_shader_str :
e_data.vert_shader_str,
NULL,
frag_str,
@@ -1032,7 +1035,7 @@ void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
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_call_add(grp, geom, NULL);
+ DRW_shgroup_call(grp, geom, NULL);
break;
case GPU_MAT_QUEUED:
/* TODO Bypass probe compilation. */
@@ -1051,7 +1054,7 @@ void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
grp = DRW_shgroup_create(e_data.default_background, psl->background_pass);
DRW_shgroup_uniform_vec3(grp, "color", col, 1);
DRW_shgroup_uniform_float(grp, "backgroundAlpha", &stl->g_data->background_alpha, 1);
- DRW_shgroup_call_add(grp, geom, NULL);
+ DRW_shgroup_call(grp, geom, NULL);
}
}
@@ -1140,7 +1143,7 @@ void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRWShadingGroup *grp = DRW_shgroup_create(e_data.update_noise_sh, psl->update_noise_pass);
DRW_shgroup_uniform_texture(grp, "blueNoise", e_data.noise_tex);
DRW_shgroup_uniform_vec3(grp, "offsets", e_data.noise_offsets, 1);
- DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
+ DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
}
if (LOOK_DEV_OVERLAY_ENABLED(draw_ctx->v3d)) {
@@ -1165,7 +1168,7 @@ void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_uniform_float_copy(shgrp, "metallic", 0.0f);
DRW_shgroup_uniform_float_copy(shgrp, "specular", 0.5f);
DRW_shgroup_uniform_float_copy(shgrp, "roughness", 1.0f);
- DRW_shgroup_call_add(shgrp, sphere, NULL);
+ DRW_shgroup_call(shgrp, sphere, NULL);
psl->lookdev_glossy_pass = DRW_pass_create("LookDev Glossy Pass", state);
shgrp = DRW_shgroup_create(e_data.default_lit[options], psl->lookdev_glossy_pass);
@@ -1173,25 +1176,25 @@ void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_uniform_vec3(shgrp, "basecol", color_chrome, 1);
DRW_shgroup_uniform_float_copy(shgrp, "metallic", 1.0f);
DRW_shgroup_uniform_float_copy(shgrp, "roughness", 0.0f);
- DRW_shgroup_call_add(shgrp, sphere, NULL);
+ DRW_shgroup_call(shgrp, sphere, NULL);
}
}
-#define ADD_SHGROUP_CALL(shgrp, ob, ma, geom, oedata) \
+#define ADD_SHGROUP_CALL(shgrp, ob, geom, oedata) \
do { \
if (oedata) { \
- DRW_shgroup_call_object_add_with_callback( \
- shgrp, geom, ob, ma, EEVEE_lightprobes_obj_visibility_cb, oedata); \
+ DRW_shgroup_call_object_with_callback( \
+ shgrp, geom, ob, EEVEE_lightprobes_obj_visibility_cb, oedata); \
} \
else { \
- DRW_shgroup_call_object_add_ex(shgrp, geom, ob, ma, false); \
+ DRW_shgroup_call_object_ex(shgrp, geom, ob, false); \
} \
} while (0)
-#define ADD_SHGROUP_CALL_SAFE(shgrp, ob, ma, geom, oedata) \
+#define ADD_SHGROUP_CALL_SAFE(shgrp, ob, geom, oedata) \
do { \
if (shgrp) { \
- ADD_SHGROUP_CALL(shgrp, ob, ma, geom, oedata); \
+ ADD_SHGROUP_CALL(shgrp, ob, geom, oedata); \
} \
} while (0)
@@ -1205,7 +1208,6 @@ static void material_opaque(Material *ma,
GHash *material_hash,
EEVEE_ViewLayerData *sldata,
EEVEE_Data *vedata,
- bool do_cull,
struct GPUMaterial **gpumat,
struct GPUMaterial **gpumat_depth,
struct DRWShadingGroup **shgrp,
@@ -1225,6 +1227,7 @@ static void material_opaque(Material *ma,
float *spec_p = &ma->spec;
float *rough_p = &ma->roughness;
+ const bool do_cull = (ma->blend_flag & MA_BL_CULL_BACKFACE) != 0;
const bool use_gpumat = (ma->use_nodes && ma->nodetree);
const bool use_ssrefract = ((ma->blend_flag & MA_BL_SS_REFRACTION) != 0) &&
((effects->enabled_effects & EFFECT_REFRACT) != 0);
@@ -1457,7 +1460,6 @@ static void material_opaque(Material *ma,
static void material_transparent(Material *ma,
EEVEE_ViewLayerData *sldata,
EEVEE_Data *vedata,
- bool do_cull,
struct GPUMaterial **gpumat,
struct DRWShadingGroup **shgrp,
struct DRWShadingGroup **shgrp_depth)
@@ -1468,6 +1470,7 @@ static void material_transparent(Material *ma,
EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
EEVEE_LightsInfo *linfo = sldata->lights;
+ const bool do_cull = (ma->blend_flag & MA_BL_CULL_BACKFACE) != 0;
const bool use_ssrefract = (((ma->blend_flag & MA_BL_SS_REFRACTION) != 0) &&
((stl->effects->enabled_effects & EFFECT_REFRACT) != 0));
float *color_p = &ma->r;
@@ -1601,8 +1604,6 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata,
Scene *scene = draw_ctx->scene;
GHash *material_hash = stl->g_data->material_hash;
- const bool do_cull = (draw_ctx->v3d &&
- (draw_ctx->v3d->shading.flag & V3D_SHADING_BACKFACE_CULLING));
bool is_sculpt_mode = DRW_object_use_pbvh_drawing(ob);
/* For now just force fully shaded with eevee when supported. */
is_sculpt_mode = is_sculpt_mode &&
@@ -1638,7 +1639,6 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata,
material_hash,
sldata,
vedata,
- do_cull,
&gpumat_array[i],
&gpumat_depth_array[i],
&shgrp_array[i],
@@ -1651,7 +1651,6 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata,
material_transparent(ma_array[i],
sldata,
vedata,
- do_cull,
&gpumat_array[i],
&shgrp_array[i],
&shgrp_depth_array[i]);
@@ -1686,10 +1685,11 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata,
}
if (is_sculpt_mode) {
- /* TODO(fclem): Support Vcol. */
- DRW_shgroup_call_sculpt_with_materials_add(shgrp_array, ma_array, ob, false);
- DRW_shgroup_call_sculpt_with_materials_add(shgrp_depth_array, ma_array, ob, false);
- DRW_shgroup_call_sculpt_with_materials_add(shgrp_depth_clip_array, ma_array, ob, false);
+ /* Vcol is not supported in the modes that require PBVH drawing. */
+ bool use_vcol = false;
+ DRW_shgroup_call_sculpt_with_materials(shgrp_array, ob, use_vcol);
+ DRW_shgroup_call_sculpt_with_materials(shgrp_depth_array, ob, use_vcol);
+ DRW_shgroup_call_sculpt_with_materials(shgrp_depth_clip_array, ob, use_vcol);
/* TODO(fclem): Support shadows in sculpt mode. */
}
else if (mat_geom) {
@@ -1714,9 +1714,9 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata,
oedata->test_data = &sldata->probes->vis_data;
}
- ADD_SHGROUP_CALL(shgrp_array[i], ob, ma_array[i], mat_geom[i], oedata);
- ADD_SHGROUP_CALL_SAFE(shgrp_depth_array[i], ob, ma_array[i], mat_geom[i], oedata);
- ADD_SHGROUP_CALL_SAFE(shgrp_depth_clip_array[i], ob, ma_array[i], mat_geom[i], oedata);
+ ADD_SHGROUP_CALL(shgrp_array[i], ob, mat_geom[i], oedata);
+ ADD_SHGROUP_CALL_SAFE(shgrp_depth_array[i], ob, mat_geom[i], oedata);
+ ADD_SHGROUP_CALL_SAFE(shgrp_depth_clip_array[i], ob, mat_geom[i], oedata);
char *name = auto_layer_names;
for (int j = 0; j < auto_layer_count; ++j) {
@@ -1895,6 +1895,7 @@ void EEVEE_materials_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.volume_shader_lib);
DRW_SHADER_FREE_SAFE(e_data.default_hair_prepass_sh);
DRW_SHADER_FREE_SAFE(e_data.default_hair_prepass_clip_sh);
diff --git a/source/blender/draw/engines/eevee/eevee_mist.c b/source/blender/draw/engines/eevee/eevee_mist.c
index 1ea1e086aea..d8127d7ea1f 100644
--- a/source/blender/draw/engines/eevee/eevee_mist.c
+++ b/source/blender/draw/engines/eevee/eevee_mist.c
@@ -111,7 +111,7 @@ void EEVEE_mist_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_vec3(grp, "mistSettings", &g_data->mist_start, 1);
- DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
+ DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
}
void EEVEE_mist_output_accumulate(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
diff --git a/source/blender/draw/engines/eevee/eevee_motion_blur.c b/source/blender/draw/engines/eevee/eevee_motion_blur.c
index f8795a7ff0e..f38252590d8 100644
--- a/source/blender/draw/engines/eevee/eevee_motion_blur.c
+++ b/source/blender/draw/engines/eevee/eevee_motion_blur.c
@@ -203,7 +203,7 @@ void EEVEE_motion_blur_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Dat
DRW_shgroup_uniform_mat4(grp, "pastViewProjMatrix", effects->past_world_to_ndc);
DRW_shgroup_uniform_texture_ref(grp, "colorBuffer", &effects->source_buffer);
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
- DRW_shgroup_call_add(grp, quad, NULL);
+ DRW_shgroup_call(grp, quad, NULL);
}
}
diff --git a/source/blender/draw/engines/eevee/eevee_occlusion.c b/source/blender/draw/engines/eevee/eevee_occlusion.c
index 822df19f899..577d7125641 100644
--- a/source/blender/draw/engines/eevee/eevee_occlusion.c
+++ b/source/blender/draw/engines/eevee/eevee_occlusion.c
@@ -159,7 +159,7 @@ void EEVEE_occlusion_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata
DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &effects->ssr_normal_input);
DRW_shgroup_uniform_texture_ref(grp, "horizonBuffer", &effects->gtao_horizons);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
- DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
+ DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
}
else {
/* Cleanup to release memory */
@@ -196,7 +196,7 @@ void EEVEE_occlusion_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_uniform_texture_ref(grp, "maxzBuffer", &txl->maxzbuffer);
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &effects->ao_src_depth);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
- DRW_shgroup_call_add(grp, quad, NULL);
+ DRW_shgroup_call(grp, quad, NULL);
psl->ao_horizon_search_layer = DRW_pass_create("GTAO Horizon Search Layer",
DRW_STATE_WRITE_COLOR);
@@ -206,7 +206,7 @@ void EEVEE_occlusion_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_uniform_texture_ref(grp, "depthBufferLayered", &effects->ao_src_depth);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_int(grp, "layer", &stl->effects->ao_depth_layer, 1);
- DRW_shgroup_call_add(grp, quad, NULL);
+ DRW_shgroup_call(grp, quad, NULL);
if (G.debug_value == 6) {
psl->ao_horizon_debug = DRW_pass_create("GTAO Horizon Debug", DRW_STATE_WRITE_COLOR);
@@ -217,7 +217,7 @@ void EEVEE_occlusion_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &effects->ssr_normal_input);
DRW_shgroup_uniform_texture_ref(grp, "horizonBuffer", &effects->gtao_horizons);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
- DRW_shgroup_call_add(grp, quad, NULL);
+ DRW_shgroup_call(grp, quad, NULL);
}
}
}
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index 6112921ff39..ca9314daa95 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -606,7 +606,7 @@ typedef struct EEVEE_EffectsInfo {
/* Other */
float prev_persmat[4][4];
/* Lookdev */
- int ball_size;
+ int sphere_size;
int anchor[2];
/* Bloom */
int bloom_iteration_len;
@@ -816,8 +816,7 @@ typedef struct EEVEE_PrivateData {
struct DRWShadingGroup *refract_depth_shgrp_cull;
struct DRWShadingGroup *refract_depth_shgrp_clip;
struct DRWShadingGroup *refract_depth_shgrp_clip_cull;
- struct DRWShadingGroup *cube_display_shgrp;
- struct DRWShadingGroup *planar_display_shgrp;
+ struct DRWCallBuffer *planar_display_shgrp;
struct GHash *material_hash;
float background_alpha; /* TODO find a better place for this. */
/* Chosen lightcache: can come from Lookdev or the viewlayer. */
diff --git a/source/blender/draw/engines/eevee/eevee_screen_raytrace.c b/source/blender/draw/engines/eevee/eevee_screen_raytrace.c
index 22c7dd00b97..ed69c5f4727 100644
--- a/source/blender/draw/engines/eevee/eevee_screen_raytrace.c
+++ b/source/blender/draw/engines/eevee/eevee_screen_raytrace.c
@@ -230,7 +230,7 @@ void EEVEE_screen_raytrace_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *v
if (!effects->reflection_trace_full) {
DRW_shgroup_uniform_ivec2(grp, "halfresOffset", effects->ssr_halfres_ofs, 1);
}
- DRW_shgroup_call_add(grp, quad, NULL);
+ DRW_shgroup_call(grp, quad, NULL);
psl->ssr_resolve = DRW_pass_create("SSR Resolve", DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE);
grp = DRW_shgroup_create(resolve_shader, psl->ssr_resolve);
@@ -253,7 +253,7 @@ void EEVEE_screen_raytrace_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *v
DRW_shgroup_uniform_texture_ref(grp, "horizonBuffer", &effects->gtao_horizons);
}
- DRW_shgroup_call_add(grp, quad, NULL);
+ DRW_shgroup_call(grp, quad, NULL);
}
}
diff --git a/source/blender/draw/engines/eevee/eevee_subsurface.c b/source/blender/draw/engines/eevee/eevee_subsurface.c
index cbe0f474ac7..592de2b2389 100644
--- a/source/blender/draw/engines/eevee/eevee_subsurface.c
+++ b/source/blender/draw/engines/eevee/eevee_subsurface.c
@@ -229,7 +229,7 @@ void EEVEE_subsurface_add_pass(EEVEE_ViewLayerData *sldata,
DRW_shgroup_uniform_block(grp, "sssProfile", sss_profile);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_stencil_mask(grp, sss_id);
- DRW_shgroup_call_add(grp, quad, NULL);
+ DRW_shgroup_call(grp, quad, NULL);
struct GPUShader *sh = (effects->sss_separate_albedo) ? e_data.sss_sh[2] : e_data.sss_sh[1];
grp = DRW_shgroup_create(sh, psl->sss_resolve_ps);
@@ -239,7 +239,7 @@ void EEVEE_subsurface_add_pass(EEVEE_ViewLayerData *sldata,
DRW_shgroup_uniform_block(grp, "sssProfile", sss_profile);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_stencil_mask(grp, sss_id);
- DRW_shgroup_call_add(grp, quad, NULL);
+ DRW_shgroup_call(grp, quad, NULL);
if (effects->sss_separate_albedo) {
DRW_shgroup_uniform_texture_ref(grp, "sssAlbedo", &effects->sss_albedo);
@@ -253,7 +253,7 @@ void EEVEE_subsurface_add_pass(EEVEE_ViewLayerData *sldata,
DRW_shgroup_uniform_block(grp, "sssProfile", sss_profile);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_stencil_mask(grp, sss_id);
- DRW_shgroup_call_add(grp, quad, NULL);
+ DRW_shgroup_call(grp, quad, NULL);
if (effects->sss_separate_albedo) {
DRW_shgroup_uniform_texture_ref(grp, "sssAlbedo", &effects->sss_albedo);
diff --git a/source/blender/draw/engines/eevee/eevee_temporal_sampling.c b/source/blender/draw/engines/eevee/eevee_temporal_sampling.c
index 194fff9b93c..1b7adba4284 100644
--- a/source/blender/draw/engines/eevee/eevee_temporal_sampling.c
+++ b/source/blender/draw/engines/eevee/eevee_temporal_sampling.c
@@ -287,7 +287,7 @@ void EEVEE_temporal_sampling_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data
else {
DRW_shgroup_uniform_float(grp, "alpha", &effects->taa_alpha, 1);
}
- DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
+ DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
}
}
diff --git a/source/blender/draw/engines/eevee/eevee_volumes.c b/source/blender/draw/engines/eevee/eevee_volumes.c
index 76c8f010142..8867bf107ec 100644
--- a/source/blender/draw/engines/eevee/eevee_volumes.c
+++ b/source/blender/draw/engines/eevee/eevee_volumes.c
@@ -400,8 +400,7 @@ void EEVEE_volumes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
!LOOK_DEV_STUDIO_LIGHT_ENABLED(draw_ctx->v3d)) {
struct GPUMaterial *mat = EEVEE_material_world_volume_get(scene, wo);
- grp = DRW_shgroup_material_empty_tri_batch_create(
- mat, psl->volumetric_world_ps, common_data->vol_tex_size[2]);
+ grp = DRW_shgroup_material_create(mat, psl->volumetric_world_ps);
if (grp) {
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
@@ -416,15 +415,18 @@ void EEVEE_volumes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_uniform_texture(grp, "sampdensity", e_data.dummy_density);
DRW_shgroup_uniform_texture(grp, "sampflame", e_data.dummy_flame);
DRW_shgroup_uniform_vec2(grp, "unftemperature", (float[2]){0.0f, 1.0f}, 1);
+
+ DRW_shgroup_call_procedural_triangles(grp, common_data->vol_tex_size[2], NULL);
}
}
if (grp == NULL) {
/* If no world or volume material is present just clear the buffer with this drawcall */
- grp = DRW_shgroup_empty_tri_batch_create(
- e_data.volumetric_clear_sh, psl->volumetric_world_ps, common_data->vol_tex_size[2]);
+ grp = DRW_shgroup_create(e_data.volumetric_clear_sh, psl->volumetric_world_ps);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+
+ DRW_shgroup_call_procedural_triangles(grp, common_data->vol_tex_size[2], NULL);
}
/* Volumetric Objects */
@@ -435,8 +437,7 @@ void EEVEE_volumes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
e_data.volumetric_scatter_with_lights_sh :
e_data.volumetric_scatter_sh;
psl->volumetric_scatter_ps = DRW_pass_create("Volumetric Scattering", DRW_STATE_WRITE_COLOR);
- grp = DRW_shgroup_empty_tri_batch_create(
- scatter_sh, psl->volumetric_scatter_ps, common_data->vol_tex_size[2]);
+ grp = DRW_shgroup_create(scatter_sh, psl->volumetric_scatter_ps);
DRW_shgroup_uniform_texture_ref(grp, "irradianceGrid", &lcache->grid_tx.tex);
DRW_shgroup_uniform_texture_ref(grp, "shadowCubeTexture", &sldata->shadow_cube_pool);
DRW_shgroup_uniform_texture_ref(grp, "shadowCascadeTexture", &sldata->shadow_cascade_pool);
@@ -451,15 +452,17 @@ void EEVEE_volumes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+ DRW_shgroup_call_procedural_triangles(grp, common_data->vol_tex_size[2], NULL);
+
psl->volumetric_integration_ps = DRW_pass_create("Volumetric Integration",
DRW_STATE_WRITE_COLOR);
- grp = DRW_shgroup_empty_tri_batch_create(e_data.volumetric_integration_sh,
- psl->volumetric_integration_ps,
- common_data->vol_tex_size[2]);
+ grp = DRW_shgroup_create(e_data.volumetric_integration_sh, psl->volumetric_integration_ps);
DRW_shgroup_uniform_texture_ref(grp, "volumeScattering", &txl->volume_scatter);
DRW_shgroup_uniform_texture_ref(grp, "volumeExtinction", &txl->volume_transmittance);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+ DRW_shgroup_call_procedural_triangles(grp, common_data->vol_tex_size[2], NULL);
+
psl->volumetric_resolve_ps = DRW_pass_create("Volumetric Resolve", DRW_STATE_WRITE_COLOR);
grp = DRW_shgroup_create(e_data.volumetric_resolve_sh, psl->volumetric_resolve_ps);
DRW_shgroup_uniform_texture_ref(grp, "inScattering", &txl->volume_scatter);
@@ -467,7 +470,7 @@ void EEVEE_volumes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_uniform_texture_ref(grp, "inSceneColor", &e_data.color_src);
DRW_shgroup_uniform_texture_ref(grp, "inSceneDepth", &e_data.depth_src);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
- DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
+ DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
}
}
@@ -500,11 +503,7 @@ void EEVEE_volumes_cache_object_add(EEVEE_ViewLayerData *sldata,
return;
}
- DRWShadingGroup *grp = DRW_shgroup_material_empty_tri_batch_create(
- mat, vedata->psl->volumetric_objects_ps, sldata->common_data.vol_tex_size[2]);
-
- /* Making sure it's updated. */
- invert_m4_m4(ob->imat, ob->obmat);
+ DRWShadingGroup *grp = DRW_shgroup_material_create(mat, vedata->psl->volumetric_objects_ps);
BKE_mesh_texspace_get_reference((struct Mesh *)ob->data, NULL, &texcoloc, NULL, &texcosize);
@@ -578,6 +577,10 @@ void EEVEE_volumes_cache_object_add(EEVEE_ViewLayerData *sldata,
DRW_shgroup_uniform_vec3(grp, "volumeColor", white, 1);
DRW_shgroup_uniform_vec2(grp, "unftemperature", (float[2]){0.0f, 1.0f}, 1);
}
+
+ /* TODO Reduce to number of slices intersecting. */
+ /* TODO Preemptive culling. */
+ DRW_shgroup_call_procedural_triangles(grp, sldata->common_data.vol_tex_size[2], NULL);
}
void EEVEE_volumes_compute(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
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 3a5f20b952e..12e60f0250f 100644
--- a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
@@ -15,7 +15,7 @@ uniform sampler2D maxzBuffer;
uniform sampler2D minzBuffer;
uniform sampler2DArray planarDepth;
-#define cameraForward normalize(ViewMatrixInverse[2].xyz)
+#define cameraForward ViewMatrixInverse[2].xyz
#define cameraPos ViewMatrixInverse[3].xyz
#define cameraVec \
((ProjectionMatrix[3][3] == 0.0) ? normalize(cameraPos - worldPosition) : cameraForward)
@@ -836,18 +836,22 @@ Closure closure_mix(Closure cl1, Closure cl2, float fac)
cl.radiance /= max(1e-8, cl.opacity);
# ifdef USE_SSS
- cl.sss_data.rgb = mix(cl1.sss_data.rgb, cl2.sss_data.rgb, fac);
- cl.sss_data.a = (cl1.sss_data.a > 0.0) ? cl1.sss_data.a : cl2.sss_data.a;
+ /* Apply Mix on input */
+ cl1.sss_data.rgb *= 1.0 - fac;
+ cl2.sss_data.rgb *= fac;
+
+ /* Select biggest radius. */
+ bool use_cl1 = (cl1.sss_data.a > cl2.sss_data.a);
+ cl.sss_data = (use_cl1) ? cl1.sss_data : cl2.sss_data;
# ifdef USE_SSS_ALBEDO
/* TODO Find a solution to this. Dither? */
- cl.sss_albedo = (cl1.sss_data.a > 0.0) ? cl1.sss_albedo : cl2.sss_albedo;
+ cl.sss_albedo = (use_cl1) ? cl1.sss_albedo : cl2.sss_albedo;
/* Add radiance that was supposed to be filtered but was rejected. */
- cl.radiance += (cl1.sss_data.a > 0.0) ? cl2.sss_data.rgb * cl2.sss_albedo :
- cl1.sss_data.rgb * cl1.sss_albedo;
+ cl.radiance += (use_cl1) ? cl2.sss_data.rgb * cl2.sss_albedo : cl1.sss_data.rgb * cl1.sss_albedo;
# else
/* Add radiance that was supposed to be filtered but was rejected. */
- cl.radiance += (cl1.sss_data.a > 0.0) ? cl2.sss_data.rgb : cl1.sss_data.rgb;
+ cl.radiance += (use_cl1) ? cl2.sss_data.rgb : cl1.sss_data.rgb;
# endif
# endif
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_planar_downsample_vert.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_planar_downsample_vert.glsl
index 1c943bd51bc..588cd402bb3 100644
--- a/source/blender/draw/engines/eevee/shaders/lightprobe_planar_downsample_vert.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_planar_downsample_vert.glsl
@@ -1,11 +1,12 @@
-in vec2 pos;
-
out int instance;
out vec2 vPos;
void main()
{
- instance = gl_InstanceID;
- vPos = pos;
+ int v = gl_VertexID % 3;
+ vPos.x = -1.0 + float((v & 1) << 2);
+ vPos.y = -1.0 + float((v & 2) << 1);
+
+ instance = gl_VertexID / 3;
}
diff --git a/source/blender/draw/engines/eevee/shaders/lit_surface_vert.glsl b/source/blender/draw/engines/eevee/shaders/lit_surface_vert.glsl
index 40075ed64be..0a2785bafca 100644
--- a/source/blender/draw/engines/eevee/shaders/lit_surface_vert.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lit_surface_vert.glsl
@@ -1,13 +1,4 @@
-uniform mat4 ModelViewProjectionMatrix;
-uniform mat4 ModelViewMatrix;
-uniform mat3 WorldNormalMatrix;
-#ifndef USE_ATTR
-uniform mat4 ModelMatrix;
-uniform mat3 NormalMatrix;
-uniform mat4 ModelMatrixInverse;
-#endif
-
#ifndef HAIR_SHADER
in vec3 pos;
in vec3 nor;
@@ -57,20 +48,20 @@ void main()
hairThickness,
hairThickTime);
- gl_Position = ViewProjectionMatrix * vec4(pos, 1.0);
- viewPosition = (ViewMatrix * vec4(pos, 1.0)).xyz;
- worldPosition = pos;
hairTangent = normalize(hairTangent);
worldNormal = cross(binor, hairTangent);
- viewNormal = mat3(ViewMatrix) * worldNormal;
+ worldPosition = pos;
#else
- gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
- viewPosition = (ModelViewMatrix * vec4(pos, 1.0)).xyz;
- worldPosition = (ModelMatrix * vec4(pos, 1.0)).xyz;
- worldNormal = normalize(WorldNormalMatrix * nor);
- viewNormal = normalize(NormalMatrix * nor);
+ worldPosition = point_object_to_world(pos);
+ worldNormal = normalize(normal_object_to_world(nor));
#endif
+ /* No need to normalize since this is just a rotation. */
+ viewNormal = normal_world_to_view(worldNormal);
+
+ viewPosition = point_world_to_view(worldPosition);
+ gl_Position = point_world_to_ndc(worldPosition);
+
/* Used for planar reflections */
gl_ClipDistance[0] = dot(vec4(worldPosition, 1.0), ClipPlanes[0]);
diff --git a/source/blender/draw/engines/eevee/shaders/prepass_vert.glsl b/source/blender/draw/engines/eevee/shaders/prepass_vert.glsl
index 9196253478a..fe274f59167 100644
--- a/source/blender/draw/engines/eevee/shaders/prepass_vert.glsl
+++ b/source/blender/draw/engines/eevee/shaders/prepass_vert.glsl
@@ -1,8 +1,4 @@
-uniform mat4 ModelViewProjectionMatrix;
-uniform mat4 ModelMatrix;
-uniform mat4 ModelMatrixInverse;
-
#ifdef CLIP_PLANES
/* keep in sync with DRWManager.view_data */
layout(std140) uniform clip_block
@@ -19,25 +15,23 @@ void main()
{
#ifdef HAIR_SHADER
float time, thick_time, thickness;
- vec3 pos, tan, binor;
+ vec3 worldPosition, tan, binor;
hair_get_pos_tan_binor_time((ProjectionMatrix[3][3] == 0.0),
ModelMatrixInverse,
ViewMatrixInverse[3].xyz,
ViewMatrixInverse[2].xyz,
- pos,
+ worldPosition,
tan,
binor,
time,
thickness,
thick_time);
-
- gl_Position = ViewProjectionMatrix * vec4(pos, 1.0);
- vec4 worldPosition = vec4(pos, 1.0);
#else
- gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
- vec4 worldPosition = (ModelMatrix * vec4(pos, 1.0));
+ vec3 worldPosition = point_object_to_world(pos);
#endif
+ gl_Position = point_world_to_ndc(worldPosition);
+
#ifdef CLIP_PLANES
gl_ClipDistance[0] = dot(vec4(worldPosition.xyz, 1.0), ClipPlanes[0]);
#endif
diff --git a/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl b/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl
index f9225cd100b..7dd9af310ed 100644
--- a/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl
+++ b/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl
@@ -1,14 +1,4 @@
-uniform mat4 ModelViewProjectionMatrix;
-#ifdef MESH_SHADER
-uniform mat4 ModelViewMatrix;
-uniform mat3 WorldNormalMatrix;
-# ifndef USE_ATTR
-uniform mat4 ModelMatrix;
-uniform mat3 NormalMatrix;
-# endif
-#endif
-
in vec3 pos;
in vec3 nor;
@@ -21,12 +11,15 @@ out vec3 viewNormal;
void main()
{
- gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ vec3 world_pos = point_object_to_world(pos);
+ gl_Position = point_world_to_ndc(world_pos);
#ifdef MESH_SHADER
- viewPosition = (ModelViewMatrix * vec4(pos, 1.0)).xyz;
- worldPosition = (ModelMatrix * vec4(pos, 1.0)).xyz;
- viewNormal = normalize(NormalMatrix * nor);
- worldNormal = normalize(WorldNormalMatrix * nor);
+ worldPosition = world_pos;
+ viewPosition = point_world_to_view(worldPosition);
+
+ worldNormal = normalize(normal_object_to_world(nor));
+ /* No need to normalize since this is just a rotation. */
+ viewNormal = normal_world_to_view(worldNormal);
# ifdef USE_ATTR
pass_attr(pos);
# endif
diff --git a/source/blender/draw/engines/external/external_engine.c b/source/blender/draw/engines/external/external_engine.c
index ed8c609c01f..643f51facd4 100644
--- a/source/blender/draw/engines/external/external_engine.c
+++ b/source/blender/draw/engines/external/external_engine.c
@@ -191,7 +191,7 @@ static void external_cache_populate(void *vedata, Object *ob)
struct GPUBatch *geom = DRW_cache_object_surface_get(ob);
if (geom) {
/* Depth Prepass */
- DRW_shgroup_call_add(stl->g_data->depth_shgrp, geom, ob->obmat);
+ DRW_shgroup_call(stl->g_data->depth_shgrp, geom, ob->obmat);
}
}
}
diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c b/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
index 7dabbcf4c41..7b2c0ed168e 100644
--- a/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
+++ b/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
@@ -133,7 +133,8 @@ static void gpencil_vbo_ensure_size(GpencilBatchCacheElem *be, int totvertex)
void DRW_gpencil_get_point_geom(GpencilBatchCacheElem *be,
bGPDstroke *gps,
short thickness,
- const float ink[4])
+ const float ink[4],
+ const int alignment_mode)
{
int totvertex = gps->totpoints;
if (be->vbo == NULL) {
@@ -177,26 +178,34 @@ void DRW_gpencil_get_point_geom(GpencilBatchCacheElem *be,
/* use previous point to determine stroke direction */
bGPDspoint *pt2 = NULL;
float fpt[3];
- if (i == 0) {
- if (gps->totpoints > 1) {
- /* extrapolate a point before first point */
- pt2 = &gps->points[1];
- interp_v3_v3v3(fpt, &pt2->x, &pt->x, 1.5f);
- GPU_vertbuf_attr_set(be->vbo, be->prev_pos_id, be->vbo_len, fpt);
+ if (alignment_mode != GP_STYLE_FOLLOW_PATH) {
+ /* add small offset to get a vector */
+ copy_v3_v3(fpt, &pt->x);
+ fpt[0] += 0.00001f;
+ fpt[1] += 0.00001f;
+ GPU_vertbuf_attr_set(be->vbo, be->prev_pos_id, be->vbo_len, fpt);
+ }
+ else {
+ if (i == 0) {
+ if (gps->totpoints > 1) {
+ /* extrapolate a point before first point */
+ pt2 = &gps->points[1];
+ interp_v3_v3v3(fpt, &pt2->x, &pt->x, 1.5f);
+ GPU_vertbuf_attr_set(be->vbo, be->prev_pos_id, be->vbo_len, fpt);
+ }
+ else {
+ /* add small offset to get a vector */
+ copy_v3_v3(fpt, &pt->x);
+ fpt[0] += 0.00001f;
+ fpt[1] += 0.00001f;
+ GPU_vertbuf_attr_set(be->vbo, be->prev_pos_id, be->vbo_len, fpt);
+ }
}
else {
- /* add small offset to get a vector */
- copy_v3_v3(fpt, &pt->x);
- fpt[0] += 0.00001f;
- fpt[1] += 0.00001f;
- GPU_vertbuf_attr_set(be->vbo, be->prev_pos_id, be->vbo_len, fpt);
+ pt2 = &gps->points[i - 1];
+ GPU_vertbuf_attr_set(be->vbo, be->prev_pos_id, be->vbo_len, &pt2->x);
}
}
- else {
- pt2 = &gps->points[i - 1];
- GPU_vertbuf_attr_set(be->vbo, be->prev_pos_id, be->vbo_len, &pt2->x);
- }
-
be->vbo_len++;
}
}
diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c
index 4b6c913785d..71e83dac461 100644
--- a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c
+++ b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c
@@ -465,7 +465,7 @@ static DRWShadingGroup *DRW_gpencil_shgroup_fill_create(GPENCIL_e_data *e_data,
BKE_image_release_ibuf(image, ibuf, NULL);
}
else {
- GPUTexture *texture = GPU_texture_from_blender(gp_style->ima, &iuser, GL_TEXTURE_2D, true);
+ GPUTexture *texture = GPU_texture_from_blender(gp_style->ima, &iuser, GL_TEXTURE_2D);
DRW_shgroup_uniform_texture(grp, "myTexture", texture);
stl->shgroups[id].texture_clamp = gp_style->flag & GP_STYLE_COLOR_TEX_CLAMP ? 1 : 0;
@@ -631,7 +631,7 @@ DRWShadingGroup *DRW_gpencil_shgroup_stroke_create(GPENCIL_e_data *e_data,
BKE_image_release_ibuf(image, ibuf, NULL);
}
else {
- GPUTexture *texture = GPU_texture_from_blender(gp_style->sima, &iuser, GL_TEXTURE_2D, true);
+ GPUTexture *texture = GPU_texture_from_blender(gp_style->sima, &iuser, GL_TEXTURE_2D);
DRW_shgroup_uniform_texture(grp, "myTexture", texture);
BKE_image_release_ibuf(image, ibuf, NULL);
@@ -725,8 +725,8 @@ static DRWShadingGroup *DRW_gpencil_shgroup_point_create(GPENCIL_e_data *e_data,
DRW_shgroup_uniform_float(grp, "mix_stroke_factor", &stl->shgroups[id].mix_stroke_factor, 1);
/* lock rotation of dots and boxes */
- stl->shgroups[id].use_follow_path = (gp_style->flag & GP_STYLE_COLOR_LOCK_DOTS) ? 0 : 1;
- DRW_shgroup_uniform_int(grp, "use_follow_path", &stl->shgroups[id].use_follow_path, 1);
+ stl->shgroups[id].alignment_mode = gp_style->alignment_mode;
+ DRW_shgroup_uniform_int(grp, "alignment_mode", &stl->shgroups[id].alignment_mode, 1);
}
else {
stl->storage->obj_scale = 1.0f;
@@ -758,7 +758,7 @@ static DRWShadingGroup *DRW_gpencil_shgroup_point_create(GPENCIL_e_data *e_data,
DRW_shgroup_uniform_float(grp, "mix_stroke_factor", &stl->storage->mix_stroke_factor, 1);
/* lock rotation of dots and boxes */
- DRW_shgroup_uniform_int(grp, "use_follow_path", &stl->storage->use_follow_path, 1);
+ DRW_shgroup_uniform_int(grp, "alignment_mode", &stl->storage->alignment_mode, 1);
}
DRW_shgroup_uniform_vec4(grp, "colormix", gp_style->stroke_rgba, 1);
@@ -787,7 +787,7 @@ static DRWShadingGroup *DRW_gpencil_shgroup_point_create(GPENCIL_e_data *e_data,
BKE_image_release_ibuf(image, ibuf, NULL);
}
else {
- GPUTexture *texture = GPU_texture_from_blender(gp_style->sima, &iuser, GL_TEXTURE_2D, true);
+ GPUTexture *texture = GPU_texture_from_blender(gp_style->sima, &iuser, GL_TEXTURE_2D);
DRW_shgroup_uniform_texture(grp, "myTexture", texture);
BKE_image_release_ibuf(image, ibuf, NULL);
@@ -870,6 +870,7 @@ static void gpencil_add_stroke_vertexdata(GpencilBatchCache *cache,
float ink[4];
short sthickness;
MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, gps->mat_nr + 1);
+ const int alignment_mode = (gp_style) ? gp_style->alignment_mode : GP_STYLE_FOLLOW_PATH;
/* set color using base color, tint color and opacity */
if (cache->is_dirty) {
@@ -919,7 +920,7 @@ static void gpencil_add_stroke_vertexdata(GpencilBatchCache *cache,
else {
/* create vertex data */
const int old_len = cache->b_point.vbo_len;
- DRW_gpencil_get_point_geom(&cache->b_point, gps, sthickness, ink);
+ DRW_gpencil_get_point_geom(&cache->b_point, gps, sthickness, ink, alignment_mode);
/* add to list of groups */
if (old_len < cache->b_point.vbo_len) {
@@ -1490,7 +1491,7 @@ void DRW_gpencil_populate_buffer_strokes(GPENCIL_e_data *e_data,
/* save gradient info */
stl->storage->gradient_f = brush->gpencil_settings->gradient_f;
copy_v2_v2(stl->storage->gradient_s, brush->gpencil_settings->gradient_s);
- stl->storage->use_follow_path = (gp_style->flag & GP_STYLE_COLOR_LOCK_DOTS) ? 0 : 1;
+ stl->storage->alignment_mode = (gp_style) ? gp_style->alignment_mode : GP_STYLE_FOLLOW_PATH;
/* if only one point, don't need to draw buffer because the user has no time to see it */
if (gpd->runtime.sbuffer_size > 1) {
@@ -1543,9 +1544,9 @@ void DRW_gpencil_populate_buffer_strokes(GPENCIL_e_data *e_data,
}
/* buffer strokes, must show stroke always */
- DRW_shgroup_call_add(stl->g_data->shgrps_drawing_stroke,
- e_data->batch_buffer_stroke,
- stl->storage->unit_matrix);
+ DRW_shgroup_call(stl->g_data->shgrps_drawing_stroke,
+ e_data->batch_buffer_stroke,
+ stl->storage->unit_matrix);
if ((gpd->runtime.sbuffer_size >= 3) &&
(gpd->runtime.sfill[3] > GPENCIL_ALPHA_OPACITY_THRESH) &&
@@ -1567,9 +1568,9 @@ void DRW_gpencil_populate_buffer_strokes(GPENCIL_e_data *e_data,
}
e_data->batch_buffer_fill = DRW_gpencil_get_buffer_fill_geom(gpd);
- DRW_shgroup_call_add(stl->g_data->shgrps_drawing_fill,
- e_data->batch_buffer_fill,
- stl->storage->unit_matrix);
+ DRW_shgroup_call(stl->g_data->shgrps_drawing_fill,
+ e_data->batch_buffer_fill,
+ stl->storage->unit_matrix);
stl->storage->buffer_fill = true;
}
stl->storage->buffer_stroke = true;
@@ -1599,7 +1600,7 @@ void DRW_gpencil_populate_buffer_strokes(GPENCIL_e_data *e_data,
e_data->batch_buffer_ctrlpoint = DRW_gpencil_get_buffer_ctrlpoint_geom(gpd);
- DRW_shgroup_call_add(shgrp, e_data->batch_buffer_ctrlpoint, stl->storage->unit_matrix);
+ DRW_shgroup_call(shgrp, e_data->batch_buffer_ctrlpoint, stl->storage->unit_matrix);
stl->storage->buffer_ctrlpoint = true;
}
@@ -1721,12 +1722,12 @@ static void DRW_gpencil_shgroups_create(GPENCIL_e_data *e_data,
scale,
cache_ob->shading_type);
if ((do_onion) || (elm->onion == false)) {
- DRW_shgroup_call_range_add(shgrp,
- cache->b_stroke.batch,
- (!cache_ob->is_dup_ob) ? gpf->runtime.viewmatrix :
- cache_ob->obmat,
- start_stroke,
- len);
+ DRW_shgroup_call_range(shgrp,
+ cache->b_stroke.batch,
+ (!cache_ob->is_dup_ob) ? gpf->runtime.viewmatrix :
+ cache_ob->obmat,
+ start_stroke,
+ len);
}
stl->storage->shgroup_id++;
start_stroke = elm->vertex_idx;
@@ -1750,12 +1751,12 @@ static void DRW_gpencil_shgroups_create(GPENCIL_e_data *e_data,
cache_ob->shading_type);
if ((do_onion) || (elm->onion == false)) {
- DRW_shgroup_call_range_add(shgrp,
- cache->b_point.batch,
- (!cache_ob->is_dup_ob) ? gpf->runtime.viewmatrix :
- cache_ob->obmat,
- start_point,
- len);
+ DRW_shgroup_call_range(shgrp,
+ cache->b_point.batch,
+ (!cache_ob->is_dup_ob) ? gpf->runtime.viewmatrix :
+ cache_ob->obmat,
+ start_point,
+ len);
}
stl->storage->shgroup_id++;
start_point = elm->vertex_idx;
@@ -1776,12 +1777,12 @@ static void DRW_gpencil_shgroups_create(GPENCIL_e_data *e_data,
cache_ob->shading_type);
if ((do_onion) || (elm->onion == false)) {
- DRW_shgroup_call_range_add(shgrp,
- cache->b_fill.batch,
- (!cache_ob->is_dup_ob) ? gpf->runtime.viewmatrix :
- cache_ob->obmat,
- start_fill,
- len);
+ DRW_shgroup_call_range(shgrp,
+ cache->b_fill.batch,
+ (!cache_ob->is_dup_ob) ? gpf->runtime.viewmatrix :
+ cache_ob->obmat,
+ start_fill,
+ len);
}
stl->storage->shgroup_id++;
start_fill = elm->vertex_idx;
@@ -1791,12 +1792,12 @@ static void DRW_gpencil_shgroups_create(GPENCIL_e_data *e_data,
if (stl->g_data->shgrps_edit_point) {
const int len = elm->vertex_idx - start_edit;
/* use always the same group */
- DRW_shgroup_call_range_add(stl->g_data->shgrps_edit_point,
- cache->b_edit.batch,
- (!cache_ob->is_dup_ob) ? gpf->runtime.viewmatrix :
- cache_ob->obmat,
- start_edit,
- len);
+ DRW_shgroup_call_range(stl->g_data->shgrps_edit_point,
+ cache->b_edit.batch,
+ (!cache_ob->is_dup_ob) ? gpf->runtime.viewmatrix :
+ cache_ob->obmat,
+ start_edit,
+ len);
start_edit = elm->vertex_idx;
}
@@ -1806,12 +1807,12 @@ static void DRW_gpencil_shgroups_create(GPENCIL_e_data *e_data,
if (stl->g_data->shgrps_edit_line) {
const int len = elm->vertex_idx - start_edlin;
/* use always the same group */
- DRW_shgroup_call_range_add(stl->g_data->shgrps_edit_line,
- cache->b_edlin.batch,
- (!cache_ob->is_dup_ob) ? gpf->runtime.viewmatrix :
- cache_ob->obmat,
- start_edlin,
- len);
+ DRW_shgroup_call_range(stl->g_data->shgrps_edit_line,
+ cache->b_edlin.batch,
+ (!cache_ob->is_dup_ob) ? gpf->runtime.viewmatrix :
+ cache_ob->obmat,
+ start_edlin,
+ len);
start_edlin = elm->vertex_idx;
}
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c
index ea578187765..280702020df 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.c
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.c
@@ -61,6 +61,8 @@ extern char datatoc_gpencil_edit_point_geom_glsl[];
extern char datatoc_gpencil_edit_point_frag_glsl[];
extern char datatoc_gpencil_blend_frag_glsl[];
+extern char datatoc_common_view_lib_glsl[];
+
/* *********** STATIC *********** */
static GPENCIL_e_data e_data = {NULL}; /* Engine data */
@@ -167,31 +169,37 @@ static void GPENCIL_create_shaders(void)
{
/* normal fill shader */
if (!e_data.gpencil_fill_sh) {
- e_data.gpencil_fill_sh = DRW_shader_create(
- datatoc_gpencil_fill_vert_glsl, NULL, datatoc_gpencil_fill_frag_glsl, NULL);
+ e_data.gpencil_fill_sh = DRW_shader_create_with_lib(datatoc_gpencil_fill_vert_glsl,
+ NULL,
+ datatoc_gpencil_fill_frag_glsl,
+ datatoc_common_view_lib_glsl,
+ NULL);
}
/* normal stroke shader using geometry to display lines (line mode) */
if (!e_data.gpencil_stroke_sh) {
- e_data.gpencil_stroke_sh = DRW_shader_create(datatoc_gpencil_stroke_vert_glsl,
- datatoc_gpencil_stroke_geom_glsl,
- datatoc_gpencil_stroke_frag_glsl,
- NULL);
+ e_data.gpencil_stroke_sh = DRW_shader_create_with_lib(datatoc_gpencil_stroke_vert_glsl,
+ datatoc_gpencil_stroke_geom_glsl,
+ datatoc_gpencil_stroke_frag_glsl,
+ datatoc_common_view_lib_glsl,
+ NULL);
}
/* dot/rectangle mode for normal strokes using geometry */
if (!e_data.gpencil_point_sh) {
- e_data.gpencil_point_sh = DRW_shader_create(datatoc_gpencil_point_vert_glsl,
- datatoc_gpencil_point_geom_glsl,
- datatoc_gpencil_point_frag_glsl,
- NULL);
+ e_data.gpencil_point_sh = DRW_shader_create_with_lib(datatoc_gpencil_point_vert_glsl,
+ datatoc_gpencil_point_geom_glsl,
+ datatoc_gpencil_point_frag_glsl,
+ datatoc_common_view_lib_glsl,
+ NULL);
}
/* used for edit points or strokes with one point only */
if (!e_data.gpencil_edit_point_sh) {
- e_data.gpencil_edit_point_sh = DRW_shader_create(datatoc_gpencil_edit_point_vert_glsl,
- datatoc_gpencil_edit_point_geom_glsl,
- datatoc_gpencil_edit_point_frag_glsl,
- NULL);
+ e_data.gpencil_edit_point_sh = DRW_shader_create_with_lib(datatoc_gpencil_edit_point_vert_glsl,
+ datatoc_gpencil_edit_point_geom_glsl,
+ datatoc_gpencil_edit_point_frag_glsl,
+ datatoc_common_view_lib_glsl,
+ NULL);
}
/* used for edit lines for edit modes */
@@ -454,7 +462,7 @@ void GPENCIL_cache_init(void *vedata)
DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND |
DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
DRWShadingGroup *mix_shgrp = DRW_shgroup_create(e_data.gpencil_fullscreen_sh, psl->mix_pass);
- DRW_shgroup_call_add(mix_shgrp, quad, NULL);
+ DRW_shgroup_call(mix_shgrp, quad, NULL);
DRW_shgroup_uniform_texture_ref(mix_shgrp, "strokeColor", &e_data.input_color_tx);
DRW_shgroup_uniform_texture_ref(mix_shgrp, "strokeDepth", &e_data.input_depth_tx);
DRW_shgroup_uniform_int(mix_shgrp, "tonemapping", &stl->storage->tonemapping, 1);
@@ -472,7 +480,7 @@ void GPENCIL_cache_init(void *vedata)
DRW_STATE_DEPTH_LESS);
DRWShadingGroup *mix_shgrp_noblend = DRW_shgroup_create(e_data.gpencil_fullscreen_sh,
psl->mix_pass_noblend);
- DRW_shgroup_call_add(mix_shgrp_noblend, quad, NULL);
+ DRW_shgroup_call(mix_shgrp_noblend, quad, NULL);
DRW_shgroup_uniform_texture_ref(mix_shgrp_noblend, "strokeColor", &e_data.input_color_tx);
DRW_shgroup_uniform_texture_ref(mix_shgrp_noblend, "strokeDepth", &e_data.input_depth_tx);
DRW_shgroup_uniform_int(mix_shgrp_noblend, "tonemapping", &stl->storage->tonemapping, 1);
@@ -490,7 +498,7 @@ void GPENCIL_cache_init(void *vedata)
DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
DRWShadingGroup *background_shgrp = DRW_shgroup_create(e_data.gpencil_background_sh,
psl->background_pass);
- DRW_shgroup_call_add(background_shgrp, quad, NULL);
+ DRW_shgroup_call(background_shgrp, quad, NULL);
DRW_shgroup_uniform_texture_ref(background_shgrp, "strokeColor", &e_data.background_color_tx);
DRW_shgroup_uniform_texture_ref(background_shgrp, "strokeDepth", &e_data.background_depth_tx);
@@ -503,7 +511,7 @@ void GPENCIL_cache_init(void *vedata)
psl->paper_pass = DRW_pass_create("GPencil Paper Pass",
DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND);
DRWShadingGroup *paper_shgrp = DRW_shgroup_create(e_data.gpencil_paper_sh, psl->paper_pass);
- DRW_shgroup_call_add(paper_shgrp, quad, NULL);
+ DRW_shgroup_call(paper_shgrp, quad, NULL);
DRW_shgroup_uniform_vec3(paper_shgrp, "color", v3d->shading.background_color, 1);
DRW_shgroup_uniform_float(paper_shgrp, "opacity", &v3d->overlay.gpencil_paper_opacity, 1);
}
@@ -522,7 +530,7 @@ void GPENCIL_cache_init(void *vedata)
DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
DRWShadingGroup *blend_shgrp = DRW_shgroup_create(e_data.gpencil_blend_fullscreen_sh,
psl->blend_pass);
- DRW_shgroup_call_add(blend_shgrp, quad, NULL);
+ DRW_shgroup_call(blend_shgrp, quad, NULL);
DRW_shgroup_uniform_texture_ref(blend_shgrp, "strokeColor", &e_data.temp_color_tx_a);
DRW_shgroup_uniform_texture_ref(blend_shgrp, "strokeDepth", &e_data.temp_depth_tx_a);
DRW_shgroup_uniform_texture_ref(blend_shgrp, "blendColor", &e_data.temp_color_tx_fx);
@@ -674,7 +682,7 @@ void GPENCIL_cache_populate(void *vedata, Object *ob)
copy_v3_v3(stl->storage->grid_matrix[3], ob->obmat[3]);
}
- DRW_shgroup_call_add(stl->g_data->shgrps_grid, e_data.batch_grid, stl->storage->grid_matrix);
+ DRW_shgroup_call(stl->g_data->shgrps_grid, e_data.batch_grid, stl->storage->grid_matrix);
}
}
}
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.h b/source/blender/draw/engines/gpencil/gpencil_engine.h
index 2ac1dc3211c..9ebd168bc4c 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.h
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.h
@@ -129,7 +129,7 @@ typedef struct GPENCIL_shgroup {
int caps_mode[2];
float obj_scale;
int xray_mode;
- int use_follow_path;
+ int alignment_mode;
float gradient_f;
float gradient_s[2];
@@ -182,7 +182,7 @@ typedef struct GPENCIL_Storage {
float gradient_f;
float gradient_s[2];
- int use_follow_path;
+ int alignment_mode;
float mix_stroke_factor;
@@ -437,7 +437,8 @@ void DRW_gpencil_multisample_ensure(struct GPENCIL_Data *vedata, int rect_w, int
void DRW_gpencil_get_point_geom(struct GpencilBatchCacheElem *be,
struct bGPDstroke *gps,
short thickness,
- const float ink[4]);
+ const float ink[4],
+ const int follow_mode);
void DRW_gpencil_get_stroke_geom(struct GpencilBatchCacheElem *be,
struct bGPDstroke *gps,
short thickness,
@@ -514,7 +515,7 @@ void GPENCIL_render_to_image(void *vedata,
/* Use of multisample framebuffers. */
#define MULTISAMPLE_GP_SYNC_ENABLE(lvl, fbl) \
{ \
- if ((lvl > 0) && (fbl->multisample_fb != NULL)) { \
+ if ((lvl > 0) && (fbl->multisample_fb != NULL) && (DRW_state_is_fbo())) { \
DRW_stats_query_start("GP Multisample Blit"); \
GPU_framebuffer_bind(fbl->multisample_fb); \
GPU_framebuffer_clear_color_depth(fbl->multisample_fb, (const float[4]){0.0f}, 1.0f); \
@@ -525,7 +526,7 @@ void GPENCIL_render_to_image(void *vedata,
#define MULTISAMPLE_GP_SYNC_DISABLE(lvl, fbl, fb, txl) \
{ \
- if ((lvl > 0) && (fbl->multisample_fb != NULL)) { \
+ if ((lvl > 0) && (fbl->multisample_fb != NULL) && (DRW_state_is_fbo())) { \
DRW_stats_query_start("GP Multisample Resolve"); \
GPU_framebuffer_bind(fb); \
DRW_multisamples_resolve(txl->multisample_depth, txl->multisample_color, true); \
diff --git a/source/blender/draw/engines/gpencil/gpencil_shader_fx.c b/source/blender/draw/engines/gpencil/gpencil_shader_fx.c
index 355235618f6..ccb79ea2b93 100644
--- a/source/blender/draw/engines/gpencil/gpencil_shader_fx.c
+++ b/source/blender/draw/engines/gpencil/gpencil_shader_fx.c
@@ -210,7 +210,7 @@ static void DRW_gpencil_fx_blur(ShaderFxData *fx,
GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_blur_sh, psl->fx_shader_pass_blend);
- DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
+ DRW_shgroup_call(fx_shgrp, fxquad, NULL);
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
DRW_shgroup_uniform_vec2(fx_shgrp, "Viewport", DRW_viewport_size_get(), 1);
@@ -235,7 +235,7 @@ static void DRW_gpencil_fx_colorize(ShaderFxData *fx, GPENCIL_e_data *e_data, GP
GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_colorize_sh, psl->fx_shader_pass);
- DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
+ DRW_shgroup_call(fx_shgrp, fxquad, NULL);
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
DRW_shgroup_uniform_vec4(fx_shgrp, "low_color", &fxd->low_color[0], 1);
@@ -267,7 +267,7 @@ static void DRW_gpencil_fx_flip(ShaderFxData *fx, GPENCIL_e_data *e_data, GPENCI
GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_flip_sh, psl->fx_shader_pass);
- DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
+ DRW_shgroup_call(fx_shgrp, fxquad, NULL);
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
DRW_shgroup_uniform_int(fx_shgrp, "flipmode", &fxd->flipmode, 1);
@@ -297,7 +297,7 @@ static void DRW_gpencil_fx_light(ShaderFxData *fx,
GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_light_sh, psl->fx_shader_pass);
- DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
+ DRW_shgroup_call(fx_shgrp, fxquad, NULL);
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
@@ -352,7 +352,7 @@ static void DRW_gpencil_fx_pixel(ShaderFxData *fx,
GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_pixel_sh, psl->fx_shader_pass);
- DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
+ DRW_shgroup_call(fx_shgrp, fxquad, NULL);
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
DRW_shgroup_uniform_int(fx_shgrp, "size", &fxd->size[0], 3);
@@ -386,7 +386,7 @@ static void DRW_gpencil_fx_rim(ShaderFxData *fx,
/* prepare pass */
fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_rim_prepare_sh, psl->fx_shader_pass_blend);
- DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
+ DRW_shgroup_call(fx_shgrp, fxquad, NULL);
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
DRW_shgroup_uniform_vec2(fx_shgrp, "Viewport", DRW_viewport_size_get(), 1);
@@ -403,7 +403,7 @@ static void DRW_gpencil_fx_rim(ShaderFxData *fx,
/* blur pass */
fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_blur_sh, psl->fx_shader_pass_blend);
- DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
+ DRW_shgroup_call(fx_shgrp, fxquad, NULL);
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_fx);
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_fx);
DRW_shgroup_uniform_vec2(fx_shgrp, "Viewport", DRW_viewport_size_get(), 1);
@@ -417,7 +417,7 @@ static void DRW_gpencil_fx_rim(ShaderFxData *fx,
/* resolve pass */
fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_rim_resolve_sh, psl->fx_shader_pass_blend);
- DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
+ DRW_shgroup_call(fx_shgrp, fxquad, NULL);
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeRim", &e_data->temp_color_tx_fx);
@@ -453,7 +453,7 @@ static void DRW_gpencil_fx_shadow(ShaderFxData *fx,
GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
/* prepare pass */
fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_shadow_prepare_sh, psl->fx_shader_pass_blend);
- DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
+ DRW_shgroup_call(fx_shgrp, fxquad, NULL);
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
DRW_shgroup_uniform_vec2(fx_shgrp, "Viewport", DRW_viewport_size_get(), 1);
@@ -488,7 +488,7 @@ static void DRW_gpencil_fx_shadow(ShaderFxData *fx,
/* blur pass */
fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_blur_sh, psl->fx_shader_pass_blend);
- DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
+ DRW_shgroup_call(fx_shgrp, fxquad, NULL);
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_fx);
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_fx);
DRW_shgroup_uniform_vec2(fx_shgrp, "Viewport", DRW_viewport_size_get(), 1);
@@ -502,7 +502,7 @@ static void DRW_gpencil_fx_shadow(ShaderFxData *fx,
/* resolve pass */
fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_shadow_resolve_sh, psl->fx_shader_pass_blend);
- DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
+ DRW_shgroup_call(fx_shgrp, fxquad, NULL);
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
DRW_shgroup_uniform_texture_ref(fx_shgrp, "shadowColor", &e_data->temp_color_tx_fx);
@@ -531,7 +531,7 @@ static void DRW_gpencil_fx_glow(ShaderFxData *fx,
GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
/* prepare pass */
fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_glow_prepare_sh, psl->fx_shader_pass_blend);
- DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
+ DRW_shgroup_call(fx_shgrp, fxquad, NULL);
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
@@ -544,7 +544,7 @@ static void DRW_gpencil_fx_glow(ShaderFxData *fx,
/* blur pass */
fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_blur_sh, psl->fx_shader_pass_blend);
- DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
+ DRW_shgroup_call(fx_shgrp, fxquad, NULL);
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_fx);
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_fx);
DRW_shgroup_uniform_vec2(fx_shgrp, "Viewport", DRW_viewport_size_get(), 1);
@@ -558,7 +558,7 @@ static void DRW_gpencil_fx_glow(ShaderFxData *fx,
/* resolve pass */
fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_glow_resolve_sh, psl->fx_shader_pass_blend);
- DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
+ DRW_shgroup_call(fx_shgrp, fxquad, NULL);
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
DRW_shgroup_uniform_texture_ref(fx_shgrp, "glowColor", &e_data->temp_color_tx_fx);
@@ -593,7 +593,7 @@ static void DRW_gpencil_fx_swirl(ShaderFxData *fx,
GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_swirl_sh, psl->fx_shader_pass);
- DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
+ DRW_shgroup_call(fx_shgrp, fxquad, NULL);
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
@@ -624,7 +624,7 @@ static void DRW_gpencil_fx_wave(ShaderFxData *fx, GPENCIL_e_data *e_data, GPENCI
GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
DRWShadingGroup *fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_wave_sh, psl->fx_shader_pass);
- DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
+ DRW_shgroup_call(fx_shgrp, fxquad, NULL);
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
DRW_shgroup_uniform_float(fx_shgrp, "amplitude", &fxd->amplitude, 1);
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_geom.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_geom.glsl
index 8c3fd022004..e0634a7d1a7 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_geom.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_geom.glsl
@@ -1,4 +1,3 @@
-uniform mat4 ModelViewProjectionMatrix;
uniform vec2 Viewport;
layout(points) in;
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_vert.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_vert.glsl
index eea28755ae6..a1cfb2ae4ae 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_vert.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_vert.glsl
@@ -1,4 +1,3 @@
-uniform mat4 ModelViewProjectionMatrix;
in vec3 pos;
in vec4 color;
@@ -9,7 +8,7 @@ out float finalThickness;
void main()
{
- gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ gl_Position = point_object_to_ndc(pos);
finalColor = color;
finalThickness = size;
}
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_fill_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_fill_frag.glsl
index acf60fc2d59..192720a4e98 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_fill_frag.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_fill_frag.glsl
@@ -89,6 +89,27 @@ void set_color(in vec4 color,
ocolor.a *= layer_opacity;
}
+float linearrgb_to_srgb(float c)
+{
+ if (c < 0.0031308) {
+ return (c < 0.0) ? 0.0 : c * 12.92;
+ }
+ else {
+ return 1.055 * pow(c, 1.0 / 2.4) - 0.055;
+ }
+}
+
+vec4 texture_read_as_srgb(sampler2D tex, vec2 co)
+{
+ /* By convention image textures return scene linear colors, but
+ * grease pencil still works in srgb. */
+ vec4 color = texture(tex, co);
+ color.r = linearrgb_to_srgb(color.r);
+ color.g = linearrgb_to_srgb(color.g);
+ color.b = linearrgb_to_srgb(color.b);
+ return color;
+}
+
void main()
{
vec2 t_center = vec2(0.5, 0.5);
@@ -97,8 +118,8 @@ void main()
vec2 rot_tex = (matrot_tex * (texCoord_interp - t_center)) + t_center + texture_offset;
vec4 tmp_color;
tmp_color = (texture_clamp == 0) ?
- texture2D(myTexture, rot_tex * texture_scale) :
- texture2D(myTexture, clamp(rot_tex * texture_scale, 0.0, 1.0));
+ texture_read_as_srgb(myTexture, rot_tex * texture_scale) :
+ texture_read_as_srgb(myTexture, clamp(rot_tex * texture_scale, 0.0, 1.0));
vec4 text_color = vec4(tmp_color[0], tmp_color[1], tmp_color[2], tmp_color[3] * texture_opacity);
vec4 chesscolor;
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_fill_vert.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_fill_vert.glsl
index d71f57eb98c..eb452f4c660 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_fill_vert.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_fill_vert.glsl
@@ -1,14 +1,14 @@
-uniform mat4 ModelViewProjectionMatrix;
in vec3 pos;
in vec4 color;
in vec2 texCoord;
+
out vec4 finalColor;
out vec2 texCoord_interp;
void main(void)
{
- gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ gl_Position = point_object_to_ndc(pos);
finalColor = color;
texCoord_interp = texCoord;
}
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_paper_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_paper_frag.glsl
index 3c1424f98ff..1d1cd6349dc 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_paper_frag.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_paper_frag.glsl
@@ -5,5 +5,5 @@ out vec4 FragColor;
void main()
{
- FragColor = vec4(color, opacity);
+ FragColor = vec4(color, 1.0 - opacity);
}
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_point_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_point_frag.glsl
index cc47e12b303..569a68679b4 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_point_frag.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_point_frag.glsl
@@ -47,6 +47,27 @@ vec2 check_box_point(vec2 pt, vec2 radius)
return rtn;
}
+float linearrgb_to_srgb(float c)
+{
+ if (c < 0.0031308) {
+ return (c < 0.0) ? 0.0 : c * 12.92;
+ }
+ else {
+ return 1.055 * pow(c, 1.0 / 2.4) - 0.055;
+ }
+}
+
+vec4 texture_read_as_srgb(sampler2D tex, vec2 co)
+{
+ /* By convention image textures return scene linear colors, but
+ * grease pencil still works in srgb. */
+ vec4 color = texture(tex, co);
+ color.r = linearrgb_to_srgb(color.r);
+ color.g = linearrgb_to_srgb(color.g);
+ color.b = linearrgb_to_srgb(color.b);
+ return color;
+}
+
void main()
{
vec2 centered = mTexCoord - vec2(0.5);
@@ -65,7 +86,7 @@ void main()
}
}
- vec4 tmp_color = texture2D(myTexture, mTexCoord);
+ vec4 tmp_color = texture_read_as_srgb(myTexture, mTexCoord);
/* Solid */
if ((color_type == GPENCIL_COLOR_SOLID) || (no_texture)) {
@@ -73,7 +94,7 @@ void main()
}
/* texture */
if ((color_type == GPENCIL_COLOR_TEXTURE) && (!no_texture)) {
- vec4 text_color = texture2D(myTexture, mTexCoord);
+ vec4 text_color = texture_read_as_srgb(myTexture, mTexCoord);
if (mix_stroke_factor > 0.0) {
fragColor.rgb = mix(text_color.rgb, colormix.rgb, mix_stroke_factor);
fragColor.a = text_color.a;
@@ -87,7 +108,7 @@ void main()
}
/* pattern */
if ((color_type == GPENCIL_COLOR_PATTERN) && (!no_texture)) {
- vec4 text_color = texture2D(myTexture, mTexCoord);
+ vec4 text_color = texture_read_as_srgb(myTexture, mTexCoord);
fragColor = mColor;
/* mult both alpha factor to use strength factor with color alpha limit */
fragColor.a = min(text_color.a * mColor.a, mColor.a);
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_point_geom.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_point_geom.glsl
index a64a7ecb9be..a2f4c1f9b15 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_point_geom.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_point_geom.glsl
@@ -1,7 +1,6 @@
-uniform mat4 ModelViewProjectionMatrix;
uniform vec2 Viewport;
uniform int xraymode;
-uniform int use_follow_path;
+uniform int alignment_mode;
layout(points) in;
layout(triangle_strip, max_vertices = 4) out;
@@ -21,6 +20,9 @@ out vec2 mTexCoord;
#define M_2PI 6.28318530717958647692 /* 2*pi */
#define FALSE 0
+/* keep this definition equals to GP_STYLE_FOLLOW_FIXED value */
+#define FIXED 2
+
/* project 3d point to 2d on screen space */
vec2 toScreenSpace(vec4 vertex)
{
@@ -70,7 +72,7 @@ float getAngle(vec2 pt0, vec2 pt1)
return 0.0;
}
- if (use_follow_path == FALSE) {
+ if (alignment_mode == FIXED) {
return 0.0;
}
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_point_vert.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_point_vert.glsl
index 9cef7601770..ef8b361373f 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_point_vert.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_point_vert.glsl
@@ -1,5 +1,3 @@
-uniform mat4 ModelViewProjectionMatrix;
-uniform mat4 ProjectionMatrix;
uniform float pixsize; /* rv3d->pixsize */
uniform int keep_size;
@@ -32,8 +30,8 @@ float defaultpixsize = pixsize * (1000.0 / pixfactor);
void main()
{
- gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
- finalprev_pos = ModelViewProjectionMatrix * vec4(prev_pos, 1.0);
+ gl_Position = point_object_to_ndc(pos);
+ finalprev_pos = point_object_to_ndc(prev_pos);
finalColor = color;
if (keep_size == TRUE) {
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_frag.glsl
index 6b7cee888ea..a5580e305d6 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_frag.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_frag.glsl
@@ -27,6 +27,27 @@ out vec4 fragColor;
bool no_texture = (shading_type[0] == OB_SOLID) && (shading_type[1] != V3D_SHADING_TEXTURE_COLOR);
+float linearrgb_to_srgb(float c)
+{
+ if (c < 0.0031308) {
+ return (c < 0.0) ? 0.0 : c * 12.92;
+ }
+ else {
+ return 1.055 * pow(c, 1.0 / 2.4) - 0.055;
+ }
+}
+
+vec4 texture_read_as_srgb(sampler2D tex, vec2 co)
+{
+ /* By convention image textures return scene linear colors, but
+ * grease pencil still works in srgb. */
+ vec4 color = texture(tex, co);
+ color.r = linearrgb_to_srgb(color.r);
+ color.g = linearrgb_to_srgb(color.g);
+ color.b = linearrgb_to_srgb(color.b);
+ return color;
+}
+
void main()
{
@@ -47,10 +68,10 @@ void main()
/* texture for endcaps */
vec4 text_color;
if (uvfac[1] == ENDCAP) {
- text_color = texture2D(myTexture, vec2(mTexCoord.x, mTexCoord.y));
+ text_color = texture_read_as_srgb(myTexture, vec2(mTexCoord.x, mTexCoord.y));
}
else {
- text_color = texture2D(myTexture, mTexCoord);
+ text_color = texture_read_as_srgb(myTexture, mTexCoord);
}
/* texture */
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_geom.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_geom.glsl
index b90f5b33a57..9ea96806481 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_geom.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_geom.glsl
@@ -1,4 +1,3 @@
-uniform mat4 ModelViewProjectionMatrix;
uniform vec2 Viewport;
uniform int xraymode;
uniform int color_type;
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_vert.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_vert.glsl
index 946b39c006a..c7089f357f9 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_vert.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_vert.glsl
@@ -1,5 +1,3 @@
-uniform mat4 ModelViewProjectionMatrix;
-uniform mat4 ProjectionMatrix;
uniform float pixsize; /* rv3d->pixsize */
uniform int keep_size;
@@ -30,7 +28,7 @@ float defaultpixsize = pixsize * (1000.0 / pixfactor);
void main(void)
{
- gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ gl_Position = point_object_to_ndc(pos);
finalColor = color;
if (keep_size == TRUE) {
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 c76ad8c1d7b..96f8f6e4c7a 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl
@@ -140,32 +140,18 @@ vec2 matcap_uv_compute(vec3 I, vec3 N, bool flipped)
return matcap_uv * 0.496 + 0.5;
}
-float srgb_to_linearrgb(float c)
-{
- if (c < 0.04045) {
- return (c < 0.0) ? 0.0 : c * (1.0 / 12.92);
- }
- else {
- return pow((c + 0.055) * (1.0 / 1.055), 2.4);
- }
-}
-
-vec4 srgb_to_linearrgb(vec4 col_from)
-{
- vec4 col_to;
- col_to.r = srgb_to_linearrgb(col_from.r);
- col_to.g = srgb_to_linearrgb(col_from.g);
- col_to.b = srgb_to_linearrgb(col_from.b);
- col_to.a = col_from.a;
- return col_to;
-}
-
-vec4 workbench_sample_texture(sampler2D image, vec2 coord, bool srgb, bool nearest_sampling)
+vec4 workbench_sample_texture(sampler2D image, vec2 coord, bool nearest_sampling)
{
vec2 tex_size = vec2(textureSize(image, 0).xy);
/* TODO(fclem) We could do the same with sampler objects.
* But this is a quick workaround instead of messing with the GPUTexture itself. */
vec2 uv = nearest_sampling ? (floor(coord * tex_size) + 0.5) / tex_size : coord;
vec4 color = texture(image, uv);
- return (srgb) ? srgb_to_linearrgb(color) : color;
+
+ /* Unpremultiply, ideally shaders would be added so this is not needed. */
+ if (!(color.a == 0.0 || color.a == 1.0)) {
+ color.rgb = color.rgb / color.a;
+ }
+
+ return color;
}
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_deferred_composite_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_deferred_composite_frag.glsl
index 65196c1a836..a1f80440404 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_deferred_composite_frag.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_deferred_composite_frag.glsl
@@ -1,8 +1,5 @@
out vec4 fragColor;
-uniform mat4 ProjectionMatrix;
-uniform mat4 ViewMatrixInverse;
-
uniform usampler2D objectId;
uniform sampler2D materialBuffer;
uniform sampler2D normalBuffer;
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl
index 5eff0b41e20..51bce639b63 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl
@@ -1,11 +1,8 @@
uniform float ImageTransparencyCutoff = 0.1;
uniform sampler2D image;
-uniform bool imageSrgb;
uniform bool imageNearest;
-uniform mat4 ProjectionMatrix;
-uniform mat4 ViewMatrixInverse;
uniform float alpha = 0.5;
uniform vec2 invertedViewportSize;
uniform vec4 viewvecs[3];
@@ -46,7 +43,7 @@ void main()
vec4 diffuse_color;
#if defined(V3D_SHADING_TEXTURE_COLOR)
- diffuse_color = workbench_sample_texture(image, uv_interp, imageSrgb, imageNearest);
+ diffuse_color = workbench_sample_texture(image, uv_interp, imageNearest);
if (diffuse_color.a < ImageTransparencyCutoff) {
discard;
}
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl
index 2596fc4cf88..af9f1d14f4a 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl
@@ -6,7 +6,6 @@ uniform float materialRoughness;
uniform sampler2D image;
uniform float ImageTransparencyCutoff = 0.1;
-uniform bool imageSrgb;
uniform bool imageNearest;
#ifdef NORMAL_VIEWPORT_PASS_ENABLED
@@ -41,7 +40,7 @@ void main()
vec4 color;
# if defined(V3D_SHADING_TEXTURE_COLOR)
- color = workbench_sample_texture(image, uv_interp, imageSrgb, imageNearest);
+ color = workbench_sample_texture(image, uv_interp, imageNearest);
if (color.a < ImageTransparencyCutoff) {
discard;
}
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_prepass_vert.glsl b/source/blender/draw/engines/workbench/shaders/workbench_prepass_vert.glsl
index f2c684cdb6a..5d4153999c0 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_prepass_vert.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_prepass_vert.glsl
@@ -1,10 +1,3 @@
-uniform mat4 ModelViewProjectionMatrix;
-uniform mat4 ModelMatrix;
-uniform mat4 ModelMatrixInverse;
-uniform mat4 ProjectionMatrix;
-uniform mat4 ViewProjectionMatrix;
-uniform mat4 ViewMatrixInverse;
-uniform mat3 NormalMatrix;
#ifndef HAIR_SHADER
in vec3 pos;
@@ -50,6 +43,18 @@ vec3 srgb_to_linear_attr(vec3 c)
}
#endif
+vec3 workbench_hair_hair_normal(vec3 tan, vec3 binor, float rand)
+{
+ /* To "simulate" anisotropic shading, randomize hair normal per strand. */
+ tan = normalize(tan);
+ vec3 nor = normalize(cross(binor, tan));
+ // nor = normalize(mix(nor, -tan, rand * 0.1));
+ // float cos_theta = (rand * 2.0 - 1.0) * 0.2;
+ // float sin_theta = sqrt(max(0.0, 1.0 - cos_theta * cos_theta));
+ // nor = nor * sin_theta + binor * cos_theta;
+ return nor;
+}
+
void main()
{
#ifdef HAIR_SHADER
@@ -57,29 +62,25 @@ void main()
vec2 uv = hair_get_customdata_vec2(u);
# endif
float time, thick_time, thickness;
- vec3 pos, tan, binor;
+ vec3 world_pos, tan, binor;
hair_get_pos_tan_binor_time((ProjectionMatrix[3][3] == 0.0),
ModelMatrixInverse,
ViewMatrixInverse[3].xyz,
ViewMatrixInverse[2].xyz,
- pos,
+ world_pos,
tan,
binor,
time,
thickness,
thick_time);
- /* To "simulate" anisotropic shading, randomize hair normal per strand. */
+
hair_rand = integer_noise(hair_get_strand_id());
- tan = normalize(tan);
- vec3 nor = normalize(cross(binor, tan));
- nor = normalize(mix(nor, -tan, hair_rand * 0.10));
- float cos_theta = (hair_rand * 2.0 - 1.0) * 0.20;
- float sin_theta = sqrt(max(0.0, 1.0f - cos_theta * cos_theta));
- nor = nor * sin_theta + binor * cos_theta;
- gl_Position = ViewProjectionMatrix * vec4(pos, 1.0);
+ vec3 nor = workbench_hair_hair_normal(tan, binor, hair_rand);
#else
- gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ vec3 world_pos = point_object_to_world(pos);
#endif
+ gl_Position = point_world_to_ndc(world_pos);
+
#ifdef V3D_SHADING_TEXTURE_COLOR
uv_interp = uv;
#endif
@@ -91,13 +92,13 @@ void main()
#endif
#ifdef NORMAL_VIEWPORT_PASS_ENABLED
- normal_viewport = NormalMatrix * nor;
+ normal_viewport = normal_object_to_view(nor);
# ifndef HAIR_SHADER
normal_viewport = normalize(normal_viewport);
# endif
#endif
#ifdef USE_WORLD_CLIP_PLANES
- world_clip_planes_calc_clip_distance((ModelMatrix * vec4(pos, 1.0)).xyz);
+ world_clip_planes_calc_clip_distance(world_pos);
#endif
}
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_shadow_vert.glsl b/source/blender/draw/engines/workbench/shaders/workbench_shadow_vert.glsl
index afd704a7d3a..e07f87525e2 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_shadow_vert.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_shadow_vert.glsl
@@ -1,7 +1,5 @@
#define INFINITE 1000.0
-uniform mat4 ModelViewProjectionMatrix;
-
uniform vec3 lightDirection = vec3(0.57, 0.57, -0.57);
uniform float lightDistance = 1e4;
@@ -18,6 +16,6 @@ vData;
void main()
{
vData.pos = pos;
- vData.frontPosition = ModelViewProjectionMatrix * vec4(pos, 1.0);
- vData.backPosition = ModelViewProjectionMatrix * vec4(pos + lightDirection * lightDistance, 1.0);
+ vData.frontPosition = point_object_to_ndc(pos);
+ vData.backPosition = point_object_to_ndc(pos + lightDirection * lightDistance);
}
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 a1c269d5a65..848cd49bf53 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl
@@ -1,8 +1,4 @@
-uniform mat4 ProjectionMatrix;
-uniform mat4 ModelMatrixInverse;
-uniform mat4 ModelViewMatrixInverse;
-uniform mat4 ModelMatrix;
uniform vec3 OrcoTexCoFactors[2];
uniform sampler2D depthBuffer;
@@ -219,9 +215,11 @@ void main()
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);
- vec3 ls_ray_dir = mat3(ModelViewMatrixInverse) * vs_ray_dir * OrcoTexCoFactors[1] * 2.0;
- vec3 ls_ray_ori = (ModelViewMatrixInverse * vec4(vs_ray_ori, 1.0)).xyz;
- vec3 ls_ray_end = (ModelViewMatrixInverse * vec4(vs_ray_end, 1.0)).xyz;
+ /* TODO(fclem) Precompute the matrix/ */
+ vec3 ls_ray_dir = vs_ray_dir * OrcoTexCoFactors[1] * 2.0;
+ ls_ray_dir = mat3(ModelMatrixInverse) * (mat3(ViewMatrixInverse) * ls_ray_dir);
+ vec3 ls_ray_ori = point_view_to_object(vs_ray_ori);
+ vec3 ls_ray_end = point_view_to_object(vs_ray_end);
ls_ray_ori = (OrcoTexCoFactors[0] + ls_ray_ori * OrcoTexCoFactors[1]) * 2.0 - 1.0;
ls_ray_end = (OrcoTexCoFactors[0] + ls_ray_end * OrcoTexCoFactors[1]) * 2.0 - 1.0;
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_volume_vert.glsl b/source/blender/draw/engines/workbench/shaders/workbench_volume_vert.glsl
index 7a418243fd3..6f0bb56fafd 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_volume_vert.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_volume_vert.glsl
@@ -1,5 +1,4 @@
-uniform mat4 ModelViewProjectionMatrix;
uniform vec3 OrcoTexCoFactors[2];
uniform float slicePosition;
uniform int sliceAxis; /* -1 is no slice, 0 is X, 1 is Y, 2 is Z. */
@@ -29,5 +28,5 @@ void main()
vec3 final_pos = pos;
#endif
final_pos = ((final_pos * 0.5 + 0.5) - OrcoTexCoFactors[0]) / OrcoTexCoFactors[1];
- gl_Position = ModelViewProjectionMatrix * vec4(final_pos, 1.0);
+ gl_Position = point_object_to_ndc(final_pos);
}
diff --git a/source/blender/draw/engines/workbench/workbench_deferred.c b/source/blender/draw/engines/workbench/workbench_deferred.c
index abf167d53b0..eacd319cc4a 100644
--- a/source/blender/draw/engines/workbench/workbench_deferred.c
+++ b/source/blender/draw/engines/workbench/workbench_deferred.c
@@ -91,6 +91,7 @@ static struct {
/* Shaders */
extern char datatoc_common_hair_lib_glsl[];
+extern char datatoc_common_view_lib_glsl[];
extern char datatoc_workbench_prepass_vert_glsl[];
extern char datatoc_workbench_prepass_frag_glsl[];
@@ -119,6 +120,7 @@ static char *workbench_build_composite_frag(WORKBENCH_PrivateData *wpd)
{
DynStr *ds = BLI_dynstr_new();
+ BLI_dynstr_append(ds, datatoc_common_view_lib_glsl);
BLI_dynstr_append(ds, datatoc_workbench_data_lib_glsl);
BLI_dynstr_append(ds, datatoc_workbench_common_lib_glsl);
BLI_dynstr_append(ds, datatoc_workbench_background_lib_glsl);
@@ -159,6 +161,7 @@ static char *workbench_build_prepass_vert(bool is_hair)
if (is_hair) {
BLI_dynstr_append(ds, datatoc_common_hair_lib_glsl);
}
+ BLI_dynstr_append(ds, datatoc_common_view_lib_glsl);
BLI_dynstr_append(ds, datatoc_workbench_prepass_vert_glsl);
char *str = BLI_dynstr_get_cstring(ds);
BLI_dynstr_free(ds);
@@ -382,33 +385,60 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata)
const char *shadow_frag = datatoc_gpu_shader_depth_only_frag_glsl;
#endif
/* TODO only compile on demand */
- e_data.shadow_pass_sh = DRW_shader_create(datatoc_workbench_shadow_vert_glsl,
- datatoc_workbench_shadow_geom_glsl,
- shadow_frag,
- "#define SHADOW_PASS\n"
- "#define DOUBLE_MANIFOLD\n");
- e_data.shadow_pass_manifold_sh = DRW_shader_create(datatoc_workbench_shadow_vert_glsl,
- datatoc_workbench_shadow_geom_glsl,
- shadow_frag,
- "#define SHADOW_PASS\n");
- e_data.shadow_fail_sh = DRW_shader_create(datatoc_workbench_shadow_vert_glsl,
- datatoc_workbench_shadow_geom_glsl,
- shadow_frag,
- "#define SHADOW_FAIL\n"
- "#define DOUBLE_MANIFOLD\n");
- e_data.shadow_fail_manifold_sh = DRW_shader_create(datatoc_workbench_shadow_vert_glsl,
- datatoc_workbench_shadow_geom_glsl,
- shadow_frag,
- "#define SHADOW_FAIL\n");
- e_data.shadow_caps_sh = DRW_shader_create(datatoc_workbench_shadow_vert_glsl,
- datatoc_workbench_shadow_caps_geom_glsl,
- shadow_frag,
- "#define SHADOW_FAIL\n"
- "#define DOUBLE_MANIFOLD\n");
- e_data.shadow_caps_manifold_sh = DRW_shader_create(datatoc_workbench_shadow_vert_glsl,
- datatoc_workbench_shadow_caps_geom_glsl,
- shadow_frag,
- "#define SHADOW_FAIL\n");
+ e_data.shadow_pass_sh = GPU_shader_create_from_arrays({
+ .vert = (const char *[]){datatoc_common_view_lib_glsl,
+ datatoc_workbench_shadow_vert_glsl,
+ NULL},
+ .geom = (const char *[]){datatoc_workbench_shadow_geom_glsl, NULL},
+ .frag = (const char *[]){shadow_frag, NULL},
+ .defs = (const char *[]){"#define SHADOW_PASS\n"
+ "#define DOUBLE_MANIFOLD\n",
+ NULL},
+ });
+ e_data.shadow_pass_manifold_sh = GPU_shader_create_from_arrays({
+ .vert = (const char *[]){datatoc_common_view_lib_glsl,
+ datatoc_workbench_shadow_vert_glsl,
+ NULL},
+ .geom = (const char *[]){datatoc_workbench_shadow_geom_glsl, NULL},
+ .frag = (const char *[]){shadow_frag, NULL},
+ .defs = (const char *[]){"#define SHADOW_PASS\n", NULL},
+ });
+ e_data.shadow_fail_sh = GPU_shader_create_from_arrays({
+ .vert = (const char *[]){datatoc_common_view_lib_glsl,
+ datatoc_workbench_shadow_vert_glsl,
+ NULL},
+ .geom = (const char *[]){datatoc_workbench_shadow_geom_glsl, NULL},
+ .frag = (const char *[]){shadow_frag, NULL},
+ .defs = (const char *[]){"#define SHADOW_FAIL\n"
+ "#define DOUBLE_MANIFOLD\n",
+ NULL},
+ });
+ e_data.shadow_fail_manifold_sh = GPU_shader_create_from_arrays({
+ .vert = (const char *[]){datatoc_common_view_lib_glsl,
+ datatoc_workbench_shadow_vert_glsl,
+ NULL},
+ .geom = (const char *[]){datatoc_workbench_shadow_geom_glsl, NULL},
+ .frag = (const char *[]){shadow_frag, NULL},
+ .defs = (const char *[]){"#define SHADOW_FAIL\n", NULL},
+ });
+ e_data.shadow_caps_sh = GPU_shader_create_from_arrays({
+ .vert = (const char *[]){datatoc_common_view_lib_glsl,
+ datatoc_workbench_shadow_vert_glsl,
+ NULL},
+ .geom = (const char *[]){datatoc_workbench_shadow_caps_geom_glsl, NULL},
+ .frag = (const char *[]){shadow_frag, NULL},
+ .defs = (const char *[]){"#define SHADOW_FAIL\n"
+ "#define DOUBLE_MANIFOLD\n",
+ NULL},
+ });
+ e_data.shadow_caps_manifold_sh = GPU_shader_create_from_arrays({
+ .vert = (const char *[]){datatoc_common_view_lib_glsl,
+ datatoc_workbench_shadow_vert_glsl,
+ NULL},
+ .geom = (const char *[]){datatoc_workbench_shadow_caps_geom_glsl, NULL},
+ .frag = (const char *[]){shadow_frag, NULL},
+ .defs = (const char *[]){"#define SHADOW_FAIL\n", NULL},
+ });
e_data.ghost_resolve_sh = DRW_shader_create_fullscreen(
datatoc_workbench_ghost_resolve_frag_glsl, NULL);
@@ -549,7 +579,7 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata)
DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS);
grp = DRW_shgroup_create(e_data.ghost_resolve_sh, psl->ghost_resolve_pass);
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &e_data.ghost_depth_tx);
- DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
+ DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
}
{
@@ -583,7 +613,7 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata)
DRW_shgroup_uniform_vec2(grp, "curvature_settings", &wpd->world_data.curvature_ridge, 1);
}
- DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
+ DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
}
}
@@ -694,13 +724,13 @@ void workbench_deferred_cache_init(WORKBENCH_Data *vedata)
if (OBJECT_OUTLINE_ENABLED(wpd)) {
DRW_shgroup_uniform_texture_ref(grp, "objectId", &e_data.object_id_tx);
}
- DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
+ DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
if (draw_ctx->rv3d && (draw_ctx->rv3d->rflag & RV3D_CLIPPING) && draw_ctx->rv3d->clipbb) {
GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR_BACKGROUND);
grp = DRW_shgroup_create(shader, psl->background_pass);
wpd->world_clip_planes_batch = DRW_draw_background_clipping_batch_from_rv3d(draw_ctx->rv3d);
- DRW_shgroup_call_add(grp, wpd->world_clip_planes_batch, NULL);
+ DRW_shgroup_call(grp, wpd->world_clip_planes_batch, NULL);
DRW_shgroup_uniform_vec4(grp, "color", &wpd->world_clip_planes_color[0], 1);
}
}
@@ -720,7 +750,7 @@ void workbench_deferred_cache_init(WORKBENCH_Data *vedata)
DRW_shgroup_uniform_float(grp, "shadowMultiplier", &wpd->shadow_multiplier, 1);
DRW_shgroup_uniform_float_copy(grp, "shadowShift", scene->display.shadow_shift);
DRW_shgroup_uniform_float_copy(grp, "shadowFocus", wpd->shadow_focus);
- DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
+ DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
/* Stencil Shadow passes. */
#ifdef DEBUG_SHADOW_VOLUME
@@ -765,7 +795,7 @@ void workbench_deferred_cache_init(WORKBENCH_Data *vedata)
DRW_shgroup_uniform_float(grp, "shadowMultiplier", &wpd->shadow_multiplier, 1);
DRW_shgroup_uniform_float_copy(grp, "shadowShift", scene->display.shadow_shift);
DRW_shgroup_uniform_float_copy(grp, "shadowFocus", wpd->shadow_focus);
- DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
+ DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
#endif
}
else {
@@ -773,7 +803,7 @@ void workbench_deferred_cache_init(WORKBENCH_Data *vedata)
DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_GREATER);
grp = DRW_shgroup_create(wpd->composite_sh, psl->composite_pass);
workbench_composite_uniforms(wpd, grp);
- DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
+ DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
}
}
@@ -807,7 +837,7 @@ void workbench_deferred_cache_init(WORKBENCH_Data *vedata)
DRW_shgroup_uniform_texture_ref(grp, "transparentAccum", &e_data.oit_accum_tx);
DRW_shgroup_uniform_texture_ref(grp, "transparentRevealage", &e_data.oit_revealage_tx);
DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
- DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
+ DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
}
}
}
@@ -961,7 +991,7 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
material = get_or_create_material_data(
vedata, ob, mat, image, iuser, color_type, interp);
}
- DRW_shgroup_call_object_add(material->shgrp, geom_array[i], ob);
+ DRW_shgroup_call_object(material->shgrp, geom_array[i], ob);
}
}
}
@@ -986,7 +1016,7 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
if (is_sculpt_mode) {
bool use_vcol = (color_type == V3D_SHADING_VERTEX_COLOR);
- DRW_shgroup_call_sculpt_add(material->shgrp, ob, false, false, use_vcol);
+ DRW_shgroup_call_sculpt(material->shgrp, ob, false, false, use_vcol);
}
else {
struct GPUBatch *geom;
@@ -998,7 +1028,7 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
}
if (geom) {
- DRW_shgroup_call_object_add(material->shgrp, geom, ob);
+ DRW_shgroup_call_object(material->shgrp, geom, ob);
}
}
}
@@ -1006,24 +1036,23 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
/* Draw material color */
if (is_sculpt_mode) {
struct DRWShadingGroup **shgrps = BLI_array_alloca(shgrps, materials_len);
- struct Material **mats = BLI_array_alloca(mats, materials_len);
for (int i = 0; i < materials_len; ++i) {
- mats[i] = give_current_material(ob, i + 1);
- if (mats[i] != NULL && mats[i]->a < 1.0f) {
+ struct Material *mat = give_current_material(ob, i + 1);
+ if (mat != NULL && mat->a < 1.0f) {
/* Hack */
- wpd->shading.xray_alpha = mats[i]->a;
+ wpd->shading.xray_alpha = mat->a;
material = workbench_forward_get_or_create_material_data(
- vedata, ob, mats[i], NULL, NULL, V3D_SHADING_MATERIAL_COLOR, 0, is_sculpt_mode);
+ vedata, ob, mat, NULL, NULL, V3D_SHADING_MATERIAL_COLOR, 0, is_sculpt_mode);
has_transp_mat = true;
}
else {
material = get_or_create_material_data(
- vedata, ob, mats[i], NULL, NULL, V3D_SHADING_MATERIAL_COLOR, 0);
+ vedata, ob, mat, NULL, NULL, V3D_SHADING_MATERIAL_COLOR, 0);
}
shgrps[i] = material->shgrp;
}
- DRW_shgroup_call_sculpt_with_materials_add(shgrps, mats, ob, false);
+ DRW_shgroup_call_sculpt_with_materials(shgrps, ob, false);
}
else {
struct GPUBatch **geoms;
@@ -1046,7 +1075,7 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
material = get_or_create_material_data(
vedata, ob, mat, NULL, NULL, V3D_SHADING_MATERIAL_COLOR, 0);
}
- DRW_shgroup_call_object_add(material->shgrp, geoms[i], ob);
+ DRW_shgroup_call_object(material->shgrp, geoms[i], ob);
}
}
}
@@ -1060,7 +1089,7 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
/* Currently unsupported in sculpt mode. We could revert to the slow
* method in this case but I'm not sure if it's a good idea given that
* sculpted meshes are heavy to begin with. */
- // DRW_shgroup_call_sculpt_add(wpd->shadow_shgrp, ob, ob->obmat);
+ // DRW_shgroup_call_sculpt(wpd->shadow_shgrp, ob, ob->obmat);
}
else {
WORKBENCH_ObjectData *engine_object_data = (WORKBENCH_ObjectData *)DRW_drawdata_ensure(
@@ -1072,7 +1101,6 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
if (studiolight_object_cast_visible_shadow(wpd, ob, engine_object_data)) {
- invert_m4_m4(ob->imat, ob->obmat);
mul_v3_mat3_m4v3(
engine_object_data->shadow_dir, ob->imat, e_data.display.light_direction);
@@ -1090,7 +1118,7 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
}
DRW_shgroup_uniform_vec3(grp, "lightDirection", engine_object_data->shadow_dir, 1);
DRW_shgroup_uniform_float_copy(grp, "lightDistance", 1e5f);
- DRW_shgroup_call_add(grp, geom_shadow, ob->obmat);
+ DRW_shgroup_call(grp, geom_shadow, ob->obmat);
#ifdef DEBUG_SHADOW_VOLUME
DRW_debug_bbox(&engine_object_data->shadow_bbox, (float[4]){1.0f, 0.0f, 0.0f, 1.0f});
#endif
@@ -1112,7 +1140,7 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
}
DRW_shgroup_uniform_vec3(grp, "lightDirection", engine_object_data->shadow_dir, 1);
DRW_shgroup_uniform_float_copy(grp, "lightDistance", extrude_distance);
- DRW_shgroup_call_add(grp, DRW_cache_object_surface_get(ob), ob->obmat);
+ DRW_shgroup_call(grp, DRW_cache_object_surface_get(ob), ob->obmat);
}
if (is_manifold) {
@@ -1124,7 +1152,7 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
}
DRW_shgroup_uniform_vec3(grp, "lightDirection", engine_object_data->shadow_dir, 1);
DRW_shgroup_uniform_float_copy(grp, "lightDistance", extrude_distance);
- DRW_shgroup_call_add(grp, geom_shadow, ob->obmat);
+ DRW_shgroup_call(grp, geom_shadow, ob->obmat);
#ifdef DEBUG_SHADOW_VOLUME
DRW_debug_bbox(&engine_object_data->shadow_bbox, (float[4]){0.0f, 1.0f, 0.0f, 1.0f});
#endif
diff --git a/source/blender/draw/engines/workbench/workbench_effect_dof.c b/source/blender/draw/engines/workbench/workbench_effect_dof.c
index 3dea99a76cf..ee8c8a0343f 100644
--- a/source/blender/draw/engines/workbench/workbench_effect_dof.c
+++ b/source/blender/draw/engines/workbench/workbench_effect_dof.c
@@ -314,37 +314,37 @@ void workbench_dof_create_pass(WORKBENCH_Data *vedata,
DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
DRW_shgroup_uniform_vec3(grp, "dofParams", &wpd->dof_aperturesize, 1);
DRW_shgroup_uniform_vec2(grp, "nearFar", wpd->dof_near_far, 1);
- DRW_shgroup_call_add(grp, quad, NULL);
+ DRW_shgroup_call(grp, quad, NULL);
}
{
DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_dof_downsample_sh, psl->dof_down2_ps);
DRW_shgroup_uniform_texture(grp, "sceneColorTex", txl->dof_source_tx);
DRW_shgroup_uniform_texture(grp, "inputCocTex", txl->coc_halfres_tx);
- DRW_shgroup_call_add(grp, quad, NULL);
+ DRW_shgroup_call(grp, quad, NULL);
}
#if 0
{
DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_dof_flatten_h_sh,
psl->dof_flatten_h_ps);
DRW_shgroup_uniform_texture(grp, "inputCocTex", txl->coc_halfres_tx);
- DRW_shgroup_call_add(grp, quad, NULL);
+ DRW_shgroup_call(grp, quad, NULL);
}
{
DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_dof_flatten_v_sh,
psl->dof_flatten_v_ps);
DRW_shgroup_uniform_texture(grp, "inputCocTex", wpd->coc_temp_tx);
- DRW_shgroup_call_add(grp, quad, NULL);
+ DRW_shgroup_call(grp, quad, NULL);
}
{
DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_dof_dilate_v_sh, psl->dof_dilate_v_ps);
DRW_shgroup_uniform_texture(grp, "inputCocTex", wpd->coc_tiles_tx[0]);
- DRW_shgroup_call_add(grp, quad, NULL);
+ DRW_shgroup_call(grp, quad, NULL);
}
{
DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_dof_dilate_h_sh, psl->dof_dilate_h_ps);
DRW_shgroup_uniform_texture(grp, "inputCocTex", wpd->coc_tiles_tx[1]);
- DRW_shgroup_call_add(grp, quad, NULL);
+ DRW_shgroup_call(grp, quad, NULL);
}
#endif
{
@@ -357,14 +357,14 @@ void workbench_dof_create_pass(WORKBENCH_Data *vedata,
DRW_shgroup_uniform_texture(grp, "halfResColorTex", txl->dof_source_tx);
DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
DRW_shgroup_uniform_float_copy(grp, "noiseOffset", offset);
- DRW_shgroup_call_add(grp, quad, NULL);
+ DRW_shgroup_call(grp, quad, NULL);
}
{
DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_dof_blur2_sh, psl->dof_blur2_ps);
DRW_shgroup_uniform_texture(grp, "inputCocTex", txl->coc_halfres_tx);
DRW_shgroup_uniform_texture(grp, "blurTex", wpd->dof_blur_tx);
DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
- DRW_shgroup_call_add(grp, quad, NULL);
+ DRW_shgroup_call(grp, quad, NULL);
}
{
DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_dof_resolve_sh, psl->dof_resolve_ps);
@@ -373,7 +373,7 @@ void workbench_dof_create_pass(WORKBENCH_Data *vedata,
DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
DRW_shgroup_uniform_vec3(grp, "dofParams", &wpd->dof_aperturesize, 1);
DRW_shgroup_uniform_vec2(grp, "nearFar", wpd->dof_near_far, 1);
- DRW_shgroup_call_add(grp, quad, NULL);
+ DRW_shgroup_call(grp, quad, NULL);
}
}
diff --git a/source/blender/draw/engines/workbench/workbench_effect_fxaa.c b/source/blender/draw/engines/workbench/workbench_effect_fxaa.c
index 47355f324a8..6e3bf1658ab 100644
--- a/source/blender/draw/engines/workbench/workbench_effect_fxaa.c
+++ b/source/blender/draw/engines/workbench/workbench_effect_fxaa.c
@@ -49,7 +49,7 @@ DRWPass *workbench_fxaa_create_pass(GPUTexture **color_buffer_tx)
DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_fxaa_sh, pass);
DRW_shgroup_uniform_texture_ref(grp, "colorBuffer", color_buffer_tx);
DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
- DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
+ DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
return pass;
}
diff --git a/source/blender/draw/engines/workbench/workbench_effect_taa.c b/source/blender/draw/engines/workbench/workbench_effect_taa.c
index 7c411135634..7b2faf0ddcd 100644
--- a/source/blender/draw/engines/workbench/workbench_effect_taa.c
+++ b/source/blender/draw/engines/workbench/workbench_effect_taa.c
@@ -91,23 +91,19 @@ int workbench_taa_calculate_num_iterations(WORKBENCH_Data *vedata)
WORKBENCH_StorageList *stl = vedata->stl;
WORKBENCH_PrivateData *wpd = stl->g_data;
const Scene *scene = DRW_context_state_get()->scene;
- int result = scene->display.viewport_aa;
+ int result;
if (workbench_is_taa_enabled(wpd)) {
if (DRW_state_is_image_render()) {
- result = scene->display.render_aa;
- }
- else if (IN_RANGE_INCL(wpd->preferences->gpu_viewport_quality,
- GPU_VIEWPORT_QUALITY_TAA8,
- GPU_VIEWPORT_QUALITY_TAA16)) {
- result = MIN2(result, 8);
- }
- else if (IN_RANGE_INCL(wpd->preferences->gpu_viewport_quality,
- GPU_VIEWPORT_QUALITY_TAA16,
- GPU_VIEWPORT_QUALITY_TAA32)) {
- result = MIN2(result, 16);
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ if (draw_ctx->v3d) {
+ result = scene->display.viewport_aa;
+ }
+ else {
+ result = scene->display.render_aa;
+ }
}
else {
- result = MIN2(result, 32);
+ result = wpd->preferences->viewport_aa;
}
}
else {
@@ -205,7 +201,7 @@ DRWPass *workbench_taa_create_pass(WORKBENCH_Data *vedata, GPUTexture **color_bu
DRW_shgroup_uniform_texture_ref(grp, "colorBuffer", color_buffer_tx);
DRW_shgroup_uniform_texture_ref(grp, "historyBuffer", &txl->history_buffer_tx);
DRW_shgroup_uniform_float(grp, "mixFactor", &effect_info->taa_mix_factor, 1);
- DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
+ DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
/*
* Set the offset for the cavity shader so every iteration different
diff --git a/source/blender/draw/engines/workbench/workbench_forward.c b/source/blender/draw/engines/workbench/workbench_forward.c
index fe3e0579c8e..f12902b6801 100644
--- a/source/blender/draw/engines/workbench/workbench_forward.c
+++ b/source/blender/draw/engines/workbench/workbench_forward.c
@@ -68,6 +68,7 @@ static struct {
/* Shaders */
extern char datatoc_common_hair_lib_glsl[];
+extern char datatoc_common_view_lib_glsl[];
extern char datatoc_workbench_forward_composite_frag_glsl[];
extern char datatoc_workbench_forward_depth_frag_glsl[];
@@ -88,6 +89,7 @@ static char *workbench_build_forward_vert(bool is_hair)
if (is_hair) {
BLI_dynstr_append(ds, datatoc_common_hair_lib_glsl);
}
+ BLI_dynstr_append(ds, datatoc_common_view_lib_glsl);
BLI_dynstr_append(ds, datatoc_workbench_prepass_vert_glsl);
char *str = BLI_dynstr_get_cstring(ds);
@@ -99,6 +101,7 @@ static char *workbench_build_forward_transparent_accum_frag(void)
{
DynStr *ds = BLI_dynstr_new();
+ BLI_dynstr_append(ds, datatoc_common_view_lib_glsl);
BLI_dynstr_append(ds, datatoc_workbench_data_lib_glsl);
BLI_dynstr_append(ds, datatoc_workbench_common_lib_glsl);
BLI_dynstr_append(ds, datatoc_workbench_world_light_lib_glsl);
@@ -199,8 +202,7 @@ WORKBENCH_MaterialData *workbench_forward_get_or_create_material_data(WORKBENCH_
V3D_SHADING_TEXTURE_COLOR) {
material->shgrp_object_outline = DRW_shgroup_create(sh_data->object_outline_texture_sh,
psl->object_outline_pass);
- GPUTexture *tex = GPU_texture_from_blender(
- material->ima, material->iuser, GL_TEXTURE_2D, false);
+ GPUTexture *tex = GPU_texture_from_blender(material->ima, material->iuser, GL_TEXTURE_2D);
DRW_shgroup_uniform_texture(material->shgrp_object_outline, "image", tex);
}
else {
@@ -399,7 +401,7 @@ void workbench_forward_engine_init(WORKBENCH_Data *vedata)
DRW_shgroup_uniform_texture_ref(grp, "transparentRevealage", &e_data.transparent_revealage_tx);
DRW_shgroup_uniform_block(grp, "world_block", wpd->world_ubo);
DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
- DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
+ DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
}
/* TODO(campbell): displays but masks geometry,
@@ -411,7 +413,7 @@ void workbench_forward_engine_init(WORKBENCH_Data *vedata)
GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR_BACKGROUND);
grp = DRW_shgroup_create(shader, psl->background_pass);
wpd->world_clip_planes_batch = DRW_draw_background_clipping_batch_from_rv3d(draw_ctx->rv3d);
- DRW_shgroup_call_add(grp, wpd->world_clip_planes_batch, NULL);
+ DRW_shgroup_call(grp, wpd->world_clip_planes_batch, NULL);
DRW_shgroup_uniform_vec4(grp, "color", &wpd->world_clip_planes_color[0], 1);
}
@@ -441,7 +443,7 @@ void workbench_forward_engine_init(WORKBENCH_Data *vedata)
int state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS;
psl->checker_depth_pass = DRW_pass_create("Checker Depth", state);
grp = DRW_shgroup_create(e_data.checker_depth_sh, psl->checker_depth_pass);
- DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
+ DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
DRW_shgroup_uniform_float_copy(grp, "threshold", blend_threshold);
DRW_shgroup_uniform_float_copy(grp, "offset", noise_offset);
}
@@ -580,8 +582,8 @@ void workbench_forward_cache_populate(WORKBENCH_Data *vedata, Object *ob)
int color_type = workbench_material_determine_color_type(wpd, image, ob, is_sculpt_mode);
material = workbench_forward_get_or_create_material_data(
vedata, ob, mat, image, iuser, color_type, interp, is_sculpt_mode);
- DRW_shgroup_call_object_add(material->shgrp_object_outline, geom_array[i], ob);
- DRW_shgroup_call_object_add(material->shgrp, geom_array[i], ob);
+ DRW_shgroup_call_object(material->shgrp_object_outline, geom_array[i], ob);
+ DRW_shgroup_call_object(material->shgrp, geom_array[i], ob);
}
}
else if (ELEM(wpd->shading.color_type,
@@ -597,9 +599,9 @@ void workbench_forward_cache_populate(WORKBENCH_Data *vedata, Object *ob)
vedata, ob, NULL, NULL, NULL, color_type, 0, is_sculpt_mode);
bool use_vcol = (color_type == V3D_SHADING_VERTEX_COLOR);
/* TODO(fclem) make this call optional */
- DRW_shgroup_call_sculpt_add(material->shgrp_object_outline, ob, false, false, false);
+ DRW_shgroup_call_sculpt(material->shgrp_object_outline, ob, false, false, false);
if (!is_wire) {
- DRW_shgroup_call_sculpt_add(material->shgrp, ob, false, false, use_vcol);
+ DRW_shgroup_call_sculpt(material->shgrp, ob, false, false, use_vcol);
}
}
else {
@@ -610,9 +612,9 @@ void workbench_forward_cache_populate(WORKBENCH_Data *vedata, Object *ob)
material = workbench_forward_get_or_create_material_data(
vedata, ob, NULL, NULL, NULL, color_type, 0, is_sculpt_mode);
/* TODO(fclem) make this call optional */
- DRW_shgroup_call_object_add(material->shgrp_object_outline, geom, ob);
+ DRW_shgroup_call_object(material->shgrp_object_outline, geom, ob);
if (!is_wire) {
- DRW_shgroup_call_object_add(material->shgrp, geom, ob);
+ DRW_shgroup_call_object(material->shgrp, geom, ob);
}
}
}
@@ -621,18 +623,17 @@ void workbench_forward_cache_populate(WORKBENCH_Data *vedata, Object *ob)
/* Draw material color */
if (is_sculpt_mode) {
struct DRWShadingGroup **shgrps = BLI_array_alloca(shgrps, materials_len);
- struct Material **mats = BLI_array_alloca(mats, materials_len);
for (int i = 0; i < materials_len; ++i) {
- mats[i] = give_current_material(ob, i + 1);
+ struct Material *mat = give_current_material(ob, i + 1);
material = workbench_forward_get_or_create_material_data(
- vedata, ob, mats[i], NULL, NULL, V3D_SHADING_MATERIAL_COLOR, 0, is_sculpt_mode);
+ vedata, ob, mat, NULL, NULL, V3D_SHADING_MATERIAL_COLOR, 0, is_sculpt_mode);
shgrps[i] = material->shgrp;
}
/* TODO(fclem) make this call optional */
- DRW_shgroup_call_sculpt_add(material->shgrp_object_outline, ob, false, false, false);
+ DRW_shgroup_call_sculpt(material->shgrp_object_outline, ob, false, false, false);
if (!is_wire) {
- DRW_shgroup_call_sculpt_with_materials_add(shgrps, mats, ob, false);
+ DRW_shgroup_call_sculpt_with_materials(shgrps, ob, false);
}
}
else {
@@ -651,9 +652,9 @@ void workbench_forward_cache_populate(WORKBENCH_Data *vedata, Object *ob)
material = workbench_forward_get_or_create_material_data(
vedata, ob, mat, NULL, NULL, V3D_SHADING_MATERIAL_COLOR, 0, is_sculpt_mode);
/* TODO(fclem) make this call optional */
- DRW_shgroup_call_object_add(material->shgrp_object_outline, mat_geom[i], ob);
+ DRW_shgroup_call_object(material->shgrp_object_outline, mat_geom[i], ob);
if (!is_wire) {
- DRW_shgroup_call_object_add(material->shgrp, mat_geom[i], ob);
+ DRW_shgroup_call_object(material->shgrp, mat_geom[i], ob);
}
}
}
diff --git a/source/blender/draw/engines/workbench/workbench_materials.c b/source/blender/draw/engines/workbench/workbench_materials.c
index c403e358d6a..b280b6fd01a 100644
--- a/source/blender/draw/engines/workbench/workbench_materials.c
+++ b/source/blender/draw/engines/workbench/workbench_materials.c
@@ -294,15 +294,8 @@ void workbench_material_shgroup_uniform(WORKBENCH_PrivateData *wpd,
if (workbench_material_determine_color_type(wpd, material->ima, ob, false) ==
V3D_SHADING_TEXTURE_COLOR) {
- ImBuf *ibuf = BKE_image_acquire_ibuf(material->ima, material->iuser, NULL);
- const bool do_color_correction = wpd->use_color_management &&
- (ibuf &&
- (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA) == 0);
- BKE_image_release_ibuf(material->ima, ibuf, NULL);
- GPUTexture *tex = GPU_texture_from_blender(
- material->ima, material->iuser, GL_TEXTURE_2D, false);
+ GPUTexture *tex = GPU_texture_from_blender(material->ima, material->iuser, GL_TEXTURE_2D);
DRW_shgroup_uniform_texture(grp, "image", tex);
- DRW_shgroup_uniform_bool_copy(grp, "imageSrgb", do_color_correction);
DRW_shgroup_uniform_bool_copy(grp, "imageNearest", (interp == SHD_INTERP_CLOSEST));
}
else {
diff --git a/source/blender/draw/engines/workbench/workbench_private.h b/source/blender/draw/engines/workbench/workbench_private.h
index e25503aef6e..09d9ad65717 100644
--- a/source/blender/draw/engines/workbench/workbench_private.h
+++ b/source/blender/draw/engines/workbench/workbench_private.h
@@ -319,23 +319,32 @@ typedef struct WORKBENCH_ObjectData {
BLI_INLINE bool workbench_is_taa_enabled(WORKBENCH_PrivateData *wpd)
{
if (DRW_state_is_image_render()) {
- return DRW_context_state_get()->scene->display.render_aa > SCE_DISPLAY_AA_FXAA;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ if (draw_ctx->v3d) {
+ return draw_ctx->scene->display.viewport_aa > SCE_DISPLAY_AA_FXAA;
+ }
+ else {
+ return draw_ctx->scene->display.render_aa > SCE_DISPLAY_AA_FXAA;
+ }
}
else {
- return DRW_context_state_get()->scene->display.viewport_aa > SCE_DISPLAY_AA_FXAA &&
- wpd->preferences->gpu_viewport_quality >= GPU_VIEWPORT_QUALITY_TAA8 &&
- !wpd->is_playback;
+ return wpd->preferences->viewport_aa > SCE_DISPLAY_AA_FXAA && !wpd->is_playback;
}
}
BLI_INLINE bool workbench_is_fxaa_enabled(WORKBENCH_PrivateData *wpd)
{
if (DRW_state_is_image_render()) {
- return DRW_context_state_get()->scene->display.render_aa == SCE_DISPLAY_AA_FXAA;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ if (draw_ctx->v3d) {
+ return draw_ctx->scene->display.viewport_aa == SCE_DISPLAY_AA_FXAA;
+ }
+ else {
+ return draw_ctx->scene->display.render_aa == SCE_DISPLAY_AA_FXAA;
+ }
}
else {
- if (wpd->preferences->gpu_viewport_quality >= GPU_VIEWPORT_QUALITY_FXAA &&
- DRW_context_state_get()->scene->display.viewport_aa == SCE_DISPLAY_AA_FXAA) {
+ if (wpd->preferences->viewport_aa == SCE_DISPLAY_AA_FXAA) {
return true;
}
diff --git a/source/blender/draw/engines/workbench/workbench_volume.c b/source/blender/draw/engines/workbench/workbench_volume.c
index accc7e91576..1620584dc06 100644
--- a/source/blender/draw/engines/workbench/workbench_volume.c
+++ b/source/blender/draw/engines/workbench/workbench_volume.c
@@ -53,6 +53,7 @@ static struct {
extern char datatoc_workbench_volume_vert_glsl[];
extern char datatoc_workbench_volume_frag_glsl[];
+extern char datatoc_common_view_lib_glsl[];
static GPUShader *volume_shader_get(bool slice, bool coba, bool cubic)
{
@@ -77,8 +78,11 @@ static GPUShader *volume_shader_get(bool slice, bool coba, bool cubic)
char *defines = BLI_dynstr_get_cstring(ds);
BLI_dynstr_free(ds);
- e_data.volume_sh[id] = DRW_shader_create(
- datatoc_workbench_volume_vert_glsl, NULL, datatoc_workbench_volume_frag_glsl, defines);
+ e_data.volume_sh[id] = DRW_shader_create_with_lib(datatoc_workbench_volume_vert_glsl,
+ NULL,
+ datatoc_workbench_volume_frag_glsl,
+ datatoc_common_view_lib_glsl,
+ defines);
MEM_freeN(defines);
}
@@ -207,10 +211,10 @@ void workbench_volume_cache_populate(WORKBENCH_Data *vedata,
DRW_shgroup_uniform_float_copy(grp, "densityScale", 10.0f * sds->display_thickness);
if (use_slice) {
- DRW_shgroup_call_object_add(grp, DRW_cache_quad_get(), ob);
+ DRW_shgroup_call_object(grp, DRW_cache_quad_get(), ob);
}
else {
- DRW_shgroup_call_object_add(grp, DRW_cache_cube_get(), ob);
+ DRW_shgroup_call_object(grp, DRW_cache_cube_get(), ob);
}
BLI_addtail(&wpd->smoke_domains, BLI_genericNodeN(smd));
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index 51747c4aecc..19148352756 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -44,6 +44,7 @@
#include "DNA_world_types.h"
#include "GPU_framebuffer.h"
+#include "GPU_primitive.h"
#include "GPU_texture.h"
#include "GPU_shader.h"
@@ -83,6 +84,9 @@ typedef struct DRWPass DRWPass;
typedef struct DRWShadingGroup DRWShadingGroup;
typedef struct DRWUniform DRWUniform;
+/* Opaque type to avoid usage as a DRWCall but it is exactly the same thing. */
+typedef struct DRWCallBuffer DRWCallBuffer;
+
/* TODO Put it somewhere else? */
typedef struct BoundSphere {
float center[3], radius;
@@ -105,7 +109,7 @@ typedef char DRWViewportEmptyList;
/* Use of multisample framebuffers. */
#define MULTISAMPLE_SYNC_ENABLE(dfbl, dtxl) \
{ \
- if (dfbl->multisample_fb != NULL) { \
+ if (dfbl->multisample_fb != NULL && DRW_state_is_fbo()) { \
DRW_stats_query_start("Multisample Blit"); \
GPU_framebuffer_bind(dfbl->multisample_fb); \
/* TODO clear only depth but need to do alpha to coverage for transparencies. */ \
@@ -117,7 +121,7 @@ typedef char DRWViewportEmptyList;
#define MULTISAMPLE_SYNC_DISABLE(dfbl, dtxl) \
{ \
- if (dfbl->multisample_fb != NULL) { \
+ if (dfbl->multisample_fb != NULL && DRW_state_is_fbo()) { \
DRW_stats_query_start("Multisample Resolve"); \
GPU_framebuffer_bind(dfbl->default_fb); \
DRW_multisamples_resolve(dtxl->multisample_depth, dtxl->multisample_color, true); \
@@ -128,7 +132,7 @@ typedef char DRWViewportEmptyList;
#define MULTISAMPLE_SYNC_DISABLE_NO_DEPTH(dfbl, dtxl) \
{ \
- if (dfbl->multisample_fb != NULL) { \
+ if (dfbl->multisample_fb != NULL && DRW_state_is_fbo()) { \
DRW_stats_query_start("Multisample Resolve"); \
GPU_framebuffer_bind(dfbl->default_fb); \
DRW_multisamples_resolve(dtxl->multisample_depth, dtxl->multisample_color, false); \
@@ -324,8 +328,8 @@ typedef enum {
DRW_STATE_DEPTH_GREATER_EQUAL = (1 << 7),
DRW_STATE_CULL_BACK = (1 << 8),
DRW_STATE_CULL_FRONT = (1 << 9),
- DRW_STATE_WIRE = (1 << 10),
- DRW_STATE_POINT = (1 << 11),
+ DRW_STATE_WIRE = (1 << 10), /* TODO remove */
+ DRW_STATE_POINT = (1 << 11), /* TODO remove */
/** Polygon offset. Does not work with lines and points. */
DRW_STATE_OFFSET_POSITIVE = (1 << 12),
/** Polygon offset. Does not work with lines and points. */
@@ -382,26 +386,6 @@ struct GPUVertFormat *DRW_shgroup_instance_format_array(const DRWInstanceAttrFor
DRWShadingGroup *DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass);
DRWShadingGroup *DRW_shgroup_create_sub(DRWShadingGroup *shgroup);
DRWShadingGroup *DRW_shgroup_material_create(struct GPUMaterial *material, DRWPass *pass);
-DRWShadingGroup *DRW_shgroup_material_instance_create(struct GPUMaterial *material,
- DRWPass *pass,
- struct GPUBatch *geom,
- struct Object *ob,
- struct GPUVertFormat *format);
-DRWShadingGroup *DRW_shgroup_material_empty_tri_batch_create(struct GPUMaterial *material,
- DRWPass *pass,
- int size);
-DRWShadingGroup *DRW_shgroup_instance_create(struct GPUShader *shader,
- DRWPass *pass,
- struct GPUBatch *geom,
- struct GPUVertFormat *format);
-DRWShadingGroup *DRW_shgroup_point_batch_create(struct GPUShader *shader, DRWPass *pass);
-DRWShadingGroup *DRW_shgroup_line_batch_create_with_format(struct GPUShader *shader,
- DRWPass *pass,
- struct GPUVertFormat *format);
-DRWShadingGroup *DRW_shgroup_line_batch_create(struct GPUShader *shader, DRWPass *pass);
-DRWShadingGroup *DRW_shgroup_empty_tri_batch_create(struct GPUShader *shader,
- DRWPass *pass,
- int size);
DRWShadingGroup *DRW_shgroup_transform_feedback_create(struct GPUShader *shader,
DRWPass *pass,
struct GPUVertBuf *tf_target);
@@ -409,66 +393,57 @@ DRWShadingGroup *DRW_shgroup_transform_feedback_create(struct GPUShader *shader,
/* return final visibility */
typedef bool(DRWCallVisibilityFn)(bool vis_in, void *user_data);
-void DRW_shgroup_instance_batch(DRWShadingGroup *shgroup, struct GPUBatch *batch);
-
-void DRW_shgroup_call_add(DRWShadingGroup *shgroup, struct GPUBatch *geom, float (*obmat)[4]);
-void DRW_shgroup_call_range_add(
- DRWShadingGroup *shgroup, struct GPUBatch *geom, float (*obmat)[4], uint v_sta, uint v_count);
-void DRW_shgroup_call_procedural_points_add(DRWShadingGroup *shgroup,
- uint point_len,
- float (*obmat)[4]);
-void DRW_shgroup_call_procedural_lines_add(DRWShadingGroup *shgroup,
- uint line_count,
- float (*obmat)[4]);
-void DRW_shgroup_call_procedural_triangles_add(DRWShadingGroup *shgroup,
- uint tria_count,
- float (*obmat)[4]);
-void DRW_shgroup_call_object_add_ex(DRWShadingGroup *shgroup,
- struct GPUBatch *geom,
- struct Object *ob,
- struct Material *ma,
- bool bypass_culling);
-#define DRW_shgroup_call_object_add(shgroup, geom, ob) \
- DRW_shgroup_call_object_add_ex(shgroup, geom, ob, NULL, false)
-#define DRW_shgroup_call_object_add_no_cull(shgroup, geom, ob) \
- DRW_shgroup_call_object_add_ex(shgroup, geom, ob, NULL, true)
-void DRW_shgroup_call_object_add_with_callback(DRWShadingGroup *shgroup,
- struct GPUBatch *geom,
- struct Object *ob,
- struct Material *ma,
- DRWCallVisibilityFn *callback,
- void *user_data);
-
-void DRW_shgroup_call_sculpt_add(DRWShadingGroup *shading_group,
- Object *object,
- bool use_wire,
- bool use_mask,
- bool use_vert_color);
-void DRW_shgroup_call_sculpt_with_materials_add(DRWShadingGroup **shgroups,
- Material **materials,
- Object *ob,
- bool use_vcol);
-
-/* Used for drawing a batch with instancing without instance attributes. */
-void DRW_shgroup_call_instances_add(DRWShadingGroup *shgroup,
- struct GPUBatch *geom,
- float (*obmat)[4],
- uint *count);
-void DRW_shgroup_call_object_instances_add(DRWShadingGroup *shgroup,
+/* TODO(fclem): Remove the _add suffix. */
+void DRW_shgroup_call(DRWShadingGroup *sh, struct GPUBatch *geom, float (*obmat)[4]);
+void DRW_shgroup_call_range(
+ DRWShadingGroup *sh, struct GPUBatch *geom, float (*obmat)[4], uint v_sta, uint v_ct);
+
+void DRW_shgroup_call_procedural_points(DRWShadingGroup *sh, uint point_ct, float (*obmat)[4]);
+void DRW_shgroup_call_procedural_lines(DRWShadingGroup *sh, uint line_ct, float (*obmat)[4]);
+void DRW_shgroup_call_procedural_triangles(DRWShadingGroup *sh, uint tri_ct, float (*obmat)[4]);
+
+void DRW_shgroup_call_object_ex(DRWShadingGroup *shgroup,
+ struct GPUBatch *geom,
+ struct Object *ob,
+ bool bypass_culling);
+#define DRW_shgroup_call_object(shgroup, geom, ob) \
+ DRW_shgroup_call_object_ex(shgroup, geom, ob, false)
+#define DRW_shgroup_call_object_no_cull(shgroup, geom, ob) \
+ DRW_shgroup_call_object_ex(shgroup, geom, ob, true)
+
+void DRW_shgroup_call_object_with_callback(DRWShadingGroup *shgroup,
struct GPUBatch *geom,
struct Object *ob,
- uint *count);
-void DRW_shgroup_call_dynamic_add_array(DRWShadingGroup *shgroup,
- const void *attr[],
- uint attr_len);
-#define DRW_shgroup_call_dynamic_add(shgroup, ...) \
+ DRWCallVisibilityFn *callback,
+ void *user_data);
+
+void DRW_shgroup_call_instances(DRWShadingGroup *shgroup,
+ struct GPUBatch *geom,
+ float (*obmat)[4],
+ uint count);
+void DRW_shgroup_call_instances_with_attribs(DRWShadingGroup *shgroup,
+ struct GPUBatch *geom,
+ float (*obmat)[4],
+ struct GPUBatch *inst_attributes);
+
+void DRW_shgroup_call_sculpt(DRWShadingGroup *sh, Object *ob, bool wire, bool mask, bool vcol);
+void DRW_shgroup_call_sculpt_with_materials(DRWShadingGroup **sh, Object *ob, bool vcol);
+
+DRWCallBuffer *DRW_shgroup_call_buffer(DRWShadingGroup *shading_group,
+ struct GPUVertFormat *format,
+ GPUPrimType prim_type);
+DRWCallBuffer *DRW_shgroup_call_buffer_instance(DRWShadingGroup *shading_group,
+ struct GPUVertFormat *format,
+ struct GPUBatch *geom);
+
+void DRW_buffer_add_entry_array(DRWCallBuffer *buffer, const void *attr[], uint attr_len);
+
+#define DRW_buffer_add_entry(buffer, ...) \
do { \
const void *array[] = {__VA_ARGS__}; \
- DRW_shgroup_call_dynamic_add_array(shgroup, array, (sizeof(array) / sizeof(*array))); \
+ DRW_buffer_add_entry_array(buffer, array, (sizeof(array) / sizeof(*array))); \
} while (0)
-uint DRW_shgroup_get_instance_count(const DRWShadingGroup *shgroup);
-
void DRW_shgroup_state_enable(DRWShadingGroup *shgroup, DRWState state);
void DRW_shgroup_state_disable(DRWShadingGroup *shgroup, DRWState state);
void DRW_shgroup_stencil_mask(DRWShadingGroup *shgroup, uint mask);
@@ -539,6 +514,7 @@ void DRW_shgroup_uniform_mat4(DRWShadingGroup *shgroup, const char *name, const
void DRW_shgroup_uniform_int_copy(DRWShadingGroup *shgroup, const char *name, const int value);
void DRW_shgroup_uniform_bool_copy(DRWShadingGroup *shgroup, const char *name, const bool value);
void DRW_shgroup_uniform_float_copy(DRWShadingGroup *shgroup, const char *name, const float value);
+void DRW_shgroup_uniform_vec2_copy(DRWShadingGroup *shgroup, const char *name, const float *value);
bool DRW_shgroup_is_empty(DRWShadingGroup *shgroup);
@@ -636,6 +612,7 @@ DrawData *DRW_drawdata_ensure(ID *id,
size_t size,
DrawDataInitCb init_cb,
DrawDataFreeCb free_cb);
+void **DRW_duplidata_get(void *vedata);
/* Settings */
bool DRW_object_is_renderable(const struct Object *ob);
diff --git a/source/blender/draw/intern/draw_anim_viz.c b/source/blender/draw/intern/draw_anim_viz.c
index a6026c9da3a..31d7a45ede9 100644
--- a/source/blender/draw/intern/draw_anim_viz.c
+++ b/source/blender/draw/intern/draw_anim_viz.c
@@ -215,7 +215,7 @@ static void MPATH_cache_motion_path(MPATH_PassList *psl,
DRW_shgroup_uniform_vec3(shgrp, "customColor", mpath->color, 1);
}
/* Only draw the required range. */
- DRW_shgroup_call_range_add(shgrp, mpath_batch_line_get(mpath), NULL, start_index, len);
+ DRW_shgroup_call_range(shgrp, mpath_batch_line_get(mpath), NULL, start_index, len);
}
/* Draw points. */
@@ -231,7 +231,7 @@ static void MPATH_cache_motion_path(MPATH_PassList *psl,
DRW_shgroup_uniform_vec3(shgrp, "customColor", mpath->color, 1);
}
/* Only draw the required range. */
- DRW_shgroup_call_range_add(shgrp, mpath_batch_points_get(mpath), NULL, start_index, len);
+ DRW_shgroup_call_range(shgrp, mpath_batch_points_get(mpath), NULL, start_index, len);
/* Draw frame numbers at each framestep value */
bool show_kf_no = (avs->path_viewflag & MOTIONPATH_VIEW_KFNOS) != 0;
diff --git a/source/blender/draw/intern/draw_armature.c b/source/blender/draw/intern/draw_armature.c
index 9b52f282944..3f651b27dd0 100644
--- a/source/blender/draw/intern/draw_armature.c
+++ b/source/blender/draw/intern/draw_armature.c
@@ -37,6 +37,8 @@
#include "BKE_armature.h"
+#include "DEG_depsgraph_query.h"
+
#include "ED_armature.h"
#include "UI_resources.h"
@@ -57,26 +59,26 @@ static struct {
/* Current armature object */
Object *ob;
/* Reset when changing current_armature */
- DRWShadingGroup *bone_octahedral_solid;
- DRWShadingGroup *bone_octahedral_wire;
- DRWShadingGroup *bone_octahedral_outline;
- DRWShadingGroup *bone_box_solid;
- DRWShadingGroup *bone_box_wire;
- DRWShadingGroup *bone_box_outline;
- DRWShadingGroup *bone_wire;
- DRWShadingGroup *bone_stick;
- DRWShadingGroup *bone_dof_sphere;
- DRWShadingGroup *bone_dof_lines;
- DRWShadingGroup *bone_envelope_solid;
- DRWShadingGroup *bone_envelope_distance;
- DRWShadingGroup *bone_envelope_wire;
- DRWShadingGroup *bone_point_solid;
- DRWShadingGroup *bone_point_wire;
- DRWShadingGroup *bone_axes;
- DRWShadingGroup *lines_relationship;
- DRWShadingGroup *lines_ik;
- DRWShadingGroup *lines_ik_no_target;
- DRWShadingGroup *lines_ik_spline;
+ DRWCallBuffer *bone_octahedral_solid;
+ DRWCallBuffer *bone_octahedral_wire;
+ DRWCallBuffer *bone_octahedral_outline;
+ DRWCallBuffer *bone_box_solid;
+ DRWCallBuffer *bone_box_wire;
+ DRWCallBuffer *bone_box_outline;
+ DRWCallBuffer *bone_wire;
+ DRWCallBuffer *bone_stick;
+ DRWCallBuffer *bone_dof_sphere;
+ DRWCallBuffer *bone_dof_lines;
+ DRWCallBuffer *bone_envelope_solid;
+ DRWCallBuffer *bone_envelope_distance;
+ DRWCallBuffer *bone_envelope_wire;
+ DRWCallBuffer *bone_point_solid;
+ DRWCallBuffer *bone_point_wire;
+ DRWCallBuffer *bone_axes;
+ DRWCallBuffer *lines_relationship;
+ DRWCallBuffer *lines_ik;
+ DRWCallBuffer *lines_ik_no_target;
+ DRWCallBuffer *lines_ik_spline;
DRWArmaturePasses passes;
@@ -120,22 +122,21 @@ static void drw_shgroup_bone_octahedral(const float (*bone_mat)[4],
{
if (g_data.bone_octahedral_outline == NULL) {
struct GPUBatch *geom = DRW_cache_bone_octahedral_wire_get();
- g_data.bone_octahedral_outline = shgroup_instance_bone_shape_outline(
+ g_data.bone_octahedral_outline = buffer_instance_bone_shape_outline(
g_data.passes.bone_outline, geom, sh_cfg);
}
if (g_data.bone_octahedral_solid == NULL && g_data.passes.bone_solid != NULL) {
struct GPUBatch *geom = DRW_cache_bone_octahedral_get();
- g_data.bone_octahedral_solid = shgroup_instance_bone_shape_solid(
+ g_data.bone_octahedral_solid = buffer_instance_bone_shape_solid(
g_data.passes.bone_solid, geom, g_data.transparent, sh_cfg);
}
float final_bonemat[4][4];
mul_m4_m4m4(final_bonemat, g_data.ob->obmat, bone_mat);
if (g_data.bone_octahedral_solid != NULL) {
- DRW_shgroup_call_dynamic_add(
- g_data.bone_octahedral_solid, final_bonemat, bone_color, hint_color);
+ DRW_buffer_add_entry(g_data.bone_octahedral_solid, final_bonemat, bone_color, hint_color);
}
if (outline_color[3] > 0.0f) {
- DRW_shgroup_call_dynamic_add(g_data.bone_octahedral_outline, final_bonemat, outline_color);
+ DRW_buffer_add_entry(g_data.bone_octahedral_outline, final_bonemat, outline_color);
}
}
@@ -148,21 +149,21 @@ static void drw_shgroup_bone_box(const float (*bone_mat)[4],
{
if (g_data.bone_box_wire == NULL) {
struct GPUBatch *geom = DRW_cache_bone_box_wire_get();
- g_data.bone_box_outline = shgroup_instance_bone_shape_outline(
+ g_data.bone_box_outline = buffer_instance_bone_shape_outline(
g_data.passes.bone_outline, geom, sh_cfg);
}
if (g_data.bone_box_solid == NULL && g_data.passes.bone_solid != NULL) {
struct GPUBatch *geom = DRW_cache_bone_box_get();
- g_data.bone_box_solid = shgroup_instance_bone_shape_solid(
+ g_data.bone_box_solid = buffer_instance_bone_shape_solid(
g_data.passes.bone_solid, geom, g_data.transparent, sh_cfg);
}
float final_bonemat[4][4];
mul_m4_m4m4(final_bonemat, g_data.ob->obmat, bone_mat);
if (g_data.bone_box_solid != NULL) {
- DRW_shgroup_call_dynamic_add(g_data.bone_box_solid, final_bonemat, bone_color, hint_color);
+ DRW_buffer_add_entry(g_data.bone_box_solid, final_bonemat, bone_color, hint_color);
}
if (outline_color[3] > 0.0f) {
- DRW_shgroup_call_dynamic_add(g_data.bone_box_outline, final_bonemat, outline_color);
+ DRW_buffer_add_entry(g_data.bone_box_outline, final_bonemat, outline_color);
}
}
@@ -172,15 +173,15 @@ static void drw_shgroup_bone_wire(const float (*bone_mat)[4],
const eGPUShaderConfig sh_cfg)
{
if (g_data.bone_wire == NULL) {
- g_data.bone_wire = shgroup_dynlines_flat_color(g_data.passes.bone_wire, sh_cfg);
+ g_data.bone_wire = buffer_dynlines_flat_color(g_data.passes.bone_wire, sh_cfg);
}
float head[3], tail[3];
mul_v3_m4v3(head, g_data.ob->obmat, bone_mat[3]);
- DRW_shgroup_call_dynamic_add(g_data.bone_wire, head, color);
+ DRW_buffer_add_entry(g_data.bone_wire, head, color);
add_v3_v3v3(tail, bone_mat[3], bone_mat[1]);
mul_m4_v3(g_data.ob->obmat, tail);
- DRW_shgroup_call_dynamic_add(g_data.bone_wire, tail, color);
+ DRW_buffer_add_entry(g_data.bone_wire, tail, color);
}
/* Stick */
@@ -192,12 +193,12 @@ static void drw_shgroup_bone_stick(const float (*bone_mat)[4],
const eGPUShaderConfig sh_cfg)
{
if (g_data.bone_stick == NULL) {
- g_data.bone_stick = shgroup_instance_bone_stick(g_data.passes.bone_wire, sh_cfg);
+ g_data.bone_stick = buffer_instance_bone_stick(g_data.passes.bone_wire, sh_cfg);
}
float final_bonemat[4][4], tail[4];
mul_m4_m4m4(final_bonemat, g_data.ob->obmat, bone_mat);
add_v3_v3v3(tail, final_bonemat[3], final_bonemat[1]);
- DRW_shgroup_call_dynamic_add(
+ DRW_buffer_add_entry(
g_data.bone_stick, final_bonemat[3], tail, col_wire, col_bone, col_head, col_tail);
}
@@ -210,7 +211,7 @@ static void drw_shgroup_bone_envelope_distance(const float (*bone_mat)[4],
{
if (g_data.passes.bone_envelope != NULL) {
if (g_data.bone_envelope_distance == NULL) {
- g_data.bone_envelope_distance = shgroup_instance_bone_envelope_distance(
+ g_data.bone_envelope_distance = buffer_instance_bone_envelope_distance(
g_data.passes.bone_envelope, sh_cfg);
/* passes.bone_envelope should have the DRW_STATE_CULL_FRONT state enabled. */
}
@@ -225,7 +226,7 @@ static void drw_shgroup_bone_envelope_distance(const float (*bone_mat)[4],
head_sphere[3] += *distance;
tail_sphere[3] = *radius_tail;
tail_sphere[3] += *distance;
- DRW_shgroup_call_dynamic_add(
+ DRW_buffer_add_entry(
g_data.bone_envelope_distance, head_sphere, tail_sphere, final_bonemat[0]);
}
}
@@ -239,22 +240,19 @@ static void drw_shgroup_bone_envelope(const float (*bone_mat)[4],
const eGPUShaderConfig sh_cfg)
{
if (g_data.bone_point_wire == NULL) {
- g_data.bone_point_wire = shgroup_instance_bone_sphere_outline(g_data.passes.bone_wire, sh_cfg);
+ g_data.bone_point_wire = buffer_instance_bone_sphere_outline(g_data.passes.bone_wire, sh_cfg);
}
if (g_data.bone_point_solid == NULL && g_data.passes.bone_solid != NULL) {
- g_data.bone_point_solid = shgroup_instance_bone_sphere_solid(
+ g_data.bone_point_solid = buffer_instance_bone_sphere_solid(
g_data.passes.bone_solid, g_data.transparent, sh_cfg);
}
if (g_data.bone_envelope_wire == NULL) {
- g_data.bone_envelope_wire = shgroup_instance_bone_envelope_outline(g_data.passes.bone_wire,
- sh_cfg);
+ g_data.bone_envelope_wire = buffer_instance_bone_envelope_outline(g_data.passes.bone_wire,
+ sh_cfg);
}
if (g_data.bone_envelope_solid == NULL && g_data.passes.bone_solid != NULL) {
- g_data.bone_envelope_solid = shgroup_instance_bone_envelope_solid(
+ g_data.bone_envelope_solid = buffer_instance_bone_envelope_solid(
g_data.passes.bone_solid, g_data.transparent, sh_cfg);
- /* We can have a lot of overdraw if we don't do this. Also envelope are not subject to
- * inverted matrix. */
- DRW_shgroup_state_enable(g_data.bone_envelope_solid, DRW_STATE_CULL_BACK);
}
float head_sphere[4] = {0.0f, 0.0f, 0.0f, 1.0f}, tail_sphere[4] = {0.0f, 1.0f, 0.0f, 1.0f};
@@ -272,10 +270,10 @@ static void drw_shgroup_bone_envelope(const float (*bone_mat)[4],
tmp[3][3] = 1.0f;
copy_v3_v3(tmp[3], tail_sphere);
if (g_data.bone_point_solid != NULL) {
- DRW_shgroup_call_dynamic_add(g_data.bone_point_solid, tmp, bone_color, hint_color);
+ DRW_buffer_add_entry(g_data.bone_point_solid, tmp, bone_color, hint_color);
}
if (outline_color[3] > 0.0f) {
- DRW_shgroup_call_dynamic_add(g_data.bone_point_wire, tmp, outline_color);
+ DRW_buffer_add_entry(g_data.bone_point_wire, tmp, outline_color);
}
}
else if (tail_sphere[3] < 0.0f) {
@@ -285,10 +283,10 @@ static void drw_shgroup_bone_envelope(const float (*bone_mat)[4],
tmp[3][3] = 1.0f;
copy_v3_v3(tmp[3], head_sphere);
if (g_data.bone_point_solid != NULL) {
- DRW_shgroup_call_dynamic_add(g_data.bone_point_solid, tmp, bone_color, hint_color);
+ DRW_buffer_add_entry(g_data.bone_point_solid, tmp, bone_color, hint_color);
}
if (outline_color[3] > 0.0f) {
- DRW_shgroup_call_dynamic_add(g_data.bone_point_wire, tmp, outline_color);
+ DRW_buffer_add_entry(g_data.bone_point_wire, tmp, outline_color);
}
}
else {
@@ -305,15 +303,15 @@ static void drw_shgroup_bone_envelope(const float (*bone_mat)[4],
interp_v4_v4v4(head_sphere, tail_sphere, head_sphere, fac_head);
interp_v4_v4v4(tail_sphere, tmp_sphere, tail_sphere, fac_tail);
if (g_data.bone_envelope_solid != NULL) {
- DRW_shgroup_call_dynamic_add(g_data.bone_envelope_solid,
- head_sphere,
- tail_sphere,
- bone_color,
- hint_color,
- final_bonemat[0]);
+ DRW_buffer_add_entry(g_data.bone_envelope_solid,
+ head_sphere,
+ tail_sphere,
+ bone_color,
+ hint_color,
+ final_bonemat[0]);
}
if (outline_color[3] > 0.0f) {
- DRW_shgroup_call_dynamic_add(
+ DRW_buffer_add_entry(
g_data.bone_envelope_wire, head_sphere, tail_sphere, outline_color, final_bonemat[0]);
}
}
@@ -325,10 +323,10 @@ static void drw_shgroup_bone_envelope(const float (*bone_mat)[4],
tmp[3][3] = 1.0f;
copy_v3_v3(tmp[3], tmp_sphere);
if (g_data.bone_point_solid != NULL) {
- DRW_shgroup_call_dynamic_add(g_data.bone_point_solid, tmp, bone_color, hint_color);
+ DRW_buffer_add_entry(g_data.bone_point_solid, tmp, bone_color, hint_color);
}
if (outline_color[3] > 0.0f) {
- DRW_shgroup_call_dynamic_add(g_data.bone_point_wire, tmp, outline_color);
+ DRW_buffer_add_entry(g_data.bone_point_wire, tmp, outline_color);
}
}
}
@@ -336,6 +334,7 @@ static void drw_shgroup_bone_envelope(const float (*bone_mat)[4],
/* Custom (geometry) */
+extern void drw_batch_cache_validate(Object *custom);
extern void drw_batch_cache_generate_requested(Object *custom);
static void drw_shgroup_bone_custom_solid(const float (*bone_mat)[4],
@@ -345,6 +344,10 @@ static void drw_shgroup_bone_custom_solid(const float (*bone_mat)[4],
const eGPUShaderConfig sh_cfg,
Object *custom)
{
+ /* TODO(fclem) arg... less than ideal but we never iter on this object
+ * to assure batch cache is valid. */
+ drw_batch_cache_validate(custom);
+
struct GPUBatch *surf = DRW_cache_object_surface_get(custom);
struct GPUBatch *edges = DRW_cache_object_edge_detection_get(custom, NULL);
struct GPUBatch *ledges = DRW_cache_object_loose_edges_get(custom);
@@ -357,50 +360,50 @@ static void drw_shgroup_bone_custom_solid(const float (*bone_mat)[4],
BLI_assert(g_data.passes.custom_shapes != NULL);
if (surf && g_data.passes.bone_solid != NULL) {
- DRWShadingGroup *shgrp_geom_solid = BLI_ghash_lookup(g_data.passes.custom_shapes, surf);
+ DRWCallBuffer *buf_geom_solid = BLI_ghash_lookup(g_data.passes.custom_shapes, surf);
- if (shgrp_geom_solid == NULL) {
+ if (buf_geom_solid == NULL) {
/* TODO(fclem) needs to be moved elsewhere. */
drw_batch_cache_generate_requested(custom);
/* NOTE! g_data.transparent require a separate shading group if the
* object is transparent. This is done by passing a different ghash
* for transparent armature in pose mode. */
- shgrp_geom_solid = shgroup_instance_bone_shape_solid(
+ buf_geom_solid = buffer_instance_bone_shape_solid(
g_data.passes.bone_solid, surf, g_data.transparent, sh_cfg);
- BLI_ghash_insert(g_data.passes.custom_shapes, surf, shgrp_geom_solid);
+ BLI_ghash_insert(g_data.passes.custom_shapes, surf, buf_geom_solid);
}
- DRW_shgroup_call_dynamic_add(shgrp_geom_solid, final_bonemat, bone_color, hint_color);
+ DRW_buffer_add_entry(buf_geom_solid, final_bonemat, bone_color, hint_color);
}
if (edges && outline_color[3] > 0.0f) {
- DRWShadingGroup *shgrp_geom_wire = BLI_ghash_lookup(g_data.passes.custom_shapes, edges);
+ DRWCallBuffer *buf_geom_wire = BLI_ghash_lookup(g_data.passes.custom_shapes, edges);
- if (shgrp_geom_wire == NULL) {
+ if (buf_geom_wire == NULL) {
/* TODO(fclem) needs to be moved elsewhere. */
drw_batch_cache_generate_requested(custom);
- shgrp_geom_wire = shgroup_instance_bone_shape_outline(
+ buf_geom_wire = buffer_instance_bone_shape_outline(
g_data.passes.bone_outline, edges, sh_cfg);
- BLI_ghash_insert(g_data.passes.custom_shapes, edges, shgrp_geom_wire);
+ BLI_ghash_insert(g_data.passes.custom_shapes, edges, buf_geom_wire);
}
- DRW_shgroup_call_dynamic_add(shgrp_geom_wire, final_bonemat, outline_color);
+ DRW_buffer_add_entry(buf_geom_wire, final_bonemat, outline_color);
}
if (ledges) {
- DRWShadingGroup *shgrp_geom_ledges = BLI_ghash_lookup(g_data.passes.custom_shapes, ledges);
+ DRWCallBuffer *buf_geom_ledges = BLI_ghash_lookup(g_data.passes.custom_shapes, ledges);
- if (shgrp_geom_ledges == NULL) {
+ if (buf_geom_ledges == NULL) {
/* TODO(fclem) needs to be moved elsewhere. */
drw_batch_cache_generate_requested(custom);
- shgrp_geom_ledges = shgroup_instance_wire(g_data.passes.bone_wire, ledges);
+ buf_geom_ledges = buffer_instance_wire(g_data.passes.bone_wire, ledges);
- BLI_ghash_insert(g_data.passes.custom_shapes, ledges, shgrp_geom_ledges);
+ BLI_ghash_insert(g_data.passes.custom_shapes, ledges, buf_geom_ledges);
}
float final_color[4] = {outline_color[0], outline_color[1], outline_color[2], 1.0f};
- DRW_shgroup_call_dynamic_add(shgrp_geom_ledges, final_bonemat, final_color);
+ DRW_buffer_add_entry(buf_geom_ledges, final_bonemat, final_color);
}
}
@@ -408,23 +411,27 @@ static void drw_shgroup_bone_custom_wire(const float (*bone_mat)[4],
const float color[4],
Object *custom)
{
+ /* TODO(fclem) arg... less than ideal but we never iter on this object
+ * to assure batch cache is valid. */
+ drw_batch_cache_validate(custom);
+
struct GPUBatch *geom = DRW_cache_object_all_edges_get(custom);
if (geom) {
- DRWShadingGroup *shgrp_geom_wire = BLI_ghash_lookup(g_data.passes.custom_shapes, geom);
+ DRWCallBuffer *buf_geom_wire = BLI_ghash_lookup(g_data.passes.custom_shapes, geom);
- if (shgrp_geom_wire == NULL) {
+ if (buf_geom_wire == NULL) {
/* TODO(fclem) needs to be moved elsewhere. */
drw_batch_cache_generate_requested(custom);
- shgrp_geom_wire = shgroup_instance_wire(g_data.passes.bone_wire, geom);
+ buf_geom_wire = buffer_instance_wire(g_data.passes.bone_wire, geom);
- BLI_ghash_insert(g_data.passes.custom_shapes, geom, shgrp_geom_wire);
+ BLI_ghash_insert(g_data.passes.custom_shapes, geom, buf_geom_wire);
}
float final_color[4] = {color[0], color[1], color[2], 1.0f};
float final_bonemat[4][4];
mul_m4_m4m4(final_bonemat, g_data.ob->obmat, bone_mat);
- DRW_shgroup_call_dynamic_add(shgrp_geom_wire, final_bonemat, final_color);
+ DRW_buffer_add_entry(buf_geom_wire, final_bonemat, final_color);
}
}
@@ -436,19 +443,19 @@ static void drw_shgroup_bone_point(const float (*bone_mat)[4],
const eGPUShaderConfig sh_cfg)
{
if (g_data.bone_point_wire == NULL) {
- g_data.bone_point_wire = shgroup_instance_bone_sphere_outline(g_data.passes.bone_wire, sh_cfg);
+ g_data.bone_point_wire = buffer_instance_bone_sphere_outline(g_data.passes.bone_wire, sh_cfg);
}
if (g_data.bone_point_solid == NULL && g_data.passes.bone_solid != NULL) {
- g_data.bone_point_solid = shgroup_instance_bone_sphere_solid(
+ g_data.bone_point_solid = buffer_instance_bone_sphere_solid(
g_data.passes.bone_solid, g_data.transparent, sh_cfg);
}
float final_bonemat[4][4];
mul_m4_m4m4(final_bonemat, g_data.ob->obmat, bone_mat);
if (g_data.bone_point_solid != NULL) {
- DRW_shgroup_call_dynamic_add(g_data.bone_point_solid, final_bonemat, bone_color, hint_color);
+ DRW_buffer_add_entry(g_data.bone_point_solid, final_bonemat, bone_color, hint_color);
}
if (outline_color[3] > 0.0f) {
- DRW_shgroup_call_dynamic_add(g_data.bone_point_wire, final_bonemat, outline_color);
+ DRW_buffer_add_entry(g_data.bone_point_wire, final_bonemat, outline_color);
}
}
@@ -458,11 +465,11 @@ static void drw_shgroup_bone_axes(const float (*bone_mat)[4],
const eGPUShaderConfig sh_cfg)
{
if (g_data.bone_axes == NULL) {
- g_data.bone_axes = shgroup_instance_bone_axes(g_data.passes.bone_axes, sh_cfg);
+ g_data.bone_axes = buffer_instance_bone_axes(g_data.passes.bone_axes, sh_cfg);
}
float final_bonemat[4][4];
mul_m4_m4m4(final_bonemat, g_data.ob->obmat, bone_mat);
- DRW_shgroup_call_dynamic_add(g_data.bone_axes, final_bonemat, color);
+ DRW_buffer_add_entry(g_data.bone_axes, final_bonemat, color);
}
/* Relationship lines */
@@ -471,15 +478,15 @@ static void drw_shgroup_bone_relationship_lines(const float start[3],
const eGPUShaderConfig sh_cfg)
{
if (g_data.lines_relationship == NULL) {
- g_data.lines_relationship = shgroup_dynlines_dashed_uniform_color(
+ g_data.lines_relationship = buffer_dynlines_dashed_uniform_color(
g_data.passes.relationship_lines, g_theme.wire_color, sh_cfg);
}
/* reverse order to have less stipple overlap */
float v[3];
mul_v3_m4v3(v, g_data.ob->obmat, end);
- DRW_shgroup_call_dynamic_add(g_data.lines_relationship, v);
+ DRW_buffer_add_entry(g_data.lines_relationship, v);
mul_v3_m4v3(v, g_data.ob->obmat, start);
- DRW_shgroup_call_dynamic_add(g_data.lines_relationship, v);
+ DRW_buffer_add_entry(g_data.lines_relationship, v);
}
static void drw_shgroup_bone_ik_lines(const float start[3],
@@ -488,15 +495,15 @@ static void drw_shgroup_bone_ik_lines(const float start[3],
{
if (g_data.lines_ik == NULL) {
static float fcolor[4] = {0.8f, 0.5f, 0.0f, 1.0f}; /* add theme! */
- g_data.lines_ik = shgroup_dynlines_dashed_uniform_color(
+ g_data.lines_ik = buffer_dynlines_dashed_uniform_color(
g_data.passes.relationship_lines, fcolor, sh_cfg);
}
/* reverse order to have less stipple overlap */
float v[3];
mul_v3_m4v3(v, g_data.ob->obmat, end);
- DRW_shgroup_call_dynamic_add(g_data.lines_ik, v);
+ DRW_buffer_add_entry(g_data.lines_ik, v);
mul_v3_m4v3(v, g_data.ob->obmat, start);
- DRW_shgroup_call_dynamic_add(g_data.lines_ik, v);
+ DRW_buffer_add_entry(g_data.lines_ik, v);
}
static void drw_shgroup_bone_ik_no_target_lines(const float start[3],
@@ -505,15 +512,15 @@ static void drw_shgroup_bone_ik_no_target_lines(const float start[3],
{
if (g_data.lines_ik_no_target == NULL) {
static float fcolor[4] = {0.8f, 0.8f, 0.2f, 1.0f}; /* add theme! */
- g_data.lines_ik_no_target = shgroup_dynlines_dashed_uniform_color(
+ g_data.lines_ik_no_target = buffer_dynlines_dashed_uniform_color(
g_data.passes.relationship_lines, fcolor, sh_cfg);
}
/* reverse order to have less stipple overlap */
float v[3];
mul_v3_m4v3(v, g_data.ob->obmat, end);
- DRW_shgroup_call_dynamic_add(g_data.lines_ik_no_target, v);
+ DRW_buffer_add_entry(g_data.lines_ik_no_target, v);
mul_v3_m4v3(v, g_data.ob->obmat, start);
- DRW_shgroup_call_dynamic_add(g_data.lines_ik_no_target, v);
+ DRW_buffer_add_entry(g_data.lines_ik_no_target, v);
}
static void drw_shgroup_bone_ik_spline_lines(const float start[3],
@@ -522,15 +529,15 @@ static void drw_shgroup_bone_ik_spline_lines(const float start[3],
{
if (g_data.lines_ik_spline == NULL) {
static float fcolor[4] = {0.8f, 0.8f, 0.2f, 1.0f}; /* add theme! */
- g_data.lines_ik_spline = shgroup_dynlines_dashed_uniform_color(
+ g_data.lines_ik_spline = buffer_dynlines_dashed_uniform_color(
g_data.passes.relationship_lines, fcolor, sh_cfg);
}
/* reverse order to have less stipple overlap */
float v[3];
mul_v3_m4v3(v, g_data.ob->obmat, end);
- DRW_shgroup_call_dynamic_add(g_data.lines_ik_spline, v);
+ DRW_buffer_add_entry(g_data.lines_ik_spline, v);
mul_v3_m4v3(v, g_data.ob->obmat, start);
- DRW_shgroup_call_dynamic_add(g_data.lines_ik_spline, v);
+ DRW_buffer_add_entry(g_data.lines_ik_spline, v);
}
/** \} */
@@ -1634,12 +1641,10 @@ static void draw_bone_dofs(bPoseChannel *pchan)
}
if (g_data.bone_dof_sphere == NULL) {
- g_data.bone_dof_lines = shgroup_instance_bone_dof(g_data.passes.bone_wire,
- DRW_cache_bone_dof_lines_get());
- g_data.bone_dof_sphere = shgroup_instance_bone_dof(g_data.passes.bone_envelope,
- DRW_cache_bone_dof_sphere_get());
- DRW_shgroup_state_enable(g_data.bone_dof_sphere, DRW_STATE_BLEND);
- DRW_shgroup_state_disable(g_data.bone_dof_sphere, DRW_STATE_CULL_FRONT);
+ g_data.bone_dof_lines = buffer_instance_bone_dof(
+ g_data.passes.bone_wire, DRW_cache_bone_dof_lines_get(), false);
+ g_data.bone_dof_sphere = buffer_instance_bone_dof(
+ g_data.passes.bone_envelope, DRW_cache_bone_dof_sphere_get(), true);
}
/* *0.5f here comes from M_PI/360.0f when rotations were still in degrees */
@@ -1672,20 +1677,20 @@ static void draw_bone_dofs(bPoseChannel *pchan)
amax[0] = xminmax[1];
amin[1] = zminmax[0];
amax[1] = zminmax[1];
- DRW_shgroup_call_dynamic_add(g_data.bone_dof_sphere, final_bonemat, col_sphere, amin, amax);
- DRW_shgroup_call_dynamic_add(g_data.bone_dof_lines, final_bonemat, col_lines, amin, amax);
+ DRW_buffer_add_entry(g_data.bone_dof_sphere, final_bonemat, col_sphere, amin, amax);
+ DRW_buffer_add_entry(g_data.bone_dof_lines, final_bonemat, col_lines, amin, amax);
}
if (pchan->ikflag & BONE_IK_XLIMIT) {
amin[0] = xminmax[0];
amax[0] = xminmax[1];
amin[1] = amax[1] = 0.0f;
- DRW_shgroup_call_dynamic_add(g_data.bone_dof_lines, final_bonemat, col_xaxis, amin, amax);
+ DRW_buffer_add_entry(g_data.bone_dof_lines, final_bonemat, col_xaxis, amin, amax);
}
if (pchan->ikflag & BONE_IK_ZLIMIT) {
amin[1] = zminmax[0];
amax[1] = zminmax[1];
amin[0] = amax[0] = 0.0f;
- DRW_shgroup_call_dynamic_add(g_data.bone_dof_lines, final_bonemat, col_zaxis, amin, amax);
+ DRW_buffer_add_entry(g_data.bone_dof_lines, final_bonemat, col_zaxis, amin, amax);
}
}
@@ -1839,7 +1844,9 @@ static void draw_armature_edit(Object *ob)
const bool show_text = DRW_state_show_text();
const bool show_relations = ((draw_ctx->v3d->flag & V3D_HIDE_HELPLINES) == 0);
- for (eBone = arm->edbo->first, index = ob->select_id; eBone;
+ const Object *orig_object = DEG_get_original_object(ob);
+
+ for (eBone = arm->edbo->first, index = orig_object->runtime.select_id; eBone;
eBone = eBone->next, index += 0x10000) {
if (eBone->layer & arm->layer) {
if ((eBone->flag & BONE_HIDDEN_A) == 0) {
@@ -1934,7 +1941,8 @@ static void draw_armature_pose(Object *ob, const float const_color[4])
}
if (arm->flag & ARM_POSEMODE) {
- index = ob->select_id;
+ const Object *orig_object = DEG_get_original_object(ob);
+ index = orig_object->runtime.select_id;
}
}
diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c
index 08cf56982ea..c40e9772340 100644
--- a/source/blender/draw/intern/draw_cache.c
+++ b/source/blender/draw/intern/draw_cache.c
@@ -46,6 +46,9 @@
/* Batch's only (free'd as an array) */
static struct DRWShapeCache {
+ GPUBatch *drw_procedural_verts;
+ GPUBatch *drw_procedural_lines;
+ GPUBatch *drw_procedural_tris;
GPUBatch *drw_single_vertice;
GPUBatch *drw_cursor;
GPUBatch *drw_cursor_only_circle;
@@ -138,6 +141,54 @@ void DRW_shape_cache_reset(void)
}
/* -------------------------------------------------------------------- */
+/** \name Procedural Batches
+ * \{ */
+
+GPUBatch *drw_cache_procedural_points_get(void)
+{
+ if (!SHC.drw_procedural_verts) {
+ /* TODO(fclem) get rid of this dummy VBO. */
+ GPUVertFormat format = {0};
+ GPU_vertformat_attr_add(&format, "dummy", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
+ GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
+ GPU_vertbuf_data_alloc(vbo, 1);
+
+ SHC.drw_procedural_verts = GPU_batch_create_ex(GPU_PRIM_POINTS, vbo, NULL, GPU_BATCH_OWNS_VBO);
+ }
+ return SHC.drw_procedural_verts;
+}
+
+GPUBatch *drw_cache_procedural_lines_get(void)
+{
+ if (!SHC.drw_procedural_lines) {
+ /* TODO(fclem) get rid of this dummy VBO. */
+ GPUVertFormat format = {0};
+ GPU_vertformat_attr_add(&format, "dummy", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
+ GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
+ GPU_vertbuf_data_alloc(vbo, 1);
+
+ SHC.drw_procedural_lines = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO);
+ }
+ return SHC.drw_procedural_lines;
+}
+
+GPUBatch *drw_cache_procedural_triangles_get(void)
+{
+ if (!SHC.drw_procedural_tris) {
+ /* TODO(fclem) get rid of this dummy VBO. */
+ GPUVertFormat format = {0};
+ GPU_vertformat_attr_add(&format, "dummy", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
+ GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
+ GPU_vertbuf_data_alloc(vbo, 1);
+
+ SHC.drw_procedural_tris = GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, NULL, GPU_BATCH_OWNS_VBO);
+ }
+ return SHC.drw_procedural_tris;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Helper functions
* \{ */
@@ -3953,68 +4004,32 @@ GPUBatch *DRW_cache_cursor_get(bool crosshair_lines)
/** \name Batch Cache Impl. common
* \{ */
-GPUBatch *DRW_batch_request(GPUBatch **batch)
+void drw_batch_cache_validate(Object *ob)
{
- /* XXX TODO(fclem): We are writting to batch cache here. Need to make this thread safe. */
- if (*batch == NULL) {
- *batch = MEM_callocN(sizeof(GPUBatch), "GPUBatch");
- }
- return *batch;
-}
-
-bool DRW_batch_requested(GPUBatch *batch, int prim_type)
-{
- /* Batch has been requested if it has been created but not initialized. */
- if (batch != NULL && batch->verts[0] == NULL) {
- /* HACK. We init without a valid VBO and let the first vbo binding
- * fill verts[0]. */
- GPU_batch_init_ex(batch, prim_type, (GPUVertBuf *)1, NULL, 0);
- batch->verts[0] = NULL;
- return true;
- }
- return false;
-}
-
-void DRW_ibo_request(GPUBatch *batch, GPUIndexBuf **ibo)
-{
- if (*ibo == NULL) {
- *ibo = MEM_callocN(sizeof(GPUIndexBuf), "GPUIndexBuf");
- }
- GPU_batch_vao_cache_clear(batch);
- batch->elem = *ibo;
-}
-
-bool DRW_ibo_requested(GPUIndexBuf *ibo)
-{
- /* TODO do not rely on data uploaded. This prevents multithreading.
- * (need access to a gl context) */
- return (ibo != NULL && ibo->ibo_id == 0 && ibo->data == NULL);
-}
-
-void DRW_vbo_request(GPUBatch *batch, GPUVertBuf **vbo)
-{
- if (*vbo == NULL) {
- *vbo = MEM_callocN(sizeof(GPUVertBuf), "GPUVertBuf");
- }
- /* HACK set first vbo if not init. */
- if (batch->verts[0] == NULL) {
- GPU_batch_vao_cache_clear(batch);
- batch->verts[0] = *vbo;
- }
- else {
- /* HACK: bypass assert */
- int vbo_vert_len = (*vbo)->vertex_len;
- (*vbo)->vertex_len = batch->verts[0]->vertex_len;
- GPU_batch_vertbuf_add(batch, *vbo);
- (*vbo)->vertex_len = vbo_vert_len;
+ struct Mesh *mesh_eval = ob->runtime.mesh_eval;
+ switch (ob->type) {
+ case OB_MESH:
+ DRW_mesh_batch_cache_validate((Mesh *)ob->data);
+ break;
+ case OB_CURVE:
+ case OB_FONT:
+ case OB_SURF:
+ if (mesh_eval != NULL) {
+ DRW_mesh_batch_cache_validate(mesh_eval);
+ }
+ DRW_curve_batch_cache_validate((Curve *)ob->data);
+ break;
+ case OB_MBALL:
+ DRW_mball_batch_cache_validate((MetaBall *)ob->data);
+ break;
+ case OB_LATTICE:
+ DRW_lattice_batch_cache_validate((Lattice *)ob->data);
+ break;
+ default:
+ break;
}
}
-bool DRW_vbo_requested(GPUVertBuf *vbo)
-{
- return (vbo != NULL && vbo->format.attr_len == 0);
-}
-
void drw_batch_cache_generate_requested(Object *ob)
{
const DRWContextState *draw_ctx = DRW_context_state_get();
diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h
index 508ae678778..4dc58972ce6 100644
--- a/source/blender/draw/intern/draw_cache_impl.h
+++ b/source/blender/draw/intern/draw_cache_impl.h
@@ -44,15 +44,19 @@ struct bGPdata;
/* Expose via BKE callbacks */
void DRW_mball_batch_cache_dirty_tag(struct MetaBall *mb, int mode);
+void DRW_mball_batch_cache_validate(struct MetaBall *mb);
void DRW_mball_batch_cache_free(struct MetaBall *mb);
void DRW_curve_batch_cache_dirty_tag(struct Curve *cu, int mode);
+void DRW_curve_batch_cache_validate(struct Curve *cu);
void DRW_curve_batch_cache_free(struct Curve *cu);
void DRW_mesh_batch_cache_dirty_tag(struct Mesh *me, int mode);
+void DRW_mesh_batch_cache_validate(struct Mesh *me);
void DRW_mesh_batch_cache_free(struct Mesh *me);
void DRW_lattice_batch_cache_dirty_tag(struct Lattice *lt, int mode);
+void DRW_lattice_batch_cache_validate(struct Lattice *lt);
void DRW_lattice_batch_cache_free(struct Lattice *lt);
void DRW_particle_batch_cache_dirty_tag(struct ParticleSystem *psys, int mode);
@@ -202,30 +206,4 @@ struct GPUBatch *DRW_particles_batch_cache_get_edit_tip_points(struct Object *ob
struct ParticleSystem *psys,
struct PTCacheEdit *edit);
-/* Common */
-// #define DRW_DEBUG_MESH_CACHE_REQUEST
-
-#ifdef DRW_DEBUG_MESH_CACHE_REQUEST
-# define DRW_ADD_FLAG_FROM_VBO_REQUEST(flag, vbo, value) \
- (flag |= DRW_vbo_requested(vbo) ? (printf(" VBO requested " #vbo "\n") ? value : value) : 0)
-# define DRW_ADD_FLAG_FROM_IBO_REQUEST(flag, ibo, value) \
- (flag |= DRW_ibo_requested(ibo) ? (printf(" IBO requested " #ibo "\n") ? value : value) : 0)
-#else
-# define DRW_ADD_FLAG_FROM_VBO_REQUEST(flag, vbo, value) \
- (flag |= DRW_vbo_requested(vbo) ? (value) : 0)
-# define DRW_ADD_FLAG_FROM_IBO_REQUEST(flag, ibo, value) \
- (flag |= DRW_ibo_requested(ibo) ? (value) : 0)
-#endif
-
-/* Test and assign NULL if test fails */
-#define DRW_TEST_ASSIGN_VBO(v) (v = (DRW_vbo_requested(v) ? (v) : NULL))
-#define DRW_TEST_ASSIGN_IBO(v) (v = (DRW_ibo_requested(v) ? (v) : NULL))
-
-struct GPUBatch *DRW_batch_request(struct GPUBatch **batch);
-bool DRW_batch_requested(struct GPUBatch *batch, int prim_type);
-void DRW_ibo_request(struct GPUBatch *batch, struct GPUIndexBuf **ibo);
-bool DRW_ibo_requested(struct GPUIndexBuf *ibo);
-void DRW_vbo_request(struct GPUBatch *batch, struct GPUVertBuf **vbo);
-bool DRW_vbo_requested(struct GPUVertBuf *vbo);
-
#endif /* __DRAW_CACHE_IMPL_H__ */
diff --git a/source/blender/draw/intern/draw_cache_impl_curve.c b/source/blender/draw/intern/draw_cache_impl_curve.c
index 33b872109a5..663fbf647a6 100644
--- a/source/blender/draw/intern/draw_cache_impl_curve.c
+++ b/source/blender/draw/intern/draw_cache_impl_curve.c
@@ -42,6 +42,8 @@
#include "DRW_render.h"
+#include "draw_cache_inline.h"
+
#include "draw_cache_impl.h" /* own include */
#define SELECT 1
@@ -472,12 +474,16 @@ static void curve_batch_cache_init(Curve *cu)
cache->is_dirty = false;
}
-static CurveBatchCache *curve_batch_cache_get(Curve *cu)
+void DRW_curve_batch_cache_validate(Curve *cu)
{
if (!curve_batch_cache_valid(cu)) {
curve_batch_cache_clear(cu);
curve_batch_cache_init(cu);
}
+}
+
+static CurveBatchCache *curve_batch_cache_get(Curve *cu)
+{
return cu->batch_cache;
}
diff --git a/source/blender/draw/intern/draw_cache_impl_displist.c b/source/blender/draw/intern/draw_cache_impl_displist.c
index ea394359b05..d1c214c2aa6 100644
--- a/source/blender/draw/intern/draw_cache_impl_displist.c
+++ b/source/blender/draw/intern/draw_cache_impl_displist.c
@@ -37,6 +37,8 @@
#include "GPU_batch.h"
#include "GPU_extensions.h"
+#include "draw_cache_inline.h"
+
#include "draw_cache_impl.h" /* own include */
static int dl_vert_len(const DispList *dl)
@@ -402,7 +404,6 @@ void DRW_displist_vertbuf_create_loop_pos_and_nor_and_uv(ListBase *lb,
&format_pos_nor, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
attr_id.nor = GPU_vertformat_attr_add(
&format_pos_nor, "nor", GPU_COMP_I10, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
- GPU_vertformat_triple_load(&format_pos_nor);
/* UVs are in [0..1] range. We can compress them. */
attr_id.uv = GPU_vertformat_attr_add(
&format_uv, "u", GPU_COMP_I16, 2, GPU_FETCH_INT_TO_FLOAT_UNIT);
diff --git a/source/blender/draw/intern/draw_cache_impl_lattice.c b/source/blender/draw/intern/draw_cache_impl_lattice.c
index b5223bc047c..8b3864684b5 100644
--- a/source/blender/draw/intern/draw_cache_impl_lattice.c
+++ b/source/blender/draw/intern/draw_cache_impl_lattice.c
@@ -340,12 +340,16 @@ static void lattice_batch_cache_init(Lattice *lt)
cache->is_dirty = false;
}
-static LatticeBatchCache *lattice_batch_cache_get(Lattice *lt)
+void DRW_lattice_batch_cache_validate(Lattice *lt)
{
if (!lattice_batch_cache_valid(lt)) {
lattice_batch_cache_clear(lt);
lattice_batch_cache_init(lt);
}
+}
+
+static LatticeBatchCache *lattice_batch_cache_get(Lattice *lt)
+{
return lt->batch_cache;
}
diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c
index f3b7e7adff0..eb626e2f954 100644
--- a/source/blender/draw/intern/draw_cache_impl_mesh.c
+++ b/source/blender/draw/intern/draw_cache_impl_mesh.c
@@ -61,6 +61,8 @@
#include "ED_mesh.h"
#include "ED_uvedit.h"
+#include "draw_cache_inline.h"
+
#include "draw_cache_impl.h" /* own include */
static void mesh_batch_cache_clear(Mesh *me);
@@ -421,13 +423,13 @@ static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Mesh *me,
const CustomData *cd_ldata = (me->edit_mesh) ? &me->edit_mesh->bm->ldata : &me->ldata;
/* See: DM_vertex_attributes_from_gpu for similar logic */
- GPUVertAttrLayers gpu_attrs = {{{0}}};
DRW_MeshCDMask cd_used;
mesh_cd_layers_type_clear(&cd_used);
for (int i = 0; i < gpumat_array_len; i++) {
GPUMaterial *gpumat = gpumat_array[i];
if (gpumat) {
+ GPUVertAttrLayers gpu_attrs;
GPU_material_vertex_attrs(gpumat, &gpu_attrs);
for (int j = 0; j < gpu_attrs.totlayer; j++) {
const char *name = gpu_attrs.layer[j].name;
@@ -1140,11 +1142,12 @@ static MeshRenderData *mesh_render_data_create_ex(Mesh *me,
rdata->cd.layers.tangent_len);
int i_dst = 0;
+ int act_tan = rdata->cd.layers.tangent_active;
for (int i_src = 0; i_src < cd_layers_src.uv_len; i_src++, i_dst++) {
if ((cd_used->tan & (1 << i_src)) == 0) {
i_dst--;
if (rdata->cd.layers.tangent_active >= i_src) {
- rdata->cd.layers.tangent_active--;
+ act_tan--;
}
}
else {
@@ -1168,6 +1171,11 @@ static MeshRenderData *mesh_render_data_create_ex(Mesh *me,
}
}
}
+ if (rdata->cd.layers.tangent_active != -1) {
+ /* Actual active UV slot inside uv layers used for shading. */
+ rdata->cd.layers.tangent_active = act_tan;
+ }
+
if (cd_used->tan_orco != 0) {
const char *name = CustomData_get_layer_name(&rdata->cd.output.ldata, CD_TANGENT, i_dst);
uint hash = BLI_ghashutil_strhash_p(name);
@@ -1892,6 +1900,39 @@ static void drw_mesh_weight_state_extract(Object *ob,
/** \name Mesh GPUBatch Cache
* \{ */
+typedef enum DRWBatchFlag {
+ MBC_SURFACE = (1 << 0),
+ MBC_SURFACE_WEIGHTS = (1 << 1),
+ MBC_EDIT_TRIANGLES = (1 << 2),
+ MBC_EDIT_VERTICES = (1 << 3),
+ MBC_EDIT_EDGES = (1 << 4),
+ MBC_EDIT_LNOR = (1 << 5),
+ MBC_EDIT_FACEDOTS = (1 << 6),
+ MBC_EDIT_MESH_ANALYSIS = (1 << 7),
+ MBC_EDITUV_FACES_STRECH_AREA = (1 << 8),
+ MBC_EDITUV_FACES_STRECH_ANGLE = (1 << 9),
+ MBC_EDITUV_FACES = (1 << 10),
+ MBC_EDITUV_EDGES = (1 << 11),
+ MBC_EDITUV_VERTS = (1 << 12),
+ MBC_EDITUV_FACEDOTS = (1 << 13),
+ MBC_EDIT_SELECTION_VERTS = (1 << 14),
+ MBC_EDIT_SELECTION_EDGES = (1 << 15),
+ MBC_EDIT_SELECTION_FACES = (1 << 16),
+ MBC_EDIT_SELECTION_FACEDOTS = (1 << 17),
+ MBC_ALL_VERTS = (1 << 18),
+ MBC_ALL_EDGES = (1 << 19),
+ MBC_LOOSE_EDGES = (1 << 20),
+ MBC_EDGE_DETECTION = (1 << 21),
+ MBC_WIRE_EDGES = (1 << 22),
+ MBC_WIRE_LOOPS = (1 << 23),
+ MBC_WIRE_LOOPS_UVS = (1 << 24),
+ MBC_SURF_PER_MAT = (1 << 25),
+} DRWBatchFlag;
+
+#define MBC_EDITUV \
+ (MBC_EDITUV_FACES_STRECH_AREA | MBC_EDITUV_FACES_STRECH_ANGLE | MBC_EDITUV_FACES | \
+ MBC_EDITUV_EDGES | MBC_EDITUV_VERTS | MBC_EDITUV_FACEDOTS)
+
typedef struct MeshBatchCache {
/* In order buffers: All verts only specified once
* or once per loop. To be used with a GPUIndexBuf. */
@@ -1997,14 +2038,16 @@ typedef struct MeshBatchCache {
int *auto_layer_is_srgb;
int auto_layer_len;
+ DRWBatchFlag batch_requested;
+ DRWBatchFlag batch_ready;
+
/* settings to determine if cache is invalid */
- bool is_maybe_dirty;
- bool is_dirty; /* Instantly invalidates cache, skipping mesh check */
int edge_len;
int tri_len;
int poly_len;
int vert_len;
int mat_len;
+ bool is_dirty; /* Instantly invalidates cache, skipping mesh check */
bool is_editmode;
bool is_uvsyncsel;
@@ -2014,13 +2057,15 @@ typedef struct MeshBatchCache {
int lastmatch;
- /* XXX, only keep for as long as sculpt mode uses shaded drawing. */
- bool is_sculpt_points_tag;
-
/* Valid only if edge_detection is up to date. */
bool is_manifold;
} MeshBatchCache;
+BLI_INLINE void mesh_batch_cache_add_request(MeshBatchCache *cache, DRWBatchFlag new_flag)
+{
+ atomic_fetch_and_or_uint32((uint32_t *)(&cache->batch_requested), *(uint32_t *)&new_flag);
+}
+
/* GPUBatch cache management. */
static bool mesh_batch_cache_valid(Mesh *me)
@@ -2031,10 +2076,6 @@ static bool mesh_batch_cache_valid(Mesh *me)
return false;
}
- if (cache->mat_len != mesh_render_mat_len_get(me)) {
- return false;
- }
-
if (cache->is_editmode != (me->edit_mesh != NULL)) {
return false;
}
@@ -2043,20 +2084,8 @@ static bool mesh_batch_cache_valid(Mesh *me)
return false;
}
- if (cache->is_maybe_dirty == false) {
- return true;
- }
- else {
- if (cache->is_editmode) {
- return false;
- }
- else if ((cache->vert_len != mesh_render_verts_len_get(me)) ||
- (cache->edge_len != mesh_render_edges_len_get(me)) ||
- (cache->tri_len != mesh_render_looptri_len_get(me)) ||
- (cache->poly_len != mesh_render_polys_len_get(me)) ||
- (cache->mat_len != mesh_render_mat_len_get(me))) {
- return false;
- }
+ if (cache->mat_len != mesh_render_mat_len_get(me)) {
+ return false;
}
return true;
@@ -2087,18 +2116,23 @@ static void mesh_batch_cache_init(Mesh *me)
__func__);
cache->surf_per_mat = MEM_callocN(sizeof(*cache->surf_per_mat) * cache->mat_len, __func__);
- cache->is_maybe_dirty = false;
cache->is_dirty = false;
+ cache->batch_ready = 0;
+ cache->batch_requested = 0;
drw_mesh_weight_state_clear(&cache->weight_state);
}
-static MeshBatchCache *mesh_batch_cache_get(Mesh *me)
+void DRW_mesh_batch_cache_validate(Mesh *me)
{
if (!mesh_batch_cache_valid(me)) {
mesh_batch_cache_clear(me);
mesh_batch_cache_init(me);
}
+}
+
+static MeshBatchCache *mesh_batch_cache_get(Mesh *me)
+{
return me->runtime.batch_cache;
}
@@ -2109,6 +2143,8 @@ static void mesh_batch_cache_check_vertex_group(MeshBatchCache *cache,
GPU_BATCH_CLEAR_SAFE(cache->batch.surface_weights);
GPU_VERTBUF_DISCARD_SAFE(cache->ordered.weights);
+ cache->batch_ready &= ~MBC_SURFACE_WEIGHTS;
+
drw_mesh_weight_state_clear(&cache->weight_state);
}
}
@@ -2133,6 +2169,8 @@ static void mesh_batch_cache_discard_shaded_tri(MeshBatchCache *cache)
}
MEM_SAFE_FREE(cache->surf_per_mat);
+ cache->batch_ready &= ~MBC_SURF_PER_MAT;
+
MEM_SAFE_FREE(cache->auto_layer_names);
MEM_SAFE_FREE(cache->auto_layer_is_srgb);
@@ -2158,6 +2196,8 @@ static void mesh_batch_cache_discard_uvedit(MeshBatchCache *cache)
GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_edges);
GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_verts);
GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_facedots);
+
+ cache->batch_ready &= ~MBC_EDITUV;
}
void DRW_mesh_batch_cache_dirty_tag(Mesh *me, int mode)
@@ -2167,9 +2207,6 @@ void DRW_mesh_batch_cache_dirty_tag(Mesh *me, int mode)
return;
}
switch (mode) {
- case BKE_MESH_BATCH_DIRTY_MAYBE_ALL:
- cache->is_maybe_dirty = true;
- break;
case BKE_MESH_BATCH_DIRTY_SELECT:
GPU_VERTBUF_DISCARD_SAFE(cache->edit.loop_data);
GPU_VERTBUF_DISCARD_SAFE(cache->edit.facedots_pos_nor_data);
@@ -2178,6 +2215,8 @@ void DRW_mesh_batch_cache_dirty_tag(Mesh *me, int mode)
GPU_BATCH_DISCARD_SAFE(cache->batch.edit_edges);
GPU_BATCH_DISCARD_SAFE(cache->batch.edit_facedots);
GPU_BATCH_DISCARD_SAFE(cache->batch.edit_mesh_analysis);
+ cache->batch_ready &= ~(MBC_EDIT_TRIANGLES | MBC_EDIT_VERTICES | MBC_EDIT_EDGES |
+ MBC_EDIT_FACEDOTS | MBC_EDIT_MESH_ANALYSIS);
/* Because visible UVs depends on edit mode selection, discard everything. */
mesh_batch_cache_discard_uvedit(cache);
break;
@@ -2192,6 +2231,7 @@ void DRW_mesh_batch_cache_dirty_tag(Mesh *me, int mode)
GPU_BATCH_DISCARD_SAFE(cache->surf_per_mat[i]);
}
}
+ cache->batch_ready &= ~(MBC_SURFACE | MBC_WIRE_LOOPS | MBC_SURF_PER_MAT);
break;
case BKE_MESH_BATCH_DIRTY_ALL:
cache->is_dirty = true;
@@ -2200,9 +2240,6 @@ void DRW_mesh_batch_cache_dirty_tag(Mesh *me, int mode)
mesh_batch_cache_discard_shaded_tri(cache);
mesh_batch_cache_discard_uvedit(cache);
break;
- case BKE_MESH_BATCH_DIRTY_SCULPT_COORDS:
- cache->is_sculpt_points_tag = true;
- break;
case BKE_MESH_BATCH_DIRTY_UVEDIT_ALL:
mesh_batch_cache_discard_uvedit(cache);
break;
@@ -2215,6 +2252,7 @@ void DRW_mesh_batch_cache_dirty_tag(Mesh *me, int mode)
GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_edges);
GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_verts);
GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_facedots);
+ cache->batch_ready &= ~MBC_EDITUV;
break;
default:
BLI_assert(0);
@@ -2249,6 +2287,8 @@ static void mesh_batch_cache_clear(Mesh *me)
mesh_batch_cache_discard_uvedit(cache);
+ cache->batch_ready = 0;
+
drw_mesh_weight_state_clear(&cache->weight_state);
}
@@ -4227,36 +4267,42 @@ static void texpaint_request_active_vcol(MeshBatchCache *cache, Mesh *me)
GPUBatch *DRW_mesh_batch_cache_get_all_verts(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
+ mesh_batch_cache_add_request(cache, MBC_ALL_VERTS);
return DRW_batch_request(&cache->batch.all_verts);
}
GPUBatch *DRW_mesh_batch_cache_get_all_edges(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
+ mesh_batch_cache_add_request(cache, MBC_ALL_EDGES);
return DRW_batch_request(&cache->batch.all_edges);
}
GPUBatch *DRW_mesh_batch_cache_get_surface(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
+ mesh_batch_cache_add_request(cache, MBC_SURFACE);
return DRW_batch_request(&cache->batch.surface);
}
GPUBatch *DRW_mesh_batch_cache_get_loose_edges(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
+ mesh_batch_cache_add_request(cache, MBC_LOOSE_EDGES);
return DRW_batch_request(&cache->batch.loose_edges);
}
GPUBatch *DRW_mesh_batch_cache_get_surface_weights(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
+ mesh_batch_cache_add_request(cache, MBC_SURFACE_WEIGHTS);
return DRW_batch_request(&cache->batch.surface_weights);
}
GPUBatch *DRW_mesh_batch_cache_get_edge_detection(Mesh *me, bool *r_is_manifold)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
+ mesh_batch_cache_add_request(cache, MBC_EDGE_DETECTION);
/* Even if is_manifold is not correct (not updated),
* the default (not manifold) is just the worst case. */
if (r_is_manifold) {
@@ -4268,12 +4314,14 @@ GPUBatch *DRW_mesh_batch_cache_get_edge_detection(Mesh *me, bool *r_is_manifold)
GPUBatch *DRW_mesh_batch_cache_get_wireframes_face(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
+ mesh_batch_cache_add_request(cache, MBC_WIRE_EDGES);
return DRW_batch_request(&cache->batch.wire_edges);
}
GPUBatch *DRW_mesh_batch_cache_get_edit_mesh_analysis(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
+ mesh_batch_cache_add_request(cache, MBC_EDIT_MESH_ANALYSIS);
return DRW_batch_request(&cache->batch.edit_mesh_analysis);
}
@@ -4299,6 +4347,8 @@ GPUBatch **DRW_mesh_batch_cache_get_surface_shaded(Mesh *me,
&cache->auto_layer_len);
}
+ mesh_batch_cache_add_request(cache, MBC_SURF_PER_MAT);
+
if (auto_layer_names) {
*auto_layer_names = cache->auto_layer_names;
*auto_layer_is_srgb = cache->auto_layer_is_srgb;
@@ -4313,6 +4363,7 @@ GPUBatch **DRW_mesh_batch_cache_get_surface_shaded(Mesh *me,
GPUBatch **DRW_mesh_batch_cache_get_surface_texpaint(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
+ mesh_batch_cache_add_request(cache, MBC_SURF_PER_MAT);
texpaint_request_active_uv(cache, me);
for (int i = 0; i < cache->mat_len; ++i) {
DRW_batch_request(&cache->surf_per_mat[i]);
@@ -4324,6 +4375,7 @@ GPUBatch *DRW_mesh_batch_cache_get_surface_texpaint_single(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
texpaint_request_active_uv(cache, me);
+ mesh_batch_cache_add_request(cache, MBC_SURFACE);
return DRW_batch_request(&cache->batch.surface);
}
@@ -4331,6 +4383,7 @@ GPUBatch *DRW_mesh_batch_cache_get_surface_vertpaint(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
texpaint_request_active_vcol(cache, me);
+ mesh_batch_cache_add_request(cache, MBC_SURFACE);
return DRW_batch_request(&cache->batch.surface);
}
@@ -4343,30 +4396,35 @@ GPUBatch *DRW_mesh_batch_cache_get_surface_vertpaint(Mesh *me)
GPUBatch *DRW_mesh_batch_cache_get_edit_triangles(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
+ mesh_batch_cache_add_request(cache, MBC_EDIT_TRIANGLES);
return DRW_batch_request(&cache->batch.edit_triangles);
}
GPUBatch *DRW_mesh_batch_cache_get_edit_edges(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
+ mesh_batch_cache_add_request(cache, MBC_EDIT_EDGES);
return DRW_batch_request(&cache->batch.edit_edges);
}
GPUBatch *DRW_mesh_batch_cache_get_edit_vertices(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
+ mesh_batch_cache_add_request(cache, MBC_EDIT_VERTICES);
return DRW_batch_request(&cache->batch.edit_vertices);
}
GPUBatch *DRW_mesh_batch_cache_get_edit_lnors(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
+ mesh_batch_cache_add_request(cache, MBC_EDIT_LNOR);
return DRW_batch_request(&cache->batch.edit_lnor);
}
GPUBatch *DRW_mesh_batch_cache_get_edit_facedots(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
+ mesh_batch_cache_add_request(cache, MBC_EDIT_FACEDOTS);
return DRW_batch_request(&cache->batch.edit_facedots);
}
@@ -4379,24 +4437,28 @@ GPUBatch *DRW_mesh_batch_cache_get_edit_facedots(Mesh *me)
GPUBatch *DRW_mesh_batch_cache_get_triangles_with_select_id(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
+ mesh_batch_cache_add_request(cache, MBC_EDIT_SELECTION_FACES);
return DRW_batch_request(&cache->batch.edit_selection_faces);
}
GPUBatch *DRW_mesh_batch_cache_get_facedots_with_select_id(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
+ mesh_batch_cache_add_request(cache, MBC_EDIT_SELECTION_FACEDOTS);
return DRW_batch_request(&cache->batch.edit_selection_facedots);
}
GPUBatch *DRW_mesh_batch_cache_get_edges_with_select_id(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
+ mesh_batch_cache_add_request(cache, MBC_EDIT_SELECTION_EDGES);
return DRW_batch_request(&cache->batch.edit_selection_edges);
}
GPUBatch *DRW_mesh_batch_cache_get_verts_with_select_id(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
+ mesh_batch_cache_add_request(cache, MBC_EDIT_SELECTION_VERTS);
return DRW_batch_request(&cache->batch.edit_selection_verts);
}
@@ -4409,36 +4471,42 @@ GPUBatch *DRW_mesh_batch_cache_get_verts_with_select_id(Mesh *me)
GPUBatch *DRW_mesh_batch_cache_get_edituv_faces_strech_area(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
+ mesh_batch_cache_add_request(cache, MBC_EDITUV_FACES_STRECH_AREA);
return DRW_batch_request(&cache->batch.edituv_faces_strech_area);
}
GPUBatch *DRW_mesh_batch_cache_get_edituv_faces_strech_angle(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
+ mesh_batch_cache_add_request(cache, MBC_EDITUV_FACES_STRECH_ANGLE);
return DRW_batch_request(&cache->batch.edituv_faces_strech_angle);
}
GPUBatch *DRW_mesh_batch_cache_get_edituv_faces(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
+ mesh_batch_cache_add_request(cache, MBC_EDITUV_FACES);
return DRW_batch_request(&cache->batch.edituv_faces);
}
GPUBatch *DRW_mesh_batch_cache_get_edituv_edges(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
+ mesh_batch_cache_add_request(cache, MBC_EDITUV_EDGES);
return DRW_batch_request(&cache->batch.edituv_edges);
}
GPUBatch *DRW_mesh_batch_cache_get_edituv_verts(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
+ mesh_batch_cache_add_request(cache, MBC_EDITUV_VERTS);
return DRW_batch_request(&cache->batch.edituv_verts);
}
GPUBatch *DRW_mesh_batch_cache_get_edituv_facedots(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
+ mesh_batch_cache_add_request(cache, MBC_EDITUV_FACEDOTS);
return DRW_batch_request(&cache->batch.edituv_facedots);
}
@@ -4446,12 +4514,14 @@ GPUBatch *DRW_mesh_batch_cache_get_uv_edges(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
texpaint_request_active_uv(cache, me);
+ mesh_batch_cache_add_request(cache, MBC_WIRE_LOOPS_UVS);
return DRW_batch_request(&cache->batch.wire_loops_uvs);
}
GPUBatch *DRW_mesh_batch_cache_get_surface_edges(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
+ mesh_batch_cache_add_request(cache, MBC_WIRE_LOOPS);
return DRW_batch_request(&cache->batch.wire_loops);
}
@@ -4669,14 +4739,18 @@ static void uvedit_fill_buffer_data(MeshRenderData *rdata,
GPU_indexbuf_add_generic_vert(elb_face, vidx);
GPU_indexbuf_add_primitive_restart(elb_face);
}
- if (elb_edge && e_origindex[l[i].e] != ORIGINDEX_NONE) {
+ if (elb_edge) {
for (i = 0; i < mpoly->totloop; ++i) {
- GPU_indexbuf_add_line_verts(elb_edge, vidx + i, vidx + (i + 1) % mpoly->totloop);
+ if (e_origindex[l[i].e] != ORIGINDEX_NONE) {
+ GPU_indexbuf_add_line_verts(elb_edge, vidx + i, vidx + (i + 1) % mpoly->totloop);
+ }
}
}
- if (elb_vert && v_origindex[l[i].v] != ORIGINDEX_NONE) {
+ if (elb_vert) {
for (i = 0; i < mpoly->totloop; ++i) {
- GPU_indexbuf_add_generic_vert(elb_vert, vidx + i);
+ if (v_origindex[l[i].v] != ORIGINDEX_NONE) {
+ GPU_indexbuf_add_generic_vert(elb_vert, vidx + i);
+ }
}
}
}
@@ -4831,82 +4905,113 @@ void DRW_mesh_batch_cache_create_requested(
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
- /* Check vertex weights. */
- if ((cache->batch.surface_weights != 0) && (ts != NULL)) {
- struct DRW_MeshWeightState wstate;
- BLI_assert(ob->type == OB_MESH);
- drw_mesh_weight_state_extract(ob, me, ts, is_paint_mode, &wstate);
- mesh_batch_cache_check_vertex_group(cache, &wstate);
- drw_mesh_weight_state_copy(&cache->weight_state, &wstate);
- drw_mesh_weight_state_clear(&wstate);
+ /* Early out */
+ if (cache->batch_requested == 0) {
+#ifdef DEBUG
+ goto check;
+#endif
+ return;
}
- /* Optimization : Only create orco layer if mesh is deformed. */
- if (cache->cd_needed.orco != 0) {
- CustomData *cd_vdata = (me->edit_mesh) ? &me->edit_mesh->bm->vdata : &me->vdata;
- if (CustomData_get_layer(cd_vdata, CD_ORCO) != NULL && ob->modifiers.first != NULL) {
- /* Orco layer is needed. */
- }
- else if (cache->cd_needed.tan_orco == 0) {
- /* Skip orco calculation if not needed by tangent generation. */
- cache->cd_needed.orco = 0;
+ DRWBatchFlag batch_requested = cache->batch_requested;
+ cache->batch_requested = 0;
+
+ if (batch_requested & MBC_SURFACE_WEIGHTS) {
+ /* Check vertex weights. */
+ if ((cache->batch.surface_weights != NULL) && (ts != NULL)) {
+ struct DRW_MeshWeightState wstate;
+ BLI_assert(ob->type == OB_MESH);
+ drw_mesh_weight_state_extract(ob, me, ts, is_paint_mode, &wstate);
+ mesh_batch_cache_check_vertex_group(cache, &wstate);
+ drw_mesh_weight_state_copy(&cache->weight_state, &wstate);
+ drw_mesh_weight_state_clear(&wstate);
}
}
- /* Verify that all surface batches have needed attribute layers. */
- /* TODO(fclem): We could be a bit smarter here and only do it per material. */
- bool cd_overlap = mesh_cd_layers_type_overlap(cache->cd_used, cache->cd_needed);
- if (cd_overlap == false) {
- if ((cache->cd_used.uv & cache->cd_needed.uv) != cache->cd_needed.uv ||
- (cache->cd_used.tan & cache->cd_needed.tan) != cache->cd_needed.tan ||
- cache->cd_used.tan_orco != cache->cd_needed.tan_orco) {
- GPU_VERTBUF_DISCARD_SAFE(cache->ordered.loop_uv_tan);
- }
- if (cache->cd_used.orco != cache->cd_needed.orco) {
- GPU_VERTBUF_DISCARD_SAFE(cache->ordered.loop_orco);
+ if (batch_requested & (MBC_SURFACE | MBC_SURF_PER_MAT | MBC_WIRE_LOOPS_UVS)) {
+ /* Optimization : Only create orco layer if mesh is deformed. */
+ if (cache->cd_needed.orco != 0) {
+ CustomData *cd_vdata = (me->edit_mesh) ? &me->edit_mesh->bm->vdata : &me->vdata;
+ if (CustomData_get_layer(cd_vdata, CD_ORCO) != NULL && ob->modifiers.first != NULL) {
+ /* Orco layer is needed. */
+ }
+ else if (cache->cd_needed.tan_orco == 0) {
+ /* Skip orco calculation if not needed by tangent generation.
+ */
+ cache->cd_needed.orco = 0;
+ }
}
- if ((cache->cd_used.vcol & cache->cd_needed.vcol) != cache->cd_needed.vcol) {
- GPU_VERTBUF_DISCARD_SAFE(cache->ordered.loop_vcol);
+
+ /* Verify that all surface batches have needed attribute layers.
+ */
+ /* TODO(fclem): We could be a bit smarter here and only do it per
+ * material. */
+ bool cd_overlap = mesh_cd_layers_type_overlap(cache->cd_used, cache->cd_needed);
+ if (cd_overlap == false) {
+ if ((cache->cd_used.uv & cache->cd_needed.uv) != cache->cd_needed.uv ||
+ (cache->cd_used.tan & cache->cd_needed.tan) != cache->cd_needed.tan ||
+ cache->cd_used.tan_orco != cache->cd_needed.tan_orco) {
+ GPU_VERTBUF_DISCARD_SAFE(cache->ordered.loop_uv_tan);
+ }
+ if (cache->cd_used.orco != cache->cd_needed.orco) {
+ GPU_VERTBUF_DISCARD_SAFE(cache->ordered.loop_orco);
+ }
+ if ((cache->cd_used.vcol & cache->cd_needed.vcol) != cache->cd_needed.vcol) {
+ GPU_VERTBUF_DISCARD_SAFE(cache->ordered.loop_vcol);
+ }
+ /* We can't discard batches at this point as they have been
+ * referenced for drawing. Just clear them in place. */
+ for (int i = 0; i < cache->mat_len; ++i) {
+ GPU_BATCH_CLEAR_SAFE(cache->surf_per_mat[i]);
+ }
+ GPU_BATCH_CLEAR_SAFE(cache->batch.surface);
+ cache->batch_ready &= ~(MBC_SURFACE | MBC_SURF_PER_MAT);
+
+ mesh_cd_layers_type_merge(&cache->cd_used, cache->cd_needed);
}
- /* We can't discard batches at this point as they have been
- * referenced for drawing. Just clear them in place. */
- for (int i = 0; i < cache->mat_len; ++i) {
- GPU_BATCH_CLEAR_SAFE(cache->surf_per_mat[i]);
+ mesh_cd_layers_type_merge(&cache->cd_used_over_time, cache->cd_needed);
+ mesh_cd_layers_type_clear(&cache->cd_needed);
+ }
+
+ if (batch_requested & MBC_EDITUV) {
+ /* Discard UV batches if sync_selection changes */
+ if (ts != NULL) {
+ const bool is_uvsyncsel = (ts->uv_flag & UV_SYNC_SELECTION);
+ if (cache->is_uvsyncsel != is_uvsyncsel) {
+ cache->is_uvsyncsel = is_uvsyncsel;
+ GPU_VERTBUF_DISCARD_SAFE(cache->edit.loop_uv_data);
+ GPU_VERTBUF_DISCARD_SAFE(cache->edit.loop_stretch_angle);
+ GPU_VERTBUF_DISCARD_SAFE(cache->edit.loop_stretch_area);
+ GPU_VERTBUF_DISCARD_SAFE(cache->edit.loop_uv);
+ GPU_VERTBUF_DISCARD_SAFE(cache->edit.facedots_uv);
+ GPU_INDEXBUF_DISCARD_SAFE(cache->ibo.edituv_loops_tri_fans);
+ GPU_INDEXBUF_DISCARD_SAFE(cache->ibo.edituv_loops_line_strips);
+ GPU_INDEXBUF_DISCARD_SAFE(cache->ibo.edituv_loops_points);
+ /* We only clear the batches as they may already have been
+ * referenced. */
+ GPU_BATCH_CLEAR_SAFE(cache->batch.edituv_faces_strech_area);
+ GPU_BATCH_CLEAR_SAFE(cache->batch.edituv_faces_strech_angle);
+ GPU_BATCH_CLEAR_SAFE(cache->batch.edituv_faces);
+ GPU_BATCH_CLEAR_SAFE(cache->batch.edituv_edges);
+ GPU_BATCH_CLEAR_SAFE(cache->batch.edituv_verts);
+ GPU_BATCH_CLEAR_SAFE(cache->batch.edituv_facedots);
+ cache->batch_ready &= ~MBC_EDITUV;
+ }
}
- GPU_BATCH_CLEAR_SAFE(cache->batch.surface);
+ }
- mesh_cd_layers_type_merge(&cache->cd_used, cache->cd_needed);
+ /* Second chance to early out */
+ if ((batch_requested & ~cache->batch_ready) == 0) {
+#ifdef DEBUG
+ goto check;
+#endif
+ return;
}
- mesh_cd_layers_type_merge(&cache->cd_used_over_time, cache->cd_needed);
- mesh_cd_layers_type_clear(&cache->cd_needed);
- /* Discard UV batches if sync_selection changes */
- if (ts != NULL) {
- const bool is_uvsyncsel = (ts->uv_flag & UV_SYNC_SELECTION);
- if (cache->is_uvsyncsel != is_uvsyncsel) {
- cache->is_uvsyncsel = is_uvsyncsel;
- GPU_VERTBUF_DISCARD_SAFE(cache->edit.loop_uv_data);
- GPU_VERTBUF_DISCARD_SAFE(cache->edit.loop_stretch_angle);
- GPU_VERTBUF_DISCARD_SAFE(cache->edit.loop_stretch_area);
- GPU_VERTBUF_DISCARD_SAFE(cache->edit.loop_uv);
- GPU_VERTBUF_DISCARD_SAFE(cache->edit.facedots_uv);
- GPU_INDEXBUF_DISCARD_SAFE(cache->ibo.edituv_loops_tri_fans);
- GPU_INDEXBUF_DISCARD_SAFE(cache->ibo.edituv_loops_line_strips);
- GPU_INDEXBUF_DISCARD_SAFE(cache->ibo.edituv_loops_points);
- /* We only clear the batches as they may already have been referenced. */
- GPU_BATCH_CLEAR_SAFE(cache->batch.edituv_faces_strech_area);
- GPU_BATCH_CLEAR_SAFE(cache->batch.edituv_faces_strech_angle);
- GPU_BATCH_CLEAR_SAFE(cache->batch.edituv_faces);
- GPU_BATCH_CLEAR_SAFE(cache->batch.edituv_edges);
- GPU_BATCH_CLEAR_SAFE(cache->batch.edituv_verts);
- GPU_BATCH_CLEAR_SAFE(cache->batch.edituv_facedots);
- }
- }
-
- bool has_request = false;
+ cache->batch_ready |= batch_requested;
+
/* Init batches and request VBOs & IBOs */
if (DRW_batch_requested(cache->batch.surface, GPU_PRIM_TRIS)) {
- has_request = true;
DRW_ibo_request(cache->batch.surface, &cache->ibo.loops_tris);
DRW_vbo_request(cache->batch.surface, &cache->ordered.loop_pos_nor);
/* For paint overlay. Active layer should have been queried. */
@@ -4918,43 +5023,35 @@ void DRW_mesh_batch_cache_create_requested(
}
}
if (DRW_batch_requested(cache->batch.all_verts, GPU_PRIM_POINTS)) {
- has_request = true;
DRW_vbo_request(cache->batch.all_verts, &cache->ordered.pos_nor);
}
if (DRW_batch_requested(cache->batch.all_edges, GPU_PRIM_LINES)) {
- has_request = true;
DRW_ibo_request(cache->batch.all_edges, &cache->ibo.edges_lines);
DRW_vbo_request(cache->batch.all_edges, &cache->ordered.pos_nor);
}
if (DRW_batch_requested(cache->batch.loose_edges, GPU_PRIM_LINES)) {
- has_request = true;
DRW_ibo_request(cache->batch.loose_edges, &cache->ibo.loose_edges_lines);
DRW_vbo_request(cache->batch.loose_edges, &cache->ordered.pos_nor);
}
if (DRW_batch_requested(cache->batch.edge_detection, GPU_PRIM_LINES_ADJ)) {
- has_request = true;
DRW_ibo_request(cache->batch.edge_detection, &cache->ibo.edges_adj_lines);
DRW_vbo_request(cache->batch.edge_detection, &cache->ordered.pos_nor);
}
if (DRW_batch_requested(cache->batch.surface_weights, GPU_PRIM_TRIS)) {
- has_request = true;
DRW_ibo_request(cache->batch.surface_weights, &cache->ibo.surf_tris);
DRW_vbo_request(cache->batch.surface_weights, &cache->ordered.pos_nor);
DRW_vbo_request(cache->batch.surface_weights, &cache->ordered.weights);
}
if (DRW_batch_requested(cache->batch.wire_loops, GPU_PRIM_LINE_STRIP)) {
- has_request = true;
DRW_ibo_request(cache->batch.wire_loops, &cache->ibo.loops_line_strips);
DRW_vbo_request(cache->batch.wire_loops, &cache->ordered.loop_pos_nor);
}
if (DRW_batch_requested(cache->batch.wire_edges, GPU_PRIM_LINES)) {
- has_request = true;
DRW_ibo_request(cache->batch.wire_edges, &cache->ibo.loops_lines);
DRW_vbo_request(cache->batch.wire_edges, &cache->ordered.loop_pos_nor);
DRW_vbo_request(cache->batch.wire_edges, &cache->ordered.loop_edge_fac);
}
if (DRW_batch_requested(cache->batch.wire_loops_uvs, GPU_PRIM_LINE_STRIP)) {
- has_request = true;
DRW_ibo_request(cache->batch.wire_loops_uvs, &cache->ibo.loops_line_strips);
/* For paint overlay. Active layer should have been queried. */
if (cache->cd_used.uv != 0) {
@@ -4964,37 +5061,31 @@ void DRW_mesh_batch_cache_create_requested(
/* Edit Mesh */
if (DRW_batch_requested(cache->batch.edit_triangles, GPU_PRIM_TRIS)) {
- has_request = true;
DRW_ibo_request(cache->batch.edit_triangles, &cache->ibo.edit_loops_tris);
DRW_vbo_request(cache->batch.edit_triangles, &cache->edit.loop_pos_nor);
DRW_vbo_request(cache->batch.edit_triangles, &cache->edit.loop_data);
}
if (DRW_batch_requested(cache->batch.edit_vertices, GPU_PRIM_POINTS)) {
- has_request = true;
DRW_ibo_request(cache->batch.edit_vertices, &cache->ibo.edit_loops_points);
DRW_vbo_request(cache->batch.edit_vertices, &cache->edit.loop_pos_nor);
DRW_vbo_request(cache->batch.edit_vertices, &cache->edit.loop_data);
}
if (DRW_batch_requested(cache->batch.edit_edges, GPU_PRIM_LINES)) {
- has_request = true;
DRW_ibo_request(cache->batch.edit_edges, &cache->ibo.edit_loops_lines);
DRW_vbo_request(cache->batch.edit_edges, &cache->edit.loop_pos_nor);
DRW_vbo_request(cache->batch.edit_edges, &cache->edit.loop_data);
}
if (DRW_batch_requested(cache->batch.edit_lnor, GPU_PRIM_POINTS)) {
- has_request = true;
DRW_ibo_request(cache->batch.edit_lnor, &cache->ibo.edit_loops_tris);
DRW_vbo_request(cache->batch.edit_lnor, &cache->edit.loop_pos_nor);
DRW_vbo_request(cache->batch.edit_lnor, &cache->edit.loop_lnor);
}
if (DRW_batch_requested(cache->batch.edit_facedots, GPU_PRIM_POINTS)) {
- has_request = true;
DRW_vbo_request(cache->batch.edit_facedots, &cache->edit.facedots_pos_nor_data);
}
/* Mesh Analysis */
if (DRW_batch_requested(cache->batch.edit_mesh_analysis, GPU_PRIM_TRIS)) {
- has_request = true;
DRW_ibo_request(cache->batch.edit_mesh_analysis, &cache->ibo.edit_loops_tris);
DRW_vbo_request(cache->batch.edit_mesh_analysis, &cache->edit.loop_pos_nor);
DRW_vbo_request(cache->batch.edit_mesh_analysis, &cache->edit.loop_mesh_analysis);
@@ -5002,39 +5093,33 @@ void DRW_mesh_batch_cache_create_requested(
/* Edit UV */
if (DRW_batch_requested(cache->batch.edituv_faces, GPU_PRIM_TRI_FAN)) {
- has_request = true;
DRW_ibo_request(cache->batch.edituv_faces, &cache->ibo.edituv_loops_tri_fans);
DRW_vbo_request(cache->batch.edituv_faces, &cache->edit.loop_uv);
DRW_vbo_request(cache->batch.edituv_faces, &cache->edit.loop_uv_data);
}
if (DRW_batch_requested(cache->batch.edituv_faces_strech_area, GPU_PRIM_TRI_FAN)) {
- has_request = true;
DRW_ibo_request(cache->batch.edituv_faces_strech_area, &cache->ibo.edituv_loops_tri_fans);
DRW_vbo_request(cache->batch.edituv_faces_strech_area, &cache->edit.loop_uv);
DRW_vbo_request(cache->batch.edituv_faces_strech_area, &cache->edit.loop_uv_data);
DRW_vbo_request(cache->batch.edituv_faces_strech_area, &cache->edit.loop_stretch_area);
}
if (DRW_batch_requested(cache->batch.edituv_faces_strech_angle, GPU_PRIM_TRI_FAN)) {
- has_request = true;
DRW_ibo_request(cache->batch.edituv_faces_strech_angle, &cache->ibo.edituv_loops_tri_fans);
DRW_vbo_request(cache->batch.edituv_faces_strech_angle, &cache->edit.loop_uv);
DRW_vbo_request(cache->batch.edituv_faces_strech_angle, &cache->edit.loop_uv_data);
DRW_vbo_request(cache->batch.edituv_faces_strech_angle, &cache->edit.loop_stretch_angle);
}
if (DRW_batch_requested(cache->batch.edituv_edges, GPU_PRIM_LINES)) {
- has_request = true;
DRW_ibo_request(cache->batch.edituv_edges, &cache->ibo.edituv_loops_line_strips);
DRW_vbo_request(cache->batch.edituv_edges, &cache->edit.loop_uv);
DRW_vbo_request(cache->batch.edituv_edges, &cache->edit.loop_uv_data);
}
if (DRW_batch_requested(cache->batch.edituv_verts, GPU_PRIM_POINTS)) {
- has_request = true;
DRW_ibo_request(cache->batch.edituv_verts, &cache->ibo.edituv_loops_points);
DRW_vbo_request(cache->batch.edituv_verts, &cache->edit.loop_uv);
DRW_vbo_request(cache->batch.edituv_verts, &cache->edit.loop_uv_data);
}
if (DRW_batch_requested(cache->batch.edituv_facedots, GPU_PRIM_POINTS)) {
- has_request = true;
DRW_vbo_request(cache->batch.edituv_facedots, &cache->edit.facedots_uv);
DRW_vbo_request(cache->batch.edituv_facedots, &cache->edit.facedots_uv_data);
}
@@ -5042,25 +5127,21 @@ void DRW_mesh_batch_cache_create_requested(
/* Selection */
/* TODO reuse ordered.loop_pos_nor if possible. */
if (DRW_batch_requested(cache->batch.edit_selection_verts, GPU_PRIM_POINTS)) {
- has_request = true;
DRW_ibo_request(cache->batch.edit_selection_verts, &cache->ibo.edit_loops_points);
DRW_vbo_request(cache->batch.edit_selection_verts, &cache->edit.loop_pos_nor);
DRW_vbo_request(cache->batch.edit_selection_verts, &cache->edit.loop_vert_idx);
}
if (DRW_batch_requested(cache->batch.edit_selection_edges, GPU_PRIM_LINES)) {
- has_request = true;
DRW_ibo_request(cache->batch.edit_selection_edges, &cache->ibo.edit_loops_lines);
DRW_vbo_request(cache->batch.edit_selection_edges, &cache->edit.loop_pos_nor);
DRW_vbo_request(cache->batch.edit_selection_edges, &cache->edit.loop_edge_idx);
}
if (DRW_batch_requested(cache->batch.edit_selection_faces, GPU_PRIM_TRIS)) {
- has_request = true;
DRW_ibo_request(cache->batch.edit_selection_faces, &cache->ibo.edit_loops_tris);
DRW_vbo_request(cache->batch.edit_selection_faces, &cache->edit.loop_pos_nor);
DRW_vbo_request(cache->batch.edit_selection_faces, &cache->edit.loop_face_idx);
}
if (DRW_batch_requested(cache->batch.edit_selection_facedots, GPU_PRIM_POINTS)) {
- has_request = true;
DRW_vbo_request(cache->batch.edit_selection_facedots, &cache->edit.facedots_pos_nor_data);
DRW_vbo_request(cache->batch.edit_selection_facedots, &cache->edit.facedots_idx);
}
@@ -5068,7 +5149,6 @@ void DRW_mesh_batch_cache_create_requested(
/* Per Material */
for (int i = 0; i < cache->mat_len; ++i) {
if (DRW_batch_requested(cache->surf_per_mat[i], GPU_PRIM_TRIS)) {
- has_request = true;
if (cache->mat_len > 1) {
DRW_ibo_request(cache->surf_per_mat[i], &cache->surf_per_mat_tris[i]);
}
@@ -5089,11 +5169,6 @@ void DRW_mesh_batch_cache_create_requested(
}
}
- /* Early out if no request. */
- if (!has_request) {
- return;
- }
-
#ifdef DRW_DEBUG_MESH_CACHE_REQUEST
printf("-- %s %s --\n", __func__, ob->id.name + 2);
#endif
@@ -5325,6 +5400,7 @@ void DRW_mesh_batch_cache_create_requested(
}
#ifdef DEBUG
+check:
/* Make sure all requested batches have been setup. */
for (int i = 0; i < sizeof(cache->batch) / sizeof(void *); ++i) {
BLI_assert(!DRW_batch_requested(((GPUBatch **)&cache->batch)[i], 0));
diff --git a/source/blender/draw/intern/draw_cache_impl_metaball.c b/source/blender/draw/intern/draw_cache_impl_metaball.c
index 432c5092274..60f15338412 100644
--- a/source/blender/draw/intern/draw_cache_impl_metaball.c
+++ b/source/blender/draw/intern/draw_cache_impl_metaball.c
@@ -98,12 +98,16 @@ static void metaball_batch_cache_init(MetaBall *mb)
cache->is_manifold = false;
}
-static MetaBallBatchCache *metaball_batch_cache_get(MetaBall *mb)
+void DRW_mball_batch_cache_validate(MetaBall *mb)
{
if (!metaball_batch_cache_valid(mb)) {
metaball_batch_cache_clear(mb);
metaball_batch_cache_init(mb);
}
+}
+
+static MetaBallBatchCache *metaball_batch_cache_get(MetaBall *mb)
+{
return mb->batch_cache;
}
diff --git a/source/blender/draw/intern/draw_cache_inline.h b/source/blender/draw/intern/draw_cache_inline.h
new file mode 100644
index 00000000000..d94ef5b90d3
--- /dev/null
+++ b/source/blender/draw/intern/draw_cache_inline.h
@@ -0,0 +1,110 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Copyright 2016, Blender Foundation.
+ */
+
+/** \file
+ * \ingroup draw
+ */
+
+#ifndef __DRAW_CACHE_INLINE_H__
+#define __DRAW_CACHE_INLINE_H__
+
+#include "MEM_guardedalloc.h"
+#include "GPU_batch.h"
+
+/* Common */
+// #define DRW_DEBUG_MESH_CACHE_REQUEST
+
+#ifdef DRW_DEBUG_MESH_CACHE_REQUEST
+# define DRW_ADD_FLAG_FROM_VBO_REQUEST(flag, vbo, value) \
+ (flag |= DRW_vbo_requested(vbo) ? (printf(" VBO requested " #vbo "\n") ? value : value) : 0)
+# define DRW_ADD_FLAG_FROM_IBO_REQUEST(flag, ibo, value) \
+ (flag |= DRW_ibo_requested(ibo) ? (printf(" IBO requested " #ibo "\n") ? value : value) : 0)
+#else
+# define DRW_ADD_FLAG_FROM_VBO_REQUEST(flag, vbo, value) \
+ (flag |= DRW_vbo_requested(vbo) ? (value) : 0)
+# define DRW_ADD_FLAG_FROM_IBO_REQUEST(flag, ibo, value) \
+ (flag |= DRW_ibo_requested(ibo) ? (value) : 0)
+#endif
+
+/* Test and assign NULL if test fails */
+#define DRW_TEST_ASSIGN_VBO(v) (v = (DRW_vbo_requested(v) ? (v) : NULL))
+#define DRW_TEST_ASSIGN_IBO(v) (v = (DRW_ibo_requested(v) ? (v) : NULL))
+
+BLI_INLINE GPUBatch *DRW_batch_request(GPUBatch **batch)
+{
+ /* XXX TODO(fclem): We are writting to batch cache here. Need to make this thread safe. */
+ if (*batch == NULL) {
+ *batch = MEM_callocN(sizeof(GPUBatch), "GPUBatch");
+ }
+ return *batch;
+}
+
+BLI_INLINE bool DRW_batch_requested(GPUBatch *batch, int prim_type)
+{
+ /* Batch has been requested if it has been created but not initialized. */
+ if (batch != NULL && batch->verts[0] == NULL) {
+ /* HACK. We init without a valid VBO and let the first vbo binding
+ * fill verts[0]. */
+ GPU_batch_init_ex(batch, prim_type, (GPUVertBuf *)1, NULL, 0);
+ batch->verts[0] = NULL;
+ return true;
+ }
+ return false;
+}
+
+BLI_INLINE void DRW_ibo_request(GPUBatch *batch, GPUIndexBuf **ibo)
+{
+ if (*ibo == NULL) {
+ *ibo = MEM_callocN(sizeof(GPUIndexBuf), "GPUIndexBuf");
+ }
+ GPU_batch_vao_cache_clear(batch);
+ batch->elem = *ibo;
+}
+
+BLI_INLINE bool DRW_ibo_requested(GPUIndexBuf *ibo)
+{
+ /* TODO do not rely on data uploaded. This prevents multithreading.
+ * (need access to a gl context) */
+ return (ibo != NULL && ibo->ibo_id == 0 && ibo->data == NULL);
+}
+
+BLI_INLINE void DRW_vbo_request(GPUBatch *batch, GPUVertBuf **vbo)
+{
+ if (*vbo == NULL) {
+ *vbo = MEM_callocN(sizeof(GPUVertBuf), "GPUVertBuf");
+ }
+ /* HACK set first vbo if not init. */
+ if (batch->verts[0] == NULL) {
+ GPU_batch_vao_cache_clear(batch);
+ batch->verts[0] = *vbo;
+ }
+ else {
+ /* HACK: bypass assert */
+ int vbo_vert_len = (*vbo)->vertex_len;
+ (*vbo)->vertex_len = batch->verts[0]->vertex_len;
+ GPU_batch_vertbuf_add(batch, *vbo);
+ (*vbo)->vertex_len = vbo_vert_len;
+ }
+}
+
+BLI_INLINE bool DRW_vbo_requested(GPUVertBuf *vbo)
+{
+ return (vbo != NULL && vbo->format.attr_len == 0);
+}
+
+#endif /* __DRAW_CACHE_INLINE_H__ */
diff --git a/source/blender/draw/intern/draw_common.c b/source/blender/draw/intern/draw_common.c
index b4eb354ec59..51f097e79d8 100644
--- a/source/blender/draw/intern/draw_common.c
+++ b/source/blender/draw/intern/draw_common.c
@@ -233,6 +233,7 @@ extern char datatoc_armature_stick_frag_glsl[];
extern char datatoc_armature_dof_vert_glsl[];
extern char datatoc_common_globals_lib_glsl[];
+extern char datatoc_common_view_lib_glsl[];
extern char datatoc_gpu_shader_flat_color_frag_glsl[];
extern char datatoc_gpu_shader_3D_smooth_color_frag_glsl[];
@@ -284,7 +285,8 @@ static struct {
struct GPUVertFormat *instance_bone_envelope_distance;
struct GPUVertFormat *instance_bone_envelope_outline;
struct GPUVertFormat *instance_mball_handles;
- struct GPUVertFormat *dynlines_color;
+ struct GPUVertFormat *pos_color;
+ struct GPUVertFormat *pos;
} g_formats = {NULL};
void DRW_globals_free(void)
@@ -309,34 +311,36 @@ void DRW_shgroup_world_clip_planes_from_rv3d(DRWShadingGroup *shgrp, const Regio
DRW_shgroup_state_enable(shgrp, DRW_STATE_CLIP_PLANES);
}
-DRWShadingGroup *shgroup_dynlines_flat_color(DRWPass *pass, eGPUShaderConfig sh_cfg)
+struct DRWCallBuffer *buffer_dynlines_flat_color(DRWPass *pass, eGPUShaderConfig sh_cfg)
{
GPUShader *sh = GPU_shader_get_builtin_shader_with_config(GPU_SHADER_3D_FLAT_COLOR, sh_cfg);
- DRW_shgroup_instance_format(g_formats.dynlines_color,
+ DRW_shgroup_instance_format(g_formats.pos_color,
{
{"pos", DRW_ATTR_FLOAT, 3},
{"color", DRW_ATTR_FLOAT, 4},
});
- DRWShadingGroup *grp = DRW_shgroup_line_batch_create_with_format(
- sh, pass, g_formats.dynlines_color);
+ DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
if (sh_cfg == GPU_SHADER_CFG_CLIPPED) {
DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d);
}
- return grp;
+ return DRW_shgroup_call_buffer(grp, g_formats.pos_color, GPU_PRIM_LINES);
}
-DRWShadingGroup *shgroup_dynlines_dashed_uniform_color(DRWPass *pass,
- const float color[4],
- eGPUShaderConfig sh_cfg)
+struct DRWCallBuffer *buffer_dynlines_dashed_uniform_color(DRWPass *pass,
+ const float color[4],
+ eGPUShaderConfig sh_cfg)
{
GPUShader *sh = GPU_shader_get_builtin_shader_with_config(
GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR, sh_cfg);
static float dash_width = 6.0f;
static float dash_factor = 0.5f;
- DRWShadingGroup *grp = DRW_shgroup_line_batch_create(sh, pass);
+
+ DRW_shgroup_instance_format(g_formats.pos, {{"pos", DRW_ATTR_FLOAT, 3}});
+
+ DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
DRW_shgroup_uniform_vec4(grp, "color", color, 1);
DRW_shgroup_uniform_vec2(grp, "viewport_size", DRW_viewport_size_get(), 1);
DRW_shgroup_uniform_float(grp, "dash_width", &dash_width, 1);
@@ -345,60 +349,53 @@ DRWShadingGroup *shgroup_dynlines_dashed_uniform_color(DRWPass *pass,
if (sh_cfg == GPU_SHADER_CFG_CLIPPED) {
DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d);
}
- return grp;
+ return DRW_shgroup_call_buffer(grp, g_formats.pos, GPU_PRIM_LINES);
}
-DRWShadingGroup *shgroup_dynpoints_uniform_color(DRWPass *pass,
- const float color[4],
- const float *size,
- eGPUShaderConfig sh_cfg)
+struct DRWCallBuffer *buffer_dynpoints_uniform_color(DRWShadingGroup *grp)
{
- GPUShader *sh = GPU_shader_get_builtin_shader_with_config(
- GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA, sh_cfg);
+ DRW_shgroup_instance_format(g_formats.pos, {{"pos", DRW_ATTR_FLOAT, 3}});
- DRWShadingGroup *grp = DRW_shgroup_point_batch_create(sh, pass);
- DRW_shgroup_uniform_vec4(grp, "color", color, 1);
- DRW_shgroup_uniform_float(grp, "size", size, 1);
- DRW_shgroup_state_enable(grp, DRW_STATE_POINT);
- if (sh_cfg == GPU_SHADER_CFG_CLIPPED) {
- DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d);
- }
- return grp;
+ return DRW_shgroup_call_buffer(grp, g_formats.pos, GPU_PRIM_POINTS);
}
-DRWShadingGroup *shgroup_groundlines_uniform_color(DRWPass *pass,
- const float color[4],
- eGPUShaderConfig sh_cfg)
+struct DRWCallBuffer *buffer_groundlines_uniform_color(DRWPass *pass,
+ const float color[4],
+ eGPUShaderConfig sh_cfg)
{
GPUShader *sh = GPU_shader_get_builtin_shader_with_config(GPU_SHADER_3D_GROUNDLINE, sh_cfg);
- DRWShadingGroup *grp = DRW_shgroup_point_batch_create(sh, pass);
+ DRW_shgroup_instance_format(g_formats.pos, {{"pos", DRW_ATTR_FLOAT, 3}});
+
+ DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
DRW_shgroup_uniform_vec4(grp, "color", color, 1);
if (sh_cfg == GPU_SHADER_CFG_CLIPPED) {
DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d);
}
- return grp;
+ return DRW_shgroup_call_buffer(grp, g_formats.pos, GPU_PRIM_POINTS);
}
-DRWShadingGroup *shgroup_groundpoints_uniform_color(DRWPass *pass,
- const float color[4],
- eGPUShaderConfig sh_cfg)
+struct DRWCallBuffer *buffer_groundpoints_uniform_color(DRWPass *pass,
+ const float color[4],
+ eGPUShaderConfig sh_cfg)
{
GPUShader *sh = GPU_shader_get_builtin_shader_with_config(GPU_SHADER_3D_GROUNDPOINT, sh_cfg);
- DRWShadingGroup *grp = DRW_shgroup_point_batch_create(sh, pass);
+ DRW_shgroup_instance_format(g_formats.pos, {{"pos", DRW_ATTR_FLOAT, 3}});
+
+ DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
DRW_shgroup_uniform_vec4(grp, "color", color, 1);
DRW_shgroup_state_enable(grp, DRW_STATE_POINT);
if (sh_cfg == GPU_SHADER_CFG_CLIPPED) {
DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d);
}
- return grp;
+ return DRW_shgroup_call_buffer(grp, g_formats.pos, GPU_PRIM_POINTS);
}
-DRWShadingGroup *shgroup_instance_screenspace(DRWPass *pass,
- struct GPUBatch *geom,
- const float *size,
- eGPUShaderConfig sh_cfg)
+struct DRWCallBuffer *buffer_instance_screenspace(DRWPass *pass,
+ struct GPUBatch *geom,
+ const float *size,
+ eGPUShaderConfig sh_cfg)
{
GPUShader *sh = GPU_shader_get_builtin_shader_with_config(
GPU_SHADER_3D_SCREENSPACE_VARIYING_COLOR, sh_cfg);
@@ -409,18 +406,17 @@ DRWShadingGroup *shgroup_instance_screenspace(DRWPass *pass,
{"color", DRW_ATTR_FLOAT, 3},
});
- DRWShadingGroup *grp = DRW_shgroup_instance_create(
- sh, pass, geom, g_formats.instance_screenspace);
+ DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
DRW_shgroup_uniform_float(grp, "size", size, 1);
DRW_shgroup_uniform_float(grp, "pixel_size", DRW_viewport_pixelsize_get(), 1);
DRW_shgroup_uniform_vec3(grp, "screen_vecs[0]", DRW_viewport_screenvecs_get(), 2);
if (sh_cfg == GPU_SHADER_CFG_CLIPPED) {
DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d);
}
- return grp;
+ return DRW_shgroup_call_buffer_instance(grp, g_formats.instance_screenspace, geom);
}
-DRWShadingGroup *shgroup_instance_solid(DRWPass *pass, struct GPUBatch *geom)
+struct DRWCallBuffer *buffer_instance_solid(DRWPass *pass, struct GPUBatch *geom)
{
static float light[3] = {0.0f, 0.0f, 1.0f};
GPUShader *sh = GPU_shader_get_builtin_shader(
@@ -432,13 +428,13 @@ DRWShadingGroup *shgroup_instance_solid(DRWPass *pass, struct GPUBatch *geom)
{"color", DRW_ATTR_FLOAT, 4},
});
- DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom, g_formats.instance_color);
+ DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
DRW_shgroup_uniform_vec3(grp, "light", light, 1);
- return grp;
+ return DRW_shgroup_call_buffer_instance(grp, g_formats.instance_color, geom);
}
-DRWShadingGroup *shgroup_instance_wire(DRWPass *pass, struct GPUBatch *geom)
+struct DRWCallBuffer *buffer_instance_wire(DRWPass *pass, struct GPUBatch *geom)
{
GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_OBJECTSPACE_VARIYING_COLOR);
@@ -448,14 +444,14 @@ DRWShadingGroup *shgroup_instance_wire(DRWPass *pass, struct GPUBatch *geom)
{"color", DRW_ATTR_FLOAT, 4},
});
- DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom, g_formats.instance_color);
+ DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
- return grp;
+ return DRW_shgroup_call_buffer_instance(grp, g_formats.instance_color, geom);
}
-DRWShadingGroup *shgroup_instance_screen_aligned(DRWPass *pass,
- struct GPUBatch *geom,
- eGPUShaderConfig sh_cfg)
+struct DRWCallBuffer *buffer_instance_screen_aligned(DRWPass *pass,
+ struct GPUBatch *geom,
+ eGPUShaderConfig sh_cfg)
{
GPUShader *sh = GPU_shader_get_builtin_shader_with_config(GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED,
sh_cfg);
@@ -467,18 +463,17 @@ DRWShadingGroup *shgroup_instance_screen_aligned(DRWPass *pass,
{"InstanceModelMatrix", DRW_ATTR_FLOAT, 16},
});
- DRWShadingGroup *grp = DRW_shgroup_instance_create(
- sh, pass, geom, g_formats.instance_screen_aligned);
+ DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
DRW_shgroup_uniform_vec3(grp, "screen_vecs[0]", DRW_viewport_screenvecs_get(), 2);
if (sh_cfg == GPU_SHADER_CFG_CLIPPED) {
DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d);
}
- return grp;
+ return DRW_shgroup_call_buffer_instance(grp, g_formats.instance_screen_aligned, geom);
}
-DRWShadingGroup *shgroup_instance_scaled(DRWPass *pass,
- struct GPUBatch *geom,
- eGPUShaderConfig sh_cfg)
+struct DRWCallBuffer *buffer_instance_scaled(DRWPass *pass,
+ struct GPUBatch *geom,
+ eGPUShaderConfig sh_cfg)
{
GPUShader *sh_inst = GPU_shader_get_builtin_shader_with_config(
GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SCALE, sh_cfg);
@@ -490,15 +485,16 @@ DRWShadingGroup *shgroup_instance_scaled(DRWPass *pass,
{"InstanceModelMatrix", DRW_ATTR_FLOAT, 16},
});
- DRWShadingGroup *grp = DRW_shgroup_instance_create(
- sh_inst, pass, geom, g_formats.instance_scaled);
+ DRWShadingGroup *grp = DRW_shgroup_create(sh_inst, pass);
if (sh_cfg == GPU_SHADER_CFG_CLIPPED) {
DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d);
}
- return grp;
+ return DRW_shgroup_call_buffer_instance(grp, g_formats.instance_scaled, geom);
}
-DRWShadingGroup *shgroup_instance(DRWPass *pass, struct GPUBatch *geom, eGPUShaderConfig sh_cfg)
+struct DRWCallBuffer *buffer_instance(DRWPass *pass,
+ struct GPUBatch *geom,
+ eGPUShaderConfig sh_cfg)
{
GPUShader *sh_inst = GPU_shader_get_builtin_shader_with_config(
GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE, sh_cfg);
@@ -510,22 +506,16 @@ DRWShadingGroup *shgroup_instance(DRWPass *pass, struct GPUBatch *geom, eGPUShad
{"InstanceModelMatrix", DRW_ATTR_FLOAT, 16},
});
- DRWShadingGroup *grp = DRW_shgroup_instance_create(
- sh_inst, pass, geom, g_formats.instance_sized);
+ DRWShadingGroup *grp = DRW_shgroup_create(sh_inst, pass);
DRW_shgroup_state_disable(grp, DRW_STATE_BLEND);
if (sh_cfg == GPU_SHADER_CFG_CLIPPED) {
DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d);
}
- return grp;
+ return DRW_shgroup_call_buffer_instance(grp, g_formats.instance_sized, geom);
}
-DRWShadingGroup *shgroup_instance_alpha(DRWPass *pass,
- struct GPUBatch *geom,
- eGPUShaderConfig sh_cfg)
+struct DRWCallBuffer *buffer_instance_alpha(DRWShadingGroup *grp, struct GPUBatch *geom)
{
- GPUShader *sh_inst = GPU_shader_get_builtin_shader_with_config(
- GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE, sh_cfg);
-
DRW_shgroup_instance_format(g_formats.instance_sized,
{
{"color", DRW_ATTR_FLOAT, 4},
@@ -533,17 +523,12 @@ DRWShadingGroup *shgroup_instance_alpha(DRWPass *pass,
{"InstanceModelMatrix", DRW_ATTR_FLOAT, 16},
});
- DRWShadingGroup *grp = DRW_shgroup_instance_create(
- sh_inst, pass, geom, g_formats.instance_sized);
- if (sh_cfg == GPU_SHADER_CFG_CLIPPED) {
- DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d);
- }
- return grp;
+ return DRW_shgroup_call_buffer_instance(grp, g_formats.instance_sized, geom);
}
-DRWShadingGroup *shgroup_instance_empty_axes(DRWPass *pass,
- struct GPUBatch *geom,
- eGPUShaderConfig sh_cfg)
+struct DRWCallBuffer *buffer_instance_empty_axes(DRWPass *pass,
+ struct GPUBatch *geom,
+ eGPUShaderConfig sh_cfg)
{
COMMON_Shaders *sh_data = &g_shaders[sh_cfg];
if (sh_data->empty_axes_sh == NULL) {
@@ -562,16 +547,15 @@ DRWShadingGroup *shgroup_instance_empty_axes(DRWPass *pass,
{"InstanceModelMatrix", DRW_ATTR_FLOAT, 16},
});
- DRWShadingGroup *grp = DRW_shgroup_instance_create(
- sh_data->empty_axes_sh, pass, geom, g_formats.instance_sized);
+ DRWShadingGroup *grp = DRW_shgroup_create(sh_data->empty_axes_sh, pass);
DRW_shgroup_uniform_vec3(grp, "screenVecs[0]", DRW_viewport_screenvecs_get(), 2);
if (sh_cfg == GPU_SHADER_CFG_CLIPPED) {
DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d);
}
- return grp;
+ return DRW_shgroup_call_buffer_instance(grp, g_formats.instance_sized, geom);
}
-DRWShadingGroup *shgroup_instance_outline(DRWPass *pass, struct GPUBatch *geom, int *baseid)
+struct DRWCallBuffer *buffer_instance_outline(DRWPass *pass, struct GPUBatch *geom, int *baseid)
{
GPUShader *sh_inst = GPU_shader_get_builtin_shader(
GPU_SHADER_INSTANCE_VARIYING_ID_VARIYING_SIZE);
@@ -583,16 +567,15 @@ DRWShadingGroup *shgroup_instance_outline(DRWPass *pass, struct GPUBatch *geom,
{"InstanceModelMatrix", DRW_ATTR_FLOAT, 16},
});
- DRWShadingGroup *grp = DRW_shgroup_instance_create(
- sh_inst, pass, geom, g_formats.instance_outline);
+ DRWShadingGroup *grp = DRW_shgroup_create(sh_inst, pass);
DRW_shgroup_uniform_int(grp, "baseId", baseid, 1);
- return grp;
+ return DRW_shgroup_call_buffer_instance(grp, g_formats.instance_outline, geom);
}
-DRWShadingGroup *shgroup_camera_instance(DRWPass *pass,
- struct GPUBatch *geom,
- eGPUShaderConfig sh_cfg)
+struct DRWCallBuffer *buffer_camera_instance(DRWPass *pass,
+ struct GPUBatch *geom,
+ eGPUShaderConfig sh_cfg)
{
GPUShader *sh_inst = GPU_shader_get_builtin_shader_with_config(GPU_SHADER_CAMERA, sh_cfg);
@@ -605,17 +588,16 @@ DRWShadingGroup *shgroup_camera_instance(DRWPass *pass,
{"InstanceModelMatrix", DRW_ATTR_FLOAT, 16},
});
- DRWShadingGroup *grp = DRW_shgroup_instance_create(
- sh_inst, pass, geom, g_formats.instance_camera);
+ DRWShadingGroup *grp = DRW_shgroup_create(sh_inst, pass);
if (sh_cfg == GPU_SHADER_CFG_CLIPPED) {
DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d);
}
- return grp;
+ return DRW_shgroup_call_buffer_instance(grp, g_formats.instance_camera, geom);
}
-DRWShadingGroup *shgroup_distance_lines_instance(DRWPass *pass,
- struct GPUBatch *geom,
- eGPUShaderConfig sh_cfg)
+struct DRWCallBuffer *buffer_distance_lines_instance(DRWPass *pass,
+ struct GPUBatch *geom,
+ eGPUShaderConfig sh_cfg)
{
GPUShader *sh_inst = GPU_shader_get_builtin_shader_with_config(GPU_SHADER_DISTANCE_LINES,
sh_cfg);
@@ -629,18 +611,17 @@ DRWShadingGroup *shgroup_distance_lines_instance(DRWPass *pass,
{"InstanceModelMatrix", DRW_ATTR_FLOAT, 16},
});
- DRWShadingGroup *grp = DRW_shgroup_instance_create(
- sh_inst, pass, geom, g_formats.instance_distance_lines);
+ DRWShadingGroup *grp = DRW_shgroup_create(sh_inst, pass);
DRW_shgroup_uniform_float(grp, "size", &point_size, 1);
if (sh_cfg == GPU_SHADER_CFG_CLIPPED) {
DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d);
}
- return grp;
+ return DRW_shgroup_call_buffer_instance(grp, g_formats.instance_distance_lines, geom);
}
-DRWShadingGroup *shgroup_spot_instance(DRWPass *pass,
- struct GPUBatch *geom,
- eGPUShaderConfig sh_cfg)
+struct DRWCallBuffer *buffer_spot_instance(DRWPass *pass,
+ struct GPUBatch *geom,
+ eGPUShaderConfig sh_cfg)
{
GPUShader *sh_inst = GPU_shader_get_builtin_shader_with_config(
GPU_SHADER_INSTANCE_EDGES_VARIYING_COLOR, sh_cfg);
@@ -653,17 +634,17 @@ DRWShadingGroup *shgroup_spot_instance(DRWPass *pass,
{"InstanceModelMatrix", DRW_ATTR_FLOAT, 16},
});
- DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom, g_formats.instance_spot);
+ DRWShadingGroup *grp = DRW_shgroup_create(sh_inst, pass);
DRW_shgroup_uniform_bool(grp, "drawFront", &False, 1);
DRW_shgroup_uniform_bool(grp, "drawBack", &False, 1);
DRW_shgroup_uniform_bool(grp, "drawSilhouette", &True, 1);
if (sh_cfg == GPU_SHADER_CFG_CLIPPED) {
DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d);
}
- return grp;
+ return DRW_shgroup_call_buffer_instance(grp, g_formats.instance_spot, geom);
}
-DRWShadingGroup *shgroup_instance_bone_axes(DRWPass *pass, eGPUShaderConfig sh_cfg)
+struct DRWCallBuffer *buffer_instance_bone_axes(DRWPass *pass, eGPUShaderConfig sh_cfg)
{
COMMON_Shaders *sh_data = &g_shaders[sh_cfg];
if (sh_data->bone_axes == NULL) {
@@ -681,16 +662,16 @@ DRWShadingGroup *shgroup_instance_bone_axes(DRWPass *pass, eGPUShaderConfig sh_c
{"color", DRW_ATTR_FLOAT, 4},
});
- DRWShadingGroup *grp = DRW_shgroup_instance_create(
- sh_data->bone_axes, pass, DRW_cache_bone_arrows_get(), g_formats.instance_color);
+ DRWShadingGroup *grp = DRW_shgroup_create(sh_data->bone_axes, pass);
DRW_shgroup_uniform_vec3(grp, "screenVecs[0]", DRW_viewport_screenvecs_get(), 2);
if (sh_cfg == GPU_SHADER_CFG_CLIPPED) {
DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d);
}
- return grp;
+ return DRW_shgroup_call_buffer_instance(
+ grp, g_formats.instance_color, DRW_cache_bone_arrows_get());
}
-DRWShadingGroup *shgroup_instance_bone_envelope_outline(DRWPass *pass, eGPUShaderConfig sh_cfg)
+struct DRWCallBuffer *buffer_instance_bone_envelope_outline(DRWPass *pass, eGPUShaderConfig sh_cfg)
{
COMMON_Shaders *sh_data = &g_shaders[sh_cfg];
if (sh_data->bone_envelope_outline == NULL) {
@@ -711,18 +692,17 @@ DRWShadingGroup *shgroup_instance_bone_envelope_outline(DRWPass *pass, eGPUShade
{"xAxis", DRW_ATTR_FLOAT, 3},
});
- DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_data->bone_envelope_outline,
- pass,
- DRW_cache_bone_envelope_outline_get(),
- g_formats.instance_bone_envelope_outline);
+ DRWShadingGroup *grp = DRW_shgroup_create(sh_data->bone_envelope_outline, pass);
DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1);
if (sh_cfg == GPU_SHADER_CFG_CLIPPED) {
DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d);
}
- return grp;
+ return DRW_shgroup_call_buffer_instance(
+ grp, g_formats.instance_bone_envelope_outline, DRW_cache_bone_envelope_outline_get());
}
-DRWShadingGroup *shgroup_instance_bone_envelope_distance(DRWPass *pass, eGPUShaderConfig sh_cfg)
+struct DRWCallBuffer *buffer_instance_bone_envelope_distance(DRWPass *pass,
+ eGPUShaderConfig sh_cfg)
{
COMMON_Shaders *sh_data = &g_shaders[sh_cfg];
if (sh_data->bone_envelope_distance == NULL) {
@@ -742,19 +722,17 @@ DRWShadingGroup *shgroup_instance_bone_envelope_distance(DRWPass *pass, eGPUShad
{"xAxis", DRW_ATTR_FLOAT, 3},
});
- DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_data->bone_envelope_distance,
- pass,
- DRW_cache_bone_envelope_solid_get(),
- g_formats.instance_bone_envelope_distance);
+ DRWShadingGroup *grp = DRW_shgroup_create(sh_data->bone_envelope_distance, pass);
if (sh_cfg == GPU_SHADER_CFG_CLIPPED) {
DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d);
}
- return grp;
+ return DRW_shgroup_call_buffer_instance(
+ grp, g_formats.instance_bone_envelope_distance, DRW_cache_bone_envelope_solid_get());
}
-DRWShadingGroup *shgroup_instance_bone_envelope_solid(DRWPass *pass,
- bool transp,
- eGPUShaderConfig sh_cfg)
+struct DRWCallBuffer *buffer_instance_bone_envelope_solid(DRWPass *pass,
+ bool transp,
+ eGPUShaderConfig sh_cfg)
{
COMMON_Shaders *sh_data = &g_shaders[sh_cfg];
if (sh_data->bone_envelope == NULL) {
@@ -776,18 +754,19 @@ DRWShadingGroup *shgroup_instance_bone_envelope_solid(DRWPass *pass,
{"xAxis", DRW_ATTR_FLOAT, 3},
});
- DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_data->bone_envelope,
- pass,
- DRW_cache_bone_envelope_solid_get(),
- g_formats.instance_bone_envelope);
+ DRWShadingGroup *grp = DRW_shgroup_create(sh_data->bone_envelope, pass);
+ /* We can have a lot of overdraw if we don't do this. Also envelope are not subject to
+ * inverted matrix. */
+ DRW_shgroup_state_enable(grp, DRW_STATE_CULL_BACK);
DRW_shgroup_uniform_float_copy(grp, "alpha", transp ? 0.6f : 1.0f);
if (sh_cfg == GPU_SHADER_CFG_CLIPPED) {
DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d);
}
- return grp;
+ return DRW_shgroup_call_buffer_instance(
+ grp, g_formats.instance_bone_envelope, DRW_cache_bone_envelope_solid_get());
}
-DRWShadingGroup *shgroup_instance_mball_handles(DRWPass *pass, eGPUShaderConfig sh_cfg)
+struct DRWCallBuffer *buffer_instance_mball_handles(DRWPass *pass, eGPUShaderConfig sh_cfg)
{
COMMON_Shaders *sh_data = &g_shaders[sh_cfg];
if (sh_data->mball_handles == NULL) {
@@ -806,28 +785,32 @@ DRWShadingGroup *shgroup_instance_mball_handles(DRWPass *pass, eGPUShaderConfig
{"color", DRW_ATTR_FLOAT, 3},
});
- DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_data->mball_handles,
- pass,
- DRW_cache_screenspace_circle_get(),
- g_formats.instance_mball_handles);
+ DRWShadingGroup *grp = DRW_shgroup_create(sh_data->mball_handles, pass);
DRW_shgroup_uniform_vec3(grp, "screen_vecs[0]", DRW_viewport_screenvecs_get(), 2);
if (sh_cfg == GPU_SHADER_CFG_CLIPPED) {
DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d);
}
- return grp;
+ return DRW_shgroup_call_buffer_instance(
+ grp, g_formats.instance_mball_handles, DRW_cache_screenspace_circle_get());
}
/* Only works with batches with adjacency infos. */
-DRWShadingGroup *shgroup_instance_bone_shape_outline(DRWPass *pass,
- struct GPUBatch *geom,
- eGPUShaderConfig sh_cfg)
+struct DRWCallBuffer *buffer_instance_bone_shape_outline(DRWPass *pass,
+ struct GPUBatch *geom,
+ eGPUShaderConfig sh_cfg)
{
COMMON_Shaders *sh_data = &g_shaders[sh_cfg];
if (sh_data->shape_outline == NULL) {
const GPUShaderConfigData *sh_cfg_data = &GPU_shader_cfg_data[sh_cfg];
sh_data->shape_outline = GPU_shader_create_from_arrays({
- .vert = (const char *[]){sh_cfg_data->lib, datatoc_armature_shape_outline_vert_glsl, NULL},
- .geom = (const char *[]){sh_cfg_data->lib, datatoc_armature_shape_outline_geom_glsl, NULL},
+ .vert = (const char *[]){sh_cfg_data->lib,
+ datatoc_common_view_lib_glsl,
+ datatoc_armature_shape_outline_vert_glsl,
+ NULL},
+ .geom = (const char *[]){sh_cfg_data->lib,
+ datatoc_common_view_lib_glsl,
+ datatoc_armature_shape_outline_geom_glsl,
+ NULL},
.frag = (const char *[]){datatoc_gpu_shader_flat_color_frag_glsl, NULL},
.defs = (const char *[]){sh_cfg_data->def, NULL},
});
@@ -839,25 +822,27 @@ DRWShadingGroup *shgroup_instance_bone_shape_outline(DRWPass *pass,
{"outlineColorSize", DRW_ATTR_FLOAT, 4},
});
- DRWShadingGroup *grp = DRW_shgroup_instance_create(
- sh_data->shape_outline, pass, geom, g_formats.instance_bone_outline);
+ DRWShadingGroup *grp = DRW_shgroup_create(sh_data->shape_outline, pass);
DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1);
if (sh_cfg == GPU_SHADER_CFG_CLIPPED) {
DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d);
}
- return grp;
+ return DRW_shgroup_call_buffer_instance(grp, g_formats.instance_bone_outline, geom);
}
-DRWShadingGroup *shgroup_instance_bone_shape_solid(DRWPass *pass,
- struct GPUBatch *geom,
- bool transp,
- eGPUShaderConfig sh_cfg)
+struct DRWCallBuffer *buffer_instance_bone_shape_solid(DRWPass *pass,
+ struct GPUBatch *geom,
+ bool transp,
+ eGPUShaderConfig sh_cfg)
{
COMMON_Shaders *sh_data = &g_shaders[sh_cfg];
if (sh_data->shape_solid == NULL) {
const GPUShaderConfigData *sh_cfg_data = &GPU_shader_cfg_data[sh_cfg];
sh_data->shape_solid = GPU_shader_create_from_arrays({
- .vert = (const char *[]){sh_cfg_data->lib, datatoc_armature_shape_solid_vert_glsl, NULL},
+ .vert = (const char *[]){sh_cfg_data->lib,
+ datatoc_common_view_lib_glsl,
+ datatoc_armature_shape_solid_vert_glsl,
+ NULL},
.frag = (const char *[]){datatoc_armature_shape_solid_frag_glsl, NULL},
.defs = (const char *[]){sh_cfg_data->def, NULL},
});
@@ -870,18 +855,17 @@ DRWShadingGroup *shgroup_instance_bone_shape_solid(DRWPass *pass,
{"stateColor", DRW_ATTR_FLOAT, 3},
});
- DRWShadingGroup *grp = DRW_shgroup_instance_create(
- sh_data->shape_solid, pass, geom, g_formats.instance_bone);
+ DRWShadingGroup *grp = DRW_shgroup_create(sh_data->shape_solid, pass);
DRW_shgroup_uniform_float_copy(grp, "alpha", transp ? 0.6f : 1.0f);
if (sh_cfg == GPU_SHADER_CFG_CLIPPED) {
DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d);
}
- return grp;
+ return DRW_shgroup_call_buffer_instance(grp, g_formats.instance_bone, geom);
}
-DRWShadingGroup *shgroup_instance_bone_sphere_solid(DRWPass *pass,
- bool transp,
- eGPUShaderConfig sh_cfg)
+struct DRWCallBuffer *buffer_instance_bone_sphere_solid(DRWPass *pass,
+ bool transp,
+ eGPUShaderConfig sh_cfg)
{
COMMON_Shaders *sh_data = &g_shaders[sh_cfg];
if (sh_data->bone_sphere == NULL) {
@@ -900,17 +884,17 @@ DRWShadingGroup *shgroup_instance_bone_sphere_solid(DRWPass *pass,
{"stateColor", DRW_ATTR_FLOAT, 3},
});
- DRWShadingGroup *grp = DRW_shgroup_instance_create(
- sh_data->bone_sphere, pass, DRW_cache_bone_point_get(), g_formats.instance_bone);
+ DRWShadingGroup *grp = DRW_shgroup_create(sh_data->bone_sphere, pass);
/* More transparent than the shape to be less distractive. */
DRW_shgroup_uniform_float_copy(grp, "alpha", transp ? 0.4f : 1.0f);
if (sh_cfg == GPU_SHADER_CFG_CLIPPED) {
DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d);
}
- return grp;
+ return DRW_shgroup_call_buffer_instance(
+ grp, g_formats.instance_bone, DRW_cache_bone_point_get());
}
-DRWShadingGroup *shgroup_instance_bone_sphere_outline(DRWPass *pass, eGPUShaderConfig sh_cfg)
+struct DRWCallBuffer *buffer_instance_bone_sphere_outline(DRWPass *pass, eGPUShaderConfig sh_cfg)
{
COMMON_Shaders *sh_data = &g_shaders[sh_cfg];
if (sh_data->bone_sphere_outline == NULL) {
@@ -929,18 +913,16 @@ DRWShadingGroup *shgroup_instance_bone_sphere_outline(DRWPass *pass, eGPUShaderC
{"outlineColorSize", DRW_ATTR_FLOAT, 4},
});
- DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_data->bone_sphere_outline,
- pass,
- DRW_cache_bone_point_wire_outline_get(),
- g_formats.instance_bone_outline);
+ DRWShadingGroup *grp = DRW_shgroup_create(sh_data->bone_sphere_outline, pass);
DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1);
if (sh_cfg == GPU_SHADER_CFG_CLIPPED) {
DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d);
}
- return grp;
+ return DRW_shgroup_call_buffer_instance(
+ grp, g_formats.instance_bone_outline, DRW_cache_bone_point_wire_outline_get());
}
-DRWShadingGroup *shgroup_instance_bone_stick(DRWPass *pass, eGPUShaderConfig sh_cfg)
+struct DRWCallBuffer *buffer_instance_bone_stick(DRWPass *pass, eGPUShaderConfig sh_cfg)
{
COMMON_Shaders *sh_data = &g_shaders[sh_cfg];
if (sh_data->bone_stick == NULL) {
@@ -963,17 +945,19 @@ DRWShadingGroup *shgroup_instance_bone_stick(DRWPass *pass, eGPUShaderConfig sh_
{"tailColor", DRW_ATTR_FLOAT, 4},
});
- DRWShadingGroup *grp = DRW_shgroup_instance_create(
- sh_data->bone_stick, pass, DRW_cache_bone_stick_get(), g_formats.instance_bone_stick);
+ DRWShadingGroup *grp = DRW_shgroup_create(sh_data->bone_stick, pass);
DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1);
DRW_shgroup_uniform_float_copy(grp, "stickSize", 5.0f * U.pixelsize);
if (sh_cfg == GPU_SHADER_CFG_CLIPPED) {
DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d);
}
- return grp;
+ return DRW_shgroup_call_buffer_instance(
+ grp, g_formats.instance_bone_stick, DRW_cache_bone_stick_get());
}
-struct DRWShadingGroup *shgroup_instance_bone_dof(struct DRWPass *pass, struct GPUBatch *geom)
+struct DRWCallBuffer *buffer_instance_bone_dof(struct DRWPass *pass,
+ struct GPUBatch *geom,
+ bool blend)
{
COMMON_Shaders *sh_data = &g_shaders[GPU_SHADER_CFG_DEFAULT];
if (sh_data->bone_dofs == NULL) {
@@ -989,10 +973,12 @@ struct DRWShadingGroup *shgroup_instance_bone_dof(struct DRWPass *pass, struct G
{"amax", DRW_ATTR_FLOAT, 2},
});
- DRWShadingGroup *grp = DRW_shgroup_instance_create(
- sh_data->bone_dofs, pass, geom, g_formats.instance_bone_dof);
-
- return grp;
+ DRWShadingGroup *grp = DRW_shgroup_create(sh_data->bone_dofs, pass);
+ if (blend) {
+ DRW_shgroup_state_enable(grp, DRW_STATE_BLEND);
+ DRW_shgroup_state_disable(grp, DRW_STATE_CULL_FRONT);
+ }
+ return DRW_shgroup_call_buffer_instance(grp, g_formats.instance_bone_dof, geom);
}
struct GPUShader *mpath_line_shader_get(void)
@@ -1028,18 +1014,23 @@ struct GPUShader *volume_velocity_shader_get(bool use_needle)
COMMON_Shaders *sh_data = &g_shaders[GPU_SHADER_CFG_DEFAULT];
if (use_needle) {
if (sh_data->volume_velocity_needle_sh == NULL) {
- sh_data->volume_velocity_needle_sh = DRW_shader_create(
+ sh_data->volume_velocity_needle_sh = DRW_shader_create_with_lib(
datatoc_volume_velocity_vert_glsl,
NULL,
datatoc_gpu_shader_flat_color_frag_glsl,
+ datatoc_common_view_lib_glsl,
"#define USE_NEEDLE");
}
return sh_data->volume_velocity_needle_sh;
}
else {
if (sh_data->volume_velocity_sh == NULL) {
- sh_data->volume_velocity_sh = DRW_shader_create(
- datatoc_volume_velocity_vert_glsl, NULL, datatoc_gpu_shader_flat_color_frag_glsl, NULL);
+ sh_data->volume_velocity_sh = DRW_shader_create_with_lib(
+ datatoc_volume_velocity_vert_glsl,
+ NULL,
+ datatoc_gpu_shader_flat_color_frag_glsl,
+ datatoc_common_view_lib_glsl,
+ NULL);
}
return sh_data->volume_velocity_sh;
}
@@ -1075,22 +1066,27 @@ int DRW_object_wire_theme_get(Object *ob, ViewLayer *view_layer, float **r_color
theme_id = (active) ? TH_ACTIVE : TH_SELECT;
}
else {
- if (ob->type == OB_LAMP) {
- theme_id = TH_LIGHT;
- }
- else if (ob->type == OB_SPEAKER) {
- theme_id = TH_SPEAKER;
- }
- else if (ob->type == OB_CAMERA) {
- theme_id = TH_CAMERA;
- }
- else if (ob->type == OB_EMPTY) {
- theme_id = TH_EMPTY;
+ switch (ob->type) {
+ case OB_LAMP:
+ theme_id = TH_LIGHT;
+ break;
+ case OB_SPEAKER:
+ theme_id = TH_SPEAKER;
+ break;
+ case OB_CAMERA:
+ theme_id = TH_CAMERA;
+ break;
+ case OB_EMPTY:
+ theme_id = TH_EMPTY;
+ break;
+ case OB_LIGHTPROBE:
+ /* TODO add lightprobe color */
+ theme_id = TH_EMPTY;
+ break;
+ default:
+ /* fallback to TH_WIRE */
+ break;
}
- else if (ob->type == OB_LIGHTPROBE) {
- theme_id = TH_EMPTY;
- } /* TODO add lightprobe color */
- /* fallback to TH_WIRE */
}
}
diff --git a/source/blender/draw/intern/draw_common.h b/source/blender/draw/intern/draw_common.h
index 489bc7459df..df7220c0d2a 100644
--- a/source/blender/draw/intern/draw_common.h
+++ b/source/blender/draw/intern/draw_common.h
@@ -23,6 +23,7 @@
#ifndef __DRAW_COMMON_H__
#define __DRAW_COMMON_H__
+struct DRWCallBuffer;
struct DRWPass;
struct DRWShadingGroup;
struct GPUBatch;
@@ -125,77 +126,74 @@ void DRW_globals_free(void);
void DRW_shgroup_world_clip_planes_from_rv3d(struct DRWShadingGroup *shgrp,
const RegionView3D *rv3d);
-struct DRWShadingGroup *shgroup_dynlines_flat_color(struct DRWPass *pass, eGPUShaderConfig sh_cfg);
-struct DRWShadingGroup *shgroup_dynlines_dashed_uniform_color(struct DRWPass *pass,
- const float color[4],
- eGPUShaderConfig sh_cfg);
-struct DRWShadingGroup *shgroup_dynpoints_uniform_color(struct DRWPass *pass,
- const float color[4],
- const float *size,
- eGPUShaderConfig sh_cfg);
-struct DRWShadingGroup *shgroup_groundlines_uniform_color(struct DRWPass *pass,
- const float color[4],
- eGPUShaderConfig sh_cfg);
-struct DRWShadingGroup *shgroup_groundpoints_uniform_color(struct DRWPass *pass,
+/* TODO(fclem) ideally, most of the DRWCallBuffer functions shouldn't create a shgroup. */
+struct DRWCallBuffer *buffer_dynlines_flat_color(struct DRWPass *pass, eGPUShaderConfig sh_cfg);
+struct DRWCallBuffer *buffer_dynlines_dashed_uniform_color(struct DRWPass *pass,
const float color[4],
eGPUShaderConfig sh_cfg);
-struct DRWShadingGroup *shgroup_instance_screenspace(struct DRWPass *pass,
+struct DRWCallBuffer *buffer_dynpoints_uniform_color(struct DRWShadingGroup *grp);
+struct DRWCallBuffer *buffer_groundlines_uniform_color(struct DRWPass *pass,
+ const float color[4],
+ eGPUShaderConfig sh_cfg);
+struct DRWCallBuffer *buffer_groundpoints_uniform_color(struct DRWPass *pass,
+ const float color[4],
+ eGPUShaderConfig sh_cfg);
+struct DRWCallBuffer *buffer_instance_screenspace(struct DRWPass *pass,
+ struct GPUBatch *geom,
+ const float *size,
+ eGPUShaderConfig sh_cfg);
+struct DRWCallBuffer *buffer_instance_solid(struct DRWPass *pass, struct GPUBatch *geom);
+struct DRWCallBuffer *buffer_instance_wire(struct DRWPass *pass, struct GPUBatch *geom);
+struct DRWCallBuffer *buffer_instance_screen_aligned(struct DRWPass *pass,
struct GPUBatch *geom,
- const float *size,
eGPUShaderConfig sh_cfg);
-struct DRWShadingGroup *shgroup_instance_solid(struct DRWPass *pass, struct GPUBatch *geom);
-struct DRWShadingGroup *shgroup_instance_wire(struct DRWPass *pass, struct GPUBatch *geom);
-struct DRWShadingGroup *shgroup_instance_screen_aligned(struct DRWPass *pass,
- struct GPUBatch *geom,
- eGPUShaderConfig sh_cfg);
-struct DRWShadingGroup *shgroup_instance_empty_axes(struct DRWPass *pass,
- struct GPUBatch *geom,
- eGPUShaderConfig sh_cfg);
-struct DRWShadingGroup *shgroup_instance_scaled(struct DRWPass *pass,
- struct GPUBatch *geom,
- eGPUShaderConfig sh_cfg);
-struct DRWShadingGroup *shgroup_instance(struct DRWPass *pass,
- struct GPUBatch *geom,
- eGPUShaderConfig sh_cfg);
-struct DRWShadingGroup *shgroup_instance_alpha(struct DRWPass *pass,
- struct GPUBatch *geom,
- eGPUShaderConfig sh_cfg);
-struct DRWShadingGroup *shgroup_instance_outline(struct DRWPass *pass,
+struct DRWCallBuffer *buffer_instance_empty_axes(struct DRWPass *pass,
struct GPUBatch *geom,
- int *baseid);
-struct DRWShadingGroup *shgroup_camera_instance(struct DRWPass *pass,
- struct GPUBatch *geom,
- eGPUShaderConfig sh_cfg);
-struct DRWShadingGroup *shgroup_distance_lines_instance(struct DRWPass *pass,
- struct GPUBatch *geom,
- eGPUShaderConfig sh_cfg);
-struct DRWShadingGroup *shgroup_spot_instance(struct DRWPass *pass,
+ eGPUShaderConfig sh_cfg);
+struct DRWCallBuffer *buffer_instance_scaled(struct DRWPass *pass,
+ struct GPUBatch *geom,
+ eGPUShaderConfig sh_cfg);
+struct DRWCallBuffer *buffer_instance(struct DRWPass *pass,
+ struct GPUBatch *geom,
+ eGPUShaderConfig sh_cfg);
+struct DRWCallBuffer *buffer_instance_alpha(struct DRWShadingGroup *grp, struct GPUBatch *geom);
+struct DRWCallBuffer *buffer_instance_outline(struct DRWPass *pass,
struct GPUBatch *geom,
- eGPUShaderConfig sh_cfg);
-struct DRWShadingGroup *shgroup_instance_mball_handles(struct DRWPass *pass,
- eGPUShaderConfig sh_cfg);
-struct DRWShadingGroup *shgroup_instance_bone_axes(struct DRWPass *pass, eGPUShaderConfig sh_cfg);
-struct DRWShadingGroup *shgroup_instance_bone_envelope_distance(struct DRWPass *pass,
- eGPUShaderConfig sh_cfg);
-struct DRWShadingGroup *shgroup_instance_bone_envelope_outline(struct DRWPass *pass,
- eGPUShaderConfig sh_cfg);
-struct DRWShadingGroup *shgroup_instance_bone_envelope_solid(struct DRWPass *pass,
- bool transp,
+ int *baseid);
+struct DRWCallBuffer *buffer_camera_instance(struct DRWPass *pass,
+ struct GPUBatch *geom,
+ eGPUShaderConfig sh_cfg);
+struct DRWCallBuffer *buffer_distance_lines_instance(struct DRWPass *pass,
+ struct GPUBatch *geom,
+ eGPUShaderConfig sh_cfg);
+struct DRWCallBuffer *buffer_spot_instance(struct DRWPass *pass,
+ struct GPUBatch *geom,
+ eGPUShaderConfig sh_cfg);
+struct DRWCallBuffer *buffer_instance_mball_handles(struct DRWPass *pass, eGPUShaderConfig sh_cfg);
+struct DRWCallBuffer *buffer_instance_bone_axes(struct DRWPass *pass, eGPUShaderConfig sh_cfg);
+struct DRWCallBuffer *buffer_instance_bone_envelope_distance(struct DRWPass *pass,
eGPUShaderConfig sh_cfg);
-struct DRWShadingGroup *shgroup_instance_bone_shape_outline(struct DRWPass *pass,
- struct GPUBatch *geom,
+struct DRWCallBuffer *buffer_instance_bone_envelope_outline(struct DRWPass *pass,
eGPUShaderConfig sh_cfg);
-struct DRWShadingGroup *shgroup_instance_bone_shape_solid(struct DRWPass *pass,
- struct GPUBatch *geom,
+struct DRWCallBuffer *buffer_instance_bone_envelope_solid(struct DRWPass *pass,
bool transp,
eGPUShaderConfig sh_cfg);
-struct DRWShadingGroup *shgroup_instance_bone_sphere_outline(struct DRWPass *pass,
- eGPUShaderConfig sh_cfg);
-struct DRWShadingGroup *shgroup_instance_bone_sphere_solid(struct DRWPass *pass,
- bool transp,
- eGPUShaderConfig sh_cfg);
-struct DRWShadingGroup *shgroup_instance_bone_stick(struct DRWPass *pass, eGPUShaderConfig sh_cfg);
-struct DRWShadingGroup *shgroup_instance_bone_dof(struct DRWPass *pass, struct GPUBatch *geom);
+struct DRWCallBuffer *buffer_instance_bone_shape_outline(struct DRWPass *pass,
+ struct GPUBatch *geom,
+ eGPUShaderConfig sh_cfg);
+struct DRWCallBuffer *buffer_instance_bone_shape_solid(struct DRWPass *pass,
+ struct GPUBatch *geom,
+ bool transp,
+ eGPUShaderConfig sh_cfg);
+struct DRWCallBuffer *buffer_instance_bone_sphere_outline(struct DRWPass *pass,
+ eGPUShaderConfig sh_cfg);
+struct DRWCallBuffer *buffer_instance_bone_sphere_solid(struct DRWPass *pass,
+ bool transp,
+ eGPUShaderConfig sh_cfg);
+struct DRWCallBuffer *buffer_instance_bone_stick(struct DRWPass *pass, eGPUShaderConfig sh_cfg);
+struct DRWCallBuffer *buffer_instance_bone_dof(struct DRWPass *pass,
+ struct GPUBatch *geom,
+ bool blend);
struct GPUShader *mpath_line_shader_get(void);
struct GPUShader *mpath_points_shader_get(void);
diff --git a/source/blender/draw/intern/draw_hair.c b/source/blender/draw/intern/draw_hair.c
index cb83265195a..6dee25fabae 100644
--- a/source/blender/draw/intern/draw_hair.c
+++ b/source/blender/draw/intern/draw_hair.c
@@ -195,7 +195,7 @@ static DRWShadingGroup *drw_shgroup_create_hair_procedural_ex(Object *object,
shgrp, "hairCloseTip", (part->shape_flag & PART_SHAPE_CLOSE_TIP) != 0);
/* TODO(fclem): Until we have a better way to cull the hair and render with orco, bypass culling
* test. */
- DRW_shgroup_call_object_add_no_cull(
+ DRW_shgroup_call_object_no_cull(
shgrp, hair_cache->final[subdiv].proc_hairs[thickness_res - 1], object);
/* Transform Feedback subdiv. */
@@ -224,7 +224,7 @@ static DRWShadingGroup *drw_shgroup_create_hair_procedural_ex(Object *object,
DRW_shgroup_uniform_texture(tf_shgrp, "hairStrandBuffer", hair_cache->strand_tex);
DRW_shgroup_uniform_texture(tf_shgrp, "hairStrandSegBuffer", hair_cache->strand_seg_tex);
DRW_shgroup_uniform_int(tf_shgrp, "hairStrandsRes", &hair_cache->final[subdiv].strands_res, 1);
- DRW_shgroup_call_procedural_points_add(tf_shgrp, final_points_len, NULL);
+ DRW_shgroup_call_procedural_points(tf_shgrp, final_points_len, NULL);
}
return shgrp;
diff --git a/source/blender/draw/intern/draw_instance_data.c b/source/blender/draw/intern/draw_instance_data.c
index e8d91309e06..b88ad936c28 100644
--- a/source/blender/draw/intern/draw_instance_data.c
+++ b/source/blender/draw/intern/draw_instance_data.c
@@ -36,33 +36,9 @@
#include "MEM_guardedalloc.h"
#include "BLI_utildefines.h"
#include "BLI_mempool.h"
+#include "BLI_memblock.h"
-#define BUFFER_CHUNK_SIZE 32
-#define BUFFER_VERTS_CHUNK 32
-
-typedef struct DRWBatchingBuffer {
- struct DRWShadingGroup *shgroup; /* Link back to the owning shGroup. Also tells if it's used */
- GPUVertFormat *format; /* Identifier. */
- GPUVertBuf *vert; /* GPUVertBuf contained in the GPUBatch. */
- GPUBatch *batch; /* GPUBatch containing the GPUVertBuf. */
-} DRWBatchingBuffer;
-
-typedef struct DRWInstancingBuffer {
- struct DRWShadingGroup *shgroup; /* Link back to the owning shGroup. Also tells if it's used */
- GPUVertFormat *format; /* Identifier. */
- GPUBatch *instance; /* Identifier. */
- GPUVertBuf *vert; /* GPUVertBuf contained in the GPUBatch. */
- GPUBatch *batch; /* GPUBatch containing the GPUVertBuf. */
-} DRWInstancingBuffer;
-
-typedef struct DRWInstanceChunk {
- size_t cursor; /* Offset to the next instance data. */
- size_t alloc_size; /* Number of DRWBatchingBuffer/Batches alloc'd in ibufs/btchs. */
- union {
- DRWBatchingBuffer *bbufs;
- DRWInstancingBuffer *ibufs;
- };
-} DRWInstanceChunk;
+#include "intern/gpu_primitive_private.h"
struct DRWInstanceData {
struct DRWInstanceData *next;
@@ -77,212 +53,167 @@ struct DRWInstanceDataList {
DRWInstanceData *idata_head[MAX_INSTANCE_DATA_SIZE];
DRWInstanceData *idata_tail[MAX_INSTANCE_DATA_SIZE];
- DRWInstanceChunk instancing;
- DRWInstanceChunk batching;
+ BLI_memblock *pool_instancing;
+ BLI_memblock *pool_batching;
+ BLI_memblock *pool_buffers;
};
+typedef struct DRWTempBufferHandle {
+ /** Must be first for casting. */
+ GPUVertBuf buf;
+ /** Format pointer for reuse. */
+ GPUVertFormat *format;
+ /** Touched vertex length for resize. */
+ uint *vert_len;
+} DRWTempBufferHandle;
+
static ListBase g_idatalists = {NULL, NULL};
/* -------------------------------------------------------------------- */
/** \name Instance Buffer Management
* \{ */
-/**
- * This manager allows to distribute existing batches for instancing
- * attributes. This reduce the number of batches creation.
- * Querying a batch is done with a vertex format. This format should
- * be static so that it's pointer never changes (because we are using
- * this pointer as identifier [we don't want to check the full format
- * that would be too slow]).
- */
-static void instance_batch_free(GPUBatch *batch, void *UNUSED(user_data))
+static void instance_batch_free(GPUBatch *geom, void *UNUSED(user_data))
{
- if (batch->verts[0] == NULL) {
+ if (geom->verts[0] == NULL) {
/** XXX This is a false positive case.
* The batch has been requested but not init yet
* and there is a chance that it might become init.
*/
return;
}
- /* Free all batches that have the same key before they are reused. */
+
+ /* Free all batches that use the same vbos before they are reused. */
/* TODO: Make it thread safe! Batch freeing can happen from another thread. */
- /* XXX we need to iterate over all idatalists unless we make some smart
- * data structure to store the locations to update. */
- for (DRWInstanceDataList *idatalist = g_idatalists.first; idatalist;
- idatalist = idatalist->next) {
- DRWInstancingBuffer *ibuf = idatalist->instancing.ibufs;
- for (int i = 0; i < idatalist->instancing.alloc_size; i++, ibuf++) {
- if (ibuf->instance == batch) {
- BLI_assert(ibuf->shgroup == NULL); /* Make sure it has no other users. */
- GPU_VERTBUF_DISCARD_SAFE(ibuf->vert);
- GPU_BATCH_DISCARD_SAFE(ibuf->batch);
- /* Tag as non alloced. */
- ibuf->format = NULL;
+ /* FIXME: This is not really correct. The correct way would be to check based on
+ * the vertex buffers. We assume the batch containing the VBO is being when it should. */
+ /* PERF: This is doing a linear search. This can be very costly. */
+ LISTBASE_FOREACH (DRWInstanceDataList *, data_list, &g_idatalists) {
+ BLI_memblock *memblock = data_list->pool_instancing;
+ BLI_memblock_iter iter;
+ BLI_memblock_iternew(memblock, &iter);
+ GPUBatch *batch;
+ while ((batch = (GPUBatch *)BLI_memblock_iterstep(&iter))) {
+ /* Only check verts[0] that's enough. */
+ if (batch->verts[0] == geom->verts[0]) {
+ GPU_batch_clear(batch);
}
}
}
}
-void DRW_batching_buffer_request(DRWInstanceDataList *idatalist,
- GPUVertFormat *format,
- GPUPrimType type,
- struct DRWShadingGroup *shgroup,
- GPUBatch **r_batch,
- GPUVertBuf **r_vert)
+/**
+ * This manager allows to distribute existing batches for instancing
+ * attributes. This reduce the number of batches creation.
+ * Querying a batch is done with a vertex format. This format should
+ * be static so that it's pointer never changes (because we are using
+ * this pointer as identifier [we don't want to check the full format
+ * that would be too slow]).
+ */
+GPUVertBuf *DRW_temp_buffer_request(DRWInstanceDataList *idatalist,
+ GPUVertFormat *format,
+ uint *vert_len)
{
- DRWInstanceChunk *chunk = &idatalist->batching;
- DRWBatchingBuffer *bbuf = idatalist->batching.bbufs;
- BLI_assert(format);
- /* Search for an unused batch. */
- for (int i = 0; i < idatalist->batching.alloc_size; i++, bbuf++) {
- if (bbuf->shgroup == NULL) {
- if (bbuf->format == format) {
- bbuf->shgroup = shgroup;
- *r_batch = bbuf->batch;
- *r_vert = bbuf->vert;
- return;
- }
- }
- }
- int new_id = 0; /* Find insertion point. */
- for (; new_id < chunk->alloc_size; ++new_id) {
- if (chunk->bbufs[new_id].format == NULL) {
- break;
- }
+ BLI_assert(format != NULL);
+ BLI_assert(vert_len != NULL);
+
+ DRWTempBufferHandle *handle = BLI_memblock_alloc(idatalist->pool_buffers);
+ GPUVertBuf *vert = &handle->buf;
+ handle->vert_len = vert_len;
+
+ if (handle->format != format) {
+ handle->format = format;
+ /* TODO/PERF: Save the allocated data from freeing to avoid reallocation. */
+ GPU_vertbuf_clear(vert);
+ GPU_vertbuf_init_with_format_ex(vert, format, GPU_USAGE_DYNAMIC);
+ GPU_vertbuf_data_alloc(vert, DRW_BUFFER_VERTS_CHUNK);
}
- /* If there is no batch left. Allocate more. */
- if (new_id == chunk->alloc_size) {
- new_id = chunk->alloc_size;
- chunk->alloc_size += BUFFER_CHUNK_SIZE;
- chunk->bbufs = MEM_reallocN(chunk->bbufs, chunk->alloc_size * sizeof(DRWBatchingBuffer));
- memset(chunk->bbufs + new_id, 0, sizeof(DRWBatchingBuffer) * BUFFER_CHUNK_SIZE);
- }
- /* Create the batch. */
- bbuf = chunk->bbufs + new_id;
- bbuf->vert = *r_vert = GPU_vertbuf_create_with_format_ex(format, GPU_USAGE_DYNAMIC);
- bbuf->batch = *r_batch = GPU_batch_create_ex(type, bbuf->vert, NULL, 0);
- bbuf->format = format;
- bbuf->shgroup = shgroup;
- GPU_vertbuf_data_alloc(*r_vert, BUFFER_VERTS_CHUNK);
+ return vert;
}
-void DRW_instancing_buffer_request(DRWInstanceDataList *idatalist,
- GPUVertFormat *format,
- GPUBatch *instance,
- struct DRWShadingGroup *shgroup,
- GPUBatch **r_batch,
- GPUVertBuf **r_vert)
+/* NOTE: Does not return a valid drawable batch until DRW_instance_buffer_finish has run. */
+GPUBatch *DRW_temp_batch_instance_request(DRWInstanceDataList *idatalist,
+ GPUVertBuf *buf,
+ GPUBatch *geom)
{
- DRWInstanceChunk *chunk = &idatalist->instancing;
- DRWInstancingBuffer *ibuf = idatalist->instancing.ibufs;
- BLI_assert(format);
- /* Search for an unused batch. */
- for (int i = 0; i < idatalist->instancing.alloc_size; i++, ibuf++) {
- if (ibuf->shgroup == NULL) {
- if (ibuf->format == format) {
- if (ibuf->instance == instance) {
- ibuf->shgroup = shgroup;
- *r_batch = ibuf->batch;
- *r_vert = ibuf->vert;
- return;
- }
- }
+ /* Do not call this with a batch that is already an instancing batch. */
+ BLI_assert(geom->inst == NULL);
+
+ GPUBatch *batch = BLI_memblock_alloc(idatalist->pool_instancing);
+ bool is_compatible = (batch->gl_prim_type == geom->gl_prim_type) && (batch->inst == buf) &&
+ (batch->phase == GPU_BATCH_READY_TO_DRAW);
+ for (int i = 0; i < GPU_BATCH_VBO_MAX_LEN && is_compatible; i++) {
+ if (batch->verts[i] != geom->verts[i]) {
+ is_compatible = false;
}
}
- int new_id = 0; /* Find insertion point. */
- for (; new_id < chunk->alloc_size; ++new_id) {
- if (chunk->ibufs[new_id].format == NULL) {
- break;
- }
+
+ if (!is_compatible) {
+ GPU_batch_clear(batch);
+ /* Save args and init later */
+ batch->inst = buf;
+ batch->phase = GPU_BATCH_READY_TO_BUILD;
+ batch->verts[0] = (void *)geom; /* HACK to save the pointer without other alloc. */
+
+ /* Make sure to free this batch if the instance geom gets free. */
+ GPU_batch_callback_free_set(geom, &instance_batch_free, NULL);
}
- /* If there is no batch left. Allocate more. */
- if (new_id == chunk->alloc_size) {
- new_id = chunk->alloc_size;
- chunk->alloc_size += BUFFER_CHUNK_SIZE;
- chunk->ibufs = MEM_reallocN(chunk->ibufs, chunk->alloc_size * sizeof(DRWInstancingBuffer));
- memset(chunk->ibufs + new_id, 0, sizeof(DRWInstancingBuffer) * BUFFER_CHUNK_SIZE);
+ return batch;
+}
+
+/* NOTE: Use only with buf allocated via DRW_temp_buffer_request. */
+GPUBatch *DRW_temp_batch_request(DRWInstanceDataList *idatalist,
+ GPUVertBuf *buf,
+ GPUPrimType prim_type)
+{
+ GPUBatch *batch = BLI_memblock_alloc(idatalist->pool_batching);
+ bool is_compatible = (batch->verts[0] == buf) &&
+ (batch->gl_prim_type == convert_prim_type_to_gl(prim_type));
+ if (!is_compatible) {
+ GPU_batch_clear(batch);
+ GPU_batch_init(batch, prim_type, buf, NULL);
}
- /* Create the batch. */
- ibuf = chunk->ibufs + new_id;
- ibuf->vert = *r_vert = GPU_vertbuf_create_with_format_ex(format, GPU_USAGE_DYNAMIC);
- ibuf->batch = *r_batch = MEM_callocN(sizeof(GPUBatch), "GPUBatch");
- ibuf->format = format;
- ibuf->shgroup = shgroup;
- ibuf->instance = instance;
- GPU_vertbuf_data_alloc(*r_vert, BUFFER_VERTS_CHUNK);
- /* Make sure to free this ibuf if the instance batch gets free. */
- GPU_batch_callback_free_set(instance, &instance_batch_free, NULL);
+ return batch;
+}
+
+static void temp_buffer_handle_free(DRWTempBufferHandle *handle)
+{
+ handle->format = NULL;
+ GPU_vertbuf_clear(&handle->buf);
}
void DRW_instance_buffer_finish(DRWInstanceDataList *idatalist)
{
- size_t realloc_size = 1; /* Avoid 0 size realloc. */
- /* Resize down buffers in use and send data to GPU & free unused buffers. */
- DRWInstanceChunk *batching = &idatalist->batching;
- DRWBatchingBuffer *bbuf = batching->bbufs;
- for (int i = 0; i < batching->alloc_size; i++, bbuf++) {
- if (bbuf->shgroup != NULL) {
- realloc_size = i + 1;
- uint vert_len = DRW_shgroup_get_instance_count(bbuf->shgroup);
- vert_len += (vert_len == 0) ? 1 : 0; /* Do not realloc to 0 size buffer */
- if (vert_len + BUFFER_VERTS_CHUNK <= bbuf->vert->vertex_len) {
- uint size = vert_len + BUFFER_VERTS_CHUNK - 1;
- size = size - size % BUFFER_VERTS_CHUNK;
- GPU_vertbuf_data_resize(bbuf->vert, size);
+ /* Resize down buffers in use and send data to GPU. */
+ BLI_memblock_iter iter;
+ DRWTempBufferHandle *handle;
+ BLI_memblock_iternew(idatalist->pool_buffers, &iter);
+ while ((handle = BLI_memblock_iterstep(&iter))) {
+ if (handle->vert_len != NULL) {
+ uint vert_len = *(handle->vert_len);
+ uint target_buf_size = ((vert_len / DRW_BUFFER_VERTS_CHUNK) + 1) * DRW_BUFFER_VERTS_CHUNK;
+ if (target_buf_size < handle->buf.vertex_alloc) {
+ GPU_vertbuf_data_resize(&handle->buf, target_buf_size);
}
- GPU_vertbuf_use(bbuf->vert); /* Send data. */
- bbuf->shgroup = NULL; /* Set as non used for the next round. */
- }
- else {
- GPU_VERTBUF_DISCARD_SAFE(bbuf->vert);
- GPU_BATCH_DISCARD_SAFE(bbuf->batch);
- bbuf->format = NULL; /* Tag as non alloced. */
+ GPU_vertbuf_data_len_set(&handle->buf, vert_len);
+ GPU_vertbuf_use(&handle->buf); /* Send data. */
}
}
- /* Rounding up to nearest chunk size. */
- realloc_size += BUFFER_CHUNK_SIZE - 1;
- realloc_size -= realloc_size % BUFFER_CHUNK_SIZE;
- /* Resize down if necessary. */
- if (realloc_size < batching->alloc_size) {
- batching->alloc_size = realloc_size;
- batching->ibufs = MEM_reallocN(batching->ibufs, realloc_size * sizeof(DRWBatchingBuffer));
- }
-
- realloc_size = 1;
- /* Resize down buffers in use and send data to GPU & free unused buffers. */
- DRWInstanceChunk *instancing = &idatalist->instancing;
- DRWInstancingBuffer *ibuf = instancing->ibufs;
- for (int i = 0; i < instancing->alloc_size; i++, ibuf++) {
- if (ibuf->shgroup != NULL) {
- realloc_size = i + 1;
- uint vert_len = DRW_shgroup_get_instance_count(ibuf->shgroup);
- vert_len += (vert_len == 0) ? 1 : 0; /* Do not realloc to 0 size buffer */
- if (vert_len + BUFFER_VERTS_CHUNK <= ibuf->vert->vertex_len) {
- uint size = vert_len + BUFFER_VERTS_CHUNK - 1;
- size = size - size % BUFFER_VERTS_CHUNK;
- GPU_vertbuf_data_resize(ibuf->vert, size);
- }
- GPU_vertbuf_use(ibuf->vert); /* Send data. */
- /* Setup batch now that we are sure ibuf->instance is setup. */
- GPU_batch_copy(ibuf->batch, ibuf->instance);
- GPU_batch_instbuf_set(ibuf->batch, ibuf->vert, false);
- ibuf->shgroup = NULL; /* Set as non used for the next round. */
- }
- else {
- GPU_VERTBUF_DISCARD_SAFE(ibuf->vert);
- GPU_BATCH_DISCARD_SAFE(ibuf->batch);
- ibuf->format = NULL; /* Tag as non alloced. */
+ /* Finish pending instancing batches. */
+ GPUBatch *batch;
+ BLI_memblock_iternew(idatalist->pool_instancing, &iter);
+ while ((batch = BLI_memblock_iterstep(&iter))) {
+ if (batch->phase == GPU_BATCH_READY_TO_BUILD) {
+ GPUVertBuf *inst = batch->inst;
+ GPUBatch *geom = (void *)batch->verts[0]; /* HACK see DRW_temp_batch_instance_request. */
+ GPU_batch_copy(batch, geom);
+ GPU_batch_instbuf_set(batch, inst, false);
}
}
- /* Rounding up to nearest chunk size. */
- realloc_size += BUFFER_CHUNK_SIZE - 1;
- realloc_size -= realloc_size % BUFFER_CHUNK_SIZE;
- /* Resize down if necessary. */
- if (realloc_size < instancing->alloc_size) {
- instancing->alloc_size = realloc_size;
- instancing->ibufs = MEM_reallocN(instancing->ibufs,
- realloc_size * sizeof(DRWInstancingBuffer));
- }
+ /* Resize pools and free unused. */
+ BLI_memblock_clear(idatalist->pool_buffers, (MemblockValFreeFP)temp_buffer_handle_free);
+ BLI_memblock_clear(idatalist->pool_instancing, (MemblockValFreeFP)GPU_batch_clear);
+ BLI_memblock_clear(idatalist->pool_batching, (MemblockValFreeFP)GPU_batch_clear);
}
/** \} */
@@ -352,12 +283,10 @@ DRWInstanceData *DRW_instance_data_request(DRWInstanceDataList *idatalist, uint
DRWInstanceDataList *DRW_instance_data_list_create(void)
{
DRWInstanceDataList *idatalist = MEM_callocN(sizeof(DRWInstanceDataList), "DRWInstanceDataList");
- idatalist->batching.bbufs = MEM_callocN(sizeof(DRWBatchingBuffer) * BUFFER_CHUNK_SIZE,
- "DRWBatchingBuffers");
- idatalist->batching.alloc_size = BUFFER_CHUNK_SIZE;
- idatalist->instancing.ibufs = MEM_callocN(sizeof(DRWInstancingBuffer) * BUFFER_CHUNK_SIZE,
- "DRWInstancingBuffers");
- idatalist->instancing.alloc_size = BUFFER_CHUNK_SIZE;
+
+ idatalist->pool_batching = BLI_memblock_create(sizeof(GPUBatch), true);
+ idatalist->pool_instancing = BLI_memblock_create(sizeof(GPUBatch), true);
+ idatalist->pool_buffers = BLI_memblock_create(sizeof(DRWTempBufferHandle), true);
BLI_addtail(&g_idatalists, idatalist);
@@ -378,19 +307,9 @@ void DRW_instance_data_list_free(DRWInstanceDataList *idatalist)
idatalist->idata_tail[i] = NULL;
}
- DRWBatchingBuffer *bbuf = idatalist->batching.bbufs;
- for (int i = 0; i < idatalist->batching.alloc_size; i++, bbuf++) {
- GPU_VERTBUF_DISCARD_SAFE(bbuf->vert);
- GPU_BATCH_DISCARD_SAFE(bbuf->batch);
- }
- MEM_freeN(idatalist->batching.bbufs);
-
- DRWInstancingBuffer *ibuf = idatalist->instancing.ibufs;
- for (int i = 0; i < idatalist->instancing.alloc_size; i++, ibuf++) {
- GPU_VERTBUF_DISCARD_SAFE(ibuf->vert);
- GPU_BATCH_DISCARD_SAFE(ibuf->batch);
- }
- MEM_freeN(idatalist->instancing.ibufs);
+ BLI_memblock_destroy(idatalist->pool_buffers, (MemblockValFreeFP)temp_buffer_handle_free);
+ BLI_memblock_destroy(idatalist->pool_instancing, (MemblockValFreeFP)GPU_batch_clear);
+ BLI_memblock_destroy(idatalist->pool_batching, (MemblockValFreeFP)GPU_batch_clear);
BLI_remlink(&g_idatalists, idatalist);
}
diff --git a/source/blender/draw/intern/draw_instance_data.h b/source/blender/draw/intern/draw_instance_data.h
index ea5c6ac7bb2..d88de1a58e2 100644
--- a/source/blender/draw/intern/draw_instance_data.h
+++ b/source/blender/draw/intern/draw_instance_data.h
@@ -30,6 +30,8 @@
#define MAX_INSTANCE_DATA_SIZE 64 /* Can be adjusted for more */
+#define DRW_BUFFER_VERTS_CHUNK 128
+
typedef struct DRWInstanceData DRWInstanceData;
typedef struct DRWInstanceDataList DRWInstanceDataList;
@@ -38,18 +40,15 @@ struct DRWShadingGroup;
void *DRW_instance_data_next(DRWInstanceData *idata);
DRWInstanceData *DRW_instance_data_request(DRWInstanceDataList *idatalist, uint attr_size);
-void DRW_batching_buffer_request(DRWInstanceDataList *idatalist,
- GPUVertFormat *format,
- GPUPrimType type,
- struct DRWShadingGroup *shgroup,
- GPUBatch **r_batch,
- GPUVertBuf **r_vert);
-void DRW_instancing_buffer_request(DRWInstanceDataList *idatalist,
- GPUVertFormat *format,
- GPUBatch *instance,
- struct DRWShadingGroup *shgroup,
- GPUBatch **r_batch,
- GPUVertBuf **r_vert);
+GPUVertBuf *DRW_temp_buffer_request(DRWInstanceDataList *idatalist,
+ GPUVertFormat *format,
+ uint *vert_len);
+GPUBatch *DRW_temp_batch_instance_request(DRWInstanceDataList *idatalist,
+ GPUVertBuf *buf,
+ GPUBatch *geom);
+GPUBatch *DRW_temp_batch_request(DRWInstanceDataList *idatalist,
+ GPUVertBuf *buf,
+ GPUPrimType type);
/* Upload all instance data to the GPU as soon as possible. */
void DRW_instance_buffer_finish(DRWInstanceDataList *idatalist);
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index 3161528be79..cb4fc826324 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -22,16 +22,19 @@
#include <stdio.h>
+#include "BLI_alloca.h"
#include "BLI_listbase.h"
-#include "BLI_mempool.h"
+#include "BLI_memblock.h"
#include "BLI_rect.h"
#include "BLI_string.h"
#include "BLI_threads.h"
#include "BLF_api.h"
+#include "BKE_anim.h"
#include "BKE_colortools.h"
#include "BKE_curve.h"
+#include "BKE_editmesh.h"
#include "BKE_global.h"
#include "BKE_gpencil.h"
#include "BKE_lattice.h"
@@ -527,19 +530,19 @@ static void drw_viewport_cache_resize(void)
if (DST.vmempool != NULL) {
/* Release Image textures. */
- BLI_mempool_iter iter;
+ BLI_memblock_iter iter;
GPUTexture **tex;
- BLI_mempool_iternew(DST.vmempool->images, &iter);
- while ((tex = BLI_mempool_iterstep(&iter))) {
+ BLI_memblock_iternew(DST.vmempool->images, &iter);
+ while ((tex = BLI_memblock_iterstep(&iter))) {
GPU_texture_free(*tex);
}
- BLI_mempool_clear_ex(DST.vmempool->calls, BLI_mempool_len(DST.vmempool->calls));
- BLI_mempool_clear_ex(DST.vmempool->states, BLI_mempool_len(DST.vmempool->states));
- BLI_mempool_clear_ex(DST.vmempool->shgroups, BLI_mempool_len(DST.vmempool->shgroups));
- BLI_mempool_clear_ex(DST.vmempool->uniforms, BLI_mempool_len(DST.vmempool->uniforms));
- BLI_mempool_clear_ex(DST.vmempool->passes, BLI_mempool_len(DST.vmempool->passes));
- BLI_mempool_clear_ex(DST.vmempool->images, BLI_mempool_len(DST.vmempool->images));
+ BLI_memblock_clear(DST.vmempool->calls, NULL);
+ BLI_memblock_clear(DST.vmempool->states, NULL);
+ BLI_memblock_clear(DST.vmempool->shgroups, NULL);
+ BLI_memblock_clear(DST.vmempool->uniforms, NULL);
+ BLI_memblock_clear(DST.vmempool->passes, NULL);
+ BLI_memblock_clear(DST.vmempool->images, NULL);
}
DRW_instance_data_list_free_unused(DST.idatalist);
@@ -604,24 +607,22 @@ static void drw_viewport_var_init(void)
DST.vmempool = GPU_viewport_mempool_get(DST.viewport);
if (DST.vmempool->calls == NULL) {
- DST.vmempool->calls = BLI_mempool_create(sizeof(DRWCall), 0, 512, 0);
+ DST.vmempool->calls = BLI_memblock_create(sizeof(DRWCall), false);
}
if (DST.vmempool->states == NULL) {
- DST.vmempool->states = BLI_mempool_create(
- sizeof(DRWCallState), 0, 512, BLI_MEMPOOL_ALLOW_ITER);
+ DST.vmempool->states = BLI_memblock_create(sizeof(DRWCallState), false);
}
if (DST.vmempool->shgroups == NULL) {
- DST.vmempool->shgroups = BLI_mempool_create(sizeof(DRWShadingGroup), 0, 256, 0);
+ DST.vmempool->shgroups = BLI_memblock_create(sizeof(DRWShadingGroup), false);
}
if (DST.vmempool->uniforms == NULL) {
- DST.vmempool->uniforms = BLI_mempool_create(sizeof(DRWUniform), 0, 512, 0);
+ DST.vmempool->uniforms = BLI_memblock_create(sizeof(DRWUniform), false);
}
if (DST.vmempool->passes == NULL) {
- DST.vmempool->passes = BLI_mempool_create(sizeof(DRWPass), 0, 64, 0);
+ DST.vmempool->passes = BLI_memblock_create(sizeof(DRWPass), false);
}
if (DST.vmempool->images == NULL) {
- DST.vmempool->images = BLI_mempool_create(
- sizeof(GPUTexture *), 0, 512, BLI_MEMPOOL_ALLOW_ITER);
+ DST.vmempool->images = BLI_memblock_create(sizeof(GPUTexture *), false);
}
DST.idatalist = GPU_viewport_instance_data_list_get(DST.viewport);
@@ -791,6 +792,75 @@ void DRW_viewport_request_redraw(void)
/** \} */
/* -------------------------------------------------------------------- */
+/** \name Duplis
+ * \{ */
+
+static void drw_duplidata_load(DupliObject *dupli)
+{
+ if (dupli == NULL) {
+ return;
+ }
+
+ if (DST.dupli_origin != dupli->ob) {
+ DST.dupli_origin = dupli->ob;
+ }
+ else {
+ /* Same data as previous iter. No need to poll ghash for this. */
+ return;
+ }
+
+ if (DST.dupli_ghash == NULL) {
+ DST.dupli_ghash = BLI_ghash_ptr_new(__func__);
+ }
+
+ void **value;
+ if (!BLI_ghash_ensure_p(DST.dupli_ghash, DST.dupli_origin, &value)) {
+ *value = MEM_callocN(sizeof(void *) * DST.enabled_engine_count, __func__);
+
+ /* TODO: Meh a bit out of place but this is nice as it is
+ * only done once per "original" object. */
+ drw_batch_cache_validate(DST.dupli_origin);
+ }
+ DST.dupli_datas = *(void ***)value;
+}
+
+static void duplidata_value_free(void *val)
+{
+ void **dupli_datas = val;
+ for (int i = 0; i < DST.enabled_engine_count; i++) {
+ MEM_SAFE_FREE(dupli_datas[i]);
+ }
+ MEM_freeN(val);
+}
+
+static void drw_duplidata_free(void)
+{
+ if (DST.dupli_ghash != NULL) {
+ BLI_ghash_free(DST.dupli_ghash,
+ (void (*)(void *key))drw_batch_cache_generate_requested,
+ duplidata_value_free);
+ DST.dupli_ghash = NULL;
+ }
+}
+
+/* Return NULL if not a dupli or a pointer of pointer to the engine data */
+void **DRW_duplidata_get(void *vedata)
+{
+ if (DST.dupli_source == NULL) {
+ return NULL;
+ }
+ /* XXX Search engine index by using vedata array */
+ for (int i = 0; i < DST.enabled_engine_count; i++) {
+ if (DST.vedata_array[i] == vedata) {
+ return &DST.dupli_datas[i];
+ }
+ }
+ return NULL;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name ViewLayers (DRW_scenelayer)
* \{ */
@@ -1046,9 +1116,14 @@ static void drw_engines_init(void)
static void drw_engines_cache_init(void)
{
- for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
+ DST.enabled_engine_count = BLI_listbase_count(&DST.enabled_engines);
+ DST.vedata_array = MEM_mallocN(sizeof(void *) * DST.enabled_engine_count, __func__);
+
+ int i = 0;
+ for (LinkData *link = DST.enabled_engines.first; link; link = link->next, i++) {
DrawEngineType *engine = link->data;
ViewportEngineData *data = drw_viewport_engine_data_ensure(engine);
+ DST.vedata_array[i] = data;
if (data->text_draw_cache) {
DRW_text_cache_destroy(data->text_draw_cache);
@@ -1090,9 +1165,15 @@ static void drw_engines_cache_populate(Object *ob)
* ourselves here. */
drw_drawdata_unlink_dupli((ID *)ob);
- for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
+ /* Validation for dupli objects happen elsewhere. */
+ if (!DST.dupli_source) {
+ drw_batch_cache_validate(ob);
+ }
+
+ int i = 0;
+ for (LinkData *link = DST.enabled_engines.first; link; link = link->next, i++) {
DrawEngineType *engine = link->data;
- ViewportEngineData *data = drw_viewport_engine_data_ensure(engine);
+ ViewportEngineData *data = DST.vedata_array[i];
if (engine->id_update) {
engine->id_update(data, &ob->id);
@@ -1105,7 +1186,9 @@ static void drw_engines_cache_populate(Object *ob)
/* TODO: in the future it would be nice to generate once for all viewports.
* But we need threaded DRW manager first. */
- drw_batch_cache_generate_requested(ob);
+ if (!DST.dupli_source) {
+ drw_batch_cache_generate_requested(ob);
+ }
/* ... and clearing it here too because theses draw data are
* from a mempool and must not be free individually by depsgraph. */
@@ -1114,14 +1197,16 @@ static void drw_engines_cache_populate(Object *ob)
static void drw_engines_cache_finish(void)
{
- for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
+ int i = 0;
+ for (LinkData *link = DST.enabled_engines.first; link; link = link->next, i++) {
DrawEngineType *engine = link->data;
- ViewportEngineData *data = drw_viewport_engine_data_ensure(engine);
+ ViewportEngineData *data = DST.vedata_array[i];
if (engine->cache_finish) {
engine->cache_finish(data);
}
}
+ MEM_freeN(DST.vedata_array);
}
static void drw_engines_draw_background(void)
@@ -1397,17 +1482,19 @@ static void drw_engines_disable(void)
BLI_freelistN(&DST.enabled_engines);
}
-static uint DRW_engines_get_hash(void)
+static void drw_engines_data_validate(void)
{
- uint hash = 0;
- /* The cache depends on enabled engines */
- /* FIXME : if collision occurs ... segfault */
+ int enabled_engines = BLI_listbase_count(&DST.enabled_engines);
+ void **engine_handle_array = BLI_array_alloca(engine_handle_array, enabled_engines + 1);
+ int i = 0;
+
for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
DrawEngineType *engine = link->data;
- hash += BLI_ghashutil_strhash_p(engine->idname);
+ engine_handle_array[i++] = engine;
}
+ engine_handle_array[i] = NULL;
- return hash;
+ GPU_viewport_engines_data_validate(DST.viewport, engine_handle_array);
}
/* -------------------------------------------------------------------- */
@@ -1520,8 +1607,6 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph,
DST.viewport = viewport;
/* Setup viewport */
- GPU_viewport_engines_data_validate(DST.viewport, DRW_engines_get_hash());
-
DST.draw_ctx = (DRWContextState){
.ar = ar,
.rv3d = rv3d,
@@ -1541,6 +1626,8 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph,
/* Get list of enabled engines */
drw_engines_enable(view_layer, engine_type);
+ drw_engines_data_validate();
+
/* Update ubos */
DRW_globals_update();
@@ -1559,23 +1646,31 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph,
drw_engines_cache_init();
drw_engines_world_update(scene);
- const int object_type_exclude_viewport = v3d->object_type_exclude_viewport;
- const int iter_flag = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
- DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET | DEG_ITER_OBJECT_FLAG_VISIBLE |
- DEG_ITER_OBJECT_FLAG_DUPLI;
- DEG_OBJECT_ITER_BEGIN (depsgraph, ob, iter_flag) {
- if ((object_type_exclude_viewport & (1 << ob->type)) != 0) {
- continue;
- }
- if (v3d->localvd && ((v3d->local_view_uuid & ob->base_local_view_bits) == 0)) {
- continue;
+ /* Only iterate over objects for internal engines or when overlays are enabled */
+ const bool internal_engine = (engine_type->flag & RE_INTERNAL) != 0;
+ const bool draw_type_render = v3d->shading.type == OB_RENDER;
+ const bool overlays_on = (v3d->flag2 & V3D_HIDE_OVERLAYS) == 0;
+ if (internal_engine || overlays_on || !draw_type_render) {
+ const int object_type_exclude_viewport = v3d->object_type_exclude_viewport;
+ const int iter_flag = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
+ DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET | DEG_ITER_OBJECT_FLAG_VISIBLE |
+ DEG_ITER_OBJECT_FLAG_DUPLI;
+ DEG_OBJECT_ITER_BEGIN (depsgraph, ob, iter_flag) {
+ if ((object_type_exclude_viewport & (1 << ob->type)) != 0) {
+ continue;
+ }
+ if (v3d->localvd && ((v3d->local_view_uuid & ob->base_local_view_bits) == 0)) {
+ continue;
+ }
+ DST.dupli_parent = data_.dupli_parent;
+ DST.dupli_source = data_.dupli_object_current;
+ drw_duplidata_load(DST.dupli_source);
+ drw_engines_cache_populate(ob);
}
- DST.dupli_parent = data_.dupli_parent;
- DST.dupli_source = data_.dupli_object_current;
- drw_engines_cache_populate(ob);
+ DEG_OBJECT_ITER_END;
}
- DEG_OBJECT_ITER_END;
+ drw_duplidata_free();
drw_engines_cache_finish();
DRW_render_instance_buffer_finish();
@@ -1622,10 +1717,8 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph,
drw_engines_draw_scene();
-#ifdef __APPLE__
- /* Fix 3D view being "laggy" on macos. (See T56996) */
+ /* Fix 3D view being "laggy" on macos and win+nvidia. (See T56996, T61474) */
GPU_flush();
-#endif
/* annotations - temporary drawing buffer (3d space) */
/* XXX: Or should we use a proper draw/overlay engine for this case? */
@@ -1792,9 +1885,9 @@ static void DRW_render_gpencil_to_image(RenderEngine *engine,
void DRW_render_gpencil(struct RenderEngine *engine, struct Depsgraph *depsgraph)
{
- /* This function is only valid for Cycles
- * Eevee done all work in the Eevee render directly.
- * Maybe it can be done equal for both engines?
+ /* This function is only valid for Cycles & Workbench
+ * Eevee does all work in the Eevee render directly.
+ * Maybe it can be done equal for all engines?
*/
if (STREQ(engine->type->name, "Eevee")) {
return;
@@ -1861,7 +1954,7 @@ void DRW_render_gpencil(struct RenderEngine *engine, struct Depsgraph *depsgraph
}
RenderResult *render_result = RE_engine_get_result(engine);
- RenderLayer *render_layer = render_result->layers.first;
+ RenderLayer *render_layer = RE_GetRenderLayer(render_result, view_layer->name);
DRW_render_gpencil_to_image(engine, render_layer, &render_rect);
@@ -2018,12 +2111,20 @@ void DRW_render_object_iter(
DST.dupli_parent = data_.dupli_parent;
DST.dupli_source = data_.dupli_object_current;
DST.ob_state = NULL;
- callback(vedata, ob, engine, depsgraph);
+ drw_duplidata_load(DST.dupli_source);
- drw_batch_cache_generate_requested(ob);
+ if (!DST.dupli_source) {
+ drw_batch_cache_validate(ob);
+ }
+ callback(vedata, ob, engine, depsgraph);
+ if (!DST.dupli_source) {
+ drw_batch_cache_generate_requested(ob);
+ }
}
}
DEG_OBJECT_ITER_END;
+
+ drw_duplidata_free();
}
/* Assume a valid gl context is bound (and that the gl_context_mutex has been acquired).
@@ -2253,14 +2354,10 @@ void DRW_draw_select_loop(struct Depsgraph *depsgraph,
drw_engines_world_update(scene);
if (use_obedit) {
-# if 0
- drw_engines_cache_populate(obact);
-# else
FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, obact->type, obact->mode, ob_iter) {
drw_engines_cache_populate(ob_iter);
}
FOREACH_OBJECT_IN_MODE_END;
-# endif
}
else {
const int iter_flag = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
@@ -2291,16 +2388,18 @@ void DRW_draw_select_loop(struct Depsgraph *depsgraph,
/* This relies on dupli instances being after their instancing object. */
if ((ob->base_flag & BASE_FROM_DUPLI) == 0) {
Object *ob_orig = DEG_get_original_object(ob);
- DRW_select_load_id(ob_orig->select_id);
+ DRW_select_load_id(ob_orig->runtime.select_id);
}
DST.dupli_parent = data_.dupli_parent;
DST.dupli_source = data_.dupli_object_current;
+ drw_duplidata_load(DST.dupli_source);
drw_engines_cache_populate(ob);
}
}
DEG_OBJECT_ITER_END;
}
+ drw_duplidata_free();
drw_engines_cache_finish();
DRW_render_instance_buffer_finish();
@@ -2356,8 +2455,6 @@ void DRW_draw_select_loop(struct Depsgraph *depsgraph,
*/
static void drw_draw_depth_loop_imp(void)
{
- DRW_opengl_context_enable();
-
/* Setup framebuffer */
DefaultFramebufferList *fbl = (DefaultFramebufferList *)GPU_viewport_framebuffer_list_get(
DST.viewport);
@@ -2395,10 +2492,12 @@ static void drw_draw_depth_loop_imp(void)
DST.dupli_parent = data_.dupli_parent;
DST.dupli_source = data_.dupli_object_current;
+ drw_duplidata_load(DST.dupli_source);
drw_engines_cache_populate(ob);
}
DEG_OBJECT_ITER_END;
+ drw_duplidata_free();
drw_engines_cache_finish();
DRW_render_instance_buffer_finish();
@@ -2418,9 +2517,6 @@ static void drw_draw_depth_loop_imp(void)
/* TODO: Reading depth for operators should be done here. */
GPU_framebuffer_restore();
-
- /* Changin context */
- DRW_opengl_context_disable();
}
/**
@@ -2436,6 +2532,8 @@ void DRW_draw_depth_loop(struct Depsgraph *depsgraph,
ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
RegionView3D *rv3d = ar->regiondata;
+ DRW_opengl_context_enable();
+
/* Reset before using it. */
drw_state_prepare_clean_for_draw(&DST);
@@ -2470,6 +2568,9 @@ void DRW_draw_depth_loop(struct Depsgraph *depsgraph,
/* Avoid accidental reuse. */
drw_state_ensure_not_reused(&DST);
#endif
+
+ /* Changin context */
+ DRW_opengl_context_disable();
}
/**
@@ -2484,6 +2585,8 @@ void DRW_draw_depth_loop_gpencil(struct Depsgraph *depsgraph,
ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
RegionView3D *rv3d = ar->regiondata;
+ DRW_opengl_context_enable();
+
/* Reset before using it. */
drw_state_prepare_clean_for_draw(&DST);
@@ -2509,6 +2612,15 @@ void DRW_draw_depth_loop_gpencil(struct Depsgraph *depsgraph,
/* Avoid accidental reuse. */
drw_state_ensure_not_reused(&DST);
#endif
+
+ /* Changin context */
+ DRW_opengl_context_disable();
+}
+
+/** See #DRW_shgroup_world_clip_planes_from_rv3d. */
+static void draw_world_clip_planes_from_rv3d(GPUBatch *batch, const float world_clip_planes[6][4])
+{
+ GPU_batch_uniform_4fv_array(batch, "WorldClipPlanes", 6, world_clip_planes[0]);
}
/**
@@ -2554,7 +2666,7 @@ void DRW_draw_depth_object(ARegion *ar, GPUViewport *viewport, Object *object)
GPU_SHADER_CFG_DEFAULT;
GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_DEPTH_ONLY, sh_cfg);
if (world_clip_planes != NULL) {
- GPU_batch_uniform_4fv_array(batch, "WorldClipPlanes", 6, world_clip_planes[0]);
+ draw_world_clip_planes_from_rv3d(batch, world_clip_planes);
}
GPU_batch_draw(batch);
@@ -2574,6 +2686,203 @@ void DRW_draw_depth_object(ARegion *ar, GPUViewport *viewport, Object *object)
DRW_opengl_context_disable();
}
+static void draw_mesh_verts(GPUBatch *batch, int offset, const float world_clip_planes[6][4])
+{
+ GPU_point_size(UI_GetThemeValuef(TH_VERTEX_SIZE));
+
+ const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED :
+ GPU_SHADER_CFG_DEFAULT;
+ GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_FLAT_SELECT_ID, sh_cfg);
+ GPU_batch_uniform_1ui(batch, "offset", offset);
+ if (world_clip_planes != NULL) {
+ draw_world_clip_planes_from_rv3d(batch, world_clip_planes);
+ }
+ GPU_batch_draw(batch);
+}
+
+static void draw_mesh_edges(GPUBatch *batch, int offset, const float world_clip_planes[6][4])
+{
+ GPU_line_width(1.0f);
+ glProvokingVertex(GL_FIRST_VERTEX_CONVENTION);
+
+ const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED :
+ GPU_SHADER_CFG_DEFAULT;
+ GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_FLAT_SELECT_ID, sh_cfg);
+ GPU_batch_uniform_1ui(batch, "offset", offset);
+ if (world_clip_planes != NULL) {
+ draw_world_clip_planes_from_rv3d(batch, world_clip_planes);
+ }
+ GPU_batch_draw(batch);
+
+ glProvokingVertex(GL_LAST_VERTEX_CONVENTION);
+}
+
+/* two options, facecolors or black */
+static void draw_mesh_face(GPUBatch *batch,
+ int offset,
+ const bool use_select,
+ const float world_clip_planes[6][4])
+{
+ if (use_select) {
+ const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED :
+ GPU_SHADER_CFG_DEFAULT;
+ GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_FLAT_SELECT_ID, sh_cfg);
+ GPU_batch_uniform_1ui(batch, "offset", offset);
+ if (world_clip_planes != NULL) {
+ draw_world_clip_planes_from_rv3d(batch, world_clip_planes);
+ }
+ GPU_batch_draw(batch);
+ }
+ else {
+ const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED :
+ GPU_SHADER_CFG_DEFAULT;
+ GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_UNIFORM_SELECT_ID, sh_cfg);
+ GPU_batch_uniform_1ui(batch, "id", 0);
+ if (world_clip_planes != NULL) {
+ draw_world_clip_planes_from_rv3d(batch, world_clip_planes);
+ }
+ GPU_batch_draw(batch);
+ }
+}
+
+static void draw_mesh_face_dot(GPUBatch *batch, int offset, const float world_clip_planes[6][4])
+{
+ const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED :
+ GPU_SHADER_CFG_DEFAULT;
+ GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_FLAT_SELECT_ID, sh_cfg);
+ GPU_batch_uniform_1ui(batch, "offset", offset);
+ if (world_clip_planes != NULL) {
+ draw_world_clip_planes_from_rv3d(batch, world_clip_planes);
+ }
+ GPU_batch_draw(batch);
+}
+
+void DRW_draw_select_id_object(Scene *scene,
+ RegionView3D *rv3d,
+ Object *ob,
+ short select_mode,
+ bool draw_facedot,
+ uint initial_offset,
+ uint *r_vert_offset,
+ uint *r_edge_offset,
+ uint *r_face_offset)
+{
+ ToolSettings *ts = scene->toolsettings;
+ if (select_mode == -1) {
+ select_mode = ts->selectmode;
+ }
+
+ GPU_matrix_mul(ob->obmat);
+ GPU_depth_test(true);
+
+ const float(*world_clip_planes)[4] = NULL;
+ if (rv3d->rflag & RV3D_CLIPPING) {
+ ED_view3d_clipping_local(rv3d, ob->obmat);
+ world_clip_planes = rv3d->clip_local;
+ }
+
+ initial_offset += 1;
+
+ switch (ob->type) {
+ case OB_MESH:
+ if (ob->mode & OB_MODE_EDIT) {
+ Mesh *me = ob->data;
+ BMEditMesh *em = me->edit_mesh;
+ const bool use_faceselect = (select_mode & SCE_SELECT_FACE) != 0;
+
+ DRW_mesh_batch_cache_validate(me);
+
+ BM_mesh_elem_table_ensure(em->bm, BM_VERT | BM_EDGE | BM_FACE);
+
+ GPUBatch *geom_faces, *geom_edges, *geom_verts, *geom_facedots;
+ geom_faces = DRW_mesh_batch_cache_get_triangles_with_select_id(me);
+ if (select_mode & SCE_SELECT_EDGE) {
+ geom_edges = DRW_mesh_batch_cache_get_edges_with_select_id(me);
+ }
+ if (select_mode & SCE_SELECT_VERTEX) {
+ geom_verts = DRW_mesh_batch_cache_get_verts_with_select_id(me);
+ }
+ if (draw_facedot) {
+ geom_facedots = DRW_mesh_batch_cache_get_facedots_with_select_id(me);
+ }
+ DRW_mesh_batch_cache_create_requested(ob, me, NULL, false, true);
+
+ draw_mesh_face(geom_faces, initial_offset, use_faceselect, world_clip_planes);
+
+ if (use_faceselect && draw_facedot) {
+ draw_mesh_face_dot(geom_facedots, initial_offset, world_clip_planes);
+ }
+
+ if (select_mode & SCE_SELECT_FACE) {
+ *r_face_offset = initial_offset + em->bm->totface;
+ }
+ else {
+ *r_face_offset = initial_offset;
+ }
+
+ ED_view3d_polygon_offset(rv3d, 1.0);
+
+ /* Unlike faces, only draw edges if edge select mode. */
+ if (select_mode & SCE_SELECT_EDGE) {
+ draw_mesh_edges(geom_edges, *r_face_offset, world_clip_planes);
+ *r_edge_offset = *r_face_offset + em->bm->totedge;
+ }
+ else {
+ /* Note that `r_vert_offset` is calculated from `r_edge_offset`.
+ * Otherwise the first vertex is never selected, see: T53512. */
+ *r_edge_offset = *r_face_offset;
+ }
+
+ ED_view3d_polygon_offset(rv3d, 1.1);
+
+ /* Unlike faces, only verts if vert select mode. */
+ if (select_mode & SCE_SELECT_VERTEX) {
+ draw_mesh_verts(geom_verts, *r_edge_offset, world_clip_planes);
+ *r_vert_offset = *r_edge_offset + em->bm->totvert;
+ }
+ else {
+ *r_vert_offset = *r_edge_offset;
+ }
+
+ ED_view3d_polygon_offset(rv3d, 0.0);
+ }
+ else {
+ Mesh *me_orig = DEG_get_original_object(ob)->data;
+ Mesh *me_eval = ob->data;
+
+ DRW_mesh_batch_cache_validate(me_eval);
+ GPUBatch *geom_faces = DRW_mesh_batch_cache_get_triangles_with_select_id(me_eval);
+ if ((me_orig->editflag & ME_EDIT_PAINT_VERT_SEL) &&
+ /* Currently vertex select supports weight paint and vertex paint. */
+ ((ob->mode & OB_MODE_WEIGHT_PAINT) || (ob->mode & OB_MODE_VERTEX_PAINT))) {
+
+ GPUBatch *geom_verts = DRW_mesh_batch_cache_get_verts_with_select_id(me_eval);
+ DRW_mesh_batch_cache_create_requested(ob, me_eval, NULL, false, true);
+
+ /* Only draw faces to mask out verts, we don't want their selection ID's. */
+ draw_mesh_face(geom_faces, 0, false, world_clip_planes);
+ draw_mesh_verts(geom_verts, 1, world_clip_planes);
+
+ *r_vert_offset = me_eval->totvert + 1;
+ }
+ else {
+ const bool use_hide = (me_orig->editflag & ME_EDIT_PAINT_FACE_SEL);
+ DRW_mesh_batch_cache_create_requested(ob, me_eval, NULL, false, use_hide);
+
+ draw_mesh_face(geom_faces, initial_offset, true, world_clip_planes);
+
+ *r_face_offset = initial_offset + me_eval->totface;
+ }
+ }
+ break;
+ case OB_CURVE:
+ case OB_SURF:
+ break;
+ }
+
+ GPU_matrix_set(rv3d->viewmat);
+}
+
/* Set an opengl context to be used with shaders that draw on U32 colors. */
void DRW_framebuffer_select_id_setup(ARegion *ar, const bool clear)
{
@@ -2661,7 +2970,8 @@ void DRW_state_dfdy_factors_get(float dfdyfac[2])
*/
bool DRW_state_is_fbo(void)
{
- return ((DST.default_framebuffer != NULL) || DST.options.is_image_render);
+ return ((DST.default_framebuffer != NULL) || DST.options.is_image_render) &&
+ !DRW_state_is_depth() && !DRW_state_is_select();
}
/**
@@ -2849,7 +3159,6 @@ void DRW_engines_free(void)
DRW_UBO_FREE_SAFE(G_draw.view_ubo);
DRW_TEXTURE_FREE_SAFE(G_draw.ramp);
DRW_TEXTURE_FREE_SAFE(G_draw.weight_ramp);
- MEM_SAFE_FREE(g_pos_format);
MEM_SAFE_FREE(DST.uniform_names.buffer);
diff --git a/source/blender/draw/intern/draw_manager.h b/source/blender/draw/intern/draw_manager.h
index 77cf6d20117..b5dc88205db 100644
--- a/source/blender/draw/intern/draw_manager.h
+++ b/source/blender/draw/intern/draw_manager.h
@@ -100,15 +100,9 @@ enum {
/* Used by DRWCallState.matflag */
enum {
DRW_CALL_MODELINVERSE = (1 << 0),
- DRW_CALL_MODELVIEW = (1 << 1),
- DRW_CALL_MODELVIEWINVERSE = (1 << 2),
- DRW_CALL_MODELVIEWPROJECTION = (1 << 3),
- DRW_CALL_NORMALVIEW = (1 << 4),
- DRW_CALL_NORMALVIEWINVERSE = (1 << 5),
- DRW_CALL_NORMALWORLD = (1 << 6),
- DRW_CALL_ORCOTEXFAC = (1 << 7),
- DRW_CALL_EYEVEC = (1 << 8),
- DRW_CALL_OBJECTINFO = (1 << 9),
+ DRW_CALL_MODELVIEWPROJECTION = (1 << 1),
+ DRW_CALL_ORCOTEXFAC = (1 << 2),
+ DRW_CALL_OBJECTINFO = (1 << 3),
};
typedef struct DRWCallState {
@@ -116,72 +110,38 @@ typedef struct DRWCallState {
void *user_data;
uchar flag;
- uchar cache_id; /* Compared with DST.state_cache_id to see if matrices are still valid. */
- uint16_t matflag; /* Which matrices to compute. */
+ uchar cache_id; /* Compared with DST.state_cache_id to see if matrices are still valid. */
+ uchar matflag; /* Which matrices to compute. */
+ short ob_index;
/* Culling: Using Bounding Sphere for now for faster culling.
* Not ideal for planes. */
BoundSphere bsphere;
/* Matrices */
float model[4][4];
float modelinverse[4][4];
- float modelview[4][4];
- float modelviewinverse[4][4];
float modelviewprojection[4][4];
- float normalview[3][3];
- float normalviewinverse[3][3];
- float normalworld[3][3]; /* Not view dependent */
- float orcotexfac[2][3]; /* Not view dependent */
- float objectinfo[2];
- float eyevec[3];
+ float orcotexfac[2][3]; /* Not view dependent */
+ float ob_random;
} DRWCallState;
-typedef enum {
- /** A single batch. */
- DRW_CALL_SINGLE,
- /** Like single but only draw a range of vertices/indices. */
- DRW_CALL_RANGE,
- /** Draw instances without any instancing attributes. */
- DRW_CALL_INSTANCES,
- /** Generate a drawcall without any #GPUBatch. */
- DRW_CALL_PROCEDURAL,
-} DRWCallType;
-
typedef struct DRWCall {
struct DRWCall *next;
DRWCallState *state;
- union {
- struct { /* type == DRW_CALL_SINGLE */
- GPUBatch *geometry;
- short ma_index;
- } single;
- struct { /* type == DRW_CALL_RANGE */
- GPUBatch *geometry;
- uint start, count;
- } range;
- struct { /* type == DRW_CALL_INSTANCES */
- GPUBatch *geometry;
- /* Count can be adjusted between redraw. If needed, we can add fixed count. */
- uint *count;
- } instances;
- struct { /* type == DRW_CALL_PROCEDURAL */
- uint vert_count;
- GPUPrimType prim_type;
- } procedural;
- };
+ GPUBatch *batch;
+ uint vert_first;
+ uint vert_count;
+ uint inst_count;
- DRWCallType type;
#ifdef USE_GPU_SELECT
+ /* TODO(fclem) remove once we have a dedicated selection engine. */
int select_id;
+ GPUVertBuf *inst_selectid;
#endif
} DRWCall;
/* Used by DRWUniform.type */
typedef enum {
- DRW_UNIFORM_BOOL,
- DRW_UNIFORM_BOOL_COPY,
- DRW_UNIFORM_SHORT_TO_INT,
- DRW_UNIFORM_SHORT_TO_FLOAT,
DRW_UNIFORM_INT,
DRW_UNIFORM_INT_COPY,
DRW_UNIFORM_FLOAT,
@@ -199,8 +159,8 @@ struct DRWUniform {
/* For reference or array/vector types. */
const void *pvalue;
/* Single values. */
- float fvalue;
- int ivalue;
+ float fvalue[2];
+ int ivalue[2];
};
int name_ofs; /* name offset in name buffer. */
int location;
@@ -209,43 +169,18 @@ struct DRWUniform {
char arraysize; /* cannot be more than 16 too */
};
-typedef enum {
- DRW_SHG_NORMAL,
- DRW_SHG_POINT_BATCH,
- DRW_SHG_LINE_BATCH,
- DRW_SHG_TRIANGLE_BATCH,
- DRW_SHG_INSTANCE,
- DRW_SHG_INSTANCE_EXTERNAL,
- DRW_SHG_FEEDBACK_TRANSFORM,
-} DRWShadingGroupType;
-
struct DRWShadingGroup {
DRWShadingGroup *next;
GPUShader *shader; /* Shader to bind */
DRWUniform *uniforms; /* Uniforms pointers */
- /* Watch this! Can be nasty for debugging. */
- union {
- struct { /* DRW_SHG_NORMAL */
- DRWCall *first, *last; /* Linked list of DRWCall or DRWCallDynamic depending of type */
- } calls;
- struct { /* DRW_SHG_FEEDBACK_TRANSFORM */
- DRWCall *first, *last; /* Linked list of DRWCall or DRWCallDynamic depending of type */
- struct GPUVertBuf *tfeedback_target; /* Transform Feedback target. */
- };
- struct { /* DRW_SHG_***_BATCH */
- struct GPUBatch *batch_geom; /* Result of call batching */
- struct GPUVertBuf *batch_vbo;
- uint primitive_count;
- };
- struct { /* DRW_SHG_INSTANCE[_EXTERNAL] */
- struct GPUBatch *instance_geom;
- struct GPUVertBuf *instance_vbo;
- uint instance_count;
- float instance_orcofac[2][3]; /* TODO find a better place. */
- };
- };
+ struct {
+ DRWCall *first, *last; /* Linked list of DRWCall */
+ } calls;
+
+ /** TODO Maybe remove from here */
+ struct GPUVertBuf *tfeedback_target;
/** State changes for this batch only (or'd with the pass's state) */
DRWState state_extra;
@@ -253,31 +188,17 @@ struct DRWShadingGroup {
DRWState state_extra_disable;
/** Stencil mask to use for stencil test / write operations */
uint stencil_mask;
- DRWShadingGroupType type;
/* Builtin matrices locations */
int model;
int modelinverse;
- int modelview;
- int modelviewinverse;
int modelviewprojection;
- int normalview;
- int normalviewinverse;
- int normalworld;
int orcotexfac;
- int eye;
int callid;
int objectinfo;
- uint16_t matflag; /* Matrices needed, same as DRWCall.flag */
+ uchar matflag; /* Matrices needed, same as DRWCall.flag */
DRWPass *pass_parent; /* backlink to pass we're in */
-#ifndef NDEBUG
- char attrs_count;
-#endif
-#ifdef USE_GPU_SELECT
- GPUVertBuf *inst_selectid;
- int override_selectid; /* Override for single object instances. */
-#endif
};
#define MAX_PASS_NAME 32
@@ -293,6 +214,18 @@ struct DRWPass {
char name[MAX_PASS_NAME];
};
+/* TODO(fclem): Future awaits */
+#if 0
+typedef struct DRWView {
+ /* Culling function, culling result etc...*/
+} DRWView;
+
+typedef struct ModelUboStorage {
+ float model[4][4];
+ float modelinverse[4][4];
+} ModelUboStorage;
+#endif
+
typedef struct ViewUboStorage {
DRWMatrixState matstate;
float viewcamtexcofac[4];
@@ -329,6 +262,9 @@ typedef struct DRWManager {
uchar state_cache_id; /* Could be larger but 254 view changes is already a lot! */
struct DupliObject *dupli_source;
struct Object *dupli_parent;
+ struct Object *dupli_origin;
+ struct GHash *dupli_ghash;
+ void **dupli_datas; /* Array of dupli_data (one for each enabled engine) to handle duplis. */
/* Rendering state */
GPUShader *shader;
@@ -364,6 +300,8 @@ typedef struct DRWManager {
struct DRWTextStore **text_store_p;
ListBase enabled_engines; /* RenderEngineType */
+ void **vedata_array; /* ViewportEngineData */
+ int enabled_engine_count; /* Length of enabled_engines list. */
bool buffer_finish_called; /* Avoid bad usage of DRW_render_instance_buffer_finish */
@@ -437,8 +375,12 @@ void drw_state_set(DRWState state);
void drw_debug_draw(void);
void drw_debug_init(void);
+void drw_batch_cache_validate(Object *ob);
void drw_batch_cache_generate_requested(struct Object *ob);
-extern struct GPUVertFormat *g_pos_format;
+/* Procedural Drawing */
+GPUBatch *drw_cache_procedural_points_get(void);
+GPUBatch *drw_cache_procedural_lines_get(void);
+GPUBatch *drw_cache_procedural_triangles_get(void);
#endif /* __DRAW_MANAGER_H__ */
diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c
index 8f324cf08cb..e47433e60ab 100644
--- a/source/blender/draw/intern/draw_manager_data.c
+++ b/source/blender/draw/intern/draw_manager_data.c
@@ -37,13 +37,12 @@
#include "BLI_hash.h"
#include "BLI_link_utils.h"
#include "BLI_mempool.h"
+#include "BLI_memblock.h"
#include "GPU_buffers.h"
#include "intern/gpu_codegen.h"
-struct GPUVertFormat *g_pos_format = NULL;
-
/* -------------------------------------------------------------------- */
/** \name Uniform Buffer Object (DRW_uniformbuffer)
* \{ */
@@ -76,7 +75,7 @@ static void drw_shgroup_uniform_create_ex(DRWShadingGroup *shgroup,
int length,
int arraysize)
{
- DRWUniform *uni = BLI_mempool_alloc(DST.vmempool->uniforms);
+ DRWUniform *uni = BLI_memblock_alloc(DST.vmempool->uniforms);
uni->location = loc;
uni->type = type;
uni->length = length;
@@ -84,16 +83,15 @@ static void drw_shgroup_uniform_create_ex(DRWShadingGroup *shgroup,
switch (type) {
case DRW_UNIFORM_INT_COPY:
- uni->ivalue = *((int *)value);
- break;
- case DRW_UNIFORM_BOOL_COPY:
- uni->ivalue = (int)*((bool *)value);
+ BLI_assert(length <= 2);
+ memcpy(uni->ivalue, value, sizeof(int) * length);
break;
case DRW_UNIFORM_FLOAT_COPY:
- uni->fvalue = *((float *)value);
+ BLI_assert(length <= 2);
+ memcpy(uni->fvalue, value, sizeof(float) * length);
break;
default:
- uni->pvalue = value;
+ uni->pvalue = (const float *)value;
break;
}
@@ -201,7 +199,7 @@ void DRW_shgroup_uniform_bool(DRWShadingGroup *shgroup,
const int *value,
int arraysize)
{
- drw_shgroup_uniform(shgroup, name, DRW_UNIFORM_BOOL, value, 1, arraysize);
+ drw_shgroup_uniform(shgroup, name, DRW_UNIFORM_INT, value, 1, arraysize);
}
void DRW_shgroup_uniform_float(DRWShadingGroup *shgroup,
@@ -236,22 +234,6 @@ void DRW_shgroup_uniform_vec4(DRWShadingGroup *shgroup,
drw_shgroup_uniform(shgroup, name, DRW_UNIFORM_FLOAT, value, 4, arraysize);
}
-void DRW_shgroup_uniform_short_to_int(DRWShadingGroup *shgroup,
- const char *name,
- const short *value,
- int arraysize)
-{
- drw_shgroup_uniform(shgroup, name, DRW_UNIFORM_SHORT_TO_INT, value, 1, arraysize);
-}
-
-void DRW_shgroup_uniform_short_to_float(DRWShadingGroup *shgroup,
- const char *name,
- const short *value,
- int arraysize)
-{
- drw_shgroup_uniform(shgroup, name, DRW_UNIFORM_SHORT_TO_FLOAT, value, 1, arraysize);
-}
-
void DRW_shgroup_uniform_int(DRWShadingGroup *shgroup,
const char *name,
const int *value,
@@ -302,7 +284,8 @@ void DRW_shgroup_uniform_int_copy(DRWShadingGroup *shgroup, const char *name, co
void DRW_shgroup_uniform_bool_copy(DRWShadingGroup *shgroup, const char *name, const bool value)
{
- drw_shgroup_uniform(shgroup, name, DRW_UNIFORM_BOOL_COPY, &value, 1, 1);
+ int ival = value;
+ drw_shgroup_uniform(shgroup, name, DRW_UNIFORM_INT_COPY, &ival, 1, 1);
}
void DRW_shgroup_uniform_float_copy(DRWShadingGroup *shgroup, const char *name, const float value)
@@ -310,6 +293,11 @@ void DRW_shgroup_uniform_float_copy(DRWShadingGroup *shgroup, const char *name,
drw_shgroup_uniform(shgroup, name, DRW_UNIFORM_FLOAT_COPY, &value, 1, 1);
}
+void DRW_shgroup_uniform_vec2_copy(DRWShadingGroup *shgroup, const char *name, const float *value)
+{
+ drw_shgroup_uniform(shgroup, name, DRW_UNIFORM_FLOAT_COPY, value, 2, 1);
+}
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -370,13 +358,22 @@ static void drw_call_state_update_matflag(DRWCallState *state,
* This is the opposite of what draw_matrices_model_prepare() does. */
state->matflag |= shgroup->matflag;
+ if (new_flags & DRW_CALL_MODELINVERSE) {
+ if (ob) {
+ copy_m4_m4(state->modelinverse, ob->imat);
+ }
+ else {
+ invert_m4_m4(state->modelinverse, state->model);
+ }
+ }
+
/* Orco factors: We compute this at creation to not have to save the *ob_data */
- if ((new_flags & DRW_CALL_ORCOTEXFAC) != 0) {
+ if (new_flags & DRW_CALL_ORCOTEXFAC) {
drw_call_calc_orco(ob, state->orcotexfac);
}
- if ((new_flags & DRW_CALL_OBJECTINFO) != 0) {
- state->objectinfo[0] = ob ? ob->index : 0;
+ if (new_flags & DRW_CALL_OBJECTINFO) {
+ state->ob_index = ob ? ob->index : 0;
uint random;
if (DST.dupli_source) {
random = DST.dupli_source->random_id;
@@ -384,23 +381,25 @@ static void drw_call_state_update_matflag(DRWCallState *state,
else {
random = BLI_hash_int_2d(BLI_hash_string(ob->id.name + 2), 0);
}
- state->objectinfo[1] = random * (1.0f / (float)0xFFFFFFFF);
+ state->ob_random = random * (1.0f / (float)0xFFFFFFFF);
}
}
static DRWCallState *drw_call_state_create(DRWShadingGroup *shgroup, float (*obmat)[4], Object *ob)
{
- DRWCallState *state = BLI_mempool_alloc(DST.vmempool->states);
+ DRWCallState *state = BLI_memblock_alloc(DST.vmempool->states);
state->flag = 0;
state->cache_id = 0;
state->visibility_cb = NULL;
state->matflag = 0;
+ drw_call_state_update_matflag(state, shgroup, ob);
+
/* Matrices */
if (obmat != NULL) {
copy_m4_m4(state->model, obmat);
- if (is_negative_m4(state->model)) {
+ if (ob && (ob->transflag & OB_NEG_SCALE)) {
state->flag |= DRW_CALL_NEGSCALE;
}
}
@@ -422,8 +421,6 @@ static DRWCallState *drw_call_state_create(DRWShadingGroup *shgroup, float (*obm
state->bsphere.radius = -1.0f;
}
- drw_call_state_update_matflag(state, shgroup, ob);
-
return state;
}
@@ -440,173 +437,179 @@ static DRWCallState *drw_call_state_object(DRWShadingGroup *shgroup, float (*obm
return DST.ob_state;
}
-void DRW_shgroup_call_add(DRWShadingGroup *shgroup, GPUBatch *geom, float (*obmat)[4])
+void DRW_shgroup_call(DRWShadingGroup *shgroup, GPUBatch *geom, float (*obmat)[4])
{
BLI_assert(geom != NULL);
- BLI_assert(ELEM(shgroup->type, DRW_SHG_NORMAL, DRW_SHG_FEEDBACK_TRANSFORM));
- DRWCall *call = BLI_mempool_alloc(DST.vmempool->calls);
+ DRWCall *call = BLI_memblock_alloc(DST.vmempool->calls);
+ BLI_LINKS_APPEND(&shgroup->calls, call);
+
call->state = drw_call_state_create(shgroup, obmat, NULL);
- call->type = DRW_CALL_SINGLE;
- call->single.geometry = geom;
+ call->batch = geom;
+ call->vert_first = 0;
+ call->vert_count = 0; /* Auto from batch. */
+ call->inst_count = 0;
#ifdef USE_GPU_SELECT
call->select_id = DST.select_id;
+ call->inst_selectid = NULL;
#endif
-
- BLI_LINKS_APPEND(&shgroup->calls, call);
}
-void DRW_shgroup_call_range_add(
+void DRW_shgroup_call_range(
DRWShadingGroup *shgroup, GPUBatch *geom, float (*obmat)[4], uint v_sta, uint v_count)
{
BLI_assert(geom != NULL);
- BLI_assert(ELEM(shgroup->type, DRW_SHG_NORMAL, DRW_SHG_FEEDBACK_TRANSFORM));
BLI_assert(v_count);
- DRWCall *call = BLI_mempool_alloc(DST.vmempool->calls);
+ DRWCall *call = BLI_memblock_alloc(DST.vmempool->calls);
+ BLI_LINKS_APPEND(&shgroup->calls, call);
+
call->state = drw_call_state_create(shgroup, obmat, NULL);
- call->type = DRW_CALL_RANGE;
- call->range.geometry = geom;
- call->range.start = v_sta;
- call->range.count = v_count;
+ call->batch = geom;
+ call->vert_first = v_sta;
+ call->vert_count = v_count;
+ call->inst_count = 0;
#ifdef USE_GPU_SELECT
call->select_id = DST.select_id;
+ call->inst_selectid = NULL;
#endif
-
- BLI_LINKS_APPEND(&shgroup->calls, call);
}
static void drw_shgroup_call_procedural_add_ex(DRWShadingGroup *shgroup,
- GPUPrimType prim_type,
+ GPUBatch *geom,
uint vert_count,
- float (*obmat)[4],
- Object *ob)
+ float (*obmat)[4])
{
- BLI_assert(ELEM(shgroup->type, DRW_SHG_NORMAL, DRW_SHG_FEEDBACK_TRANSFORM));
- DRWCall *call = BLI_mempool_alloc(DST.vmempool->calls);
- if (ob) {
- call->state = drw_call_state_object(shgroup, ob->obmat, ob);
- }
- else {
- call->state = drw_call_state_create(shgroup, obmat, NULL);
- }
- call->type = DRW_CALL_PROCEDURAL;
- call->procedural.prim_type = prim_type;
- call->procedural.vert_count = vert_count;
+ DRWCall *call = BLI_memblock_alloc(DST.vmempool->calls);
+ BLI_LINKS_APPEND(&shgroup->calls, call);
+
+ call->state = drw_call_state_object(shgroup, obmat, NULL);
+ call->batch = geom;
+ call->vert_first = 0;
+ call->vert_count = vert_count;
+ call->inst_count = 0;
#ifdef USE_GPU_SELECT
call->select_id = DST.select_id;
+ call->inst_selectid = NULL;
#endif
-
- BLI_LINKS_APPEND(&shgroup->calls, call);
}
-void DRW_shgroup_call_procedural_points_add(DRWShadingGroup *shgroup,
- uint point_len,
- float (*obmat)[4])
+void DRW_shgroup_call_procedural_points(DRWShadingGroup *shgroup,
+ uint point_len,
+ float (*obmat)[4])
{
- drw_shgroup_call_procedural_add_ex(shgroup, GPU_PRIM_POINTS, point_len, obmat, NULL);
+ struct GPUBatch *geom = drw_cache_procedural_points_get();
+ drw_shgroup_call_procedural_add_ex(shgroup, geom, point_len, obmat);
}
-void DRW_shgroup_call_procedural_lines_add(DRWShadingGroup *shgroup,
- uint line_count,
- float (*obmat)[4])
+void DRW_shgroup_call_procedural_lines(DRWShadingGroup *shgroup,
+ uint line_count,
+ float (*obmat)[4])
{
- drw_shgroup_call_procedural_add_ex(shgroup, GPU_PRIM_LINES, line_count * 2, obmat, NULL);
+ struct GPUBatch *geom = drw_cache_procedural_lines_get();
+ drw_shgroup_call_procedural_add_ex(shgroup, geom, line_count * 2, obmat);
}
-void DRW_shgroup_call_procedural_triangles_add(DRWShadingGroup *shgroup,
- uint tria_count,
- float (*obmat)[4])
+void DRW_shgroup_call_procedural_triangles(DRWShadingGroup *shgroup,
+ uint tria_count,
+ float (*obmat)[4])
{
- drw_shgroup_call_procedural_add_ex(shgroup, GPU_PRIM_TRIS, tria_count * 3, obmat, NULL);
+ struct GPUBatch *geom = drw_cache_procedural_triangles_get();
+ drw_shgroup_call_procedural_add_ex(shgroup, geom, tria_count * 3, obmat);
}
/* These calls can be culled and are optimized for redraw */
-void DRW_shgroup_call_object_add_ex(
- DRWShadingGroup *shgroup, GPUBatch *geom, Object *ob, Material *ma, bool bypass_culling)
+void DRW_shgroup_call_object_ex(DRWShadingGroup *shgroup,
+ GPUBatch *geom,
+ Object *ob,
+ bool bypass_culling)
{
BLI_assert(geom != NULL);
- BLI_assert(ELEM(shgroup->type, DRW_SHG_NORMAL, DRW_SHG_FEEDBACK_TRANSFORM));
- DRWCall *call = BLI_mempool_alloc(DST.vmempool->calls);
+ DRWCall *call = BLI_memblock_alloc(DST.vmempool->calls);
+ BLI_LINKS_APPEND(&shgroup->calls, call);
+
call->state = drw_call_state_object(shgroup, ob->obmat, ob);
- call->type = DRW_CALL_SINGLE;
- call->single.geometry = geom;
- call->single.ma_index = ma ? ma->index : 0;
+ /* NOTE this will disable culling for the whole object. */
+ call->state->flag |= (bypass_culling) ? DRW_CALL_BYPASS_CULLING : 0;
+ call->batch = geom;
+ call->vert_first = 0;
+ call->vert_count = 0; /* Auto from batch. */
+ call->inst_count = 0;
#ifdef USE_GPU_SELECT
call->select_id = DST.select_id;
+ call->inst_selectid = NULL;
#endif
-
- /* NOTE this will disable culling for the whole object. */
- call->state->flag |= (bypass_culling) ? DRW_CALL_BYPASS_CULLING : 0;
-
- BLI_LINKS_APPEND(&shgroup->calls, call);
}
-void DRW_shgroup_call_object_add_with_callback(DRWShadingGroup *shgroup,
- GPUBatch *geom,
- Object *ob,
- Material *ma,
- DRWCallVisibilityFn *callback,
- void *user_data)
+void DRW_shgroup_call_object_with_callback(DRWShadingGroup *shgroup,
+ GPUBatch *geom,
+ Object *ob,
+ DRWCallVisibilityFn *callback,
+ void *user_data)
{
BLI_assert(geom != NULL);
- BLI_assert(ELEM(shgroup->type, DRW_SHG_NORMAL, DRW_SHG_FEEDBACK_TRANSFORM));
- DRWCall *call = BLI_mempool_alloc(DST.vmempool->calls);
+ DRWCall *call = BLI_memblock_alloc(DST.vmempool->calls);
+ BLI_LINKS_APPEND(&shgroup->calls, call);
+
call->state = drw_call_state_object(shgroup, ob->obmat, ob);
call->state->visibility_cb = callback;
call->state->user_data = user_data;
- call->type = DRW_CALL_SINGLE;
- call->single.geometry = geom;
- call->single.ma_index = ma ? ma->index : 0;
+ call->batch = geom;
+ call->vert_first = 0;
+ call->vert_count = 0; /* Auto from batch. */
+ call->inst_count = 0;
#ifdef USE_GPU_SELECT
call->select_id = DST.select_id;
+ call->inst_selectid = NULL;
#endif
-
- BLI_LINKS_APPEND(&shgroup->calls, call);
}
-void DRW_shgroup_call_instances_add(DRWShadingGroup *shgroup,
- GPUBatch *geom,
- float (*obmat)[4],
- uint *count)
+void DRW_shgroup_call_instances(DRWShadingGroup *shgroup,
+ GPUBatch *geom,
+ float (*obmat)[4],
+ uint count)
{
BLI_assert(geom != NULL);
- BLI_assert(ELEM(shgroup->type, DRW_SHG_NORMAL, DRW_SHG_FEEDBACK_TRANSFORM));
- DRWCall *call = BLI_mempool_alloc(DST.vmempool->calls);
+ DRWCall *call = BLI_memblock_alloc(DST.vmempool->calls);
+ BLI_LINKS_APPEND(&shgroup->calls, call);
+
call->state = drw_call_state_create(shgroup, obmat, NULL);
- call->type = DRW_CALL_INSTANCES;
- call->instances.geometry = geom;
- call->instances.count = count;
+ call->batch = geom;
+ call->vert_first = 0;
+ call->vert_count = 0; /* Auto from batch. */
+ call->inst_count = count;
#ifdef USE_GPU_SELECT
call->select_id = DST.select_id;
+ call->inst_selectid = NULL;
#endif
-
- BLI_LINKS_APPEND(&shgroup->calls, call);
}
-/* These calls can be culled and are optimized for redraw */
-void DRW_shgroup_call_object_instances_add(DRWShadingGroup *shgroup,
- GPUBatch *geom,
- Object *ob,
- uint *count)
+void DRW_shgroup_call_instances_with_attribs(DRWShadingGroup *shgroup,
+ struct GPUBatch *geom,
+ float (*obmat)[4],
+ struct GPUBatch *inst_attributes)
{
BLI_assert(geom != NULL);
- BLI_assert(ELEM(shgroup->type, DRW_SHG_NORMAL, DRW_SHG_FEEDBACK_TRANSFORM));
+ BLI_assert(inst_attributes->verts[0] != NULL);
- DRWCall *call = BLI_mempool_alloc(DST.vmempool->calls);
- call->state = drw_call_state_object(shgroup, ob->obmat, ob);
- call->type = DRW_CALL_INSTANCES;
- call->instances.geometry = geom;
- call->instances.count = count;
+ GPUVertBuf *buf_inst = inst_attributes->verts[0];
+
+ DRWCall *call = BLI_memblock_alloc(DST.vmempool->calls);
+ BLI_LINKS_APPEND(&shgroup->calls, call);
+
+ call->state = drw_call_state_create(shgroup, obmat, NULL);
+ call->batch = DRW_temp_batch_instance_request(DST.idatalist, buf_inst, geom);
+ call->vert_first = 0;
+ call->vert_count = 0; /* Auto from batch. */
+ call->inst_count = buf_inst->vertex_len;
#ifdef USE_GPU_SELECT
call->select_id = DST.select_id;
+ call->inst_selectid = NULL;
#endif
-
- BLI_LINKS_APPEND(&shgroup->calls, call);
}
// #define SCULPT_DEBUG_BUFFERS
@@ -614,7 +617,6 @@ void DRW_shgroup_call_object_instances_add(DRWShadingGroup *shgroup,
typedef struct DRWSculptCallbackData {
Object *ob;
DRWShadingGroup **shading_groups;
- Material **materials;
bool use_wire;
bool use_mats;
bool use_mask;
@@ -642,7 +644,6 @@ static float sculpt_debug_colors[9][4] = {
static void sculpt_draw_cb(DRWSculptCallbackData *scd, GPU_PBVH_Buffers *buffers)
{
GPUBatch *geom = GPU_pbvh_buffers_batch_get(buffers, scd->fast_mode, scd->use_wire);
- Material *ma = NULL;
short index = 0;
/* Meh... use_mask is a bit misleading here. */
@@ -652,7 +653,6 @@ static void sculpt_draw_cb(DRWSculptCallbackData *scd, GPU_PBVH_Buffers *buffers
if (scd->use_mats) {
index = GPU_pbvh_buffers_material_index_get(buffers);
- ma = scd->materials[index];
}
DRWShadingGroup *shgrp = scd->shading_groups[index];
@@ -662,9 +662,9 @@ static void sculpt_draw_cb(DRWSculptCallbackData *scd, GPU_PBVH_Buffers *buffers
shgrp = DRW_shgroup_create_sub(shgrp);
DRW_shgroup_uniform_vec3(shgrp, "materialDiffuseColor", SCULPT_DEBUG_COLOR(scd->node_nr++), 1);
#endif
- /* DRW_shgroup_call_object_add_ex reuses matrices calculations for all the drawcalls of this
+ /* DRW_shgroup_call_object_ex reuses matrices calculations for all the drawcalls of this
* object. */
- DRW_shgroup_call_object_add_ex(shgrp, geom, scd->ob, ma, true);
+ DRW_shgroup_call_object_ex(shgrp, geom, scd->ob, true);
}
}
@@ -725,13 +725,12 @@ static void drw_sculpt_generate_calls(DRWSculptCallbackData *scd, bool use_vcol)
#endif
}
-void DRW_shgroup_call_sculpt_add(
+void DRW_shgroup_call_sculpt(
DRWShadingGroup *shgroup, Object *ob, bool use_wire, bool use_mask, bool use_vcol)
{
DRWSculptCallbackData scd = {
.ob = ob,
.shading_groups = &shgroup,
- .materials = NULL,
.use_wire = use_wire,
.use_mats = false,
.use_mask = use_mask,
@@ -739,15 +738,11 @@ void DRW_shgroup_call_sculpt_add(
drw_sculpt_generate_calls(&scd, use_vcol);
}
-void DRW_shgroup_call_sculpt_with_materials_add(DRWShadingGroup **shgroups,
- Material **materials,
- Object *ob,
- bool use_vcol)
+void DRW_shgroup_call_sculpt_with_materials(DRWShadingGroup **shgroups, Object *ob, bool use_vcol)
{
DRWSculptCallbackData scd = {
.ob = ob,
.shading_groups = shgroups,
- .materials = materials,
.use_wire = false,
.use_mats = true,
.use_mask = false,
@@ -755,30 +750,95 @@ void DRW_shgroup_call_sculpt_with_materials_add(DRWShadingGroup **shgroups,
drw_sculpt_generate_calls(&scd, use_vcol);
}
-void DRW_shgroup_call_dynamic_add_array(DRWShadingGroup *shgroup,
- const void *attr[],
- uint attr_len)
+static GPUVertFormat inst_select_format = {0};
+
+DRWCallBuffer *DRW_shgroup_call_buffer(DRWShadingGroup *shgroup,
+ struct GPUVertFormat *format,
+ GPUPrimType prim_type)
{
+ BLI_assert(ELEM(prim_type, GPU_PRIM_POINTS, GPU_PRIM_LINES, GPU_PRIM_TRI_FAN));
+ BLI_assert(format != NULL);
+
+ DRWCall *call = BLI_memblock_alloc(DST.vmempool->calls);
+ BLI_LINKS_APPEND(&shgroup->calls, call);
+
+ call->state = drw_call_state_create(shgroup, NULL, NULL);
+ GPUVertBuf *buf = DRW_temp_buffer_request(DST.idatalist, format, &call->vert_count);
+ call->batch = DRW_temp_batch_request(DST.idatalist, buf, prim_type);
+ call->vert_first = 0;
+ call->vert_count = 0;
+ call->inst_count = 0;
+
+#ifdef USE_GPU_SELECT
+ if (G.f & G_FLAG_PICKSEL) {
+ /* Not actually used for rendering but alloced in one chunk. */
+ if (inst_select_format.attr_len == 0) {
+ GPU_vertformat_attr_add(&inst_select_format, "selectId", GPU_COMP_I32, 1, GPU_FETCH_INT);
+ }
+ call->inst_selectid = DRW_temp_buffer_request(
+ DST.idatalist, &inst_select_format, &call->vert_count);
+ }
+#endif
+ return (DRWCallBuffer *)call;
+}
+
+DRWCallBuffer *DRW_shgroup_call_buffer_instance(DRWShadingGroup *shgroup,
+ struct GPUVertFormat *format,
+ GPUBatch *geom)
+{
+ BLI_assert(geom != NULL);
+ BLI_assert(format != NULL);
+
+ DRWCall *call = BLI_memblock_alloc(DST.vmempool->calls);
+ BLI_LINKS_APPEND(&shgroup->calls, call);
+
+ call->state = drw_call_state_create(shgroup, NULL, NULL);
+ GPUVertBuf *buf = DRW_temp_buffer_request(DST.idatalist, format, &call->inst_count);
+ call->batch = DRW_temp_batch_instance_request(DST.idatalist, buf, geom);
+ call->vert_first = 0;
+ call->vert_count = 0; /* Auto from batch. */
+ call->inst_count = 0;
+
#ifdef USE_GPU_SELECT
if (G.f & G_FLAG_PICKSEL) {
- if (shgroup->instance_count == shgroup->inst_selectid->vertex_len) {
- GPU_vertbuf_data_resize(shgroup->inst_selectid, shgroup->instance_count + 32);
+ /* Not actually used for rendering but alloced in one chunk. */
+ if (inst_select_format.attr_len == 0) {
+ GPU_vertformat_attr_add(&inst_select_format, "selectId", GPU_COMP_I32, 1, GPU_FETCH_INT);
}
- GPU_vertbuf_attr_set(shgroup->inst_selectid, 0, shgroup->instance_count, &DST.select_id);
+ call->inst_selectid = DRW_temp_buffer_request(
+ DST.idatalist, &inst_select_format, &call->inst_count);
}
#endif
+ return (DRWCallBuffer *)call;
+}
+
+void DRW_buffer_add_entry_array(DRWCallBuffer *callbuf, const void *attr[], uint attr_len)
+{
+ DRWCall *call = (DRWCall *)callbuf;
+ const bool is_instance = call->batch->inst != NULL;
+ GPUVertBuf *buf = is_instance ? call->batch->inst : call->batch->verts[0];
+ uint count = is_instance ? call->inst_count++ : call->vert_count++;
+ const bool resize = (count == buf->vertex_alloc);
- BLI_assert(attr_len == shgroup->attrs_count);
+ BLI_assert(attr_len == buf->format.attr_len);
UNUSED_VARS_NDEBUG(attr_len);
+ if (UNLIKELY(resize)) {
+ GPU_vertbuf_data_resize(buf, count + DRW_BUFFER_VERTS_CHUNK);
+ }
+
for (int i = 0; i < attr_len; ++i) {
- if (shgroup->instance_count == shgroup->instance_vbo->vertex_len) {
- GPU_vertbuf_data_resize(shgroup->instance_vbo, shgroup->instance_count + 32);
- }
- GPU_vertbuf_attr_set(shgroup->instance_vbo, i, shgroup->instance_count, attr[i]);
+ GPU_vertbuf_attr_set(buf, i, count, attr[i]);
}
- shgroup->instance_count += 1;
+#ifdef USE_GPU_SELECT
+ if (G.f & G_FLAG_PICKSEL) {
+ if (UNLIKELY(resize)) {
+ GPU_vertbuf_data_resize(call->inst_selectid, count + DRW_BUFFER_VERTS_CHUNK);
+ }
+ GPU_vertbuf_attr_set(call->inst_selectid, 0, count, &DST.select_id);
+ }
+#endif
}
/** \} */
@@ -789,17 +849,7 @@ void DRW_shgroup_call_dynamic_add_array(DRWShadingGroup *shgroup,
static void drw_shgroup_init(DRWShadingGroup *shgroup, GPUShader *shader)
{
- shgroup->instance_geom = NULL;
- shgroup->instance_vbo = NULL;
- shgroup->instance_count = 0;
shgroup->uniforms = NULL;
-#ifdef USE_GPU_SELECT
- shgroup->inst_selectid = NULL;
- shgroup->override_selectid = -1;
-#endif
-#ifndef NDEBUG
- shgroup->attrs_count = 0;
-#endif
int view_ubo_location = GPU_shader_get_uniform_block(shader, "viewBlock");
@@ -828,159 +878,46 @@ static void drw_shgroup_init(DRWShadingGroup *shgroup, GPUShader *shader)
shgroup, GPU_UNIFORM_CAMERATEXCO, DST.view_data.viewcamtexcofac, 3, 2);
}
+ /* Not supported. */
+ BLI_assert(GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_MODELVIEW_INV) == -1);
+ BLI_assert(GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_MODELVIEW) == -1);
+ BLI_assert(GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_NORMAL) == -1);
+
shgroup->model = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_MODEL);
shgroup->modelinverse = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_MODEL_INV);
- shgroup->modelview = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_MODELVIEW);
- shgroup->modelviewinverse = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_MODELVIEW_INV);
shgroup->modelviewprojection = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_MVP);
- shgroup->normalview = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_NORMAL);
- shgroup->normalviewinverse = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_NORMAL_INV);
- shgroup->normalworld = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_WORLDNORMAL);
shgroup->orcotexfac = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_ORCO);
shgroup->objectinfo = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_OBJECT_INFO);
- shgroup->eye = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_EYE);
shgroup->callid = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_CALLID);
shgroup->matflag = 0;
if (shgroup->modelinverse > -1) {
shgroup->matflag |= DRW_CALL_MODELINVERSE;
}
- if (shgroup->modelview > -1) {
- shgroup->matflag |= DRW_CALL_MODELVIEW;
- }
- if (shgroup->modelviewinverse > -1) {
- shgroup->matflag |= DRW_CALL_MODELVIEWINVERSE;
- }
if (shgroup->modelviewprojection > -1) {
shgroup->matflag |= DRW_CALL_MODELVIEWPROJECTION;
}
- if (shgroup->normalview > -1) {
- shgroup->matflag |= DRW_CALL_NORMALVIEW;
- }
- if (shgroup->normalviewinverse > -1) {
- shgroup->matflag |= DRW_CALL_NORMALVIEWINVERSE;
- }
- if (shgroup->normalworld > -1) {
- shgroup->matflag |= DRW_CALL_NORMALWORLD;
- }
if (shgroup->orcotexfac > -1) {
shgroup->matflag |= DRW_CALL_ORCOTEXFAC;
}
if (shgroup->objectinfo > -1) {
shgroup->matflag |= DRW_CALL_OBJECTINFO;
}
- if (shgroup->eye > -1) {
- shgroup->matflag |= DRW_CALL_EYEVEC;
- }
-}
-
-static void drw_shgroup_instance_init(DRWShadingGroup *shgroup,
- GPUShader *shader,
- GPUBatch *batch,
- GPUVertFormat *format)
-{
- BLI_assert(shgroup->type == DRW_SHG_INSTANCE);
- BLI_assert(batch != NULL);
- BLI_assert(format != NULL);
-
- drw_shgroup_init(shgroup, shader);
-
- shgroup->instance_geom = batch;
-#ifndef NDEBUG
- shgroup->attrs_count = format->attr_len;
-#endif
-
- DRW_instancing_buffer_request(
- DST.idatalist, format, batch, shgroup, &shgroup->instance_geom, &shgroup->instance_vbo);
-
-#ifdef USE_GPU_SELECT
- if (G.f & G_FLAG_PICKSEL) {
- /* Not actually used for rendering but alloced in one chunk.
- * Plus we don't have to care about ownership. */
- static GPUVertFormat inst_select_format = {0};
- if (inst_select_format.attr_len == 0) {
- GPU_vertformat_attr_add(&inst_select_format, "selectId", GPU_COMP_I32, 1, GPU_FETCH_INT);
- }
- GPUBatch *batch_dummy; /* Not used */
- DRW_batching_buffer_request(DST.idatalist,
- &inst_select_format,
- GPU_PRIM_POINTS,
- shgroup,
- &batch_dummy,
- &shgroup->inst_selectid);
- }
-#endif
-}
-
-static void drw_shgroup_batching_init(DRWShadingGroup *shgroup,
- GPUShader *shader,
- GPUVertFormat *format)
-{
- drw_shgroup_init(shgroup, shader);
-
-#ifndef NDEBUG
- shgroup->attrs_count = (format != NULL) ? format->attr_len : 0;
-#endif
- BLI_assert(format != NULL);
-
- GPUPrimType type;
- switch (shgroup->type) {
- case DRW_SHG_POINT_BATCH:
- type = GPU_PRIM_POINTS;
- break;
- case DRW_SHG_LINE_BATCH:
- type = GPU_PRIM_LINES;
- break;
- case DRW_SHG_TRIANGLE_BATCH:
- type = GPU_PRIM_TRIS;
- break;
- default:
- type = GPU_PRIM_NONE;
- BLI_assert(0);
- break;
- }
-
- DRW_batching_buffer_request(
- DST.idatalist, format, type, shgroup, &shgroup->batch_geom, &shgroup->batch_vbo);
-
-#ifdef USE_GPU_SELECT
- if (G.f & G_FLAG_PICKSEL) {
- /* Not actually used for rendering but alloced in one chunk. */
- static GPUVertFormat inst_select_format = {0};
- if (inst_select_format.attr_len == 0) {
- GPU_vertformat_attr_add(&inst_select_format, "selectId", GPU_COMP_I32, 1, GPU_FETCH_INT);
- }
- GPUBatch *batch; /* Not used */
- DRW_batching_buffer_request(DST.idatalist,
- &inst_select_format,
- GPU_PRIM_POINTS,
- shgroup,
- &batch,
- &shgroup->inst_selectid);
- }
-#endif
}
static DRWShadingGroup *drw_shgroup_create_ex(struct GPUShader *shader, DRWPass *pass)
{
- DRWShadingGroup *shgroup = BLI_mempool_alloc(DST.vmempool->shgroups);
+ DRWShadingGroup *shgroup = BLI_memblock_alloc(DST.vmempool->shgroups);
BLI_LINKS_APPEND(&pass->shgroups, shgroup);
- shgroup->type = DRW_SHG_NORMAL;
shgroup->shader = shader;
shgroup->state_extra = 0;
shgroup->state_extra_disable = ~0x0;
shgroup->stencil_mask = 0;
shgroup->calls.first = NULL;
shgroup->calls.last = NULL;
-#if 0 /* All the same in the union! */
- shgroup->batch_geom = NULL;
- shgroup->batch_vbo = NULL;
-
- shgroup->instance_geom = NULL;
- shgroup->instance_vbo = NULL;
-#endif
+ shgroup->tfeedback_target = NULL;
shgroup->pass_parent = pass;
return shgroup;
@@ -1016,10 +953,9 @@ static DRWShadingGroup *drw_shgroup_material_inputs(DRWShadingGroup *grp,
GPUTexture *tex = NULL;
if (input->ima) {
- GPUTexture **tex_ref = BLI_mempool_alloc(DST.vmempool->images);
+ GPUTexture **tex_ref = BLI_memblock_alloc(DST.vmempool->images);
- *tex_ref = tex = GPU_texture_from_blender(
- input->ima, input->iuser, GL_TEXTURE_2D, input->image_isdata);
+ *tex_ref = tex = GPU_texture_from_blender(input->ima, input->iuser, GL_TEXTURE_2D);
GPU_texture_ref(tex);
}
@@ -1066,45 +1002,6 @@ DRWShadingGroup *DRW_shgroup_material_create(struct GPUMaterial *material, DRWPa
drw_shgroup_init(shgroup, GPU_pass_shader_get(gpupass));
drw_shgroup_material_inputs(shgroup, material);
}
-
- return shgroup;
-}
-
-DRWShadingGroup *DRW_shgroup_material_instance_create(
- struct GPUMaterial *material, DRWPass *pass, GPUBatch *geom, Object *ob, GPUVertFormat *format)
-{
- GPUPass *gpupass = GPU_material_get_pass(material);
- DRWShadingGroup *shgroup = drw_shgroup_material_create_ex(gpupass, pass);
-
- if (shgroup) {
- shgroup->type = DRW_SHG_INSTANCE;
- shgroup->instance_geom = geom;
- drw_call_calc_orco(ob, shgroup->instance_orcofac);
- drw_shgroup_instance_init(shgroup, GPU_pass_shader_get(gpupass), geom, format);
- drw_shgroup_material_inputs(shgroup, material);
- }
-
- return shgroup;
-}
-
-DRWShadingGroup *DRW_shgroup_material_empty_tri_batch_create(struct GPUMaterial *material,
- DRWPass *pass,
- int tri_count)
-{
-#ifdef USE_GPU_SELECT
- BLI_assert((G.f & G_FLAG_PICKSEL) == 0);
-#endif
- GPUPass *gpupass = GPU_material_get_pass(material);
- DRWShadingGroup *shgroup = drw_shgroup_material_create_ex(gpupass, pass);
-
- if (shgroup) {
- /* Calling drw_shgroup_init will cause it to call GPU_draw_primitive(). */
- drw_shgroup_init(shgroup, GPU_pass_shader_get(gpupass));
- shgroup->type = DRW_SHG_TRIANGLE_BATCH;
- shgroup->instance_count = tri_count * 3;
- drw_shgroup_material_inputs(shgroup, material);
- }
-
return shgroup;
}
@@ -1115,118 +1012,18 @@ DRWShadingGroup *DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass)
return shgroup;
}
-DRWShadingGroup *DRW_shgroup_instance_create(struct GPUShader *shader,
- DRWPass *pass,
- GPUBatch *geom,
- GPUVertFormat *format)
-{
- DRWShadingGroup *shgroup = drw_shgroup_create_ex(shader, pass);
- shgroup->type = DRW_SHG_INSTANCE;
- shgroup->instance_geom = geom;
- drw_call_calc_orco(NULL, shgroup->instance_orcofac);
- drw_shgroup_instance_init(shgroup, shader, geom, format);
-
- return shgroup;
-}
-
-DRWShadingGroup *DRW_shgroup_point_batch_create(struct GPUShader *shader, DRWPass *pass)
-{
- DRW_shgroup_instance_format(g_pos_format, {{"pos", DRW_ATTR_FLOAT, 3}});
-
- DRWShadingGroup *shgroup = drw_shgroup_create_ex(shader, pass);
- shgroup->type = DRW_SHG_POINT_BATCH;
-
- drw_shgroup_batching_init(shgroup, shader, g_pos_format);
-
- return shgroup;
-}
-
-DRWShadingGroup *DRW_shgroup_line_batch_create_with_format(struct GPUShader *shader,
- DRWPass *pass,
- GPUVertFormat *format)
-{
- DRWShadingGroup *shgroup = drw_shgroup_create_ex(shader, pass);
- shgroup->type = DRW_SHG_LINE_BATCH;
-
- drw_shgroup_batching_init(shgroup, shader, format);
-
- return shgroup;
-}
-
-DRWShadingGroup *DRW_shgroup_line_batch_create(struct GPUShader *shader, DRWPass *pass)
-{
- DRW_shgroup_instance_format(g_pos_format, {{"pos", DRW_ATTR_FLOAT, 3}});
-
- return DRW_shgroup_line_batch_create_with_format(shader, pass, g_pos_format);
-}
-
-/**
- * Very special batch. Use this if you position
- * your vertices with the vertex shader
- * and dont need any VBO attribute.
- */
-DRWShadingGroup *DRW_shgroup_empty_tri_batch_create(struct GPUShader *shader,
- DRWPass *pass,
- int tri_count)
-{
-#ifdef USE_GPU_SELECT
- BLI_assert((G.f & G_FLAG_PICKSEL) == 0);
-#endif
- DRWShadingGroup *shgroup = drw_shgroup_create_ex(shader, pass);
-
- /* Calling drw_shgroup_init will cause it to call GPU_draw_primitive(). */
- drw_shgroup_init(shgroup, shader);
-
- shgroup->type = DRW_SHG_TRIANGLE_BATCH;
- shgroup->instance_count = tri_count * 3;
-
- return shgroup;
-}
-
DRWShadingGroup *DRW_shgroup_transform_feedback_create(struct GPUShader *shader,
DRWPass *pass,
GPUVertBuf *tf_target)
{
BLI_assert(tf_target != NULL);
DRWShadingGroup *shgroup = drw_shgroup_create_ex(shader, pass);
- shgroup->type = DRW_SHG_FEEDBACK_TRANSFORM;
-
drw_shgroup_init(shgroup, shader);
-
shgroup->tfeedback_target = tf_target;
-
return shgroup;
}
/**
- * Specify an external batch instead of adding each attribute one by one.
- */
-void DRW_shgroup_instance_batch(DRWShadingGroup *shgroup, struct GPUBatch *batch)
-{
- BLI_assert(shgroup->type == DRW_SHG_INSTANCE);
- BLI_assert(shgroup->instance_count == 0);
- /* You cannot use external instancing batch without a dummy format. */
- BLI_assert(shgroup->attrs_count != 0);
-
- shgroup->type = DRW_SHG_INSTANCE_EXTERNAL;
- drw_call_calc_orco(NULL, shgroup->instance_orcofac);
- /* PERF : This destroys the vaos cache so better check if it's necessary. */
- /* Note: This WILL break if batch->verts[0] is destroyed and reallocated
- * at the same address. Bindings/VAOs would remain obsolete. */
- // if (shgroup->instancing_geom->inst != batch->verts[0])
- GPU_batch_instbuf_set(shgroup->instance_geom, batch->verts[0], false);
-
-#ifdef USE_GPU_SELECT
- shgroup->override_selectid = DST.select_id;
-#endif
-}
-
-uint DRW_shgroup_get_instance_count(const DRWShadingGroup *shgroup)
-{
- return shgroup->instance_count;
-}
-
-/**
* State is added to #Pass.state while drawing.
* Use to temporarily enable draw options.
*/
@@ -1248,27 +1045,13 @@ void DRW_shgroup_stencil_mask(DRWShadingGroup *shgroup, uint mask)
bool DRW_shgroup_is_empty(DRWShadingGroup *shgroup)
{
- switch (shgroup->type) {
- case DRW_SHG_NORMAL:
- case DRW_SHG_FEEDBACK_TRANSFORM:
- return shgroup->calls.first == NULL;
- case DRW_SHG_POINT_BATCH:
- case DRW_SHG_LINE_BATCH:
- case DRW_SHG_TRIANGLE_BATCH:
- case DRW_SHG_INSTANCE:
- case DRW_SHG_INSTANCE_EXTERNAL:
- return shgroup->instance_count == 0;
- }
- BLI_assert(!"Shading Group type not supported");
- return true;
+ return shgroup->calls.first == NULL;
}
DRWShadingGroup *DRW_shgroup_create_sub(DRWShadingGroup *shgroup)
{
/* Remove this assertion if needed but implement the other cases first! */
- BLI_assert(shgroup->type == DRW_SHG_NORMAL);
-
- DRWShadingGroup *shgroup_new = BLI_mempool_alloc(DST.vmempool->shgroups);
+ DRWShadingGroup *shgroup_new = BLI_memblock_alloc(DST.vmempool->shgroups);
*shgroup_new = *shgroup;
shgroup_new->uniforms = NULL;
@@ -1288,7 +1071,7 @@ DRWShadingGroup *DRW_shgroup_create_sub(DRWShadingGroup *shgroup)
DRWPass *DRW_pass_create(const char *name, DRWState state)
{
- DRWPass *pass = BLI_mempool_alloc(DST.vmempool->passes);
+ DRWPass *pass = BLI_memblock_alloc(DST.vmempool->passes);
pass->state = state;
if (((G.debug_value > 20) && (G.debug_value < 30)) || (G.debug & G_DEBUG)) {
BLI_strncpy(pass->name, name, MAX_PASS_NAME);
@@ -1325,12 +1108,6 @@ void DRW_pass_state_remove(DRWPass *pass, DRWState state)
pass->state &= ~state;
}
-void DRW_pass_free(DRWPass *pass)
-{
- pass->shgroups.first = NULL;
- pass->shgroups.last = NULL;
-}
-
void DRW_pass_foreach_shgroup(DRWPass *pass,
void (*callback)(void *userData, DRWShadingGroup *shgrp),
void *userData)
diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c
index 46f4d0620c8..f76c46a9146 100644
--- a/source/blender/draw/intern/draw_manager_exec.c
+++ b/source/blender/draw/intern/draw_manager_exec.c
@@ -23,13 +23,14 @@
#include "draw_manager.h"
#include "BLI_math_bits.h"
-#include "BLI_mempool.h"
+#include "BLI_memblock.h"
#include "BKE_global.h"
#include "GPU_draw.h"
#include "GPU_extensions.h"
#include "intern/gpu_shader_private.h"
+#include "intern/gpu_primitive_private.h"
#ifdef USE_GPU_SELECT
# include "GPU_select.h"
@@ -791,43 +792,10 @@ static void draw_matrices_model_prepare(DRWCallState *st)
if ((st->flag & DRW_CALL_CULLED) != 0 && (st->flag & DRW_CALL_BYPASS_CULLING) == 0) {
return;
}
- /* Order matters */
- if (st->matflag &
- (DRW_CALL_MODELVIEW | DRW_CALL_MODELVIEWINVERSE | DRW_CALL_NORMALVIEW | DRW_CALL_EYEVEC)) {
- mul_m4_m4m4(st->modelview, DST.view_data.matstate.mat[DRW_MAT_VIEW], st->model);
- }
- if (st->matflag & DRW_CALL_MODELVIEWINVERSE) {
- invert_m4_m4(st->modelviewinverse, st->modelview);
- }
+
if (st->matflag & DRW_CALL_MODELVIEWPROJECTION) {
mul_m4_m4m4(st->modelviewprojection, DST.view_data.matstate.mat[DRW_MAT_PERS], st->model);
}
- if (st->matflag & (DRW_CALL_NORMALVIEW | DRW_CALL_NORMALVIEWINVERSE | DRW_CALL_EYEVEC)) {
- copy_m3_m4(st->normalview, st->modelview);
- invert_m3(st->normalview);
- transpose_m3(st->normalview);
- }
- if (st->matflag & (DRW_CALL_NORMALVIEWINVERSE | DRW_CALL_EYEVEC)) {
- invert_m3_m3(st->normalviewinverse, st->normalview);
- }
- /* TODO remove eye vec (unused) */
- if (st->matflag & DRW_CALL_EYEVEC) {
- /* Used by orthographic wires */
- copy_v3_fl3(st->eyevec, 0.0f, 0.0f, 1.0f);
- /* set eye vector, transformed to object coords */
- mul_m3_v3(st->normalviewinverse, st->eyevec);
- }
- /* Non view dependent */
- if (st->matflag & DRW_CALL_MODELINVERSE) {
- invert_m4_m4(st->modelinverse, st->model);
- st->matflag &= ~DRW_CALL_MODELINVERSE;
- }
- if (st->matflag & DRW_CALL_NORMALWORLD) {
- copy_m3_m4(st->normalworld, st->model);
- invert_m3(st->normalworld);
- transpose_m3(st->normalworld);
- st->matflag &= ~DRW_CALL_NORMALWORLD;
- }
}
static void draw_geometry_prepare(DRWShadingGroup *shgroup, DRWCall *call)
@@ -835,73 +803,65 @@ static void draw_geometry_prepare(DRWShadingGroup *shgroup, DRWCall *call)
/* step 1 : bind object dependent matrices */
if (call != NULL) {
DRWCallState *state = call->state;
- float objectinfo[4];
- objectinfo[0] = state->objectinfo[0];
- objectinfo[1] = call->single.ma_index; /* WATCH this is only valid for single drawcalls. */
- objectinfo[2] = state->objectinfo[1];
- objectinfo[3] = (state->flag & DRW_CALL_NEGSCALE) ? -1.0f : 1.0f;
-
- GPU_shader_uniform_vector(shgroup->shader, shgroup->model, 16, 1, (float *)state->model);
- GPU_shader_uniform_vector(
- shgroup->shader, shgroup->modelinverse, 16, 1, (float *)state->modelinverse);
- GPU_shader_uniform_vector(
- shgroup->shader, shgroup->modelview, 16, 1, (float *)state->modelview);
- GPU_shader_uniform_vector(
- shgroup->shader, shgroup->modelviewinverse, 16, 1, (float *)state->modelviewinverse);
- GPU_shader_uniform_vector(
- shgroup->shader, shgroup->modelviewprojection, 16, 1, (float *)state->modelviewprojection);
- GPU_shader_uniform_vector(
- shgroup->shader, shgroup->normalview, 9, 1, (float *)state->normalview);
- GPU_shader_uniform_vector(
- shgroup->shader, shgroup->normalviewinverse, 9, 1, (float *)state->normalviewinverse);
- GPU_shader_uniform_vector(
- shgroup->shader, shgroup->normalworld, 9, 1, (float *)state->normalworld);
- GPU_shader_uniform_vector(shgroup->shader, shgroup->objectinfo, 4, 1, (float *)objectinfo);
- GPU_shader_uniform_vector(
- shgroup->shader, shgroup->orcotexfac, 3, 2, (float *)state->orcotexfac);
- GPU_shader_uniform_vector(shgroup->shader, shgroup->eye, 3, 1, (float *)state->eyevec);
+
+ if (shgroup->model != -1) {
+ GPU_shader_uniform_vector(shgroup->shader, shgroup->model, 16, 1, (float *)state->model);
+ }
+ if (shgroup->modelinverse != -1) {
+ GPU_shader_uniform_vector(
+ shgroup->shader, shgroup->modelinverse, 16, 1, (float *)state->modelinverse);
+ }
+ if (shgroup->modelviewprojection != -1) {
+ GPU_shader_uniform_vector(shgroup->shader,
+ shgroup->modelviewprojection,
+ 16,
+ 1,
+ (float *)state->modelviewprojection);
+ }
+ if (shgroup->objectinfo != -1) {
+ float infos[4];
+ infos[0] = state->ob_index;
+ // infos[1]; /* UNUSED. */
+ infos[2] = state->ob_random;
+ infos[3] = (state->flag & DRW_CALL_NEGSCALE) ? -1.0f : 1.0f;
+ GPU_shader_uniform_vector(shgroup->shader, shgroup->objectinfo, 4, 1, (float *)infos);
+ }
+ if (shgroup->orcotexfac != -1) {
+ GPU_shader_uniform_vector(
+ shgroup->shader, shgroup->orcotexfac, 3, 2, (float *)state->orcotexfac);
+ }
}
else {
- BLI_assert((shgroup->normalview == -1) && (shgroup->normalworld == -1) &&
- (shgroup->eye == -1));
/* For instancing and batching. */
float unitmat[4][4];
unit_m4(unitmat);
- GPU_shader_uniform_vector(shgroup->shader, shgroup->model, 16, 1, (float *)unitmat);
- GPU_shader_uniform_vector(shgroup->shader, shgroup->modelinverse, 16, 1, (float *)unitmat);
- GPU_shader_uniform_vector(shgroup->shader,
- shgroup->modelview,
- 16,
- 1,
- (float *)DST.view_data.matstate.mat[DRW_MAT_VIEW]);
- GPU_shader_uniform_vector(shgroup->shader,
- shgroup->modelviewinverse,
- 16,
- 1,
- (float *)DST.view_data.matstate.mat[DRW_MAT_VIEWINV]);
- GPU_shader_uniform_vector(shgroup->shader,
- shgroup->modelviewprojection,
- 16,
- 1,
- (float *)DST.view_data.matstate.mat[DRW_MAT_PERS]);
- GPU_shader_uniform_vector(shgroup->shader, shgroup->objectinfo, 4, 1, (float *)unitmat);
- GPU_shader_uniform_vector(
- shgroup->shader, shgroup->orcotexfac, 3, 2, (float *)shgroup->instance_orcofac);
+
+ if (shgroup->model != -1) {
+ GPU_shader_uniform_vector(shgroup->shader, shgroup->model, 16, 1, (float *)unitmat);
+ }
+ if (shgroup->modelinverse != -1) {
+ GPU_shader_uniform_vector(shgroup->shader, shgroup->modelinverse, 16, 1, (float *)unitmat);
+ }
+ if (shgroup->modelviewprojection != -1) {
+ GPU_shader_uniform_vector(shgroup->shader,
+ shgroup->modelviewprojection,
+ 16,
+ 1,
+ (float *)DST.view_data.matstate.mat[DRW_MAT_PERS]);
+ }
+ if (shgroup->objectinfo != -1) {
+ GPU_shader_uniform_vector(shgroup->shader, shgroup->objectinfo, 4, 1, (float *)unitmat);
+ }
+ if (shgroup->orcotexfac != -1) {
+ float orcofacs[2][3] = {{0.0f, 0.0f, 0.0f}, {1.0f, 1.0f, 1.0f}};
+ GPU_shader_uniform_vector(shgroup->shader, shgroup->orcotexfac, 3, 2, (float *)orcofacs);
+ }
}
}
-static void draw_geometry_execute_ex(
+static void draw_geometry_execute(
DRWShadingGroup *shgroup, GPUBatch *geom, uint start, uint count, bool draw_instance)
{
- /* Special case: empty drawcall, placement is done via shader, don't bind anything. */
- /* TODO use DRW_CALL_PROCEDURAL instead */
- if (geom == NULL) {
- BLI_assert(shgroup->type == DRW_SHG_TRIANGLE_BATCH); /* Add other type if needed. */
- /* Shader is already bound. */
- GPU_draw_primitive(GPU_PRIM_TRIS, count);
- return;
- }
-
/* step 2 : bind vertex array & draw */
GPU_batch_program_set_no_use(
geom, GPU_shader_get_program(shgroup->shader), GPU_shader_get_interface(shgroup->shader));
@@ -913,11 +873,6 @@ static void draw_geometry_execute_ex(
geom->program_in_use = false; /* XXX hacking gawain */
}
-static void draw_geometry_execute(DRWShadingGroup *shgroup, GPUBatch *geom)
-{
- draw_geometry_execute_ex(shgroup, geom, 0, 0, false);
-}
-
enum {
BIND_NONE = 0,
BIND_TEMP = 1, /* Release slot after this shading group. */
@@ -1086,14 +1041,55 @@ static void release_ubo_slots(bool with_persist)
}
}
+BLI_INLINE bool draw_select_do_call(DRWShadingGroup *shgroup, DRWCall *call)
+{
+#ifdef USE_GPU_SELECT
+ if ((G.f & G_FLAG_PICKSEL) == 0) {
+ return false;
+ }
+ if (call->inst_selectid != NULL) {
+ const bool is_instancing = (call->inst_count != 0);
+ uint start = 0;
+ uint count = 1;
+ uint tot = is_instancing ? call->inst_count : call->vert_count;
+ /* Hack : get vbo data without actually drawing. */
+ GPUVertBufRaw raw;
+ GPU_vertbuf_attr_get_raw_data(call->inst_selectid, 0, &raw);
+ int *select_id = GPU_vertbuf_raw_step(&raw);
+
+ /* Batching */
+ if (!is_instancing) {
+ /* FIXME: Meh a bit nasty. */
+ if (call->batch->gl_prim_type == convert_prim_type_to_gl(GPU_PRIM_TRIS)) {
+ count = 3;
+ }
+ else if (call->batch->gl_prim_type == convert_prim_type_to_gl(GPU_PRIM_LINES)) {
+ count = 2;
+ }
+ }
+
+ while (start < tot) {
+ GPU_select_load_id(select_id[start]);
+ draw_geometry_execute(shgroup, call->batch, start, count, is_instancing);
+ start += count;
+ }
+ return true;
+ }
+ else {
+ GPU_select_load_id(call->select_id);
+ return false;
+ }
+#else
+ return false;
+#endif
+}
+
static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
{
BLI_assert(shgroup->shader);
GPUTexture *tex;
GPUUniformBuffer *ubo;
- int val;
- float fval;
const bool shader_changed = (DST.shader != shgroup->shader);
bool use_tfeedback = false;
@@ -1105,8 +1101,7 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
DST.shader = shgroup->shader;
}
- if ((pass_state & DRW_STATE_TRANS_FEEDBACK) != 0 &&
- (shgroup->type == DRW_SHG_FEEDBACK_TRANSFORM)) {
+ if ((pass_state & DRW_STATE_TRANS_FEEDBACK) != 0 && (shgroup->tfeedback_target != NULL)) {
use_tfeedback = GPU_shader_transform_feedback_enable(shgroup->shader,
shgroup->tfeedback_target->vbo_id);
}
@@ -1126,34 +1121,20 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
continue;
}
}
+ const void *data = uni->pvalue;
+ if (ELEM(uni->type, DRW_UNIFORM_INT_COPY, DRW_UNIFORM_FLOAT_COPY)) {
+ data = uni->fvalue;
+ }
switch (uni->type) {
- case DRW_UNIFORM_SHORT_TO_INT:
- val = (int)*((short *)uni->pvalue);
- GPU_shader_uniform_vector_int(
- shgroup->shader, uni->location, uni->length, uni->arraysize, &val);
- break;
- case DRW_UNIFORM_SHORT_TO_FLOAT:
- fval = (float)*((short *)uni->pvalue);
- GPU_shader_uniform_vector(
- shgroup->shader, uni->location, uni->length, uni->arraysize, (float *)&fval);
- break;
- case DRW_UNIFORM_BOOL_COPY:
case DRW_UNIFORM_INT_COPY:
- GPU_shader_uniform_vector_int(
- shgroup->shader, uni->location, uni->length, uni->arraysize, &uni->ivalue);
- break;
- case DRW_UNIFORM_BOOL:
case DRW_UNIFORM_INT:
GPU_shader_uniform_vector_int(
- shgroup->shader, uni->location, uni->length, uni->arraysize, (int *)uni->pvalue);
+ shgroup->shader, uni->location, uni->length, uni->arraysize, data);
break;
case DRW_UNIFORM_FLOAT_COPY:
- GPU_shader_uniform_vector(
- shgroup->shader, uni->location, uni->length, uni->arraysize, &uni->fvalue);
- break;
case DRW_UNIFORM_FLOAT:
GPU_shader_uniform_vector(
- shgroup->shader, uni->location, uni->length, uni->arraysize, (float *)uni->pvalue);
+ shgroup->shader, uni->location, uni->length, uni->arraysize, data);
break;
case DRW_UNIFORM_TEXTURE:
tex = (GPUTexture *)uni->pvalue;
@@ -1186,102 +1167,10 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
}
}
-#ifdef USE_GPU_SELECT
-# define GPU_SELECT_LOAD_IF_PICKSEL(_select_id) \
- if (G.f & G_FLAG_PICKSEL) { \
- GPU_select_load_id(_select_id); \
- } \
- ((void)0)
-
-# define GPU_SELECT_LOAD_IF_PICKSEL_CALL(_call) \
- if ((G.f & G_FLAG_PICKSEL) && (_call)) { \
- GPU_select_load_id((_call)->select_id); \
- } \
- ((void)0)
-
-# define GPU_SELECT_LOAD_IF_PICKSEL_LIST(_shgroup, _start, _count) \
- _start = 0; \
- _count = _shgroup->instance_count; \
- int *select_id = NULL; \
- if (G.f & G_FLAG_PICKSEL) { \
- if (_shgroup->override_selectid == -1) { \
- /* Hack : get vbo data without actually drawing. */ \
- GPUVertBufRaw raw; \
- GPU_vertbuf_attr_get_raw_data(_shgroup->inst_selectid, 0, &raw); \
- select_id = GPU_vertbuf_raw_step(&raw); \
- switch (_shgroup->type) { \
- case DRW_SHG_TRIANGLE_BATCH: \
- _count = 3; \
- break; \
- case DRW_SHG_LINE_BATCH: \
- _count = 2; \
- break; \
- default: \
- _count = 1; \
- break; \
- } \
- } \
- else { \
- GPU_select_load_id(_shgroup->override_selectid); \
- } \
- } \
- while (_start < _shgroup->instance_count) { \
- if (select_id) { \
- GPU_select_load_id(select_id[_start]); \
- }
-
-# define GPU_SELECT_LOAD_IF_PICKSEL_LIST_END(_start, _count) \
- _start += _count; \
- } \
- ((void)0)
-
-#else
-# define GPU_SELECT_LOAD_IF_PICKSEL(select_id)
-# define GPU_SELECT_LOAD_IF_PICKSEL_CALL(call)
-# define GPU_SELECT_LOAD_IF_PICKSEL_LIST_END(start, count) ((void)0)
-# define GPU_SELECT_LOAD_IF_PICKSEL_LIST(_shgroup, _start, _count) \
- _start = 0; \
- _count = _shgroup->instance_count;
-
-#endif
-
BLI_assert(ubo_bindings_validate(shgroup));
/* Rendering Calls */
- if (!ELEM(shgroup->type, DRW_SHG_NORMAL, DRW_SHG_FEEDBACK_TRANSFORM)) {
- /* Replacing multiple calls with only one */
- if (ELEM(shgroup->type, DRW_SHG_INSTANCE, DRW_SHG_INSTANCE_EXTERNAL)) {
- if (shgroup->type == DRW_SHG_INSTANCE_EXTERNAL) {
- if (shgroup->instance_geom != NULL) {
- GPU_SELECT_LOAD_IF_PICKSEL(shgroup->override_selectid);
- draw_geometry_prepare(shgroup, NULL);
- draw_geometry_execute_ex(shgroup, shgroup->instance_geom, 0, 0, true);
- }
- }
- else {
- if (shgroup->instance_count > 0) {
- uint count, start;
- draw_geometry_prepare(shgroup, NULL);
- GPU_SELECT_LOAD_IF_PICKSEL_LIST (shgroup, start, count) {
- draw_geometry_execute_ex(shgroup, shgroup->instance_geom, start, count, true);
- }
- GPU_SELECT_LOAD_IF_PICKSEL_LIST_END(start, count);
- }
- }
- }
- else { /* DRW_SHG_***_BATCH */
- /* Some dynamic batch can have no geom (no call to aggregate) */
- if (shgroup->instance_count > 0) {
- uint count, start;
- draw_geometry_prepare(shgroup, NULL);
- GPU_SELECT_LOAD_IF_PICKSEL_LIST (shgroup, start, count) {
- draw_geometry_execute_ex(shgroup, shgroup->batch_geom, start, count, false);
- }
- GPU_SELECT_LOAD_IF_PICKSEL_LIST_END(start, count);
- }
- }
- }
- else {
+ {
bool prev_neg_scale = false;
int callid = 0;
for (DRWCall *call = shgroup->calls.first; call; call = call->next) {
@@ -1308,26 +1197,18 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
prev_neg_scale = neg_scale;
}
- GPU_SELECT_LOAD_IF_PICKSEL_CALL(call);
draw_geometry_prepare(shgroup, call);
- switch (call->type) {
- case DRW_CALL_SINGLE:
- draw_geometry_execute(shgroup, call->single.geometry);
- break;
- case DRW_CALL_RANGE:
- draw_geometry_execute_ex(
- shgroup, call->range.geometry, call->range.start, call->range.count, false);
- break;
- case DRW_CALL_INSTANCES:
- draw_geometry_execute_ex(
- shgroup, call->instances.geometry, 0, *call->instances.count, true);
- break;
- case DRW_CALL_PROCEDURAL:
- GPU_draw_primitive(call->procedural.prim_type, call->procedural.vert_count);
- break;
- default:
- BLI_assert(0);
+ if (draw_select_do_call(shgroup, call)) {
+ continue;
+ }
+
+ /* TODO revisit when DRW_SHG_INSTANCE and the like is gone. */
+ if (call->inst_count == 0) {
+ draw_geometry_execute(shgroup, call->batch, call->vert_first, call->vert_count, false);
+ }
+ else {
+ draw_geometry_execute(shgroup, call->batch, 0, call->inst_count, true);
}
}
/* Reset state */
@@ -1352,10 +1233,10 @@ static void drw_update_view(void)
DST.state_cache_id = 1;
/* We must reset all CallStates to ensure that not
* a single one stayed with cache_id equal to 1. */
- BLI_mempool_iter iter;
+ BLI_memblock_iter iter;
DRWCallState *state;
- BLI_mempool_iternew(DST.vmempool->states, &iter);
- while ((state = BLI_mempool_iterstep(&iter))) {
+ BLI_memblock_iternew(DST.vmempool->states, &iter);
+ while ((state = BLI_memblock_iterstep(&iter))) {
state->cache_id = 0;
}
}
diff --git a/source/blender/draw/intern/draw_manager_shader.c b/source/blender/draw/intern/draw_manager_shader.c
index b60a41ab0c9..186bbae5cad 100644
--- a/source/blender/draw/intern/draw_manager_shader.c
+++ b/source/blender/draw/intern/draw_manager_shader.c
@@ -394,6 +394,7 @@ GPUMaterial *DRW_shader_create_from_world(struct Scene *scene,
if (mat == NULL) {
scene = (Scene *)DEG_get_original_id(&DST.draw_ctx.scene->id);
mat = GPU_material_from_nodetree(scene,
+ NULL,
wo->nodetree,
&wo->gpumaterial,
engine_type,
@@ -430,6 +431,7 @@ GPUMaterial *DRW_shader_create_from_material(struct Scene *scene,
if (mat == NULL) {
scene = (Scene *)DEG_get_original_id(&DST.draw_ctx.scene->id);
mat = GPU_material_from_nodetree(scene,
+ ma,
ma->nodetree,
&ma->gpumaterial,
engine_type,
diff --git a/source/blender/draw/modes/edit_curve_mode.c b/source/blender/draw/modes/edit_curve_mode.c
index e47393c88c4..5177a8f4cd0 100644
--- a/source/blender/draw/modes/edit_curve_mode.c
+++ b/source/blender/draw/modes/edit_curve_mode.c
@@ -39,6 +39,7 @@
* Not needed for constant color. */
extern char datatoc_common_globals_lib_glsl[];
+extern char datatoc_common_view_lib_glsl[];
extern char datatoc_edit_curve_overlay_loosevert_vert_glsl[];
extern char datatoc_edit_curve_overlay_normals_vert_glsl[];
extern char datatoc_edit_curve_overlay_handle_vert_glsl[];
@@ -124,8 +125,10 @@ static void EDIT_CURVE_engine_init(void *UNUSED(vedata))
if (!sh_data->wire_normals_sh) {
sh_data->wire_normals_sh = GPU_shader_create_from_arrays({
- .vert =
- (const char *[]){sh_cfg_data->lib, datatoc_edit_curve_overlay_normals_vert_glsl, NULL},
+ .vert = (const char *[]){sh_cfg_data->lib,
+ datatoc_common_view_lib_glsl,
+ datatoc_edit_curve_overlay_normals_vert_glsl,
+ NULL},
.frag = (const char *[]){datatoc_gpu_shader_uniform_color_frag_glsl, NULL},
.defs = (const char *[]){sh_cfg_data->def, NULL},
});
@@ -133,8 +136,10 @@ static void EDIT_CURVE_engine_init(void *UNUSED(vedata))
if (!sh_data->overlay_edge_sh) {
sh_data->overlay_edge_sh = GPU_shader_create_from_arrays({
- .vert =
- (const char *[]){sh_cfg_data->lib, datatoc_edit_curve_overlay_handle_vert_glsl, NULL},
+ .vert = (const char *[]){sh_cfg_data->lib,
+ datatoc_common_view_lib_glsl,
+ datatoc_edit_curve_overlay_handle_vert_glsl,
+ NULL},
.geom = (const char *[]){sh_cfg_data->lib,
datatoc_common_globals_lib_glsl,
datatoc_edit_curve_overlay_handle_geom_glsl,
@@ -148,6 +153,7 @@ static void EDIT_CURVE_engine_init(void *UNUSED(vedata))
sh_data->overlay_vert_sh = GPU_shader_create_from_arrays({
.vert = (const char *[]){sh_cfg_data->lib,
datatoc_common_globals_lib_glsl,
+ datatoc_common_view_lib_glsl,
datatoc_edit_curve_overlay_loosevert_vert_glsl,
NULL},
.frag = (const char *[]){datatoc_gpu_shader_point_varying_color_frag_glsl, NULL},
@@ -270,31 +276,30 @@ static void EDIT_CURVE_cache_populate(void *vedata, Object *ob)
}
geom = DRW_cache_curve_edge_wire_get(ob);
- DRW_shgroup_call_add(wire_shgrp, geom, ob->obmat);
+ DRW_shgroup_call(wire_shgrp, geom, ob->obmat);
if ((cu->flag & CU_3D) && (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_CU_NORMALS) != 0) {
- static uint instance_len = 2;
geom = DRW_cache_curve_edge_normal_get(ob);
- DRW_shgroup_call_instances_add(wire_normals_shgrp, geom, ob->obmat, &instance_len);
+ DRW_shgroup_call_instances(wire_normals_shgrp, geom, ob->obmat, 2);
}
geom = DRW_cache_curve_edge_overlay_get(ob);
if (geom) {
- DRW_shgroup_call_add(stl->g_data->overlay_edge_shgrp, geom, ob->obmat);
+ DRW_shgroup_call(stl->g_data->overlay_edge_shgrp, geom, ob->obmat);
}
geom = DRW_cache_curve_vert_overlay_get(ob, stl->g_data->show_handles);
- DRW_shgroup_call_add(stl->g_data->overlay_vert_shgrp, geom, ob->obmat);
+ DRW_shgroup_call(stl->g_data->overlay_vert_shgrp, geom, ob->obmat);
}
}
if (ob->type == OB_SURF) {
if (BKE_object_is_in_editmode(ob)) {
struct GPUBatch *geom = DRW_cache_curve_edge_overlay_get(ob);
- DRW_shgroup_call_add(stl->g_data->overlay_edge_shgrp, geom, ob->obmat);
+ DRW_shgroup_call(stl->g_data->overlay_edge_shgrp, geom, ob->obmat);
geom = DRW_cache_curve_vert_overlay_get(ob, false);
- DRW_shgroup_call_add(stl->g_data->overlay_vert_shgrp, geom, ob->obmat);
+ DRW_shgroup_call(stl->g_data->overlay_vert_shgrp, geom, ob->obmat);
}
}
}
diff --git a/source/blender/draw/modes/edit_lattice_mode.c b/source/blender/draw/modes/edit_lattice_mode.c
index 273480b8127..cede3ed12c6 100644
--- a/source/blender/draw/modes/edit_lattice_mode.c
+++ b/source/blender/draw/modes/edit_lattice_mode.c
@@ -32,6 +32,7 @@
#include "draw_mode_engines.h"
extern char datatoc_common_globals_lib_glsl[];
+extern char datatoc_common_view_lib_glsl[];
extern char datatoc_edit_lattice_overlay_loosevert_vert_glsl[];
extern char datatoc_edit_lattice_overlay_frag_glsl[];
@@ -152,6 +153,7 @@ static void EDIT_LATTICE_engine_init(void *vedata)
sh_data->overlay_vert = GPU_shader_create_from_arrays({
.vert = (const char *[]){sh_cfg_data->lib,
datatoc_common_globals_lib_glsl,
+ datatoc_common_view_lib_glsl,
datatoc_edit_lattice_overlay_loosevert_vert_glsl,
NULL},
.frag = (const char *[]){datatoc_common_globals_lib_glsl,
@@ -212,10 +214,10 @@ static void EDIT_LATTICE_cache_populate(void *vedata, Object *ob)
struct GPUBatch *geom;
geom = DRW_cache_lattice_wire_get(ob, true);
- DRW_shgroup_call_add(stl->g_data->wire_shgrp, geom, ob->obmat);
+ DRW_shgroup_call(stl->g_data->wire_shgrp, geom, ob->obmat);
geom = DRW_cache_lattice_vert_overlay_get(ob);
- DRW_shgroup_call_add(stl->g_data->vert_shgrp, geom, ob->obmat);
+ DRW_shgroup_call(stl->g_data->vert_shgrp, geom, ob->obmat);
}
}
}
diff --git a/source/blender/draw/modes/edit_mesh_mode.c b/source/blender/draw/modes/edit_mesh_mode.c
index ffe7fe5845c..ee2d6239c41 100644
--- a/source/blender/draw/modes/edit_mesh_mode.c
+++ b/source/blender/draw/modes/edit_mesh_mode.c
@@ -60,6 +60,7 @@ extern char datatoc_edit_mesh_overlay_mesh_analysis_vert_glsl[];
extern char datatoc_edit_normals_vert_glsl[];
extern char datatoc_edit_normals_geom_glsl[];
extern char datatoc_common_globals_lib_glsl[];
+extern char datatoc_common_view_lib_glsl[];
extern char datatoc_gpu_shader_uniform_color_frag_glsl[];
extern char datatoc_gpu_shader_3D_smooth_color_frag_glsl[];
@@ -197,6 +198,7 @@ static void EDIT_MESH_engine_init(void *vedata)
sh_data->weight_face = GPU_shader_create_from_arrays({
.vert = (const char *[]){sh_cfg_data->lib,
datatoc_common_globals_lib_glsl,
+ datatoc_common_view_lib_glsl,
datatoc_paint_weight_vert_glsl,
NULL},
.frag = (const char *[]){datatoc_common_globals_lib_glsl,
@@ -207,6 +209,7 @@ static void EDIT_MESH_engine_init(void *vedata)
char *lib = BLI_string_joinN(sh_cfg_data->lib,
datatoc_common_globals_lib_glsl,
+ datatoc_common_view_lib_glsl,
datatoc_edit_mesh_overlay_common_lib_glsl);
/* Use geometry shader to draw edge wireframe. This ensure us
* the same result accross platforms and more flexibility. But
@@ -265,43 +268,43 @@ static void EDIT_MESH_engine_init(void *vedata)
sh_data->overlay_mix = DRW_shader_create_fullscreen(datatoc_edit_mesh_overlay_mix_frag_glsl,
NULL);
+ lib = BLI_string_joinN(sh_cfg_data->lib, datatoc_common_view_lib_glsl);
+
sh_data->normals_face = GPU_shader_create_from_arrays({
- .vert = (const char *[]){sh_cfg_data->lib, datatoc_edit_normals_vert_glsl, NULL},
- .geom = (const char *[]){sh_cfg_data->lib, datatoc_edit_normals_geom_glsl, NULL},
+ .vert = (const char *[]){lib, datatoc_edit_normals_vert_glsl, NULL},
+ .geom = (const char *[]){lib, datatoc_edit_normals_geom_glsl, NULL},
.frag = (const char *[]){datatoc_gpu_shader_uniform_color_frag_glsl, NULL},
.defs = (const char *[]){sh_cfg_data->def, "#define FACE_NORMALS\n", NULL},
});
sh_data->normals_loop = GPU_shader_create_from_arrays({
- .vert = (const char *[]){sh_cfg_data->lib, datatoc_edit_normals_vert_glsl, NULL},
- .geom = (const char *[]){sh_cfg_data->lib, datatoc_edit_normals_geom_glsl, NULL},
+ .vert = (const char *[]){lib, datatoc_edit_normals_vert_glsl, NULL},
+ .geom = (const char *[]){lib, datatoc_edit_normals_geom_glsl, NULL},
.frag = (const char *[]){datatoc_gpu_shader_uniform_color_frag_glsl, NULL},
.defs = (const char *[]){sh_cfg_data->def, "#define LOOP_NORMALS\n", NULL},
});
sh_data->normals = GPU_shader_create_from_arrays({
- .vert = (const char *[]){sh_cfg_data->lib, datatoc_edit_normals_vert_glsl, NULL},
- .geom = (const char *[]){sh_cfg_data->lib, datatoc_edit_normals_geom_glsl, NULL},
+ .vert = (const char *[]){lib, datatoc_edit_normals_vert_glsl, NULL},
+ .geom = (const char *[]){lib, datatoc_edit_normals_geom_glsl, NULL},
.frag = (const char *[]){datatoc_gpu_shader_uniform_color_frag_glsl, NULL},
.defs = (const char *[]){sh_cfg_data->def, NULL},
});
/* Mesh Analysis */
sh_data->mesh_analysis_face = GPU_shader_create_from_arrays({
- .vert = (const char *[]){sh_cfg_data->lib,
- datatoc_edit_mesh_overlay_mesh_analysis_vert_glsl,
- NULL},
+ .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_mesh_analysis_vert_glsl, NULL},
.frag = (const char *[]){datatoc_edit_mesh_overlay_mesh_analysis_frag_glsl, NULL},
.defs = (const char *[]){sh_cfg_data->def, "#define FACE_COLOR\n", NULL},
});
sh_data->mesh_analysis_vertex = GPU_shader_create_from_arrays({
- .vert = (const char *[]){sh_cfg_data->lib,
- datatoc_edit_mesh_overlay_mesh_analysis_vert_glsl,
- NULL},
+ .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_mesh_analysis_vert_glsl, NULL},
.frag = (const char *[]){datatoc_edit_mesh_overlay_mesh_analysis_frag_glsl, NULL},
.defs = (const char *[]){sh_cfg_data->def, "#define VERTEX_COLOR\n", NULL},
});
+ MEM_freeN(lib);
+
sh_data->depth = DRW_shader_create_3d_depth_only(draw_ctx->sh_cfg);
}
}
@@ -603,7 +606,7 @@ static void EDIT_MESH_cache_init(void *vedata)
psl->mix_occlude = DRW_pass_create("Mix Occluded Wires",
DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND);
DRWShadingGroup *mix_shgrp = DRW_shgroup_create(sh_data->overlay_mix, psl->mix_occlude);
- DRW_shgroup_call_add(mix_shgrp, quad, NULL);
+ DRW_shgroup_call(mix_shgrp, quad, NULL);
DRW_shgroup_uniform_float(mix_shgrp, "alpha", &backwire_opacity, 1);
DRW_shgroup_uniform_texture_ref(mix_shgrp, "wireColor", &e_data.occlude_wire_color_tx);
DRW_shgroup_uniform_texture_ref(mix_shgrp, "wireDepth", &e_data.occlude_wire_depth_tx);
@@ -636,17 +639,17 @@ static void edit_mesh_add_ob_to_pass(Scene *scene,
geom_tris = DRW_mesh_batch_cache_get_edit_triangles(ob->data);
geom_edges = DRW_mesh_batch_cache_get_edit_edges(ob->data);
- DRW_shgroup_call_add(edge_shgrp, geom_edges, ob->obmat);
- DRW_shgroup_call_add(face_shgrp, geom_tris, ob->obmat);
+ DRW_shgroup_call(edge_shgrp, geom_edges, ob->obmat);
+ DRW_shgroup_call(face_shgrp, geom_tris, ob->obmat);
if ((tsettings->selectmode & SCE_SELECT_VERTEX) != 0) {
geom_verts = DRW_mesh_batch_cache_get_edit_vertices(ob->data);
- DRW_shgroup_call_add(vert_shgrp, geom_verts, ob->obmat);
+ DRW_shgroup_call(vert_shgrp, geom_verts, ob->obmat);
}
if (facedot_shgrp && (tsettings->selectmode & SCE_SELECT_FACE) != 0) {
geom_fcenter = DRW_mesh_batch_cache_get_edit_facedots(ob->data);
- DRW_shgroup_call_add(facedot_shgrp, geom_fcenter, ob->obmat);
+ DRW_shgroup_call(facedot_shgrp, geom_fcenter, ob->obmat);
}
}
@@ -691,7 +694,7 @@ static void EDIT_MESH_cache_populate(void *vedata, Object *ob)
if (do_show_weight) {
geom = DRW_cache_mesh_surface_weights_get(ob);
- DRW_shgroup_call_add(g_data->fweights_shgrp, geom, ob->obmat);
+ DRW_shgroup_call(g_data->fweights_shgrp, geom, ob->obmat);
}
if (do_show_mesh_analysis) {
@@ -702,30 +705,30 @@ static void EDIT_MESH_cache_populate(void *vedata, Object *ob)
if (is_original) {
geom = DRW_cache_mesh_surface_mesh_analysis_get(ob);
if (geom) {
- DRW_shgroup_call_add(g_data->mesh_analysis_shgrp, geom, ob->obmat);
+ DRW_shgroup_call(g_data->mesh_analysis_shgrp, geom, ob->obmat);
}
}
}
if (do_occlude_wire || do_in_front) {
geom = DRW_cache_mesh_surface_get(ob);
- DRW_shgroup_call_add(do_in_front ? g_data->depth_shgrp_hidden_wire_in_front :
- g_data->depth_shgrp_hidden_wire,
- geom,
- ob->obmat);
+ DRW_shgroup_call(do_in_front ? g_data->depth_shgrp_hidden_wire_in_front :
+ g_data->depth_shgrp_hidden_wire,
+ geom,
+ ob->obmat);
}
if (vnormals_do) {
geom = DRW_mesh_batch_cache_get_edit_vertices(ob->data);
- DRW_shgroup_call_add(g_data->vnormals_shgrp, geom, ob->obmat);
+ DRW_shgroup_call(g_data->vnormals_shgrp, geom, ob->obmat);
}
if (lnormals_do) {
geom = DRW_mesh_batch_cache_get_edit_lnors(ob->data);
- DRW_shgroup_call_add(g_data->lnormals_shgrp, geom, ob->obmat);
+ DRW_shgroup_call(g_data->lnormals_shgrp, geom, ob->obmat);
}
if (fnormals_do) {
geom = DRW_mesh_batch_cache_get_edit_facedots(ob->data);
- DRW_shgroup_call_add(g_data->fnormals_shgrp, geom, ob->obmat);
+ DRW_shgroup_call(g_data->fnormals_shgrp, geom, ob->obmat);
}
if (g_data->do_zbufclip) {
diff --git a/source/blender/draw/modes/edit_metaball_mode.c b/source/blender/draw/modes/edit_metaball_mode.c
index aa7c6863423..11ff95a212b 100644
--- a/source/blender/draw/modes/edit_metaball_mode.c
+++ b/source/blender/draw/modes/edit_metaball_mode.c
@@ -26,6 +26,8 @@
#include "BKE_object.h"
+#include "DEG_depsgraph_query.h"
+
#include "ED_mball.h"
/* If builtin shaders are needed */
@@ -86,7 +88,7 @@ typedef struct EDIT_METABALL_Data {
typedef struct EDIT_METABALL_PrivateData {
/* This keeps the references of the shading groups for
* easy access in EDIT_METABALL_cache_populate() */
- DRWShadingGroup *group;
+ DRWCallBuffer *group;
} EDIT_METABALL_PrivateData; /* Transient data */
/* *********** FUNCTIONS *********** */
@@ -119,7 +121,7 @@ static void EDIT_METABALL_cache_init(void *vedata)
psl->pass = DRW_pass_create("My Pass", state);
/* Create a shadingGroup using a function in draw_common.c or custom one */
- stl->g_data->group = shgroup_instance_mball_handles(psl->pass, draw_ctx->sh_cfg);
+ stl->g_data->group = buffer_instance_mball_handles(psl->pass, draw_ctx->sh_cfg);
}
}
@@ -131,7 +133,7 @@ static void EDIT_METABALL_cache_populate(void *vedata, Object *ob)
if (ob->type == OB_MBALL) {
const DRWContextState *draw_ctx = DRW_context_state_get();
- DRWShadingGroup *group = stl->g_data->group;
+ DRWCallBuffer *group = stl->g_data->group;
if ((ob == draw_ctx->object_edit) || BKE_object_is_in_editmode(ob)) {
MetaBall *mb = ob->data;
@@ -160,7 +162,8 @@ static void EDIT_METABALL_cache_populate(void *vedata, Object *ob)
copy_v3_v3(draw_scale_xform[2], scamat[2]);
}
- int select_id = ob->select_id;
+ const Object *orig_object = DEG_get_original_object(ob);
+ int select_id = orig_object->runtime.select_id;
for (MetaElem *ml = mb->editelems->first; ml != NULL; ml = ml->next, select_id += 0x10000) {
float world_pos[3];
mul_v3_m4v3(world_pos, ob->obmat, &ml->x);
@@ -181,7 +184,7 @@ static void EDIT_METABALL_cache_populate(void *vedata, Object *ob)
DRW_select_load_id(select_id | MBALLSEL_RADIUS);
}
- DRW_shgroup_call_dynamic_add(group, draw_scale_xform, &ml->rad, color);
+ DRW_buffer_add_entry(group, draw_scale_xform, &ml->rad, color);
if ((ml->flag & SELECT) && !(ml->flag & MB_SCALE_RAD)) {
color = col_stiffness_select;
@@ -194,7 +197,7 @@ static void EDIT_METABALL_cache_populate(void *vedata, Object *ob)
DRW_select_load_id(select_id | MBALLSEL_STIFF);
}
- DRW_shgroup_call_dynamic_add(group, draw_scale_xform, &draw_stiffness_radius, color);
+ DRW_buffer_add_entry(group, draw_scale_xform, &draw_stiffness_radius, color);
}
}
}
diff --git a/source/blender/draw/modes/edit_text_mode.c b/source/blender/draw/modes/edit_text_mode.c
index 5f44a74b24e..fa2248e9aa5 100644
--- a/source/blender/draw/modes/edit_text_mode.c
+++ b/source/blender/draw/modes/edit_text_mode.c
@@ -102,8 +102,8 @@ typedef struct EDIT_TEXT_PrivateData {
DRWShadingGroup *wire_shgrp;
DRWShadingGroup *overlay_select_shgrp;
DRWShadingGroup *overlay_cursor_shgrp;
- DRWShadingGroup *box_shgrp;
- DRWShadingGroup *box_active_shgrp;
+ DRWCallBuffer *box_shgrp;
+ DRWCallBuffer *box_active_shgrp;
} EDIT_TEXT_PrivateData; /* Transient data */
/* *********** FUNCTIONS *********** */
@@ -179,9 +179,9 @@ static void EDIT_TEXT_cache_init(void *vedata)
psl->text_box_pass = DRW_pass_create("Font Text Boxes",
DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH);
- stl->g_data->box_shgrp = shgroup_dynlines_dashed_uniform_color(
+ stl->g_data->box_shgrp = buffer_dynlines_dashed_uniform_color(
psl->text_box_pass, G_draw.block.colorWire, draw_ctx->sh_cfg);
- stl->g_data->box_active_shgrp = shgroup_dynlines_dashed_uniform_color(
+ stl->g_data->box_active_shgrp = buffer_dynlines_dashed_uniform_color(
psl->text_box_pass, G_draw.block.colorActive, draw_ctx->sh_cfg);
}
}
@@ -241,7 +241,7 @@ static void edit_text_cache_populate_select(void *vedata, Object *ob)
v2_quad_corners_to_mat4(box, final_mat);
mul_m4_m4m4(final_mat, ob->obmat, final_mat);
- DRW_shgroup_call_add(stl->g_data->overlay_select_shgrp, geom, final_mat);
+ DRW_shgroup_call(stl->g_data->overlay_select_shgrp, geom, final_mat);
}
}
@@ -257,7 +257,7 @@ static void edit_text_cache_populate_cursor(void *vedata, Object *ob)
mul_m4_m4m4(mat, ob->obmat, mat);
struct GPUBatch *geom = DRW_cache_quad_get();
- DRW_shgroup_call_add(stl->g_data->overlay_cursor_shgrp, geom, mat);
+ DRW_shgroup_call(stl->g_data->overlay_cursor_shgrp, geom, mat);
}
static void edit_text_cache_populate_boxes(void *vedata, Object *ob)
@@ -265,7 +265,7 @@ static void edit_text_cache_populate_boxes(void *vedata, Object *ob)
EDIT_TEXT_StorageList *stl = ((EDIT_TEXT_Data *)vedata)->stl;
const Curve *cu = ob->data;
- DRWShadingGroup *shading_groups[] = {
+ DRWCallBuffer *callbufs[] = {
stl->g_data->box_active_shgrp,
stl->g_data->box_shgrp,
};
@@ -279,7 +279,7 @@ static void edit_text_cache_populate_boxes(void *vedata, Object *ob)
}
const bool is_active = i == (cu->actbox - 1);
- DRWShadingGroup *shading_group = shading_groups[is_active ? 0 : 1];
+ DRWCallBuffer *callbuf = callbufs[is_active ? 0 : 1];
vec[0] = cu->xof + tb->x;
vec[1] = cu->yof + tb->y + cu->fsize_realtime;
@@ -289,29 +289,29 @@ static void edit_text_cache_populate_boxes(void *vedata, Object *ob)
vec[0] += tb->w;
mul_v3_m4v3(vec2, ob->obmat, vec);
- DRW_shgroup_call_dynamic_add(shading_group, vec1);
- DRW_shgroup_call_dynamic_add(shading_group, vec2);
+ DRW_buffer_add_entry(callbuf, vec1);
+ DRW_buffer_add_entry(callbuf, vec2);
vec[1] -= tb->h;
copy_v3_v3(vec1, vec2);
mul_v3_m4v3(vec2, ob->obmat, vec);
- DRW_shgroup_call_dynamic_add(shading_group, vec1);
- DRW_shgroup_call_dynamic_add(shading_group, vec2);
+ DRW_buffer_add_entry(callbuf, vec1);
+ DRW_buffer_add_entry(callbuf, vec2);
vec[0] -= tb->w;
copy_v3_v3(vec1, vec2);
mul_v3_m4v3(vec2, ob->obmat, vec);
- DRW_shgroup_call_dynamic_add(shading_group, vec1);
- DRW_shgroup_call_dynamic_add(shading_group, vec2);
+ DRW_buffer_add_entry(callbuf, vec1);
+ DRW_buffer_add_entry(callbuf, vec2);
vec[1] += tb->h;
copy_v3_v3(vec1, vec2);
mul_v3_m4v3(vec2, ob->obmat, vec);
- DRW_shgroup_call_dynamic_add(shading_group, vec1);
- DRW_shgroup_call_dynamic_add(shading_group, vec2);
+ DRW_buffer_add_entry(callbuf, vec1);
+ DRW_buffer_add_entry(callbuf, vec2);
}
}
@@ -334,7 +334,7 @@ static void EDIT_TEXT_cache_populate(void *vedata, Object *ob)
if ((cu->flag & CU_FAST) || !has_surface) {
geom = DRW_cache_text_edge_wire_get(ob);
if (geom) {
- DRW_shgroup_call_add(stl->g_data->wire_shgrp, geom, ob->obmat);
+ DRW_shgroup_call(stl->g_data->wire_shgrp, geom, ob->obmat);
}
}
else {
diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c
index 378f810551e..e98f11dc6ea 100644
--- a/source/blender/draw/modes/object_mode.c
+++ b/source/blender/draw/modes/object_mode.c
@@ -88,6 +88,7 @@ extern char datatoc_object_particle_prim_vert_glsl[];
extern char datatoc_object_particle_dot_vert_glsl[];
extern char datatoc_object_particle_dot_frag_glsl[];
extern char datatoc_common_globals_lib_glsl[];
+extern char datatoc_common_view_lib_glsl[];
extern char datatoc_common_fxaa_lib_glsl[];
extern char datatoc_gpu_shader_flat_color_frag_glsl[];
extern char datatoc_gpu_shader_flat_id_frag_glsl[];
@@ -171,82 +172,82 @@ typedef struct OBJECT_ShadingGroupList {
struct DRWPass *bone_axes;
/* Empties */
- DRWShadingGroup *plain_axes;
- DRWShadingGroup *cube;
- DRWShadingGroup *circle;
- DRWShadingGroup *sphere;
- DRWShadingGroup *sphere_solid;
- DRWShadingGroup *cylinder;
- DRWShadingGroup *capsule_cap;
- DRWShadingGroup *capsule_body;
- DRWShadingGroup *cone;
- DRWShadingGroup *single_arrow;
- DRWShadingGroup *single_arrow_line;
- DRWShadingGroup *empty_axes;
+ DRWCallBuffer *plain_axes;
+ DRWCallBuffer *cube;
+ DRWCallBuffer *circle;
+ DRWCallBuffer *sphere;
+ DRWCallBuffer *sphere_solid;
+ DRWCallBuffer *cylinder;
+ DRWCallBuffer *capsule_cap;
+ DRWCallBuffer *capsule_body;
+ DRWCallBuffer *cone;
+ DRWCallBuffer *single_arrow;
+ DRWCallBuffer *single_arrow_line;
+ DRWCallBuffer *empty_axes;
/* Force Field */
- DRWShadingGroup *field_wind;
- DRWShadingGroup *field_force;
- DRWShadingGroup *field_vortex;
- DRWShadingGroup *field_curve_sta;
- DRWShadingGroup *field_curve_end;
- DRWShadingGroup *field_tube_limit;
- DRWShadingGroup *field_cone_limit;
+ DRWCallBuffer *field_wind;
+ DRWCallBuffer *field_force;
+ DRWCallBuffer *field_vortex;
+ DRWCallBuffer *field_curve_sta;
+ DRWCallBuffer *field_curve_end;
+ DRWCallBuffer *field_tube_limit;
+ DRWCallBuffer *field_cone_limit;
/* Grease Pencil */
- DRWShadingGroup *gpencil_axes;
+ DRWCallBuffer *gpencil_axes;
/* Speaker */
- DRWShadingGroup *speaker;
+ DRWCallBuffer *speaker;
/* Probe */
- DRWShadingGroup *probe_cube;
- DRWShadingGroup *probe_planar;
- DRWShadingGroup *probe_grid;
+ DRWCallBuffer *probe_cube;
+ DRWCallBuffer *probe_planar;
+ DRWCallBuffer *probe_grid;
/* MetaBalls */
- DRWShadingGroup *mball_handle;
+ DRWCallBuffer *mball_handle;
/* Lights */
- DRWShadingGroup *light_center;
- DRWShadingGroup *light_groundpoint;
- DRWShadingGroup *light_groundline;
- DRWShadingGroup *light_circle;
- DRWShadingGroup *light_circle_shadow;
- DRWShadingGroup *light_sunrays;
- DRWShadingGroup *light_distance;
- DRWShadingGroup *light_buflimit;
- DRWShadingGroup *light_buflimit_points;
- DRWShadingGroup *light_area_sphere;
- DRWShadingGroup *light_area_square;
- DRWShadingGroup *light_area_disk;
- DRWShadingGroup *light_hemi;
- DRWShadingGroup *light_spot_cone;
- DRWShadingGroup *light_spot_blend;
- DRWShadingGroup *light_spot_pyramid;
- DRWShadingGroup *light_spot_blend_rect;
- DRWShadingGroup *light_spot_volume;
- DRWShadingGroup *light_spot_volume_rect;
- DRWShadingGroup *light_spot_volume_outside;
- DRWShadingGroup *light_spot_volume_rect_outside;
+ DRWCallBuffer *light_center;
+ DRWCallBuffer *light_groundpoint;
+ DRWCallBuffer *light_groundline;
+ DRWCallBuffer *light_circle;
+ DRWCallBuffer *light_circle_shadow;
+ DRWCallBuffer *light_sunrays;
+ DRWCallBuffer *light_distance;
+ DRWCallBuffer *light_buflimit;
+ DRWCallBuffer *light_buflimit_points;
+ DRWCallBuffer *light_area_sphere;
+ DRWCallBuffer *light_area_square;
+ DRWCallBuffer *light_area_disk;
+ DRWCallBuffer *light_hemi;
+ DRWCallBuffer *light_spot_cone;
+ DRWCallBuffer *light_spot_blend;
+ DRWCallBuffer *light_spot_pyramid;
+ DRWCallBuffer *light_spot_blend_rect;
+ DRWCallBuffer *light_spot_volume;
+ DRWCallBuffer *light_spot_volume_rect;
+ DRWCallBuffer *light_spot_volume_outside;
+ DRWCallBuffer *light_spot_volume_rect_outside;
/* Helpers */
- DRWShadingGroup *relationship_lines;
- DRWShadingGroup *constraint_lines;
+ DRWCallBuffer *relationship_lines;
+ DRWCallBuffer *constraint_lines;
/* Camera */
- DRWShadingGroup *camera;
- DRWShadingGroup *camera_frame;
- DRWShadingGroup *camera_tria;
- DRWShadingGroup *camera_focus;
- DRWShadingGroup *camera_clip;
- DRWShadingGroup *camera_clip_points;
- DRWShadingGroup *camera_mist;
- DRWShadingGroup *camera_mist_points;
- DRWShadingGroup *camera_stereo_plane;
- DRWShadingGroup *camera_stereo_plane_wires;
- DRWShadingGroup *camera_stereo_volume;
- DRWShadingGroup *camera_stereo_volume_wires;
+ DRWCallBuffer *camera;
+ DRWCallBuffer *camera_frame;
+ DRWCallBuffer *camera_tria;
+ DRWCallBuffer *camera_focus;
+ DRWCallBuffer *camera_clip;
+ DRWCallBuffer *camera_clip_points;
+ DRWCallBuffer *camera_mist;
+ DRWCallBuffer *camera_mist_points;
+ DRWCallBuffer *camera_stereo_plane;
+ DRWCallBuffer *camera_stereo_plane_wires;
+ DRWCallBuffer *camera_stereo_volume;
+ DRWCallBuffer *camera_stereo_volume_wires;
ListBase camera_path;
/* Wire */
@@ -268,7 +269,7 @@ typedef struct OBJECT_ShadingGroupList {
DRWShadingGroup *points_dupli_select;
/* Texture Space */
- DRWShadingGroup *texspace;
+ DRWCallBuffer *texspace;
} OBJECT_ShadingGroupList;
typedef struct OBJECT_PrivateData {
@@ -284,22 +285,22 @@ typedef struct OBJECT_PrivateData {
DRWShadingGroup *outlines_transform;
/* Lightprobes */
- DRWShadingGroup *lightprobes_cube_select;
- DRWShadingGroup *lightprobes_cube_select_dupli;
- DRWShadingGroup *lightprobes_cube_active;
- DRWShadingGroup *lightprobes_cube_transform;
+ DRWCallBuffer *lightprobes_cube_select;
+ DRWCallBuffer *lightprobes_cube_select_dupli;
+ DRWCallBuffer *lightprobes_cube_active;
+ DRWCallBuffer *lightprobes_cube_transform;
- DRWShadingGroup *lightprobes_planar_select;
- DRWShadingGroup *lightprobes_planar_select_dupli;
- DRWShadingGroup *lightprobes_planar_active;
- DRWShadingGroup *lightprobes_planar_transform;
+ DRWCallBuffer *lightprobes_planar_select;
+ DRWCallBuffer *lightprobes_planar_select_dupli;
+ DRWCallBuffer *lightprobes_planar_active;
+ DRWCallBuffer *lightprobes_planar_transform;
/* Objects Centers */
- DRWShadingGroup *center_active;
- DRWShadingGroup *center_selected;
- DRWShadingGroup *center_deselected;
- DRWShadingGroup *center_selected_lib;
- DRWShadingGroup *center_deselected_lib;
+ DRWCallBuffer *center_active;
+ DRWCallBuffer *center_selected;
+ DRWCallBuffer *center_deselected;
+ DRWCallBuffer *center_selected_lib;
+ DRWCallBuffer *center_deselected_lib;
/* Outlines id offset (accessed as an array) */
int id_ofs_active;
@@ -316,15 +317,20 @@ typedef struct OBJECT_PrivateData {
bool xray_enabled_and_not_wire;
} OBJECT_PrivateData; /* Transient data */
+typedef struct OBJECT_DupliData {
+ DRWShadingGroup *outline_shgrp;
+ GPUBatch *outline_geom;
+ DRWShadingGroup *extra_shgrp;
+ GPUBatch *extra_geom;
+} OBJECT_DupliData;
+
static struct {
/* Instance Data format */
- struct GPUVertFormat *particle_format;
struct GPUVertFormat *empty_image_format;
struct GPUVertFormat *empty_image_wire_format;
OBJECT_Shaders sh_data[GPU_SHADER_CFG_LEN];
- float camera_pos[3];
float grid_settings[5];
float grid_mesh_size;
int grid_flag;
@@ -412,8 +418,14 @@ static void OBJECT_engine_init(void *vedata)
.defs = (const char *[]){sh_cfg_data->def, NULL},
});
sh_data->outline_prepass_wire = GPU_shader_create_from_arrays({
- .vert = (const char *[]){sh_cfg_data->lib, datatoc_object_outline_prepass_vert_glsl, NULL},
- .geom = (const char *[]){sh_cfg_data->lib, datatoc_object_outline_prepass_geom_glsl, NULL},
+ .vert = (const char *[]){sh_cfg_data->lib,
+ datatoc_common_view_lib_glsl,
+ datatoc_object_outline_prepass_vert_glsl,
+ NULL},
+ .geom = (const char *[]){sh_cfg_data->lib,
+ datatoc_common_view_lib_glsl,
+ datatoc_object_outline_prepass_geom_glsl,
+ NULL},
.frag = (const char *[]){datatoc_object_outline_prepass_frag_glsl, NULL},
.defs = (const char *[]){sh_cfg_data->def, NULL},
});
@@ -455,37 +467,53 @@ static void OBJECT_engine_init(void *vedata)
"#define DEPTH_BACK " STRINGIFY(OB_EMPTY_IMAGE_DEPTH_BACK) "\n");
sh_data->object_empty_image = GPU_shader_create_from_arrays({
- .vert = (const char *[]){sh_cfg_data->lib, datatoc_object_empty_image_vert_glsl, NULL},
+ .vert = (const char *[]){sh_cfg_data->lib,
+ datatoc_common_view_lib_glsl,
+ datatoc_object_empty_image_vert_glsl,
+ NULL},
.frag = (const char *[]){datatoc_object_empty_image_frag_glsl, NULL},
.defs = (const char *[]){sh_cfg_data->def, empty_image_defs, NULL},
});
sh_data->object_empty_image_wire = GPU_shader_create_from_arrays({
- .vert = (const char *[]){sh_cfg_data->lib, datatoc_object_empty_image_vert_glsl, NULL},
+ .vert = (const char *[]){sh_cfg_data->lib,
+ datatoc_common_view_lib_glsl,
+ datatoc_object_empty_image_vert_glsl,
+ NULL},
.frag = (const char *[]){datatoc_object_empty_image_frag_glsl, NULL},
.defs = (const char *[]){sh_cfg_data->def, "#define USE_WIRE\n", empty_image_defs, NULL},
});
}
/* Grid */
- sh_data->grid = DRW_shader_create_with_lib(datatoc_object_grid_vert_glsl,
- NULL,
- datatoc_object_grid_frag_glsl,
- datatoc_common_globals_lib_glsl,
- NULL);
+ sh_data->grid = GPU_shader_create_from_arrays({
+ .vert = (const char *[]){datatoc_common_globals_lib_glsl,
+ datatoc_common_view_lib_glsl,
+ datatoc_object_grid_vert_glsl,
+ NULL},
+ .frag = (const char *[]){datatoc_common_globals_lib_glsl,
+ datatoc_common_view_lib_glsl,
+ datatoc_object_grid_frag_glsl,
+ NULL},
+ });
/* Particles */
- sh_data->part_prim = DRW_shader_create(datatoc_object_particle_prim_vert_glsl,
- NULL,
- datatoc_gpu_shader_flat_color_frag_glsl,
- NULL);
-
- sh_data->part_axis = DRW_shader_create(datatoc_object_particle_prim_vert_glsl,
- NULL,
- datatoc_gpu_shader_flat_color_frag_glsl,
- "#define USE_AXIS\n");
-
- sh_data->part_dot = DRW_shader_create(
- datatoc_object_particle_dot_vert_glsl, NULL, datatoc_object_particle_dot_frag_glsl, NULL);
+ sh_data->part_prim = DRW_shader_create_with_lib(datatoc_object_particle_prim_vert_glsl,
+ NULL,
+ datatoc_gpu_shader_flat_color_frag_glsl,
+ datatoc_common_view_lib_glsl,
+ NULL);
+
+ sh_data->part_axis = DRW_shader_create_with_lib(datatoc_object_particle_prim_vert_glsl,
+ NULL,
+ datatoc_gpu_shader_flat_color_frag_glsl,
+ datatoc_common_view_lib_glsl,
+ "#define USE_AXIS\n");
+
+ sh_data->part_dot = DRW_shader_create_with_lib(datatoc_object_particle_dot_vert_glsl,
+ NULL,
+ datatoc_object_particle_dot_frag_glsl,
+ datatoc_common_view_lib_glsl,
+ NULL);
/* Lightprobes */
sh_data->lightprobe_grid = DRW_shader_create(datatoc_object_lightprobe_grid_vert_glsl,
@@ -523,9 +551,6 @@ static void OBJECT_engine_init(void *vedata)
DRW_viewport_matrix_get(invwinmat, DRW_MAT_WININV);
DRW_viewport_matrix_get(invviewmat, DRW_MAT_VIEWINV);
- /* Setup camera pos */
- copy_v3_v3(e_data.camera_pos, invviewmat[3]);
-
/* if perps */
if (winmat[3][3] == 0.0f) {
float fov;
@@ -597,8 +622,9 @@ static void OBJECT_engine_init(void *vedata)
if (((rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO)) && show_axis_z) {
e_data.zpos_flag = SHOW_AXIS_Z;
- float zvec[4] = {0.0f, 0.0f, -1.0f, 0.0f};
- mul_m4_v4(invviewmat, zvec);
+ float zvec[3], campos[3];
+ negate_v3_v3(zvec, invviewmat[2]);
+ copy_v3_v3(campos, invviewmat[3]);
/* z axis : chose the most facing plane */
if (fabsf(zvec[0]) < fabsf(zvec[1])) {
@@ -612,7 +638,7 @@ static void OBJECT_engine_init(void *vedata)
/* Persp : If camera is below floor plane, we switch clipping
* Ortho : If eye vector is looking up, we switch clipping */
- if (((winmat[3][3] == 0.0f) && (e_data.camera_pos[2] > 0.0f)) ||
+ if (((winmat[3][3] == 0.0f) && (campos[2] > 0.0f)) ||
((winmat[3][3] != 0.0f) && (zvec[2] < 0.0f))) {
e_data.zpos_flag |= CLIP_ZPOS;
e_data.zneg_flag |= CLIP_ZNEG;
@@ -661,7 +687,6 @@ static void OBJECT_engine_init(void *vedata)
static void OBJECT_engine_free(void)
{
- MEM_SAFE_FREE(e_data.particle_format);
MEM_SAFE_FREE(e_data.empty_image_format);
MEM_SAFE_FREE(e_data.empty_image_wire_format);
@@ -771,8 +796,8 @@ static int *shgroup_theme_id_to_outline_counter(OBJECT_StorageList *stl,
}
}
-static DRWShadingGroup *shgroup_theme_id_to_probe_planar_outline_shgrp(OBJECT_StorageList *stl,
- int theme_id)
+static DRWCallBuffer *buffer_theme_id_to_probe_planar_outline_shgrp(OBJECT_StorageList *stl,
+ int theme_id)
{
/* does not increment counter */
switch (theme_id) {
@@ -786,9 +811,9 @@ static DRWShadingGroup *shgroup_theme_id_to_probe_planar_outline_shgrp(OBJECT_St
}
}
-static DRWShadingGroup *shgroup_theme_id_to_probe_cube_outline_shgrp(OBJECT_StorageList *stl,
- int theme_id,
- const int base_flag)
+static DRWCallBuffer *buffer_theme_id_to_probe_cube_outline_shgrp(OBJECT_StorageList *stl,
+ int theme_id,
+ const int base_flag)
{
/* does not increment counter */
if (UNLIKELY(base_flag & BASE_FROM_DUPLI)) {
@@ -961,7 +986,7 @@ static void DRW_shgroup_empty_image(OBJECT_Shaders *sh_data,
GPUTexture *tex = NULL;
if (ob->data != NULL) {
- tex = GPU_texture_from_blender(ob->data, ob->iuser, GL_TEXTURE_2D, false);
+ tex = GPU_texture_from_blender(ob->data, ob->iuser, GL_TEXTURE_2D);
if (tex) {
size[0] = GPU_texture_width(tex);
size[1] = GPU_texture_height(tex);
@@ -985,9 +1010,7 @@ static void DRW_shgroup_empty_image(OBJECT_Shaders *sh_data,
{
DRWShadingGroup *grp = DRW_shgroup_create(sh_data->object_empty_image_wire, sgl->non_meshes);
- /* TODO(fclem) implement DRW_shgroup_uniform_vec2_copy */
- DRW_shgroup_uniform_float_copy(grp, "aspectX", image_aspect[0]);
- DRW_shgroup_uniform_float_copy(grp, "aspectY", image_aspect[1]);
+ DRW_shgroup_uniform_vec2_copy(grp, "aspect", image_aspect);
DRW_shgroup_uniform_int_copy(grp, "depthMode", depth_mode);
DRW_shgroup_uniform_float(grp, "size", &ob->empty_drawsize, 1);
DRW_shgroup_uniform_vec2(grp, "offset", ob->ima_ofs, 1);
@@ -995,7 +1018,7 @@ static void DRW_shgroup_empty_image(OBJECT_Shaders *sh_data,
if (sh_cfg == GPU_SHADER_CFG_CLIPPED) {
DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d);
}
- DRW_shgroup_call_add(grp, DRW_cache_image_plane_wire_get(), ob->obmat);
+ DRW_shgroup_call(grp, DRW_cache_image_plane_wire_get(), ob->obmat);
}
if (!BKE_object_empty_image_data_is_visible_in_view3d(ob, rv3d)) {
@@ -1005,8 +1028,7 @@ static void DRW_shgroup_empty_image(OBJECT_Shaders *sh_data,
if (tex && ((ob->color[3] > 0.0f) || !use_alpha_blend)) {
DRWShadingGroup *grp = DRW_shgroup_create(
sh_data->object_empty_image, (use_alpha_blend) ? sgl->image_empties : sgl->non_meshes);
- DRW_shgroup_uniform_float_copy(grp, "aspectX", image_aspect[0]);
- DRW_shgroup_uniform_float_copy(grp, "aspectY", image_aspect[1]);
+ DRW_shgroup_uniform_vec2_copy(grp, "aspect", image_aspect);
DRW_shgroup_uniform_int_copy(grp, "depthMode", depth_mode);
DRW_shgroup_uniform_float(grp, "size", &ob->empty_drawsize, 1);
DRW_shgroup_uniform_vec2(grp, "offset", ob->ima_ofs, 1);
@@ -1016,7 +1038,7 @@ static void DRW_shgroup_empty_image(OBJECT_Shaders *sh_data,
if (sh_cfg == GPU_SHADER_CFG_CLIPPED) {
DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d);
}
- DRW_shgroup_call_add(grp, DRW_cache_image_plane_get(), ob->obmat);
+ DRW_shgroup_call(grp, DRW_cache_image_plane_get(), ob->obmat);
}
}
@@ -1081,23 +1103,23 @@ static void OBJECT_cache_init(void *vedata)
struct GPUBatch *quad = DRW_cache_quad_get();
/* Cubemap */
- g_data->lightprobes_cube_select = shgroup_instance_outline(
+ g_data->lightprobes_cube_select = buffer_instance_outline(
pass, sphere, &g_data->id_ofs_prb_select);
- g_data->lightprobes_cube_select_dupli = shgroup_instance_outline(
+ g_data->lightprobes_cube_select_dupli = buffer_instance_outline(
pass, sphere, &g_data->id_ofs_prb_select_dupli);
- g_data->lightprobes_cube_active = shgroup_instance_outline(
+ g_data->lightprobes_cube_active = buffer_instance_outline(
pass, sphere, &g_data->id_ofs_prb_active);
- g_data->lightprobes_cube_transform = shgroup_instance_outline(
+ g_data->lightprobes_cube_transform = buffer_instance_outline(
pass, sphere, &g_data->id_ofs_prb_transform);
/* Planar */
- g_data->lightprobes_planar_select = shgroup_instance_outline(
+ g_data->lightprobes_planar_select = buffer_instance_outline(
pass, quad, &g_data->id_ofs_prb_select);
- g_data->lightprobes_planar_select_dupli = shgroup_instance_outline(
+ g_data->lightprobes_planar_select_dupli = buffer_instance_outline(
pass, quad, &g_data->id_ofs_prb_select_dupli);
- g_data->lightprobes_planar_active = shgroup_instance_outline(
+ g_data->lightprobes_planar_active = buffer_instance_outline(
pass, quad, &g_data->id_ofs_prb_active);
- g_data->lightprobes_planar_transform = shgroup_instance_outline(
+ g_data->lightprobes_planar_transform = buffer_instance_outline(
pass, quad, &g_data->id_ofs_prb_transform);
g_data->id_ofs_prb_select = 0;
@@ -1123,7 +1145,7 @@ static void OBJECT_cache_init(void *vedata)
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
DRW_shgroup_uniform_float_copy(grp, "alphaOcclu", alphaOcclu);
DRW_shgroup_uniform_int(grp, "idOffsets", &stl->g_data->id_ofs_active, 4);
- DRW_shgroup_call_add(grp, quad, NULL);
+ DRW_shgroup_call(grp, quad, NULL);
/* This is the bleed pass if do_outline_expand is false. */
GPUShader *fade_sh = (do_large_expand) ? sh_data->outline_fade_large : sh_data->outline_fade;
@@ -1132,7 +1154,7 @@ static void OBJECT_cache_init(void *vedata)
grp = DRW_shgroup_create(fade_sh, psl->outlines_expand);
DRW_shgroup_uniform_texture_ref(grp, "outlineColor", &e_data.outlines_blur_tx);
DRW_shgroup_uniform_bool_copy(grp, "doExpand", do_outline_expand);
- DRW_shgroup_call_add(grp, quad, NULL);
+ DRW_shgroup_call(grp, quad, NULL);
psl->outlines_bleed = DRW_pass_create("Outlines Bleed Pass", state);
@@ -1140,7 +1162,7 @@ static void OBJECT_cache_init(void *vedata)
grp = DRW_shgroup_create(sh_data->outline_fade, psl->outlines_bleed);
DRW_shgroup_uniform_texture_ref(grp, "outlineColor", &e_data.outlines_color_tx);
DRW_shgroup_uniform_bool_copy(grp, "doExpand", false);
- DRW_shgroup_call_add(grp, quad, NULL);
+ DRW_shgroup_call(grp, quad, NULL);
}
}
@@ -1155,7 +1177,7 @@ static void OBJECT_cache_init(void *vedata)
DRWShadingGroup *grp = DRW_shgroup_create(sh_data->outline_resolve_aa, psl->outlines_resolve);
DRW_shgroup_uniform_texture_ref(grp, "outlineBluredColor", outline_tx);
DRW_shgroup_uniform_vec2(grp, "rcpDimensions", e_data.inv_viewport_size, 1);
- DRW_shgroup_call_add(grp, quad, NULL);
+ DRW_shgroup_call(grp, quad, NULL);
}
{
@@ -1172,28 +1194,27 @@ static void OBJECT_cache_init(void *vedata)
DRWShadingGroup *grp = DRW_shgroup_create(sh_data->grid, psl->grid);
DRW_shgroup_uniform_int(grp, "gridFlag", &e_data.zneg_flag, 1);
DRW_shgroup_uniform_vec3(grp, "planeAxes", e_data.zplane_axes, 1);
- DRW_shgroup_uniform_vec3(grp, "cameraPos", e_data.camera_pos, 1);
DRW_shgroup_uniform_vec4(grp, "gridSettings", e_data.grid_settings, 1);
DRW_shgroup_uniform_float_copy(grp, "lineKernel", grid_line_size);
DRW_shgroup_uniform_float_copy(grp, "meshSize", e_data.grid_mesh_size);
DRW_shgroup_uniform_float(grp, "gridOneOverLogSubdiv", &e_data.grid_settings[4], 1);
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
- DRW_shgroup_call_add(grp, geom, mat);
+ DRW_shgroup_call(grp, geom, mat);
grp = DRW_shgroup_create(sh_data->grid, psl->grid);
DRW_shgroup_uniform_int(grp, "gridFlag", &e_data.grid_flag, 1);
DRW_shgroup_uniform_vec3(grp, "planeAxes", e_data.grid_axes, 1);
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
- DRW_shgroup_call_add(grp, geom, mat);
+ DRW_shgroup_call(grp, geom, mat);
grp = DRW_shgroup_create(sh_data->grid, psl->grid);
DRW_shgroup_uniform_int(grp, "gridFlag", &e_data.zpos_flag, 1);
DRW_shgroup_uniform_vec3(grp, "planeAxes", e_data.zplane_axes, 1);
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
- DRW_shgroup_call_add(grp, geom, mat);
+ DRW_shgroup_call(grp, geom, mat);
}
for (int i = 0; i < 2; ++i) {
@@ -1236,113 +1257,111 @@ static void OBJECT_cache_init(void *vedata)
/* Empties */
geom = DRW_cache_plain_axes_get();
- sgl->plain_axes = shgroup_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
+ sgl->plain_axes = buffer_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
geom = DRW_cache_empty_cube_get();
- sgl->cube = shgroup_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
+ sgl->cube = buffer_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
geom = DRW_cache_circle_get();
- sgl->circle = shgroup_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
+ sgl->circle = buffer_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
geom = DRW_cache_empty_sphere_get();
- sgl->sphere = shgroup_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
+ sgl->sphere = buffer_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
geom = DRW_cache_sphere_get();
- sgl->sphere_solid = shgroup_instance_solid(sgl->non_meshes, geom);
+ sgl->sphere_solid = buffer_instance_solid(sgl->non_meshes, geom);
geom = DRW_cache_empty_cylinder_get();
- sgl->cylinder = shgroup_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
+ sgl->cylinder = buffer_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
geom = DRW_cache_empty_capsule_cap_get();
- sgl->capsule_cap = shgroup_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
+ sgl->capsule_cap = buffer_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
geom = DRW_cache_empty_capsule_body_get();
- sgl->capsule_body = shgroup_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
+ sgl->capsule_body = buffer_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
geom = DRW_cache_empty_cone_get();
- sgl->cone = shgroup_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
+ sgl->cone = buffer_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
geom = DRW_cache_single_arrow_get();
- sgl->single_arrow = shgroup_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
+ sgl->single_arrow = buffer_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
geom = DRW_cache_single_line_get();
- sgl->single_arrow_line = shgroup_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
+ sgl->single_arrow_line = buffer_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
geom = DRW_cache_bone_arrows_get();
- sgl->empty_axes = shgroup_instance_empty_axes(sgl->non_meshes, geom, draw_ctx->sh_cfg);
+ sgl->empty_axes = buffer_instance_empty_axes(sgl->non_meshes, geom, draw_ctx->sh_cfg);
/* Force Field */
geom = DRW_cache_field_wind_get();
- sgl->field_wind = shgroup_instance_scaled(sgl->non_meshes, geom, draw_ctx->sh_cfg);
+ sgl->field_wind = buffer_instance_scaled(sgl->non_meshes, geom, draw_ctx->sh_cfg);
geom = DRW_cache_field_force_get();
- sgl->field_force = shgroup_instance_screen_aligned(sgl->non_meshes, geom, draw_ctx->sh_cfg);
+ sgl->field_force = buffer_instance_screen_aligned(sgl->non_meshes, geom, draw_ctx->sh_cfg);
geom = DRW_cache_field_vortex_get();
- sgl->field_vortex = shgroup_instance_scaled(sgl->non_meshes, geom, draw_ctx->sh_cfg);
+ sgl->field_vortex = buffer_instance_scaled(sgl->non_meshes, geom, draw_ctx->sh_cfg);
geom = DRW_cache_screenspace_circle_get();
- sgl->field_curve_sta = shgroup_instance_screen_aligned(
- sgl->non_meshes, geom, draw_ctx->sh_cfg);
+ sgl->field_curve_sta = buffer_instance_screen_aligned(sgl->non_meshes, geom, draw_ctx->sh_cfg);
/* Grease Pencil */
geom = DRW_cache_gpencil_axes_get();
- sgl->gpencil_axes = shgroup_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
+ sgl->gpencil_axes = buffer_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
/* Speaker */
geom = DRW_cache_speaker_get();
- sgl->speaker = shgroup_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
+ sgl->speaker = buffer_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
/* Probe */
static float probeSize = 14.0f;
geom = DRW_cache_lightprobe_cube_get();
- sgl->probe_cube = shgroup_instance_screenspace(
+ sgl->probe_cube = buffer_instance_screenspace(
sgl->non_meshes, geom, &probeSize, draw_ctx->sh_cfg);
geom = DRW_cache_lightprobe_grid_get();
- sgl->probe_grid = shgroup_instance_screenspace(
+ sgl->probe_grid = buffer_instance_screenspace(
sgl->non_meshes, geom, &probeSize, draw_ctx->sh_cfg);
static float probePlanarSize = 20.0f;
geom = DRW_cache_lightprobe_planar_get();
- sgl->probe_planar = shgroup_instance_screenspace(
+ sgl->probe_planar = buffer_instance_screenspace(
sgl->non_meshes, geom, &probePlanarSize, draw_ctx->sh_cfg);
/* Camera */
geom = DRW_cache_camera_get();
- sgl->camera = shgroup_camera_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
+ sgl->camera = buffer_camera_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
geom = DRW_cache_camera_frame_get();
- sgl->camera_frame = shgroup_camera_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
+ sgl->camera_frame = buffer_camera_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
geom = DRW_cache_camera_tria_get();
- sgl->camera_tria = shgroup_camera_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
+ sgl->camera_tria = buffer_camera_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
geom = DRW_cache_plain_axes_get();
- sgl->camera_focus = shgroup_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
+ sgl->camera_focus = buffer_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
geom = DRW_cache_single_line_get();
- sgl->camera_clip = shgroup_distance_lines_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
- sgl->camera_mist = shgroup_distance_lines_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
+ sgl->camera_clip = buffer_distance_lines_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
+ sgl->camera_mist = buffer_distance_lines_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
geom = DRW_cache_single_line_endpoints_get();
- sgl->camera_clip_points = shgroup_distance_lines_instance(
+ sgl->camera_clip_points = buffer_distance_lines_instance(
sgl->non_meshes, geom, draw_ctx->sh_cfg);
- sgl->camera_mist_points = shgroup_distance_lines_instance(
+ sgl->camera_mist_points = buffer_distance_lines_instance(
sgl->non_meshes, geom, draw_ctx->sh_cfg);
geom = DRW_cache_quad_wires_get();
- sgl->camera_stereo_plane_wires = shgroup_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
- DRW_shgroup_state_enable(sgl->camera_stereo_plane_wires, DRW_STATE_WIRE);
+ sgl->camera_stereo_plane_wires = buffer_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
geom = DRW_cache_empty_cube_get();
- sgl->camera_stereo_volume_wires = shgroup_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
+ sgl->camera_stereo_volume_wires = buffer_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
BLI_listbase_clear(&sgl->camera_path);
/* Texture Space */
geom = DRW_cache_empty_cube_get();
- sgl->texspace = shgroup_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
+ sgl->texspace = buffer_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
/* Wires (for loose edges) */
sh = GPU_shader_get_builtin_shader_with_config(GPU_SHADER_3D_UNIFORM_COLOR, draw_ctx->sh_cfg);
@@ -1374,123 +1393,138 @@ static void OBJECT_cache_init(void *vedata)
DRW_shgroup_state_disable(sgl->points_dupli_select, DRW_STATE_BLEND);
/* Metaballs Handles */
- sgl->mball_handle = shgroup_instance_mball_handles(sgl->non_meshes, draw_ctx->sh_cfg);
+ sgl->mball_handle = buffer_instance_mball_handles(sgl->non_meshes, draw_ctx->sh_cfg);
/* Lights */
/* TODO
* for now we create multiple times the same VBO with only light center coordinates
* but ideally we would only create it once */
- /* start with buflimit because we don't want stipples */
- geom = DRW_cache_single_line_get();
- sgl->light_buflimit = shgroup_distance_lines_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
+ sh = GPU_shader_get_builtin_shader_with_config(
+ GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA, draw_ctx->sh_cfg);
+
+ DRWShadingGroup *grp = DRW_shgroup_create(sh, sgl->non_meshes);
+ DRW_shgroup_uniform_vec4(grp, "color", gb->colorLightNoAlpha, 1);
+ DRW_shgroup_uniform_float(grp, "size", &gb->sizeLightCenter, 1);
+ DRW_shgroup_state_enable(grp, DRW_STATE_POINT);
+ if (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) {
+ DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d);
+ }
+
+ sgl->light_center = buffer_dynpoints_uniform_color(grp);
- sgl->light_center = shgroup_dynpoints_uniform_color(
- sgl->non_meshes, gb->colorLightNoAlpha, &gb->sizeLightCenter, draw_ctx->sh_cfg);
+ geom = DRW_cache_single_line_get();
+ sgl->light_buflimit = buffer_distance_lines_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
geom = DRW_cache_light_get();
- sgl->light_circle = shgroup_instance_screenspace(
+ sgl->light_circle = buffer_instance_screenspace(
sgl->non_meshes, geom, &gb->sizeLightCircle, draw_ctx->sh_cfg);
geom = DRW_cache_light_shadows_get();
- sgl->light_circle_shadow = shgroup_instance_screenspace(
+ sgl->light_circle_shadow = buffer_instance_screenspace(
sgl->non_meshes, geom, &gb->sizeLightCircleShadow, draw_ctx->sh_cfg);
geom = DRW_cache_light_sunrays_get();
- sgl->light_sunrays = shgroup_instance_screenspace(
+ sgl->light_sunrays = buffer_instance_screenspace(
sgl->non_meshes, geom, &gb->sizeLightCircle, draw_ctx->sh_cfg);
- sgl->light_groundline = shgroup_groundlines_uniform_color(
+ sgl->light_groundline = buffer_groundlines_uniform_color(
sgl->non_meshes, gb->colorLight, draw_ctx->sh_cfg);
- sgl->light_groundpoint = shgroup_groundpoints_uniform_color(
+ sgl->light_groundpoint = buffer_groundpoints_uniform_color(
sgl->non_meshes, gb->colorLight, draw_ctx->sh_cfg);
geom = DRW_cache_screenspace_circle_get();
- sgl->light_area_sphere = shgroup_instance_screen_aligned(
+ sgl->light_area_sphere = buffer_instance_screen_aligned(
sgl->non_meshes, geom, draw_ctx->sh_cfg);
geom = DRW_cache_light_area_square_get();
- sgl->light_area_square = shgroup_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
+ sgl->light_area_square = buffer_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
geom = DRW_cache_light_area_disk_get();
- sgl->light_area_disk = shgroup_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
+ sgl->light_area_disk = buffer_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
geom = DRW_cache_light_hemi_get();
- sgl->light_hemi = shgroup_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
+ sgl->light_hemi = buffer_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
geom = DRW_cache_single_line_get();
- sgl->light_distance = shgroup_distance_lines_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
+ sgl->light_distance = buffer_distance_lines_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
geom = DRW_cache_single_line_endpoints_get();
- sgl->light_buflimit_points = shgroup_distance_lines_instance(
+ sgl->light_buflimit_points = buffer_distance_lines_instance(
sgl->non_meshes, geom, draw_ctx->sh_cfg);
geom = DRW_cache_light_spot_get();
- sgl->light_spot_cone = shgroup_spot_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
+ sgl->light_spot_cone = buffer_spot_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
geom = DRW_cache_circle_get();
- sgl->light_spot_blend = shgroup_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
+ sgl->light_spot_blend = buffer_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
geom = DRW_cache_light_spot_square_get();
- sgl->light_spot_pyramid = shgroup_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
+ sgl->light_spot_pyramid = buffer_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
geom = DRW_cache_square_get();
- sgl->light_spot_blend_rect = shgroup_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
+ sgl->light_spot_blend_rect = buffer_instance(sgl->non_meshes, geom, draw_ctx->sh_cfg);
/* -------- STIPPLES ------- */
/* Relationship Lines */
- sgl->relationship_lines = shgroup_dynlines_dashed_uniform_color(
+ sgl->relationship_lines = buffer_dynlines_dashed_uniform_color(
sgl->non_meshes, gb->colorWire, draw_ctx->sh_cfg);
- sgl->constraint_lines = shgroup_dynlines_dashed_uniform_color(
+ sgl->constraint_lines = buffer_dynlines_dashed_uniform_color(
sgl->non_meshes, gb->colorGridAxisZ, draw_ctx->sh_cfg);
/* Force Field Curve Guide End (here because of stipple) */
/* TODO port to shader stipple */
geom = DRW_cache_screenspace_circle_get();
- sgl->field_curve_end = shgroup_instance_screen_aligned(
- sgl->non_meshes, geom, draw_ctx->sh_cfg);
+ sgl->field_curve_end = buffer_instance_screen_aligned(sgl->non_meshes, geom, draw_ctx->sh_cfg);
/* Force Field Limits */
/* TODO port to shader stipple */
geom = DRW_cache_field_tube_limit_get();
- sgl->field_tube_limit = shgroup_instance_scaled(sgl->non_meshes, geom, draw_ctx->sh_cfg);
+ sgl->field_tube_limit = buffer_instance_scaled(sgl->non_meshes, geom, draw_ctx->sh_cfg);
/* TODO port to shader stipple */
geom = DRW_cache_field_cone_limit_get();
- sgl->field_cone_limit = shgroup_instance_scaled(sgl->non_meshes, geom, draw_ctx->sh_cfg);
+ sgl->field_cone_limit = buffer_instance_scaled(sgl->non_meshes, geom, draw_ctx->sh_cfg);
/* Transparent Shapes */
state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND |
DRW_STATE_CULL_FRONT;
sgl->transp_shapes = psl->transp_shapes[i] = DRW_pass_create("Transparent Shapes", state);
+ sh = GPU_shader_get_builtin_shader_with_config(
+ GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE, draw_ctx->sh_cfg);
+
+ DRWShadingGroup *grp_transp = DRW_shgroup_create(sh, sgl->transp_shapes);
+ if (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) {
+ DRW_shgroup_world_clip_planes_from_rv3d(grp_transp, DRW_context_state_get()->rv3d);
+ }
+
+ DRWShadingGroup *grp_cull_back = DRW_shgroup_create_sub(grp_transp);
+ DRW_shgroup_state_disable(grp_cull_back, DRW_STATE_CULL_FRONT);
+ DRW_shgroup_state_enable(grp_cull_back, DRW_STATE_CULL_BACK);
+
+ DRWShadingGroup *grp_cull_none = DRW_shgroup_create_sub(grp_transp);
+ DRW_shgroup_state_disable(grp_cull_none, DRW_STATE_CULL_FRONT);
+
/* Spot cones */
geom = DRW_cache_light_spot_volume_get();
- sgl->light_spot_volume = shgroup_instance_alpha(sgl->transp_shapes, geom, draw_ctx->sh_cfg);
+ sgl->light_spot_volume = buffer_instance_alpha(grp_transp, geom);
geom = DRW_cache_light_spot_square_volume_get();
- sgl->light_spot_volume_rect = shgroup_instance_alpha(
- sgl->transp_shapes, geom, draw_ctx->sh_cfg);
+ sgl->light_spot_volume_rect = buffer_instance_alpha(grp_transp, geom);
geom = DRW_cache_light_spot_volume_get();
- sgl->light_spot_volume_outside = shgroup_instance_alpha(
- sgl->transp_shapes, geom, draw_ctx->sh_cfg);
- DRW_shgroup_state_disable(sgl->light_spot_volume_outside, DRW_STATE_CULL_FRONT);
- DRW_shgroup_state_enable(sgl->light_spot_volume_outside, DRW_STATE_CULL_BACK);
+ sgl->light_spot_volume_outside = buffer_instance_alpha(grp_cull_back, geom);
geom = DRW_cache_light_spot_square_volume_get();
- sgl->light_spot_volume_rect_outside = shgroup_instance_alpha(
- sgl->transp_shapes, geom, draw_ctx->sh_cfg);
- DRW_shgroup_state_disable(sgl->light_spot_volume_rect_outside, DRW_STATE_CULL_FRONT);
- DRW_shgroup_state_enable(sgl->light_spot_volume_rect_outside, DRW_STATE_CULL_BACK);
+ sgl->light_spot_volume_rect_outside = buffer_instance_alpha(grp_cull_back, geom);
/* Camera stereo volumes */
geom = DRW_cache_cube_get();
- sgl->camera_stereo_volume = shgroup_instance_alpha(sgl->transp_shapes, geom, draw_ctx->sh_cfg);
+ sgl->camera_stereo_volume = buffer_instance_alpha(grp_transp, geom);
geom = DRW_cache_quad_get();
- sgl->camera_stereo_plane = shgroup_instance_alpha(sgl->transp_shapes, geom, draw_ctx->sh_cfg);
- DRW_shgroup_state_disable(sgl->camera_stereo_plane, DRW_STATE_CULL_FRONT);
+ sgl->camera_stereo_plane = buffer_instance_alpha(grp_cull_none, geom);
}
{
@@ -1508,7 +1542,7 @@ static void OBJECT_cache_init(void *vedata)
GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA, draw_ctx->sh_cfg);
/* Active */
- grp = DRW_shgroup_point_batch_create(sh, psl->ob_center);
+ grp = DRW_shgroup_create(sh, psl->ob_center);
DRW_shgroup_uniform_float(grp, "size", &size, 1);
DRW_shgroup_uniform_float(grp, "outlineWidth", &outlineWidth, 1);
DRW_shgroup_uniform_vec4(grp, "color", gb->colorActive, 1);
@@ -1516,39 +1550,28 @@ static void OBJECT_cache_init(void *vedata)
if (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) {
DRW_shgroup_world_clip_planes_from_rv3d(grp, draw_ctx->rv3d);
}
- stl->g_data->center_active = grp;
+ /* TODO find better name. */
+ stl->g_data->center_active = buffer_dynpoints_uniform_color(grp);
/* Select */
- grp = DRW_shgroup_point_batch_create(sh, psl->ob_center);
+ grp = DRW_shgroup_create_sub(grp);
DRW_shgroup_uniform_vec4(grp, "color", gb->colorSelect, 1);
- if (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) {
- DRW_shgroup_world_clip_planes_from_rv3d(grp, draw_ctx->rv3d);
- }
- stl->g_data->center_selected = grp;
+ stl->g_data->center_selected = buffer_dynpoints_uniform_color(grp);
/* Deselect */
- grp = DRW_shgroup_point_batch_create(sh, psl->ob_center);
+ grp = DRW_shgroup_create_sub(grp);
DRW_shgroup_uniform_vec4(grp, "color", gb->colorDeselect, 1);
- if (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) {
- DRW_shgroup_world_clip_planes_from_rv3d(grp, draw_ctx->rv3d);
- }
- stl->g_data->center_deselected = grp;
+ stl->g_data->center_deselected = buffer_dynpoints_uniform_color(grp);
/* Select (library) */
- grp = DRW_shgroup_point_batch_create(sh, psl->ob_center);
+ grp = DRW_shgroup_create_sub(grp);
DRW_shgroup_uniform_vec4(grp, "color", gb->colorLibrarySelect, 1);
- if (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) {
- DRW_shgroup_world_clip_planes_from_rv3d(grp, draw_ctx->rv3d);
- }
- stl->g_data->center_selected_lib = grp;
+ stl->g_data->center_selected_lib = buffer_dynpoints_uniform_color(grp);
/* Deselect (library) */
- grp = DRW_shgroup_point_batch_create(sh, psl->ob_center);
+ grp = DRW_shgroup_create_sub(grp);
DRW_shgroup_uniform_vec4(grp, "color", gb->colorLibrary, 1);
- if (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) {
- DRW_shgroup_world_clip_planes_from_rv3d(grp, draw_ctx->rv3d);
- }
- stl->g_data->center_deselected_lib = grp;
+ stl->g_data->center_deselected_lib = buffer_dynpoints_uniform_color(grp);
}
{
@@ -1593,7 +1616,7 @@ static void DRW_shgroup_mball_handles(OBJECT_ShadingGroupList *sgl,
draw_scale_xform[1][3] = world_pos[1];
draw_scale_xform[2][3] = world_pos[2];
- DRW_shgroup_call_dynamic_add(sgl->mball_handle, draw_scale_xform, &ml->rad, color);
+ DRW_buffer_add_entry(sgl->mball_handle, draw_scale_xform, &ml->rad, color);
}
}
@@ -1619,25 +1642,25 @@ static void DRW_shgroup_light(OBJECT_ShadingGroupList *sgl, Object *ob, ViewLaye
if ((ob->base_flag & (BASE_FROM_SET | BASE_FROM_DUPLI)) == 0) {
/* Don't draw the center if it's selected or active */
if (theme_id == TH_LIGHT) {
- DRW_shgroup_call_dynamic_add(sgl->light_center, ob->obmat[3]);
+ DRW_buffer_add_entry(sgl->light_center, ob->obmat[3]);
}
}
/* First circle */
- DRW_shgroup_call_dynamic_add(sgl->light_circle, ob->obmat[3], color);
+ DRW_buffer_add_entry(sgl->light_circle, ob->obmat[3], color);
/* draw dashed outer circle for shadow */
- DRW_shgroup_call_dynamic_add(sgl->light_circle_shadow, ob->obmat[3], color);
+ DRW_buffer_add_entry(sgl->light_circle_shadow, ob->obmat[3], color);
/* Distance */
if (ELEM(la->type, LA_SUN, LA_AREA)) {
- DRW_shgroup_call_dynamic_add(sgl->light_distance, color, &zero, &la->dist, ob->obmat);
+ DRW_buffer_add_entry(sgl->light_distance, color, &zero, &la->dist, ob->obmat);
}
copy_m4_m4(shapemat, ob->obmat);
if (la->type == LA_SUN) {
- DRW_shgroup_call_dynamic_add(sgl->light_sunrays, ob->obmat[3], color);
+ DRW_buffer_add_entry(sgl->light_sunrays, ob->obmat[3], color);
}
else if (la->type == LA_SPOT) {
float size[3], sizemat[4][4];
@@ -1659,42 +1682,39 @@ static void DRW_shgroup_light(OBJECT_ShadingGroupList *sgl, Object *ob, ViewLaye
mul_m4_m4m4(spotblendmat, shapemat, sizemat);
if (la->mode & LA_SQUARE) {
- DRW_shgroup_call_dynamic_add(sgl->light_spot_pyramid, color, &one, shapemat);
+ DRW_buffer_add_entry(sgl->light_spot_pyramid, color, &one, shapemat);
/* hide line if it is zero size or overlaps with outer border,
* previously it adjusted to always to show it but that seems
* confusing because it doesn't show the actual blend size */
if (blend != 0.0f && blend != 1.0f) {
- DRW_shgroup_call_dynamic_add(sgl->light_spot_blend_rect, color, &one, spotblendmat);
+ DRW_buffer_add_entry(sgl->light_spot_blend_rect, color, &one, spotblendmat);
}
if (la->mode & LA_SHOW_CONE) {
- DRW_shgroup_call_dynamic_add(sgl->light_spot_volume_rect, cone_inside, &one, shapemat);
- DRW_shgroup_call_dynamic_add(
- sgl->light_spot_volume_rect_outside, cone_outside, &one, shapemat);
+ DRW_buffer_add_entry(sgl->light_spot_volume_rect, cone_inside, &one, shapemat);
+ DRW_buffer_add_entry(sgl->light_spot_volume_rect_outside, cone_outside, &one, shapemat);
}
}
else {
- DRW_shgroup_call_dynamic_add(sgl->light_spot_cone, color, shapemat);
+ DRW_buffer_add_entry(sgl->light_spot_cone, color, shapemat);
/* hide line if it is zero size or overlaps with outer border,
* previously it adjusted to always to show it but that seems
* confusing because it doesn't show the actual blend size */
if (blend != 0.0f && blend != 1.0f) {
- DRW_shgroup_call_dynamic_add(sgl->light_spot_blend, color, &one, spotblendmat);
+ DRW_buffer_add_entry(sgl->light_spot_blend, color, &one, spotblendmat);
}
if (la->mode & LA_SHOW_CONE) {
- DRW_shgroup_call_dynamic_add(sgl->light_spot_volume, cone_inside, &one, shapemat);
- DRW_shgroup_call_dynamic_add(sgl->light_spot_volume_outside, cone_outside, &one, shapemat);
+ DRW_buffer_add_entry(sgl->light_spot_volume, cone_inside, &one, shapemat);
+ DRW_buffer_add_entry(sgl->light_spot_volume_outside, cone_outside, &one, shapemat);
}
}
- DRW_shgroup_call_dynamic_add(
- sgl->light_buflimit, color, &la->clipsta, &la->clipend, ob->obmat);
- DRW_shgroup_call_dynamic_add(
- sgl->light_buflimit_points, color, &la->clipsta, &la->clipend, ob->obmat);
+ DRW_buffer_add_entry(sgl->light_buflimit, color, &la->clipsta, &la->clipend, ob->obmat);
+ DRW_buffer_add_entry(sgl->light_buflimit_points, color, &la->clipsta, &la->clipend, ob->obmat);
}
else if (la->type == LA_AREA) {
float size[3] = {1.0f, 1.0f, 1.0f}, sizemat[4][4];
@@ -1706,10 +1726,10 @@ static void DRW_shgroup_light(OBJECT_ShadingGroupList *sgl, Object *ob, ViewLaye
}
if (ELEM(la->area_shape, LA_AREA_DISK, LA_AREA_ELLIPSE)) {
- DRW_shgroup_call_dynamic_add(sgl->light_area_disk, color, &la->area_size, shapemat);
+ DRW_buffer_add_entry(sgl->light_area_disk, color, &la->area_size, shapemat);
}
else {
- DRW_shgroup_call_dynamic_add(sgl->light_area_square, color, &la->area_size, shapemat);
+ DRW_buffer_add_entry(sgl->light_area_square, color, &la->area_size, shapemat);
}
}
@@ -1719,12 +1739,12 @@ static void DRW_shgroup_light(OBJECT_ShadingGroupList *sgl, Object *ob, ViewLaye
shapemat[0][1] = shapemat[0][2] = 0.0f;
shapemat[1][0] = shapemat[1][2] = 0.0f;
shapemat[2][0] = shapemat[2][1] = 0.0f;
- DRW_shgroup_call_dynamic_add(sgl->light_area_sphere, color, &la->area_size, shapemat);
+ DRW_buffer_add_entry(sgl->light_area_sphere, color, &la->area_size, shapemat);
}
/* Line and point going to the ground */
- DRW_shgroup_call_dynamic_add(sgl->light_groundline, ob->obmat[3]);
- DRW_shgroup_call_dynamic_add(sgl->light_groundpoint, ob->obmat[3]);
+ DRW_buffer_add_entry(sgl->light_groundline, ob->obmat[3]);
+ DRW_buffer_add_entry(sgl->light_groundpoint, ob->obmat[3]);
}
static GPUBatch *batch_camera_path_get(ListBase *camera_paths,
@@ -1820,19 +1840,19 @@ static void camera_view3d_stereoscopy_display_extra(OBJECT_ShadingGroupList *sgl
copy_v2_v2(drw_tria_dummy[eye][1], cam->runtime.drw_corners[eye][0]);
if (is_stereo3d_cameras) {
- DRW_shgroup_call_dynamic_add(sgl->camera_frame,
- color,
- cam->runtime.drw_corners[eye],
- &cam->runtime.drw_depth[eye],
- cam->runtime.drw_tria,
- obmat);
+ DRW_buffer_add_entry(sgl->camera_frame,
+ color,
+ cam->runtime.drw_corners[eye],
+ &cam->runtime.drw_depth[eye],
+ cam->runtime.drw_tria,
+ obmat);
- DRW_shgroup_call_dynamic_add(sgl->camera,
- color,
- cam->runtime.drw_corners[eye],
- &cam->runtime.drw_depth[eye],
- drw_tria_dummy[eye],
- obmat);
+ DRW_buffer_add_entry(sgl->camera,
+ color,
+ cam->runtime.drw_corners[eye],
+ &cam->runtime.drw_depth[eye],
+ drw_tria_dummy[eye],
+ obmat);
}
/* Connecting line. */
@@ -1841,8 +1861,8 @@ static void camera_view3d_stereoscopy_display_extra(OBJECT_ShadingGroupList *sgl
/* Draw connecting lines. */
if (is_stereo3d_cameras) {
- DRW_shgroup_call_dynamic_add(sgl->relationship_lines, origin[0]);
- DRW_shgroup_call_dynamic_add(sgl->relationship_lines, origin[1]);
+ DRW_buffer_add_entry(sgl->relationship_lines, origin[0]);
+ DRW_buffer_add_entry(sgl->relationship_lines, origin[1]);
}
/* Draw convergence plane. */
@@ -1879,9 +1899,9 @@ static void camera_view3d_stereoscopy_display_extra(OBJECT_ShadingGroupList *sgl
translate_m4(plane_mat, 2.0f * cam->shiftx, (width / height) * 2.0f * cam->shifty, 0.0f);
if (v3d->stereo3d_convergence_alpha > 0.0f) {
- DRW_shgroup_call_dynamic_add(sgl->camera_stereo_plane, color_plane[0], &one, plane_mat);
+ DRW_buffer_add_entry(sgl->camera_stereo_plane, color_plane[0], &one, plane_mat);
}
- DRW_shgroup_call_dynamic_add(sgl->camera_stereo_plane_wires, color_plane[1], &one, plane_mat);
+ DRW_buffer_add_entry(sgl->camera_stereo_plane_wires, color_plane[1], &one, plane_mat);
}
/* Draw convergence volume. */
@@ -1905,10 +1925,9 @@ static void camera_view3d_stereoscopy_display_extra(OBJECT_ShadingGroupList *sgl
invert_m4_m4(persinv, persmat);
if (v3d->stereo3d_volume_alpha > 0.0f) {
- DRW_shgroup_call_dynamic_add(sgl->camera_stereo_volume, color_volume[eye], &one, persinv);
+ DRW_buffer_add_entry(sgl->camera_stereo_volume, color_volume[eye], &one, persinv);
}
- DRW_shgroup_call_dynamic_add(
- sgl->camera_stereo_volume_wires, color_volume[2], &one, persinv);
+ DRW_buffer_add_entry(sgl->camera_stereo_volume_wires, color_volume[2], &one, persinv);
}
}
}
@@ -1916,13 +1935,14 @@ static void camera_view3d_stereoscopy_display_extra(OBJECT_ShadingGroupList *sgl
static void camera_view3d_reconstruction(OBJECT_ShadingGroupList *sgl,
Scene *scene,
View3D *v3d,
- const Object *camera_object,
+ Object *camera_object,
Object *ob,
const float color[4],
const bool is_select)
{
const DRWContextState *draw_ctx = DRW_context_state_get();
Camera *cam = ob->data;
+ const Object *orig_camera_object = DEG_get_original_object(camera_object);
if ((v3d->flag2 & V3D_SHOW_RECONSTRUCTION) == 0) {
return;
@@ -2003,7 +2023,7 @@ static void camera_view3d_reconstruction(OBJECT_ShadingGroupList *sgl,
}
if (is_select) {
- DRW_select_load_id(camera_object->select_id | (track_index << 16));
+ DRW_select_load_id(orig_camera_object->runtime.select_id | (track_index << 16));
track_index++;
}
@@ -2021,7 +2041,7 @@ static void camera_view3d_reconstruction(OBJECT_ShadingGroupList *sgl,
};
mul_m4_m4m4(bundle_mat, bundle_mat, bundle_scale_mat);
- DRW_shgroup_call_dynamic_add(sgl->sphere_solid, bundle_mat, bundle_color_v4);
+ DRW_buffer_add_entry(sgl->sphere_solid, bundle_mat, bundle_color_v4);
}
else {
DRW_shgroup_empty_ex(
@@ -2055,7 +2075,7 @@ static void camera_view3d_reconstruction(OBJECT_ShadingGroupList *sgl,
GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
DRWShadingGroup *shading_group = DRW_shgroup_create(shader, sgl->non_meshes);
DRW_shgroup_uniform_vec4(shading_group, "color", camera_path_color, 1);
- DRW_shgroup_call_add(shading_group, geom, camera_mat);
+ DRW_shgroup_call(shading_group, geom, camera_mat);
}
}
}
@@ -2069,7 +2089,7 @@ static void DRW_shgroup_camera(OBJECT_ShadingGroupList *sgl, Object *ob, ViewLay
RegionView3D *rv3d = draw_ctx->rv3d;
Camera *cam = ob->data;
- const Object *camera_object = DEG_get_evaluated_object(draw_ctx->depsgraph, v3d->camera);
+ Object *camera_object = DEG_get_evaluated_object(draw_ctx->depsgraph, v3d->camera);
const bool is_select = DRW_state_is_select();
const bool is_active = (ob == camera_object);
const bool look_through = (is_active && (rv3d->persp == RV3D_CAMOB));
@@ -2136,31 +2156,31 @@ static void DRW_shgroup_camera(OBJECT_ShadingGroupList *sgl, Object *ob, ViewLay
copy_m4_m4(mat, ob->obmat);
}
- DRW_shgroup_call_dynamic_add(sgl->camera_frame,
- color,
- cam->runtime.drw_corners[0],
- &cam->runtime.drw_depth[0],
- cam->runtime.drw_tria,
- mat);
+ DRW_buffer_add_entry(sgl->camera_frame,
+ color,
+ cam->runtime.drw_corners[0],
+ &cam->runtime.drw_depth[0],
+ cam->runtime.drw_tria,
+ mat);
}
else {
if (!is_stereo3d_cameras) {
- DRW_shgroup_call_dynamic_add(sgl->camera,
- color,
- cam->runtime.drw_corners[0],
- &cam->runtime.drw_depth[0],
- cam->runtime.drw_tria,
- ob->obmat);
+ DRW_buffer_add_entry(sgl->camera,
+ color,
+ cam->runtime.drw_corners[0],
+ &cam->runtime.drw_depth[0],
+ cam->runtime.drw_tria,
+ ob->obmat);
}
/* Active cam */
if (is_active) {
- DRW_shgroup_call_dynamic_add(sgl->camera_tria,
- color,
- cam->runtime.drw_corners[0],
- &cam->runtime.drw_depth[0],
- cam->runtime.drw_tria,
- ob->obmat);
+ DRW_buffer_add_entry(sgl->camera_tria,
+ color,
+ cam->runtime.drw_corners[0],
+ &cam->runtime.drw_depth[0],
+ cam->runtime.drw_tria,
+ ob->obmat);
}
}
@@ -2177,16 +2197,16 @@ static void DRW_shgroup_camera(OBJECT_ShadingGroupList *sgl, Object *ob, ViewLay
size_to_mat4(sizemat, size);
mul_m4_m4m4(cam->runtime.drw_focusmat, cam->runtime.drw_focusmat, sizemat);
- DRW_shgroup_call_dynamic_add(
+ DRW_buffer_add_entry(
sgl->camera_focus, (is_active ? col_hi : col), &cam->drawsize, cam->runtime.drw_focusmat);
- DRW_shgroup_call_dynamic_add(
+ DRW_buffer_add_entry(
sgl->camera_clip, color, &cam->clip_start, &cam->clip_end, cam->runtime.drw_normalmat);
- DRW_shgroup_call_dynamic_add(sgl->camera_clip_points,
- (is_active ? col_hi : col),
- &cam->clip_start,
- &cam->clip_end,
- cam->runtime.drw_normalmat);
+ DRW_buffer_add_entry(sgl->camera_clip_points,
+ (is_active ? col_hi : col),
+ &cam->clip_start,
+ &cam->clip_end,
+ cam->runtime.drw_normalmat);
}
if (cam->flag & CAM_SHOWMIST) {
@@ -2195,13 +2215,13 @@ static void DRW_shgroup_camera(OBJECT_ShadingGroupList *sgl, Object *ob, ViewLay
if (world) {
static float col[4] = {0.5f, 0.5f, 0.5f, 1.0f}, col_hi[4] = {1.0f, 1.0f, 1.0f, 1.0f};
world->mistend = world->miststa + world->mistdist;
- DRW_shgroup_call_dynamic_add(
+ DRW_buffer_add_entry(
sgl->camera_mist, color, &world->miststa, &world->mistend, cam->runtime.drw_normalmat);
- DRW_shgroup_call_dynamic_add(sgl->camera_mist_points,
- (is_active ? col_hi : col),
- &world->miststa,
- &world->mistend,
- cam->runtime.drw_normalmat);
+ DRW_buffer_add_entry(sgl->camera_mist_points,
+ (is_active ? col_hi : col),
+ &world->miststa,
+ &world->mistend,
+ cam->runtime.drw_normalmat);
}
}
@@ -2223,26 +2243,26 @@ static void DRW_shgroup_empty_ex(OBJECT_ShadingGroupList *sgl,
{
switch (draw_type) {
case OB_PLAINAXES:
- DRW_shgroup_call_dynamic_add(sgl->plain_axes, color, draw_size, mat);
+ DRW_buffer_add_entry(sgl->plain_axes, color, draw_size, mat);
break;
case OB_SINGLE_ARROW:
- DRW_shgroup_call_dynamic_add(sgl->single_arrow, color, draw_size, mat);
- DRW_shgroup_call_dynamic_add(sgl->single_arrow_line, color, draw_size, mat);
+ DRW_buffer_add_entry(sgl->single_arrow, color, draw_size, mat);
+ DRW_buffer_add_entry(sgl->single_arrow_line, color, draw_size, mat);
break;
case OB_CUBE:
- DRW_shgroup_call_dynamic_add(sgl->cube, color, draw_size, mat);
+ DRW_buffer_add_entry(sgl->cube, color, draw_size, mat);
break;
case OB_CIRCLE:
- DRW_shgroup_call_dynamic_add(sgl->circle, color, draw_size, mat);
+ DRW_buffer_add_entry(sgl->circle, color, draw_size, mat);
break;
case OB_EMPTY_SPHERE:
- DRW_shgroup_call_dynamic_add(sgl->sphere, color, draw_size, mat);
+ DRW_buffer_add_entry(sgl->sphere, color, draw_size, mat);
break;
case OB_EMPTY_CONE:
- DRW_shgroup_call_dynamic_add(sgl->cone, color, draw_size, mat);
+ DRW_buffer_add_entry(sgl->cone, color, draw_size, mat);
break;
case OB_ARROWS:
- DRW_shgroup_call_dynamic_add(sgl->empty_axes, color, draw_size, mat);
+ DRW_buffer_add_entry(sgl->empty_axes, color, draw_size, mat);
break;
case OB_EMPTY_IMAGE:
BLI_assert(!"Should never happen, use DRW_shgroup_empty instead.");
@@ -2334,19 +2354,19 @@ static void DRW_shgroup_forcefield(OBJECT_ShadingGroupList *sgl, Object *ob, Vie
switch (pd->forcefield) {
case PFIELD_WIND:
- DRW_shgroup_call_dynamic_add(sgl->field_wind, color, &pd->drawvec1, ob->obmat);
+ DRW_buffer_add_entry(sgl->field_wind, color, &pd->drawvec1, ob->obmat);
break;
case PFIELD_FORCE:
- DRW_shgroup_call_dynamic_add(sgl->field_force, color, &pd->drawvec1, ob->obmat);
+ DRW_buffer_add_entry(sgl->field_force, color, &pd->drawvec1, ob->obmat);
break;
case PFIELD_VORTEX:
- DRW_shgroup_call_dynamic_add(sgl->field_vortex, color, &pd->drawvec1, ob->obmat);
+ DRW_buffer_add_entry(sgl->field_vortex, color, &pd->drawvec1, ob->obmat);
break;
case PFIELD_GUIDE:
if (cu && (cu->flag & CU_PATH) && ob->runtime.curve_cache->path &&
ob->runtime.curve_cache->path->data) {
- DRW_shgroup_call_dynamic_add(sgl->field_curve_sta, color, &pd->f_strength, ob->obmat);
- DRW_shgroup_call_dynamic_add(sgl->field_curve_end, color, &pd->f_strength, ob->obmat);
+ DRW_buffer_add_entry(sgl->field_curve_sta, color, &pd->f_strength, ob->obmat);
+ DRW_buffer_add_entry(sgl->field_curve_end, color, &pd->f_strength, ob->obmat);
}
break;
}
@@ -2354,33 +2374,29 @@ static void DRW_shgroup_forcefield(OBJECT_ShadingGroupList *sgl, Object *ob, Vie
if (pd->falloff == PFIELD_FALL_SPHERE) {
/* as last, guide curve alters it */
if ((pd->flag & PFIELD_USEMAX) != 0) {
- DRW_shgroup_call_dynamic_add(sgl->field_curve_end, color, &pd->maxdist, ob->obmat);
+ DRW_buffer_add_entry(sgl->field_curve_end, color, &pd->maxdist, ob->obmat);
}
if ((pd->flag & PFIELD_USEMIN) != 0) {
- DRW_shgroup_call_dynamic_add(sgl->field_curve_end, color, &pd->mindist, ob->obmat);
+ DRW_buffer_add_entry(sgl->field_curve_end, color, &pd->mindist, ob->obmat);
}
}
else if (pd->falloff == PFIELD_FALL_TUBE) {
if (pd->flag & (PFIELD_USEMAX | PFIELD_USEMAXR)) {
- DRW_shgroup_call_dynamic_add(
- sgl->field_tube_limit, color, &pd->drawvec_falloff_max, ob->obmat);
+ DRW_buffer_add_entry(sgl->field_tube_limit, color, &pd->drawvec_falloff_max, ob->obmat);
}
if (pd->flag & (PFIELD_USEMIN | PFIELD_USEMINR)) {
- DRW_shgroup_call_dynamic_add(
- sgl->field_tube_limit, color, &pd->drawvec_falloff_min, ob->obmat);
+ DRW_buffer_add_entry(sgl->field_tube_limit, color, &pd->drawvec_falloff_min, ob->obmat);
}
}
else if (pd->falloff == PFIELD_FALL_CONE) {
if (pd->flag & (PFIELD_USEMAX | PFIELD_USEMAXR)) {
- DRW_shgroup_call_dynamic_add(
- sgl->field_cone_limit, color, &pd->drawvec_falloff_max, ob->obmat);
+ DRW_buffer_add_entry(sgl->field_cone_limit, color, &pd->drawvec_falloff_max, ob->obmat);
}
if (pd->flag & (PFIELD_USEMIN | PFIELD_USEMINR)) {
- DRW_shgroup_call_dynamic_add(
- sgl->field_cone_limit, color, &pd->drawvec_falloff_min, ob->obmat);
+ DRW_buffer_add_entry(sgl->field_cone_limit, color, &pd->drawvec_falloff_min, ob->obmat);
}
}
}
@@ -2412,7 +2428,7 @@ static void DRW_shgroup_volume_extra(OBJECT_ShadingGroupList *sgl,
translate_m4(voxel_cubemat, 1.0f, 1.0f, 1.0f);
mul_m4_m4m4(voxel_cubemat, ob->obmat, voxel_cubemat);
- DRW_shgroup_call_dynamic_add(sgl->cube, color, &one, voxel_cubemat);
+ DRW_buffer_add_entry(sgl->cube, color, &one, voxel_cubemat);
/* Don't show smoke before simulation starts, this could be made an option in the future. */
if (!sds->draw_velocity || !sds->fluid || CFRA < sds->point_cache[0]->startframe) {
@@ -2446,7 +2462,7 @@ static void DRW_shgroup_volume_extra(OBJECT_ShadingGroupList *sgl,
DRW_shgroup_uniform_float_copy(grp, "displaySize", sds->vector_scale);
DRW_shgroup_uniform_float_copy(grp, "slicePosition", sds->slice_depth);
DRW_shgroup_uniform_int_copy(grp, "sliceAxis", slice_axis);
- DRW_shgroup_call_procedural_lines_add(grp, line_count, ob->obmat);
+ DRW_shgroup_call_procedural_lines(grp, line_count, ob->obmat);
BLI_addtail(&e_data.smoke_domains, BLI_genericNodeN(smd));
}
@@ -2472,7 +2488,7 @@ static void DRW_shgroup_speaker(OBJECT_ShadingGroupList *sgl, Object *ob, ViewLa
static float one = 1.0f;
DRW_object_wire_theme_get(ob, view_layer, &color);
- DRW_shgroup_call_dynamic_add(sgl->speaker, color, &one, ob->obmat);
+ DRW_buffer_add_entry(sgl->speaker, color, &one, ob->obmat);
}
typedef struct OBJECT_LightProbeEngineData {
@@ -2547,7 +2563,7 @@ static void DRW_shgroup_lightprobe(OBJECT_Shaders *sh_data,
DRW_shgroup_uniform_vec3(grp, "increment_y", prb_data->increment_y, 1);
DRW_shgroup_uniform_vec3(grp, "increment_z", prb_data->increment_z, 1);
DRW_shgroup_uniform_ivec3(grp, "grid_resolution", &prb->grid_resolution_x, 1);
- DRW_shgroup_call_procedural_points_add(grp, cell_count, NULL);
+ DRW_shgroup_call_procedural_points(grp, cell_count, NULL);
}
else if (prb->type == LIGHTPROBE_TYPE_CUBE) {
float draw_size = 1.0f;
@@ -2556,17 +2572,17 @@ static void DRW_shgroup_lightprobe(OBJECT_Shaders *sh_data,
// unit_m4(prb_data->probe_cube_mat);
// copy_v3_v3(prb_data->probe_cube_mat[3], ob->obmat[3]);
- DRWShadingGroup *grp = shgroup_theme_id_to_probe_cube_outline_shgrp(
+ DRWCallBuffer *buf = buffer_theme_id_to_probe_cube_outline_shgrp(
stl, theme_id, ob->base_flag);
/* TODO remove or change the drawing of the cube probes. Theses line draws nothing on purpose
* to keep the call ids correct. */
zero_m4(probe_cube_mat);
- DRW_shgroup_call_dynamic_add(grp, call_id, &draw_size, probe_cube_mat);
+ DRW_buffer_add_entry(buf, call_id, &draw_size, probe_cube_mat);
}
else {
float draw_size = 1.0f;
- DRWShadingGroup *grp = shgroup_theme_id_to_probe_planar_outline_shgrp(stl, theme_id);
- DRW_shgroup_call_dynamic_add(grp, call_id, &draw_size, ob->obmat);
+ DRWCallBuffer *buf = buffer_theme_id_to_probe_planar_outline_shgrp(stl, theme_id);
+ DRW_buffer_add_entry(buf, call_id, &draw_size, ob->obmat);
}
*call_id += 1;
@@ -2574,14 +2590,14 @@ static void DRW_shgroup_lightprobe(OBJECT_Shaders *sh_data,
switch (prb->type) {
case LIGHTPROBE_TYPE_PLANAR:
- DRW_shgroup_call_dynamic_add(sgl->probe_planar, ob->obmat[3], color);
+ DRW_buffer_add_entry(sgl->probe_planar, ob->obmat[3], color);
break;
case LIGHTPROBE_TYPE_GRID:
- DRW_shgroup_call_dynamic_add(sgl->probe_grid, ob->obmat[3], color);
+ DRW_buffer_add_entry(sgl->probe_grid, ob->obmat[3], color);
break;
case LIGHTPROBE_TYPE_CUBE:
default:
- DRW_shgroup_call_dynamic_add(sgl->probe_cube, ob->obmat[3], color);
+ DRW_buffer_add_entry(sgl->probe_cube, ob->obmat[3], color);
break;
}
@@ -2590,13 +2606,13 @@ static void DRW_shgroup_lightprobe(OBJECT_Shaders *sh_data,
copy_m4_m4(mat, ob->obmat);
normalize_m4(mat);
- DRW_shgroup_call_dynamic_add(sgl->single_arrow, color, &ob->empty_drawsize, mat);
- DRW_shgroup_call_dynamic_add(sgl->single_arrow_line, color, &ob->empty_drawsize, mat);
+ DRW_buffer_add_entry(sgl->single_arrow, color, &ob->empty_drawsize, mat);
+ DRW_buffer_add_entry(sgl->single_arrow_line, color, &ob->empty_drawsize, mat);
copy_m4_m4(mat, ob->obmat);
zero_v3(mat[2]);
- DRW_shgroup_call_dynamic_add(sgl->cube, color, &one, mat);
+ DRW_buffer_add_entry(sgl->cube, color, &one, mat);
}
if ((prb->flag & LIGHTPROBE_FLAG_SHOW_INFLUENCE) != 0) {
@@ -2610,8 +2626,8 @@ static void DRW_shgroup_lightprobe(OBJECT_Shaders *sh_data,
}
if (prb->type == LIGHTPROBE_TYPE_GRID || prb->attenuation_type == LIGHTPROBE_SHAPE_BOX) {
- DRW_shgroup_call_dynamic_add(sgl->cube, color, &prb->distgridinf, ob->obmat);
- DRW_shgroup_call_dynamic_add(sgl->cube, color, &prb->distfalloff, ob->obmat);
+ DRW_buffer_add_entry(sgl->cube, color, &prb->distgridinf, ob->obmat);
+ DRW_buffer_add_entry(sgl->cube, color, &prb->distfalloff, ob->obmat);
}
else if (prb->type == LIGHTPROBE_TYPE_PLANAR) {
float rangemat[4][4];
@@ -2619,17 +2635,17 @@ static void DRW_shgroup_lightprobe(OBJECT_Shaders *sh_data,
normalize_v3(rangemat[2]);
mul_v3_fl(rangemat[2], prb->distinf);
- DRW_shgroup_call_dynamic_add(sgl->cube, color, &one, rangemat);
+ DRW_buffer_add_entry(sgl->cube, color, &one, rangemat);
copy_m4_m4(rangemat, ob->obmat);
normalize_v3(rangemat[2]);
mul_v3_fl(rangemat[2], prb->distfalloff);
- DRW_shgroup_call_dynamic_add(sgl->cube, color, &one, rangemat);
+ DRW_buffer_add_entry(sgl->cube, color, &one, rangemat);
}
else {
- DRW_shgroup_call_dynamic_add(sgl->sphere, color, &prb->distgridinf, ob->obmat);
- DRW_shgroup_call_dynamic_add(sgl->sphere, color, &prb->distfalloff, ob->obmat);
+ DRW_buffer_add_entry(sgl->sphere, color, &prb->distgridinf, ob->obmat);
+ DRW_buffer_add_entry(sgl->sphere, color, &prb->distfalloff, ob->obmat);
}
}
@@ -2648,10 +2664,10 @@ static void DRW_shgroup_lightprobe(OBJECT_Shaders *sh_data,
}
if (prb->parallax_type == LIGHTPROBE_SHAPE_BOX) {
- DRW_shgroup_call_dynamic_add(sgl->cube, color, dist, obmat);
+ DRW_buffer_add_entry(sgl->cube, color, dist, obmat);
}
else {
- DRW_shgroup_call_dynamic_add(sgl->sphere, color, dist, obmat);
+ DRW_buffer_add_entry(sgl->sphere, color, dist, obmat);
}
}
}
@@ -2690,9 +2706,8 @@ static void DRW_shgroup_lightprobe(OBJECT_Shaders *sh_data,
normalize_m4_m4(clipmat, ob->obmat);
mul_m4_m4m4(clipmat, clipmat, cubefacemat[i]);
- DRW_shgroup_call_dynamic_add(
- sgl->light_buflimit, color, &prb->clipsta, &prb->clipend, clipmat);
- DRW_shgroup_call_dynamic_add(
+ DRW_buffer_add_entry(sgl->light_buflimit, color, &prb->clipsta, &prb->clipend, clipmat);
+ DRW_buffer_add_entry(
sgl->light_buflimit_points, color, &prb->clipsta, &prb->clipend, clipmat);
}
}
@@ -2700,8 +2715,8 @@ static void DRW_shgroup_lightprobe(OBJECT_Shaders *sh_data,
/* Line and point going to the ground */
if (prb->type == LIGHTPROBE_TYPE_CUBE) {
- DRW_shgroup_call_dynamic_add(sgl->light_groundline, ob->obmat[3]);
- DRW_shgroup_call_dynamic_add(sgl->light_groundpoint, ob->obmat[3]);
+ DRW_buffer_add_entry(sgl->light_groundline, ob->obmat[3]);
+ DRW_buffer_add_entry(sgl->light_groundpoint, ob->obmat[3]);
}
}
@@ -2711,20 +2726,20 @@ static void DRW_shgroup_relationship_lines(OBJECT_ShadingGroupList *sgl,
Object *ob)
{
if (ob->parent && (DRW_object_visibility_in_active_context(ob->parent) & OB_VISIBLE_SELF)) {
- DRW_shgroup_call_dynamic_add(sgl->relationship_lines, ob->runtime.parent_display_origin);
- DRW_shgroup_call_dynamic_add(sgl->relationship_lines, ob->obmat[3]);
+ DRW_buffer_add_entry(sgl->relationship_lines, ob->runtime.parent_display_origin);
+ DRW_buffer_add_entry(sgl->relationship_lines, ob->obmat[3]);
}
if (ob->rigidbody_constraint) {
Object *rbc_ob1 = ob->rigidbody_constraint->ob1;
Object *rbc_ob2 = ob->rigidbody_constraint->ob2;
if (rbc_ob1 && (DRW_object_visibility_in_active_context(rbc_ob1) & OB_VISIBLE_SELF)) {
- DRW_shgroup_call_dynamic_add(sgl->relationship_lines, rbc_ob1->obmat[3]);
- DRW_shgroup_call_dynamic_add(sgl->relationship_lines, ob->obmat[3]);
+ DRW_buffer_add_entry(sgl->relationship_lines, rbc_ob1->obmat[3]);
+ DRW_buffer_add_entry(sgl->relationship_lines, ob->obmat[3]);
}
if (rbc_ob2 && (DRW_object_visibility_in_active_context(rbc_ob2) & OB_VISIBLE_SELF)) {
- DRW_shgroup_call_dynamic_add(sgl->relationship_lines, rbc_ob2->obmat[3]);
- DRW_shgroup_call_dynamic_add(sgl->relationship_lines, ob->obmat[3]);
+ DRW_buffer_add_entry(sgl->relationship_lines, rbc_ob2->obmat[3]);
+ DRW_buffer_add_entry(sgl->relationship_lines, ob->obmat[3]);
}
}
@@ -2756,8 +2771,8 @@ static void DRW_shgroup_relationship_lines(OBJECT_ShadingGroupList *sgl,
}
if (camob) {
- DRW_shgroup_call_dynamic_add(sgl->constraint_lines, camob->obmat[3]);
- DRW_shgroup_call_dynamic_add(sgl->constraint_lines, ob->obmat[3]);
+ DRW_buffer_add_entry(sgl->constraint_lines, camob->obmat[3]);
+ DRW_buffer_add_entry(sgl->constraint_lines, ob->obmat[3]);
}
}
else {
@@ -2778,8 +2793,8 @@ static void DRW_shgroup_relationship_lines(OBJECT_ShadingGroupList *sgl,
unit_m4(ct->matrix);
}
- DRW_shgroup_call_dynamic_add(sgl->constraint_lines, ct->matrix[3]);
- DRW_shgroup_call_dynamic_add(sgl->constraint_lines, ob->obmat[3]);
+ DRW_buffer_add_entry(sgl->constraint_lines, ct->matrix[3]);
+ DRW_buffer_add_entry(sgl->constraint_lines, ob->obmat[3]);
}
if (cti->flush_constraint_targets) {
@@ -2802,32 +2817,32 @@ static void DRW_shgroup_object_center(OBJECT_StorageList *stl,
return;
}
const bool is_library = ob->id.us > 1 || ID_IS_LINKED(ob);
- DRWShadingGroup *shgroup;
+ DRWCallBuffer *buf;
if (ob == OBACT(view_layer)) {
- shgroup = stl->g_data->center_active;
+ buf = stl->g_data->center_active;
}
else if (ob->base_flag & BASE_SELECTED) {
if (is_library) {
- shgroup = stl->g_data->center_selected_lib;
+ buf = stl->g_data->center_selected_lib;
}
else {
- shgroup = stl->g_data->center_selected;
+ buf = stl->g_data->center_selected;
}
}
else if (v3d->flag & V3D_DRAW_CENTERS) {
if (is_library) {
- shgroup = stl->g_data->center_deselected_lib;
+ buf = stl->g_data->center_deselected_lib;
}
else {
- shgroup = stl->g_data->center_deselected;
+ buf = stl->g_data->center_deselected;
}
}
else {
return;
}
- DRW_shgroup_call_dynamic_add(shgroup, ob->obmat[3]);
+ DRW_buffer_add_entry(buf, ob->obmat[3]);
}
static void DRW_shgroup_texture_space(OBJECT_ShadingGroupList *sgl, Object *ob, int theme_id)
@@ -2877,7 +2892,7 @@ static void DRW_shgroup_texture_space(OBJECT_ShadingGroupList *sgl, Object *ob,
float color[4];
UI_GetThemeColor4fv(theme_id, color);
- DRW_shgroup_call_dynamic_add(sgl->texspace, color, &one, tmp);
+ DRW_buffer_add_entry(sgl->texspace, color, &one, tmp);
}
static void DRW_shgroup_bounds(OBJECT_ShadingGroupList *sgl, Object *ob, int theme_id)
@@ -2914,7 +2929,7 @@ static void DRW_shgroup_bounds(OBJECT_ShadingGroupList *sgl, Object *ob, int the
size_to_mat4(tmp, size);
copy_v3_v3(tmp[3], center);
mul_m4_m4m4(tmp, ob->obmat, tmp);
- DRW_shgroup_call_dynamic_add(sgl->cube, color, &one, tmp);
+ DRW_buffer_add_entry(sgl->cube, color, &one, tmp);
break;
case OB_BOUND_SPHERE:
size[0] = max_fff(size[0], size[1], size[2]);
@@ -2922,7 +2937,7 @@ static void DRW_shgroup_bounds(OBJECT_ShadingGroupList *sgl, Object *ob, int the
size_to_mat4(tmp, size);
copy_v3_v3(tmp[3], center);
mul_m4_m4m4(tmp, ob->obmat, tmp);
- DRW_shgroup_call_dynamic_add(sgl->sphere, color, &one, tmp);
+ DRW_buffer_add_entry(sgl->sphere, color, &one, tmp);
break;
case OB_BOUND_CYLINDER:
size[0] = max_ff(size[0], size[1]);
@@ -2930,7 +2945,7 @@ static void DRW_shgroup_bounds(OBJECT_ShadingGroupList *sgl, Object *ob, int the
size_to_mat4(tmp, size);
copy_v3_v3(tmp[3], center);
mul_m4_m4m4(tmp, ob->obmat, tmp);
- DRW_shgroup_call_dynamic_add(sgl->cylinder, color, &one, tmp);
+ DRW_buffer_add_entry(sgl->cylinder, color, &one, tmp);
break;
case OB_BOUND_CONE:
size[0] = max_ff(size[0], size[1]);
@@ -2941,7 +2956,7 @@ static void DRW_shgroup_bounds(OBJECT_ShadingGroupList *sgl, Object *ob, int the
swap_v3_v3(tmp[1], tmp[2]);
tmp[3][2] -= size[2];
mul_m4_m4m4(tmp, ob->obmat, tmp);
- DRW_shgroup_call_dynamic_add(sgl->cone, color, &one, tmp);
+ DRW_buffer_add_entry(sgl->cone, color, &one, tmp);
break;
case OB_BOUND_CAPSULE:
size[0] = max_ff(size[0], size[1]);
@@ -2950,14 +2965,14 @@ static void DRW_shgroup_bounds(OBJECT_ShadingGroupList *sgl, Object *ob, int the
copy_v2_v2(tmp[3], center);
tmp[3][2] = center[2] + max_ff(0.0f, size[2] - size[0]);
mul_m4_m4m4(final_mat, ob->obmat, tmp);
- DRW_shgroup_call_dynamic_add(sgl->capsule_cap, color, &one, final_mat);
+ DRW_buffer_add_entry(sgl->capsule_cap, color, &one, final_mat);
negate_v3(tmp[2]);
tmp[3][2] = center[2] - max_ff(0.0f, size[2] - size[0]);
mul_m4_m4m4(final_mat, ob->obmat, tmp);
- DRW_shgroup_call_dynamic_add(sgl->capsule_cap, color, &one, final_mat);
+ DRW_buffer_add_entry(sgl->capsule_cap, color, &one, final_mat);
tmp[2][2] = max_ff(0.0f, size[2] * 2.0f - size[0] * 2.0f);
mul_m4_m4m4(final_mat, ob->obmat, tmp);
- DRW_shgroup_call_dynamic_add(sgl->capsule_body, color, &one, final_mat);
+ DRW_buffer_add_entry(sgl->capsule_body, color, &one, final_mat);
break;
}
}
@@ -2980,13 +2995,10 @@ static void OBJECT_cache_populate_particles(OBJECT_Shaders *sh_data,
if (draw_as != PART_DRAW_PATH) {
struct GPUBatch *geom = DRW_cache_particles_get_dots(ob, psys);
DRWShadingGroup *shgrp = NULL;
- static int screen_space[2] = {0, 1};
+ struct GPUBatch *shape = NULL;
static float def_prim_col[3] = {0.5f, 0.5f, 0.5f};
static float def_sec_col[3] = {1.0f, 1.0f, 1.0f};
- /* Dummy particle format for instancing to work. */
- DRW_shgroup_instance_format(e_data.particle_format, {{"dummy", DRW_ATTR_FLOAT, 1}});
-
Material *ma = give_current_material(ob, part->omat);
switch (draw_as) {
@@ -2997,43 +3009,36 @@ static void OBJECT_cache_populate_particles(OBJECT_Shaders *sh_data,
DRW_shgroup_uniform_float(shgrp, "pixel_size", DRW_viewport_pixelsize_get(), 1);
DRW_shgroup_uniform_float(shgrp, "size", &part->draw_size, 1);
DRW_shgroup_uniform_texture(shgrp, "ramp", G_draw.ramp);
- DRW_shgroup_call_add(shgrp, geom, mat);
+ DRW_shgroup_call(shgrp, geom, mat);
break;
case PART_DRAW_CROSS:
- shgrp = DRW_shgroup_instance_create(sh_data->part_prim,
- psl->particle,
- DRW_cache_particles_get_prim(PART_DRAW_CROSS),
- e_data.particle_format);
+ shgrp = DRW_shgroup_create(sh_data->part_prim, psl->particle);
DRW_shgroup_uniform_texture(shgrp, "ramp", G_draw.ramp);
DRW_shgroup_uniform_vec3(shgrp, "color", ma ? &ma->r : def_prim_col, 1);
- DRW_shgroup_uniform_int(shgrp, "screen_space", &screen_space[0], 1);
+ DRW_shgroup_uniform_float(shgrp, "draw_size", &part->draw_size, 1);
+ DRW_shgroup_uniform_bool_copy(shgrp, "screen_space", false);
+ shape = DRW_cache_particles_get_prim(PART_DRAW_CROSS);
+ DRW_shgroup_call_instances_with_attribs(shgrp, shape, NULL, geom);
break;
case PART_DRAW_CIRC:
- shgrp = DRW_shgroup_instance_create(sh_data->part_prim,
- psl->particle,
- DRW_cache_particles_get_prim(PART_DRAW_CIRC),
- e_data.particle_format);
+ shape = DRW_cache_particles_get_prim(PART_DRAW_CIRC);
+ shgrp = DRW_shgroup_create(sh_data->part_prim, psl->particle);
DRW_shgroup_uniform_texture(shgrp, "ramp", G_draw.ramp);
DRW_shgroup_uniform_vec3(shgrp, "color", ma ? &ma->r : def_prim_col, 1);
- DRW_shgroup_uniform_int(shgrp, "screen_space", &screen_space[1], 1);
+ DRW_shgroup_uniform_float(shgrp, "draw_size", &part->draw_size, 1);
+ DRW_shgroup_uniform_bool_copy(shgrp, "screen_space", true);
+ DRW_shgroup_call_instances_with_attribs(shgrp, shape, NULL, geom);
break;
case PART_DRAW_AXIS:
- shgrp = DRW_shgroup_instance_create(sh_data->part_axis,
- psl->particle,
- DRW_cache_particles_get_prim(PART_DRAW_AXIS),
- e_data.particle_format);
- DRW_shgroup_uniform_int(shgrp, "screen_space", &screen_space[0], 1);
+ shape = DRW_cache_particles_get_prim(PART_DRAW_AXIS);
+ shgrp = DRW_shgroup_create(sh_data->part_axis, psl->particle);
+ DRW_shgroup_uniform_float(shgrp, "draw_size", &part->draw_size, 1);
+ DRW_shgroup_uniform_bool_copy(shgrp, "screen_space", false);
+ DRW_shgroup_call_instances_with_attribs(shgrp, shape, NULL, geom);
break;
default:
break;
}
-
- if (shgrp) {
- if (draw_as != PART_DRAW_DOT) {
- DRW_shgroup_uniform_float(shgrp, "draw_size", &part->draw_size, 1);
- DRW_shgroup_instance_batch(shgrp, geom);
- }
- }
}
}
}
@@ -3096,6 +3101,24 @@ static void OBJECT_gpencil_color_names(Object *ob, struct DRWTextStore *dt, ucha
}
}
+BLI_INLINE OBJECT_DupliData *OBJECT_duplidata_get(Object *ob, void *vedata, bool *init)
+{
+ OBJECT_DupliData **dupli_data = (OBJECT_DupliData **)DRW_duplidata_get(vedata);
+ *init = false;
+ if (!ELEM(ob->type, OB_MESH, OB_SURF, OB_LATTICE, OB_CURVE, OB_FONT)) {
+ return NULL;
+ }
+
+ if (dupli_data) {
+ if (*dupli_data == NULL) {
+ *dupli_data = MEM_callocN(sizeof(OBJECT_DupliData), "OBJECT_DupliData");
+ *init = true;
+ }
+ return *dupli_data;
+ }
+ return NULL;
+}
+
static void OBJECT_cache_populate(void *vedata, Object *ob)
{
OBJECT_PassList *psl = ((OBJECT_Data *)vedata)->psl;
@@ -3132,10 +3155,15 @@ static void OBJECT_cache_populate(void *vedata, Object *ob)
/* Show if this is the camera we're looking through since it's useful for selecting. */
(((rv3d->persp == RV3D_CAMOB) && ((ID *)v3d->camera == ob->id.orig_id)) == 0));
+ /* Fast path for duplis. */
+ bool init_duplidata;
+ OBJECT_DupliData *dupli_data = OBJECT_duplidata_get(ob, vedata, &init_duplidata);
+
if (do_outlines) {
if (!BKE_object_is_in_editmode(ob) &&
!((ob == draw_ctx->obact) && (draw_ctx->object_mode & OB_MODE_ALL_PAINT))) {
struct GPUBatch *geom;
+ DRWShadingGroup *shgroup = NULL;
/* This fixes only the biggest case which is a plane in ortho view. */
int flat_axis = 0;
@@ -3143,185 +3171,211 @@ static void OBJECT_cache_populate(void *vedata, Object *ob)
DRW_object_is_flat(ob, &flat_axis) &&
DRW_object_axis_orthogonal_to_view(ob, flat_axis));
- if (stl->g_data->xray_enabled_and_not_wire || is_flat_object_viewed_from_side) {
- geom = DRW_cache_object_edge_detection_get(ob, NULL);
+ if (dupli_data && !init_duplidata) {
+ geom = dupli_data->outline_geom;
+ shgroup = dupli_data->outline_shgrp;
}
else {
- geom = DRW_cache_object_surface_get(ob);
- }
+ if (stl->g_data->xray_enabled_and_not_wire || is_flat_object_viewed_from_side) {
+ geom = DRW_cache_object_edge_detection_get(ob, NULL);
+ }
+ else {
+ geom = DRW_cache_object_surface_get(ob);
+ }
- if (geom) {
- theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL);
- DRWShadingGroup *shgroup = shgroup_theme_id_to_outline_or_null(
- stl, theme_id, ob->base_flag);
- if (shgroup != NULL) {
- DRW_shgroup_call_object_add(shgroup, geom, ob);
+ if (geom) {
+ theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL);
+ shgroup = shgroup_theme_id_to_outline_or_null(stl, theme_id, ob->base_flag);
}
}
- }
- }
- switch (ob->type) {
- case OB_MESH: {
- if (hide_object_extra) {
- break;
+ if (shgroup && geom) {
+ DRW_shgroup_call_object(shgroup, geom, ob);
}
- Mesh *me = ob->data;
- if (!is_edit_mode && me->totedge == 0) {
- struct GPUBatch *geom = DRW_cache_mesh_all_verts_get(ob);
- if (geom) {
- if (theme_id == TH_UNDEFINED) {
- theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL);
- }
- DRWShadingGroup *shgroup = shgroup_theme_id_to_point(sgl, theme_id, ob->base_flag);
- DRW_shgroup_call_object_add(shgroup, geom, ob);
- }
+
+ if (init_duplidata) {
+ dupli_data->outline_shgrp = shgroup;
+ dupli_data->outline_geom = geom;
}
- else {
- bool has_edit_mesh_cage = false;
- /* TODO: Should be its own function. */
- if (is_edit_mode) {
- BMEditMesh *embm = me->edit_mesh;
- has_edit_mesh_cage = embm->mesh_eval_cage &&
- (embm->mesh_eval_cage != embm->mesh_eval_final);
+ }
+ }
+
+ if (dupli_data && !init_duplidata) {
+ if (dupli_data->extra_shgrp && dupli_data->extra_geom) {
+ DRW_shgroup_call_object(dupli_data->extra_shgrp, dupli_data->extra_geom, ob);
+ }
+ }
+ else {
+ struct GPUBatch *geom = NULL;
+ DRWShadingGroup *shgroup = NULL;
+ switch (ob->type) {
+ case OB_MESH: {
+ if (hide_object_extra) {
+ break;
}
- if ((!is_edit_mode && me->totedge > 0) || has_edit_mesh_cage) {
- struct GPUBatch *geom = DRW_cache_mesh_loose_edges_get(ob);
+ Mesh *me = ob->data;
+ if (!is_edit_mode && me->totedge == 0) {
+ geom = DRW_cache_mesh_all_verts_get(ob);
if (geom) {
if (theme_id == TH_UNDEFINED) {
theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL);
}
- DRWShadingGroup *shgroup = shgroup_theme_id_to_wire(sgl, theme_id, ob->base_flag);
- DRW_shgroup_call_object_add(shgroup, geom, ob);
+ shgroup = shgroup_theme_id_to_point(sgl, theme_id, ob->base_flag);
+ DRW_shgroup_call_object(shgroup, geom, ob);
+ }
+ }
+ else {
+ bool has_edit_mesh_cage = false;
+ /* TODO: Should be its own function. */
+ if (is_edit_mode) {
+ BMEditMesh *embm = me->edit_mesh;
+ has_edit_mesh_cage = embm->mesh_eval_cage &&
+ (embm->mesh_eval_cage != embm->mesh_eval_final);
+ }
+ if ((!is_edit_mode && me->totedge > 0) || has_edit_mesh_cage) {
+ geom = DRW_cache_mesh_loose_edges_get(ob);
+ if (geom) {
+ if (theme_id == TH_UNDEFINED) {
+ theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL);
+ }
+ shgroup = shgroup_theme_id_to_wire(sgl, theme_id, ob->base_flag);
+ DRW_shgroup_call_object(shgroup, geom, ob);
+ }
}
}
- }
- break;
- }
- case OB_SURF: {
- if (hide_object_extra) {
- break;
- }
- struct GPUBatch *geom = DRW_cache_surf_edge_wire_get(ob);
- if (geom == NULL) {
break;
}
- if (theme_id == TH_UNDEFINED) {
- theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL);
- }
- DRWShadingGroup *shgroup = shgroup_theme_id_to_wire(sgl, theme_id, ob->base_flag);
- DRW_shgroup_call_object_add(shgroup, geom, ob);
- break;
- }
- case OB_LATTICE: {
- if (!is_edit_mode) {
+ case OB_SURF: {
if (hide_object_extra) {
break;
}
- struct GPUBatch *geom = DRW_cache_lattice_wire_get(ob, false);
- if (theme_id == TH_UNDEFINED) {
- theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL);
- }
-
- DRWShadingGroup *shgroup = shgroup_theme_id_to_wire(sgl, theme_id, ob->base_flag);
- DRW_shgroup_call_object_add(shgroup, geom, ob);
- }
- break;
- }
- case OB_CURVE: {
- if (!is_edit_mode) {
- if (hide_object_extra) {
+ geom = DRW_cache_surf_edge_wire_get(ob);
+ if (geom == NULL) {
break;
}
- struct GPUBatch *geom = DRW_cache_curve_edge_wire_get(ob);
if (theme_id == TH_UNDEFINED) {
theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL);
}
- DRWShadingGroup *shgroup = shgroup_theme_id_to_wire(sgl, theme_id, ob->base_flag);
- DRW_shgroup_call_object_add(shgroup, geom, ob);
- }
- break;
- }
- case OB_MBALL: {
- if (!is_edit_mode) {
- DRW_shgroup_mball_handles(sgl, ob, view_layer);
- }
- break;
- }
- case OB_LAMP:
- if (hide_object_extra) {
+ shgroup = shgroup_theme_id_to_wire(sgl, theme_id, ob->base_flag);
+ DRW_shgroup_call_object(shgroup, geom, ob);
break;
}
- DRW_shgroup_light(sgl, ob, view_layer);
- break;
- case OB_CAMERA:
- if (hide_object_extra) {
+ case OB_LATTICE: {
+ if (!is_edit_mode) {
+ if (hide_object_extra) {
+ break;
+ }
+ geom = DRW_cache_lattice_wire_get(ob, false);
+ if (theme_id == TH_UNDEFINED) {
+ theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL);
+ }
+
+ shgroup = shgroup_theme_id_to_wire(sgl, theme_id, ob->base_flag);
+ DRW_shgroup_call_object(shgroup, geom, ob);
+ }
break;
}
- DRW_shgroup_camera(sgl, ob, view_layer);
- break;
- case OB_EMPTY:
- if (hide_object_extra) {
+ case OB_CURVE: {
+ if (!is_edit_mode) {
+ if (hide_object_extra) {
+ break;
+ }
+ geom = DRW_cache_curve_edge_wire_get(ob);
+ if (theme_id == TH_UNDEFINED) {
+ theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL);
+ }
+ shgroup = shgroup_theme_id_to_wire(sgl, theme_id, ob->base_flag);
+ DRW_shgroup_call_object(shgroup, geom, ob);
+ }
break;
}
- DRW_shgroup_empty(sh_data, sgl, ob, view_layer, rv3d, draw_ctx->sh_cfg);
- break;
- case OB_SPEAKER:
- if (hide_object_extra) {
+ case OB_MBALL: {
+ if (!is_edit_mode) {
+ DRW_shgroup_mball_handles(sgl, ob, view_layer);
+ }
break;
}
- DRW_shgroup_speaker(sgl, ob, view_layer);
- break;
- case OB_LIGHTPROBE:
- if (hide_object_extra) {
+ case OB_LAMP:
+ if (hide_object_extra) {
+ break;
+ }
+ DRW_shgroup_light(sgl, ob, view_layer);
break;
- }
- DRW_shgroup_lightprobe(sh_data, stl, psl, ob, view_layer);
- break;
- case OB_ARMATURE: {
- if ((v3d->flag2 & V3D_HIDE_OVERLAYS) || (v3d->overlay.flag & V3D_OVERLAY_HIDE_BONES) ||
- ((ob->dt < OB_WIRE) && !DRW_state_is_select())) {
+ case OB_CAMERA:
+ if (hide_object_extra) {
+ break;
+ }
+ DRW_shgroup_camera(sgl, ob, view_layer);
break;
- }
- bArmature *arm = ob->data;
- if (arm->edbo == NULL) {
- if (DRW_state_is_select() || !DRW_pose_mode_armature(ob, draw_ctx->obact)) {
- bool is_wire = (v3d->shading.type == OB_WIRE) || (ob->dt <= OB_WIRE) ||
- XRAY_FLAG_ENABLED(v3d);
- DRWArmaturePasses passes = {
- .bone_solid = (is_wire) ? NULL : sgl->bone_solid,
- .bone_outline = sgl->bone_outline,
- .bone_wire = sgl->bone_wire,
- .bone_envelope = sgl->bone_envelope,
- .bone_axes = sgl->bone_axes,
- .relationship_lines = NULL, /* Don't draw relationship lines */
- .custom_shapes = stl->g_data->custom_shapes,
- };
- DRW_shgroup_armature_object(ob, view_layer, passes, is_wire);
+ case OB_EMPTY:
+ if (hide_object_extra) {
+ break;
+ }
+ DRW_shgroup_empty(sh_data, sgl, ob, view_layer, rv3d, draw_ctx->sh_cfg);
+ break;
+ case OB_SPEAKER:
+ if (hide_object_extra) {
+ break;
+ }
+ DRW_shgroup_speaker(sgl, ob, view_layer);
+ break;
+ case OB_LIGHTPROBE:
+ if (hide_object_extra) {
+ break;
+ }
+ DRW_shgroup_lightprobe(sh_data, stl, psl, ob, view_layer);
+ break;
+ case OB_ARMATURE: {
+ if ((v3d->flag2 & V3D_HIDE_OVERLAYS) || (v3d->overlay.flag & V3D_OVERLAY_HIDE_BONES) ||
+ ((ob->dt < OB_WIRE) && !DRW_state_is_select())) {
+ break;
+ }
+ bArmature *arm = ob->data;
+ if (arm->edbo == NULL) {
+ if (DRW_state_is_select() || !DRW_pose_mode_armature(ob, draw_ctx->obact)) {
+ bool is_wire = (v3d->shading.type == OB_WIRE) || (ob->dt <= OB_WIRE) ||
+ XRAY_FLAG_ENABLED(v3d);
+ DRWArmaturePasses passes = {
+ .bone_solid = (is_wire) ? NULL : sgl->bone_solid,
+ .bone_outline = sgl->bone_outline,
+ .bone_wire = sgl->bone_wire,
+ .bone_envelope = sgl->bone_envelope,
+ .bone_axes = sgl->bone_axes,
+ .relationship_lines = NULL, /* Don't draw relationship lines */
+ .custom_shapes = stl->g_data->custom_shapes,
+ };
+ DRW_shgroup_armature_object(ob, view_layer, passes, is_wire);
+ }
}
- }
- break;
- }
- case OB_FONT: {
- if (hide_object_extra) {
break;
}
- Curve *cu = (Curve *)ob->data;
- bool has_surface = (cu->flag & (CU_FRONT | CU_BACK)) || cu->ext1 != 0.0f || cu->ext2 != 0.0f;
- if (!has_surface) {
- struct GPUBatch *geom = DRW_cache_text_edge_wire_get(ob);
- if (geom) {
- if (theme_id == TH_UNDEFINED) {
- theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL);
+ case OB_FONT: {
+ if (hide_object_extra) {
+ break;
+ }
+ Curve *cu = (Curve *)ob->data;
+ bool has_surface = (cu->flag & (CU_FRONT | CU_BACK)) || cu->ext1 != 0.0f ||
+ cu->ext2 != 0.0f;
+ if (!has_surface) {
+ geom = DRW_cache_text_edge_wire_get(ob);
+ if (geom) {
+ if (theme_id == TH_UNDEFINED) {
+ theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL);
+ }
+ shgroup = shgroup_theme_id_to_wire(sgl, theme_id, ob->base_flag);
+ DRW_shgroup_call_object(shgroup, geom, ob);
}
- DRWShadingGroup *shgroup = shgroup_theme_id_to_wire(sgl, theme_id, ob->base_flag);
- DRW_shgroup_call_object_add(shgroup, geom, ob);
}
+ break;
}
- break;
+ default:
+ break;
+ }
+
+ if (init_duplidata) {
+ dupli_data->extra_shgrp = shgroup;
+ dupli_data->extra_geom = geom;
}
- default:
- break;
}
if (ob->pd && ob->pd->forcefield) {
@@ -3386,7 +3440,7 @@ static void OBJECT_cache_populate(void *vedata, Object *ob)
float *color, axes_size = 1.0f;
DRW_object_wire_theme_get(ob, view_layer, &color);
- DRW_shgroup_call_dynamic_add(sgl->empty_axes, color, &axes_size, ob->obmat);
+ DRW_buffer_add_entry(sgl->empty_axes, color, &axes_size, ob->obmat);
}
if ((md = modifiers_findByType(ob, eModifierType_Smoke)) &&
diff --git a/source/blender/draw/modes/overlay_mode.c b/source/blender/draw/modes/overlay_mode.c
index 90fac136f73..36493c5eff5 100644
--- a/source/blender/draw/modes/overlay_mode.c
+++ b/source/blender/draw/modes/overlay_mode.c
@@ -46,6 +46,11 @@
/* Structures */
+typedef struct OVERLAY_DupliData {
+ DRWShadingGroup *shgrp;
+ struct GPUBatch *geom;
+} OVERLAY_DupliData;
+
typedef struct OVERLAY_StorageList {
struct OVERLAY_PrivateData *g_data;
} OVERLAY_StorageList;
@@ -95,6 +100,8 @@ extern char datatoc_overlay_face_wireframe_geom_glsl[];
extern char datatoc_overlay_face_wireframe_frag_glsl[];
extern char datatoc_gpu_shader_depth_only_frag_glsl[];
+extern char datatoc_common_view_lib_glsl[];
+
/* Functions */
static void overlay_engine_init(void *vedata)
{
@@ -119,8 +126,10 @@ static void overlay_engine_init(void *vedata)
if (!sh_data->face_orientation) {
/* Face orientation */
sh_data->face_orientation = GPU_shader_create_from_arrays({
- .vert =
- (const char *[]){sh_cfg_data->lib, datatoc_overlay_face_orientation_vert_glsl, NULL},
+ .vert = (const char *[]){sh_cfg_data->lib,
+ datatoc_common_view_lib_glsl,
+ datatoc_overlay_face_orientation_vert_glsl,
+ NULL},
.frag = (const char *[]){datatoc_overlay_face_orientation_frag_glsl, NULL},
.defs = (const char *[]){sh_cfg_data->def, NULL},
});
@@ -128,7 +137,10 @@ static void overlay_engine_init(void *vedata)
if (!sh_data->face_wireframe) {
sh_data->select_wireframe = GPU_shader_create_from_arrays({
- .vert = (const char *[]){sh_cfg_data->lib, datatoc_overlay_face_wireframe_vert_glsl, NULL},
+ .vert = (const char *[]){sh_cfg_data->lib,
+ datatoc_common_view_lib_glsl,
+ datatoc_overlay_face_wireframe_vert_glsl,
+ NULL},
.geom = (const char *[]){sh_cfg_data->lib, datatoc_overlay_face_wireframe_geom_glsl, NULL},
.frag = (const char *[]){datatoc_gpu_shader_depth_only_frag_glsl, NULL},
.defs = (const char *[]){sh_cfg_data->def, "#define SELECT_EDGES\n", NULL},
@@ -136,14 +148,20 @@ static void overlay_engine_init(void *vedata)
#if USE_GEOM_SHADER_WORKAROUND
/* Apple drivers does not support wide wires. Use geometry shader as a workaround. */
sh_data->face_wireframe = GPU_shader_create_from_arrays({
- .vert = (const char *[]){sh_cfg_data->lib, datatoc_overlay_face_wireframe_vert_glsl, NULL},
+ .vert = (const char *[]){sh_cfg_data->lib,
+ datatoc_common_view_lib_glsl,
+ datatoc_overlay_face_wireframe_vert_glsl,
+ NULL},
.geom = (const char *[]){sh_cfg_data->lib, datatoc_overlay_face_wireframe_geom_glsl, NULL},
.frag = (const char *[]){datatoc_overlay_face_wireframe_frag_glsl, NULL},
.defs = (const char *[]){sh_cfg_data->def, "#define USE_GEOM\n", NULL},
});
#else
sh_data->face_wireframe = GPU_shader_create_from_arrays({
- .vert = (const char *[]){sh_cfg_data->lib, datatoc_overlay_face_wireframe_vert_glsl, NULL},
+ .vert = (const char *[]){sh_cfg_data->lib,
+ datatoc_common_view_lib_glsl,
+ datatoc_overlay_face_wireframe_vert_glsl,
+ NULL},
.frag = (const char *[]){datatoc_overlay_face_wireframe_frag_glsl, NULL},
.defs = (const char *[]){sh_cfg_data->def, NULL},
});
@@ -337,12 +355,27 @@ static void overlay_cache_populate(void *vedata, Object *ob)
if (DRW_object_is_renderable(ob) && pd->overlay.flag & V3D_OVERLAY_FACE_ORIENTATION) {
struct GPUBatch *geom = DRW_cache_object_surface_get(ob);
if (geom) {
- DRW_shgroup_call_add(pd->face_orientation_shgrp, geom, ob->obmat);
+ DRW_shgroup_call_object(pd->face_orientation_shgrp, geom, ob);
}
}
if ((pd->overlay.flag & V3D_OVERLAY_WIREFRAMES) || (v3d->shading.type == OB_WIRE) ||
(ob->dtx & OB_DRAWWIRE) || (ob->dt == OB_WIRE)) {
+
+ /* Fast path for duplis. */
+ OVERLAY_DupliData **dupli_data = (OVERLAY_DupliData **)DRW_duplidata_get(vedata);
+ if (dupli_data) {
+ if (*dupli_data == NULL) {
+ *dupli_data = MEM_callocN(sizeof(OVERLAY_DupliData), "OVERLAY_DupliData");
+ }
+ else {
+ if ((*dupli_data)->shgrp && (*dupli_data)->geom) {
+ DRW_shgroup_call_object((*dupli_data)->shgrp, (*dupli_data)->geom, ob);
+ }
+ return;
+ }
+ }
+
const bool is_edit_mode = BKE_object_is_in_editmode(ob);
bool has_edit_mesh_cage = false;
if (ob->type == OB_MESH) {
@@ -389,12 +422,18 @@ static void overlay_cache_populate(void *vedata, Object *ob)
}
if (is_sculpt_mode) {
- DRW_shgroup_call_sculpt_add(shgrp, ob, true, false, false);
+ DRW_shgroup_call_sculpt(shgrp, ob, true, false, false);
}
else {
- DRW_shgroup_call_add(shgrp, geom, ob->obmat);
+ DRW_shgroup_call_object(shgrp, geom, ob);
}
}
+
+ if (dupli_data) {
+ (*dupli_data)->shgrp = shgrp;
+ (*dupli_data)->geom = geom;
+ }
+
if (is_wire && shgrp != NULL) {
/* If object is wireframe, don't try to use stencil test. */
DRW_shgroup_state_disable(shgrp, DRW_STATE_STENCIL_EQUAL);
diff --git a/source/blender/draw/modes/paint_texture_mode.c b/source/blender/draw/modes/paint_texture_mode.c
index 3e292f4e4bc..e99a0c0dab2 100644
--- a/source/blender/draw/modes/paint_texture_mode.c
+++ b/source/blender/draw/modes/paint_texture_mode.c
@@ -27,6 +27,8 @@
#include "BKE_node.h"
+#include "BLI_string_utils.h"
+
/* If builtin shaders are needed */
#include "GPU_shader.h"
#include "GPU_texture.h"
@@ -39,6 +41,7 @@
#include "DEG_depsgraph_query.h"
extern char datatoc_common_globals_lib_glsl[];
+extern char datatoc_common_view_lib_glsl[];
extern char datatoc_paint_texture_vert_glsl[];
extern char datatoc_paint_texture_frag_glsl[];
extern char datatoc_paint_wire_vert_glsl[];
@@ -132,26 +135,31 @@ static void PAINT_TEXTURE_engine_init(void *UNUSED(vedata))
if (!e_data.fallback_sh) {
e_data.fallback_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
- e_data.image_sh = DRW_shader_create_with_lib(datatoc_paint_texture_vert_glsl,
- NULL,
- datatoc_paint_texture_frag_glsl,
- datatoc_common_globals_lib_glsl,
- NULL);
+ char *lib = BLI_string_joinN(datatoc_common_globals_lib_glsl, datatoc_common_view_lib_glsl);
+
+ e_data.image_sh = DRW_shader_create_with_lib(
+ datatoc_paint_texture_vert_glsl, NULL, datatoc_paint_texture_frag_glsl, lib, NULL);
e_data.image_masking_sh = DRW_shader_create_with_lib(datatoc_paint_texture_vert_glsl,
NULL,
datatoc_paint_texture_frag_glsl,
- datatoc_common_globals_lib_glsl,
+ lib,
"#define TEXTURE_PAINT_MASK\n");
e_data.wire_overlay_shader = DRW_shader_create_with_lib(datatoc_paint_wire_vert_glsl,
NULL,
datatoc_paint_wire_frag_glsl,
- datatoc_common_globals_lib_glsl,
+ lib,
"#define VERTEX_MODE\n");
- e_data.face_overlay_shader = DRW_shader_create(
- datatoc_paint_face_vert_glsl, NULL, datatoc_gpu_shader_uniform_color_frag_glsl, NULL);
+ e_data.face_overlay_shader = DRW_shader_create_with_lib(
+ datatoc_paint_face_vert_glsl,
+ NULL,
+ datatoc_gpu_shader_uniform_color_frag_glsl,
+ datatoc_common_view_lib_glsl,
+ NULL);
+
+ MEM_freeN(lib);
}
}
@@ -174,7 +182,7 @@ static DRWShadingGroup *create_texture_paint_shading_group(PAINT_TEXTURE_PassLis
if (masking_enabled) {
const bool masking_inverted = (imapaint->flag & IMAGEPAINT_PROJECT_LAYER_STENCIL_INV) > 0;
- GPUTexture *stencil = GPU_texture_from_blender(imapaint->stencil, NULL, GL_TEXTURE_2D, false);
+ GPUTexture *stencil = GPU_texture_from_blender(imapaint->stencil, NULL, GL_TEXTURE_2D);
DRW_shgroup_uniform_texture(grp, "maskingImage", stencil);
DRW_shgroup_uniform_vec3(grp, "maskingColor", imapaint->stencil_col, 1);
DRW_shgroup_uniform_bool_copy(grp, "maskingInvertStencil", masking_inverted);
@@ -228,7 +236,7 @@ static void PAINT_TEXTURE_cache_init(void *vedata)
NULL;
int interp = (ma && ma->texpaintslot) ? ma->texpaintslot[ma->paint_active_slot].interp :
0;
- GPUTexture *tex = GPU_texture_from_blender(ima, NULL, GL_TEXTURE_2D, false);
+ GPUTexture *tex = GPU_texture_from_blender(ima, NULL, GL_TEXTURE_2D);
if (tex) {
DRWShadingGroup *grp = create_texture_paint_shading_group(
@@ -242,7 +250,7 @@ static void PAINT_TEXTURE_cache_init(void *vedata)
}
else {
Image *ima = imapaint->canvas;
- GPUTexture *tex = GPU_texture_from_blender(ima, NULL, GL_TEXTURE_2D, false);
+ GPUTexture *tex = GPU_texture_from_blender(ima, NULL, GL_TEXTURE_2D);
if (tex) {
DRWShadingGroup *grp = create_texture_paint_shading_group(
@@ -308,24 +316,23 @@ static void PAINT_TEXTURE_cache_populate(void *vedata, Object *ob)
for (int i = 0; i < mat_nr; i++) {
const int index = use_material_slots ? i : 0;
if ((i < me->totcol) && stl->g_data->shgroup_image_array[index]) {
- DRW_shgroup_call_add(
- stl->g_data->shgroup_image_array[index], geom_array[i], ob->obmat);
+ DRW_shgroup_call(stl->g_data->shgroup_image_array[index], geom_array[i], ob->obmat);
}
else {
- DRW_shgroup_call_add(stl->g_data->shgroup_fallback, geom_array[i], ob->obmat);
+ DRW_shgroup_call(stl->g_data->shgroup_fallback, geom_array[i], ob->obmat);
}
}
}
else {
if (stl->g_data->shgroup_image_array[0]) {
struct GPUBatch *geom = DRW_cache_mesh_surface_texpaint_single_get(ob);
- DRW_shgroup_call_add(stl->g_data->shgroup_image_array[0], geom, ob->obmat);
+ DRW_shgroup_call(stl->g_data->shgroup_image_array[0], geom, ob->obmat);
}
}
}
else {
struct GPUBatch *geom = DRW_cache_mesh_surface_get(ob);
- DRW_shgroup_call_add(stl->g_data->shgroup_fallback, geom, ob->obmat);
+ DRW_shgroup_call(stl->g_data->shgroup_fallback, geom, ob->obmat);
}
}
@@ -333,10 +340,10 @@ static void PAINT_TEXTURE_cache_populate(void *vedata, Object *ob)
if (use_face_sel) {
struct GPUBatch *geom;
geom = DRW_cache_mesh_surface_edges_get(ob);
- DRW_shgroup_call_add(stl->g_data->lwire_shgrp, geom, ob->obmat);
+ DRW_shgroup_call(stl->g_data->lwire_shgrp, geom, ob->obmat);
geom = DRW_cache_mesh_surface_get(ob);
- DRW_shgroup_call_add(stl->g_data->face_shgrp, geom, ob->obmat);
+ DRW_shgroup_call(stl->g_data->face_shgrp, geom, ob->obmat);
}
}
}
diff --git a/source/blender/draw/modes/paint_vertex_mode.c b/source/blender/draw/modes/paint_vertex_mode.c
index ef3af1255eb..da76573a7e4 100644
--- a/source/blender/draw/modes/paint_vertex_mode.c
+++ b/source/blender/draw/modes/paint_vertex_mode.c
@@ -42,6 +42,7 @@ extern char datatoc_paint_wire_vert_glsl[];
extern char datatoc_paint_wire_frag_glsl[];
extern char datatoc_paint_vert_frag_glsl[];
extern char datatoc_common_globals_lib_glsl[];
+extern char datatoc_common_view_lib_glsl[];
extern char datatoc_gpu_shader_uniform_color_frag_glsl[];
@@ -115,12 +116,16 @@ static void PAINT_VERTEX_engine_init(void *UNUSED(vedata))
if (!sh_data->face_select_overlay) {
sh_data->by_mode[VERTEX_MODE].color_face = GPU_shader_create_from_arrays({
- .vert = (const char *[]){sh_cfg_data->lib, datatoc_paint_vertex_vert_glsl, NULL},
+ .vert = (const char *[]){sh_cfg_data->lib,
+ datatoc_common_view_lib_glsl,
+ datatoc_paint_vertex_vert_glsl,
+ NULL},
.frag = (const char *[]){datatoc_paint_vertex_frag_glsl, NULL},
.defs = (const char *[]){sh_cfg_data->def, NULL},
});
sh_data->by_mode[WEIGHT_MODE].color_face = GPU_shader_create_from_arrays({
.vert = (const char *[]){sh_cfg_data->lib,
+ datatoc_common_view_lib_glsl,
datatoc_common_globals_lib_glsl,
datatoc_paint_weight_vert_glsl,
NULL},
@@ -131,13 +136,17 @@ static void PAINT_VERTEX_engine_init(void *UNUSED(vedata))
});
sh_data->face_select_overlay = GPU_shader_create_from_arrays({
- .vert = (const char *[]){sh_cfg_data->lib, datatoc_paint_face_vert_glsl, NULL},
+ .vert = (const char *[]){sh_cfg_data->lib,
+ datatoc_common_view_lib_glsl,
+ datatoc_paint_face_vert_glsl,
+ NULL},
.frag = (const char *[]){datatoc_gpu_shader_uniform_color_frag_glsl, NULL},
.defs = (const char *[]){sh_cfg_data->def, NULL},
});
sh_data->vert_select_overlay = GPU_shader_create_from_arrays({
.vert = (const char *[]){sh_cfg_data->lib,
datatoc_common_globals_lib_glsl,
+ datatoc_common_view_lib_glsl,
datatoc_paint_wire_vert_glsl,
NULL},
.frag = (const char *[]){datatoc_paint_vert_frag_glsl, NULL},
@@ -152,6 +161,7 @@ static void PAINT_VERTEX_engine_init(void *UNUSED(vedata))
sh_data->by_mode[i].wire_overlay = GPU_shader_create_from_arrays({
.vert = (const char *[]){sh_cfg_data->lib,
datatoc_common_globals_lib_glsl,
+ datatoc_common_view_lib_glsl,
datatoc_paint_wire_vert_glsl,
NULL},
.frag = (const char *[]){datatoc_paint_wire_frag_glsl, NULL},
@@ -160,6 +170,7 @@ static void PAINT_VERTEX_engine_init(void *UNUSED(vedata))
sh_data->by_mode[i].wire_select_overlay = GPU_shader_create_from_arrays({
.vert = (const char *[]){sh_cfg_data->lib,
datatoc_common_globals_lib_glsl,
+ datatoc_common_view_lib_glsl,
datatoc_paint_wire_vert_glsl,
NULL},
.frag = (const char *[]){datatoc_paint_wire_frag_glsl, NULL},
@@ -301,24 +312,24 @@ static void PAINT_VERTEX_cache_populate(void *vedata, Object *ob)
}
}
if (geom != NULL) {
- DRW_shgroup_call_add(stl->g_data->by_mode[draw_mode].color_shgrp, geom, ob->obmat);
+ DRW_shgroup_call(stl->g_data->by_mode[draw_mode].color_shgrp, geom, ob->obmat);
}
if (use_face_sel || use_wire) {
DRWShadingGroup *shgrp = use_face_sel ? stl->g_data->by_mode[draw_mode].lwire_select_shgrp :
stl->g_data->by_mode[draw_mode].lwire_shgrp;
geom = DRW_cache_mesh_surface_edges_get(ob);
- DRW_shgroup_call_add(shgrp, geom, ob->obmat);
+ DRW_shgroup_call(shgrp, geom, ob->obmat);
}
if (use_face_sel) {
geom = DRW_cache_mesh_surface_get(ob);
- DRW_shgroup_call_add(stl->g_data->face_select_shgrp, geom, ob->obmat);
+ DRW_shgroup_call(stl->g_data->face_select_shgrp, geom, ob->obmat);
}
if (use_vert_sel) {
geom = DRW_cache_mesh_all_verts_get(ob);
- DRW_shgroup_call_add(stl->g_data->vert_select_shgrp, geom, ob->obmat);
+ DRW_shgroup_call(stl->g_data->vert_select_shgrp, geom, ob->obmat);
}
}
}
diff --git a/source/blender/draw/modes/particle_mode.c b/source/blender/draw/modes/particle_mode.c
index 600a29fecb4..c4a0a768796 100644
--- a/source/blender/draw/modes/particle_mode.c
+++ b/source/blender/draw/modes/particle_mode.c
@@ -27,6 +27,8 @@
#include "BKE_pointcache.h"
+#include "BLI_string_utils.h"
+
#include "GPU_shader.h"
#include "draw_common.h"
@@ -39,6 +41,7 @@
extern char datatoc_particle_strand_vert_glsl[];
extern char datatoc_particle_strand_frag_glsl[];
extern char datatoc_common_globals_lib_glsl[];
+extern char datatoc_common_view_lib_glsl[];
/* *********** LISTS *********** */
@@ -86,23 +89,23 @@ typedef struct PARTICLE_PrivateData {
static void particle_engine_init(void *UNUSED(vedata))
{
if (!e_data.strands_shader) {
- e_data.strands_shader = DRW_shader_create_with_lib(datatoc_particle_strand_vert_glsl,
- NULL,
- datatoc_particle_strand_frag_glsl,
- datatoc_common_globals_lib_glsl,
- "");
+ char *lib = BLI_string_joinN(datatoc_common_globals_lib_glsl, datatoc_common_view_lib_glsl);
+
+ e_data.strands_shader = DRW_shader_create_with_lib(
+ datatoc_particle_strand_vert_glsl, NULL, datatoc_particle_strand_frag_glsl, lib, "");
e_data.strands_weight_shader = DRW_shader_create_with_lib(datatoc_particle_strand_vert_glsl,
NULL,
datatoc_particle_strand_frag_glsl,
- datatoc_common_globals_lib_glsl,
+ lib,
"#define USE_WEIGHT");
e_data.points_shader = DRW_shader_create_with_lib(datatoc_particle_strand_vert_glsl,
NULL,
datatoc_particle_strand_frag_glsl,
- datatoc_common_globals_lib_glsl,
+ lib,
"#define USE_POINTS");
+ MEM_freeN(lib);
}
}
@@ -147,15 +150,15 @@ static void particle_edit_cache_populate(void *vedata,
{
struct GPUBatch *strands = DRW_cache_particles_get_edit_strands(
object, psys, edit, use_weight);
- DRW_shgroup_call_add(stl->g_data->strands_group, strands, NULL);
+ DRW_shgroup_call(stl->g_data->strands_group, strands, NULL);
}
if (pset->selectmode == SCE_SELECT_POINT) {
struct GPUBatch *points = DRW_cache_particles_get_edit_inner_points(object, psys, edit);
- DRW_shgroup_call_add(stl->g_data->inner_points_group, points, NULL);
+ DRW_shgroup_call(stl->g_data->inner_points_group, points, NULL);
}
if (ELEM(pset->selectmode, SCE_SELECT_POINT, SCE_SELECT_END)) {
struct GPUBatch *points = DRW_cache_particles_get_edit_tip_points(object, psys, edit);
- DRW_shgroup_call_add(stl->g_data->tip_points_group, points, NULL);
+ DRW_shgroup_call(stl->g_data->tip_points_group, points, NULL);
}
}
diff --git a/source/blender/draw/modes/pose_mode.c b/source/blender/draw/modes/pose_mode.c
index a37901a1fa9..cde0d392480 100644
--- a/source/blender/draw/modes/pose_mode.c
+++ b/source/blender/draw/modes/pose_mode.c
@@ -226,10 +226,10 @@ static void POSE_cache_populate(void *vedata, Object *ob)
struct GPUBatch *geom = DRW_cache_object_surface_get(ob);
if (geom) {
if (POSE_is_driven_by_active_armature(ob)) {
- DRW_shgroup_call_object_add(ppd->bone_selection_shgrp, geom, ob);
+ DRW_shgroup_call_object(ppd->bone_selection_shgrp, geom, ob);
}
else {
- DRW_shgroup_call_object_add(ppd->bone_selection_invert_shgrp, geom, ob);
+ DRW_shgroup_call_object(ppd->bone_selection_invert_shgrp, geom, ob);
}
}
}
diff --git a/source/blender/draw/modes/sculpt_mode.c b/source/blender/draw/modes/sculpt_mode.c
index 053e73e4068..363476445c1 100644
--- a/source/blender/draw/modes/sculpt_mode.c
+++ b/source/blender/draw/modes/sculpt_mode.c
@@ -37,6 +37,7 @@
#include "draw_common.h"
#include "draw_mode_engines.h"
+extern char datatoc_common_view_lib_glsl[];
extern char datatoc_sculpt_mask_vert_glsl[];
extern char datatoc_gpu_shader_3D_smooth_color_frag_glsl[];
@@ -111,8 +112,11 @@ static void SCULPT_engine_init(void *vedata)
UNUSED_VARS(txl, fbl, stl);
if (!e_data.shader_mask) {
- e_data.shader_mask = DRW_shader_create(
- datatoc_sculpt_mask_vert_glsl, NULL, datatoc_gpu_shader_3D_smooth_color_frag_glsl, NULL);
+ e_data.shader_mask = DRW_shader_create_with_lib(datatoc_sculpt_mask_vert_glsl,
+ NULL,
+ datatoc_gpu_shader_3D_smooth_color_frag_glsl,
+ datatoc_common_view_lib_glsl,
+ NULL);
}
}
@@ -154,7 +158,7 @@ static void SCULPT_cache_populate(void *vedata, Object *ob)
if (ob->sculpt && (ob == draw_ctx->obact)) {
PBVH *pbvh = ob->sculpt->pbvh;
if (pbvh && pbvh_has_mask(pbvh)) {
- DRW_shgroup_call_sculpt_add(stl->g_data->mask_overlay_grp, ob, false, true, false);
+ DRW_shgroup_call_sculpt(stl->g_data->mask_overlay_grp, ob, false, true, false);
}
}
}
diff --git a/source/blender/draw/modes/shaders/armature_axes_vert.glsl b/source/blender/draw/modes/shaders/armature_axes_vert.glsl
index a689dce4d70..d7ed3e9ab71 100644
--- a/source/blender/draw/modes/shaders/armature_axes_vert.glsl
+++ b/source/blender/draw/modes/shaders/armature_axes_vert.glsl
@@ -1,9 +1,7 @@
uniform mat4 ViewProjectionMatrix;
uniform vec3 screenVecs[3];
-#ifdef USE_WORLD_CLIP_PLANES
-uniform mat4 ModelMatrix;
-#endif
+
/* ---- Instantiated Attrs ---- */
in float axis; /* position on the axis. [0.0-1.0] is X axis, [1.0-2.0] is Y, etc... */
in vec2 screenPos;
@@ -32,6 +30,6 @@ void main()
finalColor.a = 1.0;
#ifdef USE_WORLD_CLIP_PLANES
- world_clip_planes_calc_clip_distance((ModelMatrix * pos_4d).xyz);
+ world_clip_planes_calc_clip_distance(pos_4d.xyz);
#endif
}
diff --git a/source/blender/draw/modes/shaders/armature_envelope_outline_vert.glsl b/source/blender/draw/modes/shaders/armature_envelope_outline_vert.glsl
index 1e7fc4d11b8..c0bde90bf28 100644
--- a/source/blender/draw/modes/shaders/armature_envelope_outline_vert.glsl
+++ b/source/blender/draw/modes/shaders/armature_envelope_outline_vert.glsl
@@ -3,9 +3,6 @@ uniform mat4 ViewMatrix;
uniform mat4 ViewMatrixInverse;
uniform mat4 ViewProjectionMatrix;
uniform mat4 ProjectionMatrix;
-#ifdef USE_WORLD_CLIP_PLANES
-uniform mat4 ModelMatrix;
-#endif
uniform vec2 viewportSize;
uniform float lineThickness = 2.0;
@@ -145,7 +142,7 @@ void main()
vec4 pos_4d = vec4(wpos1, 1.0);
#ifdef USE_WORLD_CLIP_PLANES
- world_clip_planes_calc_clip_distance((ModelMatrix * pos_4d).xyz);
+ world_clip_planes_calc_clip_distance(pos_4d.xyz);
#endif
vec4 V = ViewMatrix * pos_4d;
diff --git a/source/blender/draw/modes/shaders/armature_envelope_solid_vert.glsl b/source/blender/draw/modes/shaders/armature_envelope_solid_vert.glsl
index 7f8ccc0c95a..d9567bb84f4 100644
--- a/source/blender/draw/modes/shaders/armature_envelope_solid_vert.glsl
+++ b/source/blender/draw/modes/shaders/armature_envelope_solid_vert.glsl
@@ -2,9 +2,6 @@
uniform mat4 ViewMatrix;
uniform mat4 ViewMatrixInverse;
uniform mat4 ViewProjectionMatrix;
-#ifdef USE_WORLD_CLIP_PLANES
-uniform mat4 ModelMatrix;
-#endif
/* ---- Instantiated Attrs ---- */
in vec3 pos;
@@ -57,6 +54,6 @@ void main()
vec4 pos_4d = vec4(sp, 1.0);
gl_Position = ViewProjectionMatrix * pos_4d;
#ifdef USE_WORLD_CLIP_PLANES
- world_clip_planes_calc_clip_distance((ModelMatrix * pos_4d).xyz);
+ world_clip_planes_calc_clip_distance(pos_4d.xyz);
#endif
}
diff --git a/source/blender/draw/modes/shaders/armature_shape_outline_geom.glsl b/source/blender/draw/modes/shaders/armature_shape_outline_geom.glsl
index 54315863a2e..dc84b8924d1 100644
--- a/source/blender/draw/modes/shaders/armature_shape_outline_geom.glsl
+++ b/source/blender/draw/modes/shaders/armature_shape_outline_geom.glsl
@@ -9,7 +9,6 @@ in vec2 ssNor[];
in vec4 vColSize[];
flat out vec4 finalColor;
-uniform mat4 ProjectionMatrix;
uniform vec2 viewportSize;
uniform float lineThickness = 2.0;
diff --git a/source/blender/draw/modes/shaders/armature_shape_outline_vert.glsl b/source/blender/draw/modes/shaders/armature_shape_outline_vert.glsl
index 82a483d91a5..fb2735c196c 100644
--- a/source/blender/draw/modes/shaders/armature_shape_outline_vert.glsl
+++ b/source/blender/draw/modes/shaders/armature_shape_outline_vert.glsl
@@ -1,8 +1,4 @@
-uniform mat3 NormalMatrix;
-
-uniform mat4 ViewMatrix;
-uniform mat4 ProjectionMatrix;
uniform vec2 viewportSize;
/* ---- Instantiated Attrs ---- */
@@ -27,20 +23,19 @@ vec2 proj(vec4 pos)
void main()
{
- /* This is slow and run per vertex, but it's still faster than
- * doing it per instance on CPU and sending it on via instance attribute. */
- mat3 NormalMatrix = transpose(inverse(mat3(ViewMatrix * InstanceModelMatrix)));
-
vec4 worldPosition = InstanceModelMatrix * vec4(pos, 1.0);
vec4 viewpos = ViewMatrix * worldPosition;
vPos = viewpos.xyz;
pPos = ProjectionMatrix * viewpos;
+ /* This is slow and run per vertex, but it's still faster than
+ * doing it per instance on CPU and sending it on via instance attribute. */
+ mat3 normal_mat = transpose(inverse(mat3(InstanceModelMatrix)));
/* TODO FIX: there is still a problem with this vector
* when the bone is scaled or in persp mode. But it's
* barelly visible at the outline corners. */
- ssNor = normalize((NormalMatrix * snor).xy);
+ ssNor = normalize(normal_world_to_view(normal_mat * snor).xy);
ssPos = proj(pPos);
diff --git a/source/blender/draw/modes/shaders/armature_shape_solid_vert.glsl b/source/blender/draw/modes/shaders/armature_shape_solid_vert.glsl
index 2df25bf0e03..df6a9ce2d76 100644
--- a/source/blender/draw/modes/shaders/armature_shape_solid_vert.glsl
+++ b/source/blender/draw/modes/shaders/armature_shape_solid_vert.glsl
@@ -1,11 +1,4 @@
-uniform mat3 NormalMatrix;
-uniform mat4 ViewMatrixInverse;
-uniform mat4 ViewProjectionMatrix;
-
-uniform mat4 ViewMatrix;
-uniform mat4 ProjectionMatrix;
-
/* ---- Instantiated Attrs ---- */
in vec3 pos;
in vec3 nor;
@@ -19,8 +12,10 @@ out vec4 finalColor;
void main()
{
- mat3 NormalMatrix = transpose(inverse(mat3(ViewMatrix * InstanceModelMatrix)));
- vec3 normal = normalize(NormalMatrix * nor);
+ /* This is slow and run per vertex, but it's still faster than
+ * doing it per instance on CPU and sending it on via instance attribute. */
+ mat3 normal_mat = transpose(inverse(mat3(InstanceModelMatrix)));
+ vec3 normal = normalize(normal_world_to_view(normal_mat * nor));
/* Do lighting at an angle to avoid flat shading on front facing bone. */
const vec3 light = vec3(0.1, 0.1, 0.8);
diff --git a/source/blender/draw/modes/shaders/armature_stick_vert.glsl b/source/blender/draw/modes/shaders/armature_stick_vert.glsl
index 9e5a3d76c0d..fd8a12fcd2c 100644
--- a/source/blender/draw/modes/shaders/armature_stick_vert.glsl
+++ b/source/blender/draw/modes/shaders/armature_stick_vert.glsl
@@ -1,7 +1,7 @@
uniform mat4 ProjectionMatrix;
uniform mat4 ViewProjectionMatrix;
-uniform mat4 ModelMatrix;
+
uniform mat4 ViewMatrix;
uniform vec2 viewportSize;
@@ -88,8 +88,7 @@ void main()
gl_Position.z += (is_bone) ? 0.0 : 1e-6; /* Avoid Z fighting of head/tails. */
#ifdef USE_WORLD_CLIP_PLANES
- world_clip_planes_calc_clip_distance(
- (ModelMatrix * (is_head ? boneStart_4d : boneEnd_4d)).xyz);
+ world_clip_planes_calc_clip_distance((is_head ? boneStart_4d : boneEnd_4d).xyz);
#endif
}
else {
diff --git a/source/blender/draw/modes/shaders/common_view_lib.glsl b/source/blender/draw/modes/shaders/common_view_lib.glsl
index de9c4e2a96e..79ac351912d 100644
--- a/source/blender/draw/modes/shaders/common_view_lib.glsl
+++ b/source/blender/draw/modes/shaders/common_view_lib.glsl
@@ -13,3 +13,38 @@ layout(std140) uniform viewBlock
vec4 clipPlanes[2];
};
+
+uniform mat4 ModelMatrix;
+uniform mat4 ModelMatrixInverse;
+
+/** Transform shortcuts. */
+/* Rule of thumb: Try to reuse world positions and normals because converting though viewspace
+ * will always be decomposed in at least 2 matrix operation. */
+
+/**
+ * Some clarification:
+ * Usually Normal matrix is transpose(inverse(ViewMatrix * ModelMatrix))
+ *
+ * But since it is slow to multiply matrices we decompose it. Decomposing
+ * inversion and transposition both invert the product order leaving us with
+ * the same original order:
+ * transpose(ViewMatrixInverse) * transpose(ModelMatrixInverse)
+ *
+ * Knowing that the view matrix is orthogonal, the transpose is also the inverse.
+ * 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 normal_world_to_view(n) (mat3(ViewMatrix) * n)
+
+#define point_object_to_ndc(p) (ViewProjectionMatrix * vec4((ModelMatrix * vec4(p, 1.0)).xyz, 1.0))
+#define point_object_to_view(p) ((ViewMatrix * vec4((ModelMatrix * vec4(p, 1.0)).xyz, 1.0)).xyz)
+#define point_object_to_world(p) ((ModelMatrix * vec4(p, 1.0)).xyz)
+#define point_view_to_ndc(p) (ProjectionMatrix * vec4(p, 1.0))
+#define point_view_to_object(p) ((ModelMatrixInverse * (ViewMatrixInverse * vec4(p, 1.0))).xyz)
+#define point_view_to_world(p) ((ViewMatrixInverse * vec4(p, 1.0)).xyz)
+#define point_world_to_ndc(p) (ViewProjectionMatrix * vec4(p, 1.0))
+#define point_world_to_object(p) ((ModelMatrixInverse * vec4(p, 1.0)).xyz)
+#define point_world_to_view(p) ((ViewMatrix * vec4(p, 1.0)).xyz)
diff --git a/source/blender/draw/modes/shaders/edit_curve_overlay_handle_vert.glsl b/source/blender/draw/modes/shaders/edit_curve_overlay_handle_vert.glsl
index b7166382b19..2f3d37a6e73 100644
--- a/source/blender/draw/modes/shaders/edit_curve_overlay_handle_vert.glsl
+++ b/source/blender/draw/modes/shaders/edit_curve_overlay_handle_vert.glsl
@@ -1,6 +1,4 @@
/* Draw Curve Handles */
-uniform mat4 ModelViewProjectionMatrix;
-uniform mat4 ModelMatrix;
in vec3 pos;
in int data;
@@ -9,11 +7,11 @@ flat out int vertFlag;
void main()
{
- vec4 pos_4d = vec4(pos, 1.0);
- gl_Position = ModelViewProjectionMatrix * pos_4d;
+ vec3 world_pos = point_object_to_world(pos);
+ gl_Position = point_world_to_ndc(world_pos);
vertFlag = data;
#ifdef USE_WORLD_CLIP_PLANES
- world_clip_planes_calc_clip_distance((ModelMatrix * pos_4d).xyz);
+ world_clip_planes_calc_clip_distance(world_pos);
#endif
}
diff --git a/source/blender/draw/modes/shaders/edit_curve_overlay_loosevert_vert.glsl b/source/blender/draw/modes/shaders/edit_curve_overlay_loosevert_vert.glsl
index 4718f11db65..b1b707b59f4 100644
--- a/source/blender/draw/modes/shaders/edit_curve_overlay_loosevert_vert.glsl
+++ b/source/blender/draw/modes/shaders/edit_curve_overlay_loosevert_vert.glsl
@@ -1,6 +1,5 @@
/* Draw Curve Vertices */
-uniform mat4 ModelViewProjectionMatrix;
-uniform mat4 ModelMatrix;
+
uniform vec2 viewportSize;
in vec3 pos;
@@ -22,10 +21,10 @@ void main()
finalColor = colorVertex;
}
- vec4 pos_4d = vec4(pos, 1.0);
- gl_Position = ModelViewProjectionMatrix * pos_4d;
+ vec3 world_pos = point_object_to_world(pos);
+ gl_Position = point_world_to_ndc(world_pos);
gl_PointSize = sizeVertex * 2.0;
#ifdef USE_WORLD_CLIP_PLANES
- world_clip_planes_calc_clip_distance((ModelMatrix * pos_4d).xyz);
+ world_clip_planes_calc_clip_distance(world_pos);
#endif
}
diff --git a/source/blender/draw/modes/shaders/edit_curve_overlay_normals_vert.glsl b/source/blender/draw/modes/shaders/edit_curve_overlay_normals_vert.glsl
index 02244086711..ef60ddbc395 100644
--- a/source/blender/draw/modes/shaders/edit_curve_overlay_normals_vert.glsl
+++ b/source/blender/draw/modes/shaders/edit_curve_overlay_normals_vert.glsl
@@ -1,6 +1,5 @@
/* Draw Curve Normals */
-uniform mat4 ModelViewProjectionMatrix;
-uniform mat4 ModelMatrix;
+
uniform float normalSize;
in vec3 pos;
@@ -18,10 +17,10 @@ void main()
final_pos += normalSize * rad * (flip * nor - tan);
}
- vec4 final_pos_4d = vec4(final_pos, 1.0);
- gl_Position = ModelViewProjectionMatrix * final_pos_4d;
+ vec3 world_pos = point_object_to_world(final_pos);
+ gl_Position = point_world_to_ndc(world_pos);
#ifdef USE_WORLD_CLIP_PLANES
- world_clip_planes_calc_clip_distance((ModelMatrix * final_pos_4d).xyz);
+ world_clip_planes_calc_clip_distance(world_pos);
#endif
}
diff --git a/source/blender/draw/modes/shaders/edit_lattice_overlay_loosevert_vert.glsl b/source/blender/draw/modes/shaders/edit_lattice_overlay_loosevert_vert.glsl
index 3cf808f3c52..f7df6bb4b68 100644
--- a/source/blender/draw/modes/shaders/edit_lattice_overlay_loosevert_vert.glsl
+++ b/source/blender/draw/modes/shaders/edit_lattice_overlay_loosevert_vert.glsl
@@ -1,8 +1,5 @@
-
/* Draw Lattice Vertices */
-uniform mat4 ModelViewProjectionMatrix;
-uniform mat4 ModelMatrix;
uniform vec2 viewportSize;
in vec3 pos;
@@ -27,7 +24,8 @@ void main()
{
clipCase = 0;
- vec4 pPos = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ vec3 world_pos = point_object_to_world(pos);
+ vec4 pPos = point_world_to_ndc(world_pos);
/* only vertex position 0 is used */
eData1 = eData2 = vec4(1e10);
@@ -39,6 +37,6 @@ void main()
gl_Position = pPos;
#ifdef USE_WORLD_CLIP_PLANES
- world_clip_planes_calc_clip_distance((ModelMatrix * vec4(pos, 1.0)).xyz);
+ world_clip_planes_calc_clip_distance(world_pos);
#endif
}
diff --git a/source/blender/draw/modes/shaders/edit_mesh_overlay_facefill_vert.glsl b/source/blender/draw/modes/shaders/edit_mesh_overlay_facefill_vert.glsl
index c84d97fa1c5..a20c1124fe1 100644
--- a/source/blender/draw/modes/shaders/edit_mesh_overlay_facefill_vert.glsl
+++ b/source/blender/draw/modes/shaders/edit_mesh_overlay_facefill_vert.glsl
@@ -1,6 +1,4 @@
-uniform mat4 ModelViewProjectionMatrix;
-uniform mat4 ModelMatrix;
uniform ivec4 dataMask = ivec4(0xFF);
in vec3 pos;
@@ -10,13 +8,14 @@ flat out vec4 faceColor;
void main()
{
- gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ vec3 world_pos = point_object_to_world(pos);
+ gl_Position = point_world_to_ndc(world_pos);
ivec4 data_m = data & dataMask;
faceColor = EDIT_MESH_face_color(data_m.x);
#ifdef USE_WORLD_CLIP_PLANES
- world_clip_planes_calc_clip_distance((ModelMatrix * vec4(pos, 1.0)).xyz);
+ world_clip_planes_calc_clip_distance(world_pos);
#endif
}
diff --git a/source/blender/draw/modes/shaders/edit_mesh_overlay_mesh_analysis_vert.glsl b/source/blender/draw/modes/shaders/edit_mesh_overlay_mesh_analysis_vert.glsl
index 94d8d2e701c..968a63c7780 100644
--- a/source/blender/draw/modes/shaders/edit_mesh_overlay_mesh_analysis_vert.glsl
+++ b/source/blender/draw/modes/shaders/edit_mesh_overlay_mesh_analysis_vert.glsl
@@ -1,5 +1,3 @@
-uniform mat4 ModelViewProjectionMatrix;
-uniform mat4 ModelMatrix;
in vec3 pos;
in vec4 weight_color;
@@ -14,10 +12,11 @@ out vec4 weightColor;
void main()
{
- gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ vec3 world_pos = point_object_to_world(pos);
+ gl_Position = point_world_to_ndc(world_pos);
weightColor = vec4(weight_color.rgb, 1.0);
#ifdef USE_WORLD_CLIP_PLANES
- world_clip_planes_calc_clip_distance((ModelMatrix * vec4(pos, 1.0)).xyz);
+ world_clip_planes_calc_clip_distance(world_pos);
#endif
}
diff --git a/source/blender/draw/modes/shaders/edit_mesh_overlay_vert.glsl b/source/blender/draw/modes/shaders/edit_mesh_overlay_vert.glsl
index d700e69fb57..9aa656818cb 100644
--- a/source/blender/draw/modes/shaders/edit_mesh_overlay_vert.glsl
+++ b/source/blender/draw/modes/shaders/edit_mesh_overlay_vert.glsl
@@ -1,9 +1,4 @@
-uniform mat3 NormalMatrix;
-uniform mat4 ProjectionMatrix;
-uniform mat4 ModelViewMatrix;
-uniform mat4 ModelViewProjectionMatrix;
-uniform mat4 ModelMatrix;
uniform float faceAlphaMod;
uniform ivec4 dataMask = ivec4(0xFF);
uniform float ofs;
@@ -25,14 +20,17 @@ out int selectOveride;
void main()
{
+ vec3 world_pos = point_object_to_world(pos);
+
#if !defined(FACE)
+ /* TODO override the ViewProjection Matrix for this case. */
mat4 projmat = ProjectionMatrix;
projmat[3][2] -= ofs;
- gl_Position = projmat * (ModelViewMatrix * vec4(pos, 1.0));
+ gl_Position = projmat * (ViewMatrix * vec4(world_pos, 1.0));
#else
- gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ gl_Position = point_world_to_ndc(world_pos);
#endif
ivec4 m_data = data & dataMask;
@@ -76,17 +74,16 @@ void main()
#if !defined(FACE)
/* Facing based color blend */
- vec4 vpos = ModelViewMatrix * vec4(pos, 1.0);
- vec3 view_normal = normalize(NormalMatrix * vnor + 1e-4);
- vec3 view_vec = (ProjectionMatrix[3][3] == 0.0) ? normalize(vpos.xyz) : vec3(0.0, 0.0, 1.0);
+ vec3 vpos = point_world_to_view(world_pos);
+ vec3 view_normal = normalize(normal_object_to_view(vnor) + 1e-4);
+ vec3 view_vec = (ProjectionMatrix[3][3] == 0.0) ? normalize(vpos) : vec3(0.0, 0.0, 1.0);
float facing = dot(view_vec, view_normal);
facing = 1.0 - abs(facing) * 0.2;
finalColor.rgb = mix(colorEditMeshMiddle.rgb, finalColor.rgb, facing);
-
#endif
#ifdef USE_WORLD_CLIP_PLANES
- world_clip_planes_calc_clip_distance((ModelMatrix * vec4(pos, 1.0)).xyz);
+ world_clip_planes_calc_clip_distance(world_pos);
#endif
}
diff --git a/source/blender/draw/modes/shaders/edit_normals_vert.glsl b/source/blender/draw/modes/shaders/edit_normals_vert.glsl
index 2e34a132cb0..9bf0fb7315c 100644
--- a/source/blender/draw/modes/shaders/edit_normals_vert.glsl
+++ b/source/blender/draw/modes/shaders/edit_normals_vert.glsl
@@ -1,8 +1,4 @@
-uniform mat4 ModelViewProjectionMatrix;
-uniform mat3 NormalMatrix;
-uniform mat4 ProjectionMatrix;
-uniform mat4 ModelMatrix;
uniform float normalSize;
in vec3 pos;
@@ -25,10 +21,14 @@ flat out vec4 v2;
void main()
{
- v1 = ModelViewProjectionMatrix * vec4(pos, 1.0);
- vec3 n = normalize(NormalMatrix * nor); /* viewspace */
- v2 = v1 + ProjectionMatrix * vec4(n * normalSize, 0.0);
+ vec3 n = normalize(normal_object_to_world(nor));
+
+ vec3 world_pos = point_object_to_world(pos);
+
+ v1 = point_world_to_ndc(world_pos);
+ v2 = point_world_to_ndc(world_pos + n * normalSize);
+
#ifdef USE_WORLD_CLIP_PLANES
- world_clip_planes_calc_clip_distance((ModelMatrix * vec4(pos, 1.0)).xyz);
+ world_clip_planes_calc_clip_distance(world_pos);
#endif
}
diff --git a/source/blender/draw/modes/shaders/object_empty_axes_vert.glsl b/source/blender/draw/modes/shaders/object_empty_axes_vert.glsl
index 7fd955343fc..43c8e313fc3 100644
--- a/source/blender/draw/modes/shaders/object_empty_axes_vert.glsl
+++ b/source/blender/draw/modes/shaders/object_empty_axes_vert.glsl
@@ -1,8 +1,5 @@
uniform mat4 ViewProjectionMatrix;
-#ifdef USE_WORLD_CLIP_PLANES
-uniform mat4 ModelMatrix;
-#endif
uniform vec3 screenVecs[3];
@@ -33,6 +30,6 @@ void main()
finalColor = vec4(color, 1.0);
#ifdef USE_WORLD_CLIP_PLANES
- world_clip_planes_calc_clip_distance((ModelMatrix * pos_4d).xyz);
+ world_clip_planes_calc_clip_distance(pos_4d.xyz);
#endif
}
diff --git a/source/blender/draw/modes/shaders/object_empty_image_frag.glsl b/source/blender/draw/modes/shaders/object_empty_image_frag.glsl
index 386d05636f9..deb82a8904e 100644
--- a/source/blender/draw/modes/shaders/object_empty_image_frag.glsl
+++ b/source/blender/draw/modes/shaders/object_empty_image_frag.glsl
@@ -14,12 +14,33 @@ uniform sampler2D image;
uniform int depthMode;
uniform bool useAlphaTest;
+float linearrgb_to_srgb(float c)
+{
+ if (c < 0.0031308) {
+ return (c < 0.0) ? 0.0 : c * 12.92;
+ }
+ else {
+ return 1.055 * pow(c, 1.0 / 2.4) - 0.055;
+ }
+}
+
+vec4 texture_read_as_srgb(sampler2D tex, vec2 co)
+{
+ /* By convention image textures return scene linear colors, but
+ * overlays still assume srgb. */
+ vec4 color = texture(tex, co);
+ color.r = linearrgb_to_srgb(color.r);
+ color.g = linearrgb_to_srgb(color.g);
+ color.b = linearrgb_to_srgb(color.b);
+ return color;
+}
+
void main()
{
#ifdef USE_WIRE
fragColor = finalColor;
#else
- vec4 tex_col = texture(image, texCoord_interp);
+ vec4 tex_col = texture_read_as_srgb(image, texCoord_interp);
fragColor = finalColor * tex_col;
if (useAlphaTest) {
diff --git a/source/blender/draw/modes/shaders/object_empty_image_vert.glsl b/source/blender/draw/modes/shaders/object_empty_image_vert.glsl
index 9694c63fef1..36e86290be7 100644
--- a/source/blender/draw/modes/shaders/object_empty_image_vert.glsl
+++ b/source/blender/draw/modes/shaders/object_empty_image_vert.glsl
@@ -1,7 +1,5 @@
-uniform mat4 ModelViewProjectionMatrix;
-uniform mat4 ModelMatrix;
-uniform float aspectX;
-uniform float aspectY;
+
+uniform vec2 aspect;
uniform float size;
uniform vec2 offset;
#ifdef USE_WIRE
@@ -21,8 +19,9 @@ out vec2 texCoord_interp;
void main()
{
- vec4 pos_4d = vec4((pos + offset) * (size * vec2(aspectX, aspectY)), 0.0, 1.0);
- gl_Position = ModelViewProjectionMatrix * pos_4d;
+ vec3 pos = vec3((pos + offset) * (size * aspect), 0.0);
+ vec3 world_pos = point_object_to_world(pos);
+ gl_Position = point_world_to_ndc(world_pos);
#ifdef USE_WIRE
gl_Position.z -= 1e-5;
finalColor = vec4(color, 1.0);
@@ -32,6 +31,6 @@ void main()
#endif
#ifdef USE_WORLD_CLIP_PLANES
- world_clip_planes_calc_clip_distance((ModelMatrix * pos_4d).xyz);
+ world_clip_planes_calc_clip_distance(world_pos);
#endif
}
diff --git a/source/blender/draw/modes/shaders/object_grid_frag.glsl b/source/blender/draw/modes/shaders/object_grid_frag.glsl
index df2cfe7be82..a20f12efd93 100644
--- a/source/blender/draw/modes/shaders/object_grid_frag.glsl
+++ b/source/blender/draw/modes/shaders/object_grid_frag.glsl
@@ -8,10 +8,7 @@ in vec3 local_pos;
out vec4 FragColor;
-uniform mat4 ProjectionMatrix;
-uniform vec3 cameraPos;
uniform vec3 planeAxes;
-uniform vec3 eye;
uniform vec4 gridSettings;
uniform float meshSize;
uniform float lineKernel = 0.0;
@@ -23,6 +20,8 @@ uniform sampler2D depthBuffer;
#define gridScale gridSettings.z
#define gridSubdiv gridSettings.w
+#define cameraPos (ViewMatrixInverse[3].xyz)
+
uniform int gridFlag;
#define AXIS_X (1 << 0)
@@ -109,7 +108,7 @@ void main()
dist = 1.0; /* avoid branch after */
if ((gridFlag & PLANE_XY) != 0) {
- float angle = 1.0 - abs(eye.z);
+ float angle = 1.0 - abs(ViewMatrixInverse[2].z);
dist = 1.0 + angle * 2.0;
angle *= angle;
fade *= 1.0 - angle * angle;
diff --git a/source/blender/draw/modes/shaders/object_grid_vert.glsl b/source/blender/draw/modes/shaders/object_grid_vert.glsl
index e8f4b089b47..d247967b03a 100644
--- a/source/blender/draw/modes/shaders/object_grid_vert.glsl
+++ b/source/blender/draw/modes/shaders/object_grid_vert.glsl
@@ -2,9 +2,6 @@
/* Infinite grid
* Clément Foucault */
-uniform mat4 ViewProjectionMatrix;
-uniform mat4 ProjectionMatrix;
-uniform vec3 cameraPos;
uniform vec3 planeAxes;
uniform vec4 gridSettings;
uniform float meshSize;
@@ -16,6 +13,8 @@ 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/modes/shaders/object_mball_handles_vert.glsl b/source/blender/draw/modes/shaders/object_mball_handles_vert.glsl
index c395ed01bca..9414309570b 100644
--- a/source/blender/draw/modes/shaders/object_mball_handles_vert.glsl
+++ b/source/blender/draw/modes/shaders/object_mball_handles_vert.glsl
@@ -4,7 +4,6 @@
* Note that if the stiffness is zero, it assumes the scale is directly multiplied by the radius */
uniform mat4 ViewProjectionMatrix;
-uniform mat4 ModelMatrix;
uniform vec3 screen_vecs[2];
/* ---- Instantiated Attrs ---- */
@@ -32,6 +31,6 @@ void main()
finalColor = vec4(color, 1.0);
#ifdef USE_WORLD_CLIP_PLANES
- world_clip_planes_calc_clip_distance((ModelMatrix * world_pos).xyz);
+ world_clip_planes_calc_clip_distance(world_pos.xyz);
#endif
}
diff --git a/source/blender/draw/modes/shaders/object_outline_prepass_geom.glsl b/source/blender/draw/modes/shaders/object_outline_prepass_geom.glsl
index 97d4bdacf07..5a3eb38fb6b 100644
--- a/source/blender/draw/modes/shaders/object_outline_prepass_geom.glsl
+++ b/source/blender/draw/modes/shaders/object_outline_prepass_geom.glsl
@@ -2,8 +2,6 @@
layout(lines_adjacency) in;
layout(line_strip, max_vertices = 2) out;
-uniform mat4 ProjectionMatrix;
-
in vec4 pPos[];
in vec3 vPos[];
diff --git a/source/blender/draw/modes/shaders/object_outline_prepass_vert.glsl b/source/blender/draw/modes/shaders/object_outline_prepass_vert.glsl
index 0b5f4733ebc..e34afe95b5e 100644
--- a/source/blender/draw/modes/shaders/object_outline_prepass_vert.glsl
+++ b/source/blender/draw/modes/shaders/object_outline_prepass_vert.glsl
@@ -1,8 +1,4 @@
-uniform mat4 ModelViewMatrix;
-uniform mat4 ModelViewProjectionMatrix;
-uniform mat4 ModelMatrix;
-
in vec3 pos;
out vec4 pPos;
@@ -10,12 +6,13 @@ out vec3 vPos;
void main()
{
- vPos = (ModelViewMatrix * vec4(pos, 1.0)).xyz;
- pPos = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ vec3 world_pos = point_object_to_world(pos);
+ vPos = point_world_to_view(world_pos);
+ pPos = point_world_to_ndc(world_pos);
/* Small bias to always be on top of the geom. */
pPos.z -= 1e-3;
#ifdef USE_WORLD_CLIP_PLANES
- world_clip_planes_calc_clip_distance((ModelMatrix * vec4(pos, 1.0)).xyz);
+ world_clip_planes_calc_clip_distance(world_pos);
#endif
}
diff --git a/source/blender/draw/modes/shaders/object_particle_dot_vert.glsl b/source/blender/draw/modes/shaders/object_particle_dot_vert.glsl
index e51b829adb5..f98ae9a9515 100644
--- a/source/blender/draw/modes/shaders/object_particle_dot_vert.glsl
+++ b/source/blender/draw/modes/shaders/object_particle_dot_vert.glsl
@@ -1,6 +1,4 @@
-uniform mat4 ModelViewMatrix;
-uniform mat4 ProjectionMatrix;
uniform float pixel_size;
uniform float size;
@@ -12,10 +10,13 @@ flat out float finalVal;
void main()
{
- gl_Position = ModelViewMatrix * vec4(pos, 1.0);
+ vec3 world_pos = point_object_to_world(pos);
- float psize = (ProjectionMatrix[3][3] == 0.0) ? (size / (-gl_Position.z * pixel_size)) :
- (size / pixel_size);
+ float view_z = dot(ViewMatrixInverse[2].xyz, world_pos - ViewMatrixInverse[3].xyz);
+
+ bool is_persp = (ProjectionMatrix[3][3] == 0.0);
+ float psize = (is_persp) ? (size / (-view_z * pixel_size)) : (size / pixel_size);
+ gl_Position = point_world_to_ndc(world_pos);
gl_PointSize = psize;
@@ -31,7 +32,5 @@ void main()
// convert to PointCoord units
radii /= psize;
- gl_Position = ProjectionMatrix * gl_Position;
-
finalVal = val;
}
diff --git a/source/blender/draw/modes/shaders/object_particle_prim_vert.glsl b/source/blender/draw/modes/shaders/object_particle_prim_vert.glsl
index 0f626626498..46aceb245f4 100644
--- a/source/blender/draw/modes/shaders/object_particle_prim_vert.glsl
+++ b/source/blender/draw/modes/shaders/object_particle_prim_vert.glsl
@@ -1,18 +1,17 @@
-uniform mat4 ModelViewProjectionMatrix;
-uniform mat4 ViewProjectionMatrix;
-uniform mat4 ModelViewMatrix;
-uniform mat4 ProjectionMatrix;
-uniform int screen_space;
+uniform bool screen_space;
uniform float draw_size;
uniform vec3 color;
uniform sampler1D ramp;
+/* ---- Instantiated Attrs ---- */
+in vec3 inst_pos;
+in int axis;
+
+/* ---- Per instance Attrs ---- */
in vec3 pos;
in vec4 rot;
in float val;
-in vec3 inst_pos;
-in int axis;
flat out vec4 finalColor;
@@ -24,8 +23,9 @@ vec3 rotate(vec3 vec, vec4 quat)
void main()
{
- if (screen_space == 1) {
- gl_Position = ModelViewMatrix * vec4(pos, 1.0) + vec4(inst_pos * draw_size, 0.0);
+ if (screen_space) {
+ gl_Position = ViewMatrix * (ModelMatrix * vec4(pos, 1.0));
+ gl_Position.xyz += inst_pos * draw_size;
gl_Position = ProjectionMatrix * gl_Position;
}
else {
@@ -35,7 +35,8 @@ void main()
size *= 2;
}
- gl_Position = ModelViewProjectionMatrix * vec4(pos + rotate(inst_pos * size, rot), 1.0);
+ vec3 pos_rot = pos + rotate(inst_pos * size, rot);
+ gl_Position = point_object_to_ndc(pos_rot);
}
#ifdef USE_AXIS
diff --git a/source/blender/draw/modes/shaders/overlay_face_orientation_vert.glsl b/source/blender/draw/modes/shaders/overlay_face_orientation_vert.glsl
index 659e3cbd5f5..2dd84c0a060 100644
--- a/source/blender/draw/modes/shaders/overlay_face_orientation_vert.glsl
+++ b/source/blender/draw/modes/shaders/overlay_face_orientation_vert.glsl
@@ -1,13 +1,12 @@
-uniform mat4 ModelViewProjectionMatrix;
-uniform mat4 ModelMatrix;
in vec3 pos;
void main()
{
- gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ vec3 world_pos = point_object_to_world(pos);
+ gl_Position = point_world_to_ndc(world_pos);
#ifdef USE_WORLD_CLIP_PLANES
- world_clip_planes_calc_clip_distance((ModelMatrix * vec4(pos, 1.0)).xyz);
+ world_clip_planes_calc_clip_distance(world_pos);
#endif
}
diff --git a/source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl b/source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl
index 96acba71233..23f64e6e49c 100644
--- a/source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl
+++ b/source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl
@@ -1,9 +1,4 @@
-uniform mat4 ProjectionMatrix;
-uniform mat4 ModelViewMatrix;
-uniform mat4 ModelMatrix;
-uniform mat3 NormalMatrix;
-
uniform float wireStepParam;
uniform float ofs;
@@ -11,57 +6,41 @@ in vec3 pos;
in vec3 nor;
in float wd; /* wiredata */
-#ifndef USE_SCULPT
float get_edge_sharpness(float wd)
{
+#ifndef USE_SCULPT
return ((wd == 0.0) ? -1.5 : wd) + wireStepParam;
-}
#else
-float get_edge_sharpness(float wd)
-{
return 1.0;
-}
#endif
+}
/* Geometry shader version */
#if defined(SELECT_EDGES) || defined(USE_GEOM)
out float facing_g;
out float edgeSharpness_g;
-void main()
-{
- edgeSharpness_g = get_edge_sharpness(wd);
-
- mat4 projmat = ProjectionMatrix;
- projmat[3][2] -= ofs;
-
- gl_Position = projmat * (ModelViewMatrix * vec4(pos, 1.0));
-
- facing_g = normalize(NormalMatrix * nor).z;
-
-# ifdef USE_WORLD_CLIP_PLANES
- world_clip_planes_calc_clip_distance((ModelMatrix * vec4(pos, 1.0)).xyz);
-# endif
-}
-
#else /* USE_GEOM */
out float facing;
flat out float edgeSharpness;
+# define facing_g facing
+# define edgeSharpness_g edgeSharpness
+
+#endif /* SELECT_EDGES */
void main()
{
- edgeSharpness = get_edge_sharpness(wd);
-
mat4 projmat = ProjectionMatrix;
projmat[3][2] -= ofs;
- gl_Position = projmat * (ModelViewMatrix * vec4(pos, 1.0));
+ vec4 wpos = ModelMatrix * vec4(pos, 1.0);
+ gl_Position = projmat * (ViewMatrix * wpos);
- facing = normalize(NormalMatrix * nor).z;
+ vec3 wnor = normalize(normal_object_to_world(nor));
+ facing_g = dot(wnor, ViewMatrixInverse[2].xyz);
+ edgeSharpness_g = get_edge_sharpness(wd);
-# ifdef USE_WORLD_CLIP_PLANES
- world_clip_planes_calc_clip_distance((ModelMatrix * vec4(pos, 1.0)).xyz);
-# endif
+#ifdef USE_WORLD_CLIP_PLANES
+ world_clip_planes_calc_clip_distance(wpos.xyz);
+#endif
}
-
-#endif /* SELECT_EDGES */
diff --git a/source/blender/draw/modes/shaders/paint_face_vert.glsl b/source/blender/draw/modes/shaders/paint_face_vert.glsl
index 59b88d8d3a7..4b5191ead07 100644
--- a/source/blender/draw/modes/shaders/paint_face_vert.glsl
+++ b/source/blender/draw/modes/shaders/paint_face_vert.glsl
@@ -1,20 +1,19 @@
-uniform mat4 ModelViewProjectionMatrix;
-uniform mat4 ModelMatrix;
-
in vec3 pos;
in vec4 nor; /* select flag on the 4th component */
void main()
{
- gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ vec3 world_pos = point_object_to_world(pos);
+ gl_Position = point_world_to_ndc(world_pos);
+
/* Don't draw faces that are selected. */
if (nor.w > 0.0) {
gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
}
else {
#ifdef USE_WORLD_CLIP_PLANES
- world_clip_planes_calc_clip_distance((ModelMatrix * vec4(pos, 1.0)).xyz);
+ world_clip_planes_calc_clip_distance(world_pos);
#endif
}
}
diff --git a/source/blender/draw/modes/shaders/paint_texture_frag.glsl b/source/blender/draw/modes/shaders/paint_texture_frag.glsl
index c7e110122c5..4a3c5cb430c 100644
--- a/source/blender/draw/modes/shaders/paint_texture_frag.glsl
+++ b/source/blender/draw/modes/shaders/paint_texture_frag.glsl
@@ -16,6 +16,27 @@ uniform vec3 maskingColor;
uniform bool maskingInvertStencil;
#endif
+float linearrgb_to_srgb(float c)
+{
+ if (c < 0.0031308) {
+ return (c < 0.0) ? 0.0 : c * 12.92;
+ }
+ else {
+ return 1.055 * pow(c, 1.0 / 2.4) - 0.055;
+ }
+}
+
+vec4 texture_read_as_srgb(sampler2D tex, vec2 co)
+{
+ /* By convention image textures return scene linear colors, but
+ * overlays still assume srgb. */
+ vec4 color = texture(tex, co);
+ color.r = linearrgb_to_srgb(color.r);
+ color.g = linearrgb_to_srgb(color.g);
+ color.b = linearrgb_to_srgb(color.b);
+ return color;
+}
+
void main()
{
vec2 uv = uv_interp;
@@ -24,7 +45,7 @@ void main()
uv = (floor(uv_interp * tex_size) + 0.5) / tex_size;
}
- vec4 color = texture(image, uv);
+ vec4 color = texture_read_as_srgb(image, uv);
color.a *= alpha;
#ifdef TEXTURE_PAINT_MASK
diff --git a/source/blender/draw/modes/shaders/paint_texture_vert.glsl b/source/blender/draw/modes/shaders/paint_texture_vert.glsl
index 03d933b9196..564f988348e 100644
--- a/source/blender/draw/modes/shaders/paint_texture_vert.glsl
+++ b/source/blender/draw/modes/shaders/paint_texture_vert.glsl
@@ -1,7 +1,4 @@
-uniform mat4 ModelViewProjectionMatrix;
-uniform mat4 ModelMatrix;
-
in vec2 u; /* active uv map */
in vec3 pos;
@@ -17,7 +14,8 @@ out vec2 masking_uv_interp;
void main()
{
- gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ vec3 world_pos = point_object_to_world(pos);
+ gl_Position = point_world_to_ndc(world_pos);
uv_interp = u;
@@ -26,6 +24,6 @@ void main()
#endif
#ifdef USE_WORLD_CLIP_PLANES
- world_clip_planes_calc_clip_distance((ModelMatrix * vec4(pos, 1.0)).xyz);
+ world_clip_planes_calc_clip_distance(world_pos);
#endif
}
diff --git a/source/blender/draw/modes/shaders/paint_vertex_vert.glsl b/source/blender/draw/modes/shaders/paint_vertex_vert.glsl
index 54f6d1a4aea..53e72cc8a20 100644
--- a/source/blender/draw/modes/shaders/paint_vertex_vert.glsl
+++ b/source/blender/draw/modes/shaders/paint_vertex_vert.glsl
@@ -1,7 +1,4 @@
-uniform mat4 ModelViewProjectionMatrix;
-uniform mat4 ModelMatrix;
-
in vec3 pos;
in vec3 c; /* active color */
@@ -17,11 +14,12 @@ vec3 srgb_to_linear_attr(vec3 c)
void main()
{
- gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ vec3 world_pos = point_object_to_world(pos);
+ gl_Position = point_world_to_ndc(world_pos);
finalColor = srgb_to_linear_attr(c);
#ifdef USE_WORLD_CLIP_PLANES
- world_clip_planes_calc_clip_distance((ModelMatrix * vec4(pos, 1.0)).xyz);
+ world_clip_planes_calc_clip_distance(world_pos);
#endif
}
diff --git a/source/blender/draw/modes/shaders/paint_weight_vert.glsl b/source/blender/draw/modes/shaders/paint_weight_vert.glsl
index e95b116df79..330cc7d19f4 100644
--- a/source/blender/draw/modes/shaders/paint_weight_vert.glsl
+++ b/source/blender/draw/modes/shaders/paint_weight_vert.glsl
@@ -1,7 +1,4 @@
-uniform mat4 ModelViewProjectionMatrix;
-uniform mat4 ModelMatrix;
-
in float weight;
in vec3 pos;
@@ -9,12 +6,13 @@ out vec2 weight_interp; /* (weight, alert) */
void main()
{
- gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ vec3 world_pos = point_object_to_world(pos);
+ gl_Position = point_world_to_ndc(world_pos);
/* Separate actual weight and alerts for independent interpolation */
weight_interp = max(vec2(weight, -weight), 0.0);
#ifdef USE_WORLD_CLIP_PLANES
- world_clip_planes_calc_clip_distance((ModelMatrix * vec4(pos, 1.0)).xyz);
+ world_clip_planes_calc_clip_distance(world_pos);
#endif
}
diff --git a/source/blender/draw/modes/shaders/paint_wire_vert.glsl b/source/blender/draw/modes/shaders/paint_wire_vert.glsl
index a163fd7e8b3..10bf8729f47 100644
--- a/source/blender/draw/modes/shaders/paint_wire_vert.glsl
+++ b/source/blender/draw/modes/shaders/paint_wire_vert.glsl
@@ -1,7 +1,4 @@
-uniform mat4 ModelViewProjectionMatrix;
-uniform mat4 ModelMatrix;
-
in vec3 pos;
in vec4 nor; /* flag stored in w */
@@ -16,7 +13,8 @@ void main()
bool is_select = false;
bool is_hidden = false;
#endif
- gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ vec3 world_pos = point_object_to_world(pos);
+ gl_Position = point_world_to_ndc(world_pos);
/* Add offset in Z to avoid zfighting and render selected wires on top. */
/* TODO scale this bias using znear and zfar range. */
gl_Position.z -= (is_select ? 2e-4 : 1e-4);
@@ -46,6 +44,6 @@ void main()
finalColor.a = nor.w;
#ifdef USE_WORLD_CLIP_PLANES
- world_clip_planes_calc_clip_distance((ModelMatrix * vec4(pos, 1.0)).xyz);
+ world_clip_planes_calc_clip_distance(world_pos);
#endif
}
diff --git a/source/blender/draw/modes/shaders/particle_strand_frag.glsl b/source/blender/draw/modes/shaders/particle_strand_frag.glsl
index 578a4935b37..49d843b7e0e 100644
--- a/source/blender/draw/modes/shaders/particle_strand_frag.glsl
+++ b/source/blender/draw/modes/shaders/particle_strand_frag.glsl
@@ -1,4 +1,3 @@
-uniform mat4 ModelViewProjectionMatrix;
in vec4 finalColor;
#ifdef USE_POINTS
diff --git a/source/blender/draw/modes/shaders/particle_strand_vert.glsl b/source/blender/draw/modes/shaders/particle_strand_vert.glsl
index 6dac6d6b980..c3f8fb89c17 100644
--- a/source/blender/draw/modes/shaders/particle_strand_vert.glsl
+++ b/source/blender/draw/modes/shaders/particle_strand_vert.glsl
@@ -1,6 +1,4 @@
-uniform mat4 ModelViewProjectionMatrix;
-
in vec3 pos;
in float color;
@@ -47,7 +45,8 @@ vec3 weight_to_rgb(float weight)
void main()
{
- gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ vec3 world_pos = point_object_to_world(pos);
+ gl_Position = point_world_to_ndc(world_pos);
#ifdef USE_WEIGHT
finalColor = vec4(weight_to_rgb(color), 1.0);
diff --git a/source/blender/draw/modes/shaders/sculpt_mask_vert.glsl b/source/blender/draw/modes/shaders/sculpt_mask_vert.glsl
index e5e34fee57e..7b026836690 100644
--- a/source/blender/draw/modes/shaders/sculpt_mask_vert.glsl
+++ b/source/blender/draw/modes/shaders/sculpt_mask_vert.glsl
@@ -1,5 +1,4 @@
-uniform mat4 ModelViewProjectionMatrix;
uniform float maskOpacity;
in vec3 pos;
@@ -9,7 +8,8 @@ out vec4 finalColor;
void main()
{
- gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ vec3 world_pos = point_object_to_world(pos);
+ gl_Position = point_world_to_ndc(world_pos);
float mask = 1.0 - (msk * maskOpacity);
finalColor = vec4(mask, mask, mask, 1.0);
diff --git a/source/blender/draw/modes/shaders/volume_velocity_vert.glsl b/source/blender/draw/modes/shaders/volume_velocity_vert.glsl
index 32207afa0b1..e96a789b8b1 100644
--- a/source/blender/draw/modes/shaders/volume_velocity_vert.glsl
+++ b/source/blender/draw/modes/shaders/volume_velocity_vert.glsl
@@ -1,6 +1,4 @@
-uniform mat4 ModelViewProjectionMatrix;
-
uniform sampler3D velocityX;
uniform sampler3D velocityY;
uniform sampler3D velocityZ;
@@ -109,5 +107,6 @@ void main()
pos += (((gl_VertexID % 2) == 1) ? velocity : vec3(0.0)) * displaySize * voxel_size;
#endif
- gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ vec3 world_pos = point_object_to_world(pos);
+ gl_Position = point_world_to_ndc(world_pos);
}
diff --git a/source/blender/editors/animation/CMakeLists.txt b/source/blender/editors/animation/CMakeLists.txt
index 978bd772b6f..ce6778a1ff9 100644
--- a/source/blender/editors/animation/CMakeLists.txt
+++ b/source/blender/editors/animation/CMakeLists.txt
@@ -51,6 +51,7 @@ set(SRC
keyframes_general.c
keyframing.c
keyingsets.c
+ time_scrub_ui.c
anim_intern.h
)
diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c
index 6d1ee08d5e9..00025112835 100644
--- a/source/blender/editors/animation/anim_channels_defines.c
+++ b/source/blender/editors/animation/anim_channels_defines.c
@@ -485,16 +485,10 @@ static void acf_summary_backdrop(bAnimContext *ac, bAnimListElem *ale, float ymi
static void acf_summary_name(bAnimListElem *UNUSED(ale), char *name)
{
if (name) {
- BLI_strncpy(name, IFACE_("Dope Sheet Summary"), ANIM_CHAN_NAME_SIZE);
+ BLI_strncpy(name, IFACE_("Summary"), ANIM_CHAN_NAME_SIZE);
}
}
-// FIXME: this is really a temp icon I think
-static int acf_summary_icon(bAnimListElem *UNUSED(ale))
-{
- return ICON_BORDERMOVE;
-}
-
/* check if some setting exists for this channel */
static bool acf_summary_setting_valid(bAnimContext *UNUSED(ac),
bAnimListElem *UNUSED(ale),
@@ -557,7 +551,7 @@ static bAnimChannelType ACF_SUMMARY = {
acf_summary_name, /* name */
NULL, /* name prop */
- acf_summary_icon, /* icon */
+ NULL, /* icon */
acf_summary_setting_valid, /* has setting */
acf_summary_setting_flag, /* flag for setting */
diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c
index adc6ec3f6be..9e09fc485a6 100644
--- a/source/blender/editors/animation/anim_channels_edit.c
+++ b/source/blender/editors/animation/anim_channels_edit.c
@@ -55,6 +55,7 @@
#include "DEG_depsgraph_build.h"
#include "UI_view2d.h"
+#include "UI_interface.h"
#include "ED_anim_api.h"
#include "ED_armature.h"
@@ -2542,7 +2543,7 @@ static void box_select_anim_channels(bAnimContext *ac, rcti *rect, short selectm
float ymax;
if (ac->datatype == ANIMCONT_NLA) {
- ymax = NLACHANNEL_FIRST_TOP(snla);
+ ymax = NLACHANNEL_FIRST_TOP(ac);
}
else {
ymax = ACHANNEL_FIRST_TOP(ac);
@@ -2735,7 +2736,7 @@ static int animchannels_channel_get(bAnimContext *ac, const int mval[2])
UI_view2d_listview_view_to_cell(NLACHANNEL_NAMEWIDTH,
NLACHANNEL_STEP(snla),
0,
- NLACHANNEL_FIRST_TOP(snla),
+ NLACHANNEL_FIRST_TOP(ac),
x,
y,
NULL,
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index b94d0e3ada7..a228d819286 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -1823,7 +1823,7 @@ static size_t animdata_filter_gpencil(bAnimContext *ac,
}
/* outliner restrict-flag */
- if (ob->restrictflag & OB_RESTRICT_VIEW) {
+ if (ob->restrictflag & OB_RESTRICT_VIEWPORT) {
continue;
}
}
@@ -3022,7 +3022,7 @@ static bool animdata_filter_base_is_ok(bDopeSheet *ads, Base *base, int filter_m
}
/* outliner restrict-flag */
- if (ob->restrictflag & OB_RESTRICT_VIEW) {
+ if (ob->restrictflag & OB_RESTRICT_VIEWPORT) {
return false;
}
}
diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c
index 66cdae07a36..876bc9ae3e4 100644
--- a/source/blender/editors/animation/anim_markers.c
+++ b/source/blender/editors/animation/anim_markers.c
@@ -481,7 +481,9 @@ static void draw_markers_background(rctf *rect)
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- const unsigned char shade[4] = {0, 0, 0, 16};
+ unsigned char shade[4];
+ UI_GetThemeColor4ubv(TH_SCRUBBING_BACKGROUND, shade);
+
immUniformColor4ubv(shade);
GPU_blend(true);
diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c
index 97ba7132c3d..45bb8f3b11e 100644
--- a/source/blender/editors/animation/anim_ops.c
+++ b/source/blender/editors/animation/anim_ops.c
@@ -52,9 +52,6 @@
#include "ED_sequencer.h"
#include "ED_util.h"
-#include "DEG_depsgraph.h"
-#include "DEG_depsgraph_query.h"
-
#include "anim_intern.h"
/* ********************** frame change operator ***************************/
@@ -91,6 +88,7 @@ static bool change_frame_poll(bContext *C)
/* Set the new frame number */
static void change_frame_apply(bContext *C, wmOperator *op)
{
+ Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
float frame = RNA_float_get(op->ptr, "frame");
bool do_snap = RNA_boolean_get(op->ptr, "snap");
@@ -116,7 +114,7 @@ static void change_frame_apply(bContext *C, wmOperator *op)
FRAMENUMBER_MIN_CLAMP(CFRA);
/* do updates */
- BKE_sound_update_and_seek(CTX_data_main(C), CTX_data_depsgraph(C));
+ BKE_sound_seek_scene(bmain, scene);
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
}
diff --git a/source/blender/editors/animation/drivers.c b/source/blender/editors/animation/drivers.c
index 2a8702802aa..fe079eb59a0 100644
--- a/source/blender/editors/animation/drivers.c
+++ b/source/blender/editors/animation/drivers.c
@@ -1249,7 +1249,8 @@ static int paste_driver_button_exec(bContext *C, wmOperator *op)
UI_context_update_anim_flag(C);
DEG_relations_tag_update(CTX_data_main(C));
- DEG_id_tag_update(ptr.id.data, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
+
+ DEG_id_tag_update(ptr.id.data, ID_RECALC_ANIMATION);
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME_PROP, NULL); // XXX
diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c
index a0433b49b16..97d85d25d66 100644
--- a/source/blender/editors/animation/keyframing.c
+++ b/source/blender/editors/animation/keyframing.c
@@ -1307,8 +1307,8 @@ static bool insert_keyframe_fcurve_value(Main *bmain,
* - if we're replacing keyframes only, DO NOT create new F-Curves if they do not exist yet
* but still try to get the F-Curve if it exists...
*/
- FCurve *fcu = verify_fcurve(
- bmain, act, group, ptr, rna_path, array_index, (flag & INSERTKEY_REPLACE) == 0);
+ bool can_create_curve = (flag & (INSERTKEY_REPLACE | INSERTKEY_AVAILABLE)) == 0;
+ FCurve *fcu = verify_fcurve(bmain, act, group, ptr, rna_path, array_index, can_create_curve);
/* we may not have a F-Curve when we're replacing only... */
if (fcu) {
@@ -1432,7 +1432,7 @@ short insert_keyframe(Main *bmain,
/* Key the entire array. */
if (array_index == -1 || force_all) {
/* In force mode, if any of the curves succeeds, drop the replace mode and restart. */
- if (force_all && (flag & INSERTKEY_REPLACE) != 0) {
+ if (force_all && (flag & (INSERTKEY_REPLACE | INSERTKEY_AVAILABLE)) != 0) {
int exclude = -1;
for (array_index = 0; array_index < value_count; array_index++) {
@@ -1455,7 +1455,7 @@ short insert_keyframe(Main *bmain,
}
if (exclude != -1) {
- flag &= ~INSERTKEY_REPLACE;
+ flag &= ~(INSERTKEY_REPLACE | INSERTKEY_AVAILABLE);
for (array_index = 0; array_index < value_count; array_index++) {
if (array_index != exclude) {
diff --git a/source/blender/editors/animation/time_scrub_ui.c b/source/blender/editors/animation/time_scrub_ui.c
new file mode 100644
index 00000000000..37e7eab74d4
--- /dev/null
+++ b/source/blender/editors/animation/time_scrub_ui.c
@@ -0,0 +1,214 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2019 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup edanimation
+ */
+
+#include "BKE_context.h"
+
+#include "GPU_immediate.h"
+#include "GPU_matrix.h"
+#include "GPU_state.h"
+
+#include "ED_time_scrub_ui.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "UI_interface.h"
+#include "UI_interface_icons.h"
+#include "UI_view2d.h"
+#include "UI_resources.h"
+
+#include "DNA_scene_types.h"
+
+#include "BLI_rect.h"
+#include "BLI_math.h"
+#include "BLI_string.h"
+#include "BLI_timecode.h"
+
+#include "RNA_access.h"
+
+static void get_scrubbing_region_rect(const ARegion *ar, rcti *rect)
+{
+ rect->xmin = 0;
+ rect->xmax = ar->winx;
+ rect->ymax = ar->winy;
+ rect->ymin = rect->ymax - UI_SCRUBBING_MARGIN_Y;
+}
+
+static int get_centered_text_y(const rcti *rect)
+{
+ return BLI_rcti_cent_y(rect) - UI_DPI_FAC * 4;
+}
+
+static void draw_background(const rcti *rect)
+{
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ immUniformThemeColor(TH_SCRUBBING_BACKGROUND);
+
+ GPU_blend(true);
+ GPU_blend_set_func_separate(
+ GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+
+ immRectf(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
+
+ GPU_blend(false);
+
+ immUnbindProgram();
+}
+
+static void get_current_time_str(
+ const Scene *scene, bool display_seconds, int frame, uint max_len, char *r_str)
+{
+ if (display_seconds) {
+ BLI_timecode_string_from_time(r_str, max_len, 0, FRA2TIME(frame), FPS, U.timecode_style);
+ }
+ else {
+ BLI_snprintf(r_str, max_len, "%d", frame);
+ }
+}
+
+static void draw_current_frame(const Scene *scene,
+ bool display_seconds,
+ const View2D *v2d,
+ const rcti *scrubbing_region_rect,
+ int current_frame)
+{
+ const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
+ const unsigned char color[] = {255, 255, 255, 255};
+ int frame_x = UI_view2d_view_to_region_x(v2d, current_frame);
+
+ char frame_str[64];
+ get_current_time_str(scene, display_seconds, current_frame, sizeof(frame_str), frame_str);
+ float text_width = UI_fontstyle_string_width(fstyle, frame_str);
+ float box_width = MAX2(text_width + 8 * UI_DPI_FAC, 24 * UI_DPI_FAC);
+ float box_padding = 3 * UI_DPI_FAC;
+
+ float bg_color[4];
+ UI_GetThemeColorShade4fv(TH_CFRAME, -5, bg_color);
+
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
+
+ UI_draw_roundbox_3fvAlpha(true,
+ frame_x - box_width / 2 + U.pixelsize / 2,
+ scrubbing_region_rect->ymin + box_padding,
+ frame_x + box_width / 2 + U.pixelsize / 2,
+ scrubbing_region_rect->ymax - box_padding,
+ 4 * UI_DPI_FAC,
+ bg_color,
+ 1.0f);
+
+ UI_GetThemeColorShade4fv(TH_CFRAME, 5, bg_color);
+ UI_draw_roundbox_aa(false,
+ frame_x - box_width / 2 + U.pixelsize / 2,
+ scrubbing_region_rect->ymin + box_padding,
+ frame_x + box_width / 2 + U.pixelsize / 2,
+ scrubbing_region_rect->ymax - box_padding,
+ 4 * UI_DPI_FAC,
+ bg_color);
+
+ UI_fontstyle_draw_simple(fstyle,
+ frame_x - text_width / 2 + U.pixelsize / 2,
+ get_centered_text_y(scrubbing_region_rect),
+ frame_str,
+ color);
+}
+
+void ED_scrubbing_draw(const ARegion *ar,
+ const Scene *scene,
+ bool display_seconds,
+ bool discrete_frames)
+{
+ const View2D *v2d = &ar->v2d;
+
+ GPU_matrix_push_projection();
+ wmOrtho2_region_pixelspace(ar);
+
+ rcti scrubbing_region_rect;
+ get_scrubbing_region_rect(ar, &scrubbing_region_rect);
+
+ draw_background(&scrubbing_region_rect);
+
+ rcti numbers_rect = scrubbing_region_rect;
+ numbers_rect.ymin = get_centered_text_y(&scrubbing_region_rect) - 4 * UI_DPI_FAC;
+ if (discrete_frames) {
+ UI_view2d_draw_scale_x__discrete_frames_or_seconds(
+ ar, v2d, &numbers_rect, scene, display_seconds, TH_TEXT);
+ }
+ else {
+ UI_view2d_draw_scale_x__frames_or_seconds(
+ ar, v2d, &numbers_rect, scene, display_seconds, TH_TEXT);
+ }
+
+ draw_current_frame(scene, display_seconds, v2d, &scrubbing_region_rect, scene->r.cfra);
+
+ GPU_matrix_pop_projection();
+}
+
+bool ED_event_in_scrubbing_region(const ARegion *ar, const wmEvent *event)
+{
+ rcti rect = ar->winrct;
+ rect.ymin = rect.ymax - UI_SCRUBBING_MARGIN_Y;
+ return BLI_rcti_isect_pt(&rect, event->x, event->y);
+}
+
+void ED_channel_search_draw(const bContext *C, ARegion *ar, bDopeSheet *dopesheet)
+{
+ GPU_matrix_push_projection();
+ wmOrtho2_region_pixelspace(ar);
+
+ rcti rect;
+ rect.xmin = 0;
+ rect.xmax = ceilf(ar->sizex * UI_DPI_FAC);
+ rect.ymin = ar->sizey * UI_DPI_FAC - UI_SCRUBBING_MARGIN_Y;
+ rect.ymax = ceilf(ar->sizey * UI_DPI_FAC);
+
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformThemeColor(TH_BACK);
+ immRectf(pos, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
+ immUnbindProgram();
+
+ uiBlock *block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
+
+ PointerRNA ptr;
+ RNA_pointer_create(&CTX_wm_screen(C)->id, &RNA_DopeSheet, dopesheet, &ptr);
+ PropertyRNA *prop = RNA_struct_find_property(&ptr, "filter_text");
+
+ int padding = 2 * UI_DPI_FAC;
+ uiDefAutoButR(block,
+ &ptr,
+ prop,
+ -1,
+ "",
+ ICON_NONE,
+ rect.xmin + padding,
+ rect.ymin + padding,
+ BLI_rcti_size_x(&rect) - 2 * padding,
+ BLI_rcti_size_y(&rect) - 2 * padding);
+
+ UI_block_end(C, block);
+ UI_block_draw(C, block);
+
+ GPU_matrix_pop_projection();
+}
diff --git a/source/blender/editors/armature/armature_intern.h b/source/blender/editors/armature/armature_intern.h
index 6c2d9fe8f42..569eb7e2e04 100644
--- a/source/blender/editors/armature/armature_intern.h
+++ b/source/blender/editors/armature/armature_intern.h
@@ -210,6 +210,8 @@ void POSELIB_OT_apply_pose(struct wmOperatorType *ot);
void POSE_OT_push(struct wmOperatorType *ot);
void POSE_OT_relax(struct wmOperatorType *ot);
+void POSE_OT_push_rest(struct wmOperatorType *ot);
+void POSE_OT_relax_rest(struct wmOperatorType *ot);
void POSE_OT_breakdown(struct wmOperatorType *ot);
void POSE_OT_propagate(struct wmOperatorType *ot);
diff --git a/source/blender/editors/armature/armature_naming.c b/source/blender/editors/armature/armature_naming.c
index 083967d5d41..9a1582679a4 100644
--- a/source/blender/editors/armature/armature_naming.c
+++ b/source/blender/editors/armature/armature_naming.c
@@ -180,7 +180,17 @@ void ED_armature_bone_rename(Main *bmain,
if (bone) {
unique_bone_name(arm, newname);
+
+ if (arm->bonehash) {
+ BLI_assert(BLI_ghash_haskey(arm->bonehash, bone->name));
+ BLI_ghash_remove(arm->bonehash, bone->name, NULL, NULL);
+ }
+
BLI_strncpy(bone->name, newname, MAXBONENAME);
+
+ if (arm->bonehash) {
+ BLI_ghash_insert(arm->bonehash, bone->name, bone);
+ }
}
else {
return;
diff --git a/source/blender/editors/armature/armature_ops.c b/source/blender/editors/armature/armature_ops.c
index b53ae813f10..a29d0f5f158 100644
--- a/source/blender/editors/armature/armature_ops.c
+++ b/source/blender/editors/armature/armature_ops.c
@@ -146,6 +146,8 @@ void ED_operatortypes_armature(void)
/* POSE SLIDING */
WM_operatortype_append(POSE_OT_push);
WM_operatortype_append(POSE_OT_relax);
+ WM_operatortype_append(POSE_OT_push_rest);
+ WM_operatortype_append(POSE_OT_relax_rest);
WM_operatortype_append(POSE_OT_breakdown);
}
diff --git a/source/blender/editors/armature/armature_relations.c b/source/blender/editors/armature/armature_relations.c
index b2ca1d84520..2c61818d902 100644
--- a/source/blender/editors/armature/armature_relations.c
+++ b/source/blender/editors/armature/armature_relations.c
@@ -66,10 +66,16 @@
/* *************************************** Join *************************************** */
/* NOTE: no operator define here as this is exported to the Object-level operator */
-static void joined_armature_fix_links_constraints(
- Object *tarArm, Object *srcArm, bPoseChannel *pchan, EditBone *curbone, ListBase *lb)
+static void joined_armature_fix_links_constraints(Main *bmain,
+ Object *ob,
+ Object *tarArm,
+ Object *srcArm,
+ bPoseChannel *pchan,
+ EditBone *curbone,
+ ListBase *lb)
{
bConstraint *con;
+ bool changed = false;
for (con = lb->first; con; con = con->next) {
const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
@@ -84,10 +90,12 @@ static void joined_armature_fix_links_constraints(
if (ct->tar == srcArm) {
if (ct->subtarget[0] == '\0') {
ct->tar = tarArm;
+ changed = true;
}
else if (STREQ(ct->subtarget, pchan->name)) {
ct->tar = tarArm;
BLI_strncpy(ct->subtarget, curbone->name, sizeof(ct->subtarget));
+ changed = true;
}
}
}
@@ -104,13 +112,21 @@ static void joined_armature_fix_links_constraints(
if (data->act) {
BKE_action_fix_paths_rename(
&tarArm->id, data->act, "pose.bones[", pchan->name, curbone->name, 0, 0, false);
+
+ DEG_id_tag_update_ex(bmain, &data->act->id, ID_RECALC_COPY_ON_WRITE);
}
}
}
+
+ if (changed) {
+ DEG_id_tag_update_ex(bmain, &ob->id, ID_RECALC_COPY_ON_WRITE);
+ }
}
/* userdata for joined_armature_fix_animdata_cb() */
typedef struct tJoinArmature_AdtFixData {
+ Main *bmain;
+
Object *srcArm;
Object *tarArm;
@@ -129,6 +145,7 @@ static void joined_armature_fix_animdata_cb(ID *id, FCurve *fcu, void *user_data
ID *dst_id = &afd->tarArm->id;
GHashIterator gh_iter;
+ bool changed = false;
/* Fix paths - If this is the target object, it will have some "dirty" paths */
if ((id == src_id) && strstr(fcu->rna_path, "pose.bones[")) {
@@ -142,6 +159,8 @@ static void joined_armature_fix_animdata_cb(ID *id, FCurve *fcu, void *user_data
fcu->rna_path = BKE_animsys_fix_rna_path_rename(
id, fcu->rna_path, "pose.bones", old_name, new_name, 0, 0, false);
+ changed = true;
+
/* we don't want to apply a second remapping on this driver now,
* so stop trying names, but keep fixing drivers
*/
@@ -163,6 +182,8 @@ static void joined_armature_fix_animdata_cb(ID *id, FCurve *fcu, void *user_data
if (dtar->id == src_id) {
dtar->id = dst_id;
+ changed = true;
+
/* also check on the subtarget...
* XXX: We duplicate the logic from drivers_path_rename_fix() here, with our own
* little twists so that we know that it isn't going to clobber the wrong data
@@ -193,6 +214,10 @@ static void joined_armature_fix_animdata_cb(ID *id, FCurve *fcu, void *user_data
DRIVER_TARGETS_LOOPER_END;
}
}
+
+ if (changed) {
+ DEG_id_tag_update_ex(afd->bmain, id, ID_RECALC_COPY_ON_WRITE);
+ }
}
/* Helper function for armature joining - link fixing */
@@ -210,13 +235,14 @@ static void joined_armature_fix_links(
pose = ob->pose;
for (pchant = pose->chanbase.first; pchant; pchant = pchant->next) {
joined_armature_fix_links_constraints(
- tarArm, srcArm, pchan, curbone, &pchant->constraints);
+ bmain, ob, tarArm, srcArm, pchan, curbone, &pchant->constraints);
}
}
/* fix object-level constraints */
if (ob != srcArm) {
- joined_armature_fix_links_constraints(tarArm, srcArm, pchan, curbone, &ob->constraints);
+ joined_armature_fix_links_constraints(
+ bmain, ob, tarArm, srcArm, pchan, curbone, &ob->constraints);
}
/* See if an object is parented to this armature */
@@ -231,6 +257,8 @@ static void joined_armature_fix_links(
/* make tar armature be new parent */
ob->parent = tarArm;
+
+ DEG_id_tag_update_ex(bmain, &ob->id, ID_RECALC_COPY_ON_WRITE);
}
}
}
@@ -286,6 +314,7 @@ int join_armature_exec(bContext *C, wmOperator *op)
BLI_assert(ob_active->data != ob_iter->data);
/* init callback data for fixing up AnimData links later */
+ afd.bmain = bmain;
afd.srcArm = ob_iter;
afd.tarArm = ob_active;
afd.names_map = BLI_ghash_str_new("join_armature_adt_fix");
diff --git a/source/blender/editors/armature/armature_select.c b/source/blender/editors/armature/armature_select.c
index fbbb68d2003..23ddf77e63d 100644
--- a/source/blender/editors/armature/armature_select.c
+++ b/source/blender/editors/armature/armature_select.c
@@ -70,7 +70,7 @@ Base *ED_armature_base_and_ebone_from_select_buffer(Base **bases,
EditBone *ebone = NULL;
/* TODO(campbell): optimize, eg: sort & binary search. */
for (uint base_index = 0; base_index < bases_len; base_index++) {
- if (bases[base_index]->object->select_id == hit_object) {
+ if (bases[base_index]->object->runtime.select_id == hit_object) {
base = bases[base_index];
break;
}
@@ -94,7 +94,7 @@ Object *ED_armature_object_and_ebone_from_select_buffer(Object **objects,
EditBone *ebone = NULL;
/* TODO(campbell): optimize, eg: sort & binary search. */
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- if (objects[ob_index]->select_id == hit_object) {
+ if (objects[ob_index]->runtime.select_id == hit_object) {
ob = objects[ob_index];
break;
}
@@ -118,7 +118,7 @@ Base *ED_armature_base_and_bone_from_select_buffer(Base **bases,
Bone *bone = NULL;
/* TODO(campbell): optimize, eg: sort & binary search. */
for (uint base_index = 0; base_index < bases_len; base_index++) {
- if (bases[base_index]->object->select_id == hit_object) {
+ if (bases[base_index]->object->runtime.select_id == hit_object) {
base = bases[base_index];
break;
}
@@ -300,6 +300,7 @@ static int armature_select_linked_invoke(bContext *C, wmOperator *op, const wmEv
const bool sel = !RNA_boolean_get(op->ptr, "deselect");
view3d_operator_needs_opengl(C);
+ BKE_object_update_select_id(CTX_data_main(C));
Base *base = NULL;
bone = get_nearest_bone(C, event->mval, true, &base);
@@ -1817,6 +1818,7 @@ static int armature_shortest_path_pick_invoke(bContext *C, wmOperator *op, const
Base *base_dst = NULL;
view3d_operator_needs_opengl(C);
+ BKE_object_update_select_id(CTX_data_main(C));
ebone_src = arm->act_edbone;
ebone_dst = get_nearest_bone(C, event->mval, false, &base_dst);
diff --git a/source/blender/editors/armature/armature_utils.c b/source/blender/editors/armature/armature_utils.c
index b23081cd6fa..20dc7b6c826 100644
--- a/source/blender/editors/armature/armature_utils.c
+++ b/source/blender/editors/armature/armature_utils.c
@@ -650,6 +650,7 @@ void ED_armature_from_edit(Main *bmain, bArmature *arm)
Object *obt;
/* armature bones */
+ BKE_armature_bone_hash_free(arm);
BKE_armature_bonelist_free(&arm->bonebase);
arm->act_bone = NULL;
@@ -754,6 +755,8 @@ void ED_armature_from_edit(Main *bmain, bArmature *arm)
/* Finalize definition of restpose data (roll, bone_mat, arm_mat, head/tail...). */
armature_finalize_restpose(&arm->bonebase, arm->edbo);
+ BKE_armature_bone_hash_make(arm);
+
/* so all users of this armature should get rebuilt */
for (obt = bmain->objects.first; obt; obt = obt->id.next) {
if (obt->data == arm) {
diff --git a/source/blender/editors/armature/pose_slide.c b/source/blender/editors/armature/pose_slide.c
index d683c599f7b..9bc204c9e3b 100644
--- a/source/blender/editors/armature/pose_slide.c
+++ b/source/blender/editors/armature/pose_slide.c
@@ -134,6 +134,8 @@ typedef enum ePoseSlide_Modes {
POSESLIDE_PUSH = 0, /* exaggerate the pose... */
POSESLIDE_RELAX, /* soften the pose... */
POSESLIDE_BREAKDOWN, /* slide between the endpoint poses, finding a 'soft' spot */
+ POSESLIDE_PUSH_REST,
+ POSESLIDE_RELAX_REST,
} ePoseSlide_Modes;
/* Transforms/Channels to Affect */
@@ -627,6 +629,103 @@ static void pose_slide_apply_quat(tPoseSlideOp *pso, tPChanFCurveLink *pfl)
MEM_freeN(path);
}
+static void pose_slide_rest_pose_apply_vec3(tPoseSlideOp *pso, float vec[3], float default_value)
+{
+ /* We only slide to the rest pose. So only use the default rest pose value */
+ const int lock = pso->axislock;
+ for (int idx = 0; idx < 3; idx++) {
+ if ((lock == 0) || ((lock & PS_LOCK_X) && (idx == 0)) || ((lock & PS_LOCK_Y) && (idx == 1)) ||
+ ((lock & PS_LOCK_Z) && (idx == 2))) {
+ float diff_val = default_value - vec[idx];
+ if (pso->mode == POSESLIDE_RELAX_REST) {
+ vec[idx] += pso->percentage * diff_val;
+ }
+ else {
+ /* Push */
+ vec[idx] -= pso->percentage * diff_val;
+ }
+ }
+ }
+}
+
+static void pose_slide_rest_pose_apply_other_rot(tPoseSlideOp *pso, float vec[4], bool quat)
+{
+ /* We only slide to the rest pose. So only use the default rest pose value */
+ float default_values[] = {1.0f, 0.0f, 0.0f, 0.0f};
+ if (!quat) {
+ /* Axis Angle */
+ default_values[0] = 0.0f;
+ default_values[2] = 1.0f;
+ }
+ for (int idx = 0; idx < 4; idx++) {
+ float diff_val = default_values[idx] - vec[idx];
+ if (pso->mode == POSESLIDE_RELAX_REST) {
+ vec[idx] += pso->percentage * diff_val;
+ }
+ else {
+ /* Push */
+ vec[idx] -= pso->percentage * diff_val;
+ }
+ }
+}
+
+/* apply() - perform the pose sliding between the current pose and the rest pose */
+static void pose_slide_rest_pose_apply(bContext *C, tPoseSlideOp *pso)
+{
+ tPChanFCurveLink *pfl;
+
+ /* for each link, handle each set of transforms */
+ for (pfl = pso->pfLinks.first; pfl; pfl = pfl->next) {
+ /* valid transforms for each PoseChannel should have been noted already
+ * - sliding the pose should be a straightforward exercise for location+rotation,
+ * but rotations get more complicated since we may want to use quaternion blending
+ * for quaternions instead...
+ */
+ bPoseChannel *pchan = pfl->pchan;
+
+ if (ELEM(pso->channels, PS_TFM_ALL, PS_TFM_LOC) && (pchan->flag & POSE_LOC)) {
+ /* calculate these for the 'location' vector, and use location curves */
+ pose_slide_rest_pose_apply_vec3(pso, pchan->loc, 0.0f);
+ }
+
+ if (ELEM(pso->channels, PS_TFM_ALL, PS_TFM_SIZE) && (pchan->flag & POSE_SIZE)) {
+ /* calculate these for the 'scale' vector, and use scale curves */
+ pose_slide_rest_pose_apply_vec3(pso, pchan->size, 1.0f);
+ }
+
+ if (ELEM(pso->channels, PS_TFM_ALL, PS_TFM_ROT) && (pchan->flag & POSE_ROT)) {
+ /* everything depends on the rotation mode */
+ if (pchan->rotmode > 0) {
+ /* eulers - so calculate these for the 'eul' vector, and use euler_rotation curves */
+ pose_slide_rest_pose_apply_vec3(pso, pchan->eul, 0.0f);
+ }
+ else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
+ pose_slide_rest_pose_apply_other_rot(pso, pchan->quat, false);
+ }
+ else {
+ /* quaternions - use quaternion blending */
+ pose_slide_rest_pose_apply_other_rot(pso, pchan->quat, true);
+ }
+ }
+
+ if (ELEM(pso->channels, PS_TFM_ALL, PS_TFM_BBONE_SHAPE) && (pchan->flag & POSE_BBONE_SHAPE)) {
+ /* bbone properties - they all start a "bbone_" prefix */
+ // TODO Not implemented
+ // pose_slide_apply_props(pso, pfl, "bbone_");
+ }
+
+ if (ELEM(pso->channels, PS_TFM_ALL, PS_TFM_PROPS) && (pfl->oldprops)) {
+ /* Not strictly a transform, but custom properties contribute
+ * to the pose produced in many rigs (e.g. the facial rigs used in Sintel). */
+ // TODO Not implemented
+ // pose_slide_apply_props(pso, pfl, "[\""); /* dummy " for texteditor bugs */
+ }
+ }
+
+ /* depsgraph updates + redraws */
+ pose_slide_refresh(C, pso);
+}
+
/* apply() - perform the pose sliding based on weighting various poses */
static void pose_slide_apply(bContext *C, tPoseSlideOp *pso)
{
@@ -888,7 +987,12 @@ static int pose_slide_invoke_common(bContext *C, wmOperator *op, tPoseSlideOp *p
/* initial apply for operator... */
/* TODO: need to calculate percentage for initial round too... */
- pose_slide_apply(C, pso);
+ if (pso->mode != POSESLIDE_PUSH_REST && pso->mode != POSESLIDE_RELAX_REST) {
+ pose_slide_apply(C, pso);
+ }
+ else {
+ pose_slide_rest_pose_apply(C, pso);
+ }
/* depsgraph updates + redraws */
pose_slide_refresh(C, pso);
@@ -1122,7 +1226,12 @@ static int pose_slide_modal(bContext *C, wmOperator *op, const wmEvent *event)
pose_slide_reset(pso);
/* apply... */
- pose_slide_apply(C, pso);
+ if (pso->mode != POSESLIDE_PUSH_REST && pso->mode != POSESLIDE_RELAX_REST) {
+ pose_slide_apply(C, pso);
+ }
+ else {
+ pose_slide_rest_pose_apply(C, pso);
+ }
}
/* still running... */
@@ -1140,7 +1249,12 @@ static void pose_slide_cancel(bContext *UNUSED(C), wmOperator *op)
static int pose_slide_exec_common(bContext *C, wmOperator *op, tPoseSlideOp *pso)
{
/* settings should have been set up ok for applying, so just apply! */
- pose_slide_apply(C, pso);
+ if (pso->mode != POSESLIDE_PUSH_REST && pso->mode != POSESLIDE_RELAX_REST) {
+ pose_slide_apply(C, pso);
+ }
+ else {
+ pose_slide_rest_pose_apply(C, pso);
+ }
/* insert keyframes if needed */
pose_slide_autoKeyframe(C, pso);
@@ -1200,7 +1314,7 @@ static void pose_slide_opdef_properties(wmOperatorType *ot)
/* ------------------------------------ */
-/* invoke() - for 'push' mode */
+/* invoke() - for 'push from breakdown' mode */
static int pose_slide_push_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
tPoseSlideOp *pso;
@@ -1242,9 +1356,9 @@ static int pose_slide_push_exec(bContext *C, wmOperator *op)
void POSE_OT_push(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Push Pose";
+ ot->name = "Push Pose from Breakdown";
ot->idname = "POSE_OT_push";
- ot->description = "Exaggerate the current pose";
+ ot->description = "Exaggerate the current pose in regards to the breakdown pose";
/* callbacks */
ot->exec = pose_slide_push_exec;
@@ -1262,7 +1376,7 @@ void POSE_OT_push(wmOperatorType *ot)
/* ........................ */
-/* invoke() - for 'relax' mode */
+/* invoke() - for 'relax to breakdown' mode */
static int pose_slide_relax_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
tPoseSlideOp *pso;
@@ -1304,9 +1418,9 @@ static int pose_slide_relax_exec(bContext *C, wmOperator *op)
void POSE_OT_relax(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Relax Pose";
+ ot->name = "Relax Pose to Breakdown";
ot->idname = "POSE_OT_relax";
- ot->description = "Make the current pose more similar to its surrounding ones";
+ ot->description = "Make the current pose more similar to its breakdown pose";
/* callbacks */
ot->exec = pose_slide_relax_exec;
@@ -1323,6 +1437,129 @@ void POSE_OT_relax(wmOperatorType *ot)
}
/* ........................ */
+/* invoke() - for 'push from rest pose' mode */
+static int pose_slide_push_rest_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ tPoseSlideOp *pso;
+
+ /* initialize data */
+ if (pose_slide_init(C, op, POSESLIDE_PUSH_REST) == 0) {
+ pose_slide_exit(op);
+ return OPERATOR_CANCELLED;
+ }
+ else {
+ pso = op->customdata;
+ }
+
+ /* initialise percentage so that it won't pop on first mouse move */
+ pose_slide_mouse_update_percentage(pso, op, event);
+
+ /* do common setup work */
+ return pose_slide_invoke_common(C, op, pso);
+}
+
+/* exec() - for push */
+static int pose_slide_push_rest_exec(bContext *C, wmOperator *op)
+{
+ tPoseSlideOp *pso;
+
+ /* initialize data (from RNA-props) */
+ if (pose_slide_init(C, op, POSESLIDE_PUSH_REST) == 0) {
+ pose_slide_exit(op);
+ return OPERATOR_CANCELLED;
+ }
+ else {
+ pso = op->customdata;
+ }
+
+ /* do common exec work */
+ return pose_slide_exec_common(C, op, pso);
+}
+
+void POSE_OT_push_rest(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Push Pose from Rest Pose";
+ ot->idname = "POSE_OT_push_rest";
+ ot->description = "Push the current pose further away from the rest pose";
+
+ /* callbacks */
+ ot->exec = pose_slide_push_rest_exec;
+ ot->invoke = pose_slide_push_rest_invoke;
+ ot->modal = pose_slide_modal;
+ ot->cancel = pose_slide_cancel;
+ ot->poll = ED_operator_posemode;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING | OPTYPE_USE_EVAL_DATA;
+
+ /* Properties */
+ pose_slide_opdef_properties(ot);
+}
+
+/* ........................ */
+
+/* invoke() - for 'relax' mode */
+static int pose_slide_relax_rest_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ tPoseSlideOp *pso;
+
+ /* initialize data */
+ if (pose_slide_init(C, op, POSESLIDE_RELAX_REST) == 0) {
+ pose_slide_exit(op);
+ return OPERATOR_CANCELLED;
+ }
+ else {
+ pso = op->customdata;
+ }
+
+ /* initialise percentage so that it won't pop on first mouse move */
+ pose_slide_mouse_update_percentage(pso, op, event);
+
+ /* do common setup work */
+ return pose_slide_invoke_common(C, op, pso);
+}
+
+/* exec() - for relax */
+static int pose_slide_relax_rest_exec(bContext *C, wmOperator *op)
+{
+ tPoseSlideOp *pso;
+
+ /* initialize data (from RNA-props) */
+ if (pose_slide_init(C, op, POSESLIDE_RELAX_REST) == 0) {
+ pose_slide_exit(op);
+ return OPERATOR_CANCELLED;
+ }
+ else {
+ pso = op->customdata;
+ }
+
+ /* do common exec work */
+ return pose_slide_exec_common(C, op, pso);
+}
+
+void POSE_OT_relax_rest(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Relax Pose to Rest Pose";
+ ot->idname = "POSE_OT_relax_rest";
+ ot->description = "Make the current pose more similar to the rest pose";
+
+ /* callbacks */
+ ot->exec = pose_slide_relax_rest_exec;
+ ot->invoke = pose_slide_relax_rest_invoke;
+ ot->modal = pose_slide_modal;
+ ot->cancel = pose_slide_cancel;
+ ot->poll = ED_operator_posemode;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING | OPTYPE_USE_EVAL_DATA;
+
+ /* Properties */
+ pose_slide_opdef_properties(ot);
+}
+
+/* ........................ */
/* invoke() - for 'breakdown' mode */
static int pose_slide_breakdown_invoke(bContext *C, wmOperator *op, const wmEvent *event)
diff --git a/source/blender/editors/armature/pose_transform.c b/source/blender/editors/armature/pose_transform.c
index 6207d5412cf..49b66429515 100644
--- a/source/blender/editors/armature/pose_transform.c
+++ b/source/blender/editors/armature/pose_transform.c
@@ -59,6 +59,9 @@
#include "ED_screen.h"
#include "ED_util.h"
+#include "UI_interface.h"
+#include "UI_resources.h"
+
#include "armature_intern.h"
/* ********************************************** */
@@ -87,6 +90,229 @@ static void applyarmature_fix_boneparents(const bContext *C, Scene *scene, Objec
}
}
+/* Sets the bone head, tail and roll to match the supplied parameters. */
+static void applyarmature_set_edit_position(EditBone *curbone,
+ const float pose_mat[4][4],
+ const float new_tail[3],
+ float r_new_arm_mat[4][4])
+{
+ /* Simply copy the head/tail values from pchan over to curbone. */
+ copy_v3_v3(curbone->head, pose_mat[3]);
+ copy_v3_v3(curbone->tail, new_tail);
+
+ /* Fix roll:
+ * 1. find auto-calculated roll value for this bone now
+ * 2. remove this from the 'visual' y-rotation
+ */
+ {
+ float premat[3][3], pmat[3][3];
+ float delta[3];
+
+ /* Obtain new auto y-rotation. */
+ sub_v3_v3v3(delta, curbone->tail, curbone->head);
+
+ copy_m3_m4(pmat, pose_mat);
+ mat3_vec_to_roll(pmat, delta, &curbone->roll);
+
+ /* Compute new rest pose matrix if requested. */
+ if (r_new_arm_mat) {
+ vec_roll_to_mat3(delta, curbone->roll, premat);
+ copy_m4_m3(r_new_arm_mat, premat);
+ copy_v3_v3(r_new_arm_mat[3], pose_mat[3]);
+ }
+ }
+}
+
+/* Copy properties over from pchan to curbone and reset channels. */
+static void applyarmature_transfer_properties(EditBone *curbone,
+ bPoseChannel *pchan,
+ const bPoseChannel *pchan_eval)
+{
+ /* Combine pose and rest values for bendy bone settings,
+ * then clear the pchan values (so we don't get a double-up).
+ */
+ if (pchan->bone->segments > 1) {
+ /* Combine rest/pose values. */
+ curbone->curve_in_x += pchan_eval->curve_in_x;
+ curbone->curve_in_y += pchan_eval->curve_in_y;
+ curbone->curve_out_x += pchan_eval->curve_out_x;
+ curbone->curve_out_y += pchan_eval->curve_out_y;
+ curbone->roll1 += pchan_eval->roll1;
+ curbone->roll2 += pchan_eval->roll2;
+ curbone->ease1 += pchan_eval->ease1;
+ curbone->ease2 += pchan_eval->ease2;
+
+ curbone->scale_in_x *= pchan_eval->scale_in_x;
+ curbone->scale_in_y *= pchan_eval->scale_in_y;
+ curbone->scale_out_x *= pchan_eval->scale_out_x;
+ curbone->scale_out_y *= pchan_eval->scale_out_y;
+
+ /* Reset pose values. */
+ pchan->curve_in_x = pchan->curve_out_x = 0.0f;
+ pchan->curve_in_y = pchan->curve_out_y = 0.0f;
+ pchan->roll1 = pchan->roll2 = 0.0f;
+ pchan->ease1 = pchan->ease2 = 0.0f;
+ pchan->scale_in_x = pchan->scale_in_y = 1.0f;
+ pchan->scale_out_x = pchan->scale_out_y = 1.0f;
+ }
+
+ /* Clear transform values for pchan. */
+ zero_v3(pchan->loc);
+ zero_v3(pchan->eul);
+ unit_qt(pchan->quat);
+ unit_axis_angle(pchan->rotAxis, &pchan->rotAngle);
+ pchan->size[0] = pchan->size[1] = pchan->size[2] = 1.0f;
+
+ /* Set anim lock. */
+ curbone->flag |= BONE_UNKEYED;
+}
+
+/* Adjust the current edit position of the bone using the pose space matrix. */
+static void applyarmature_adjust_edit_position(bArmature *arm,
+ bPoseChannel *pchan,
+ const float delta_mat[4][4],
+ float r_new_arm_mat[4][4])
+{
+ EditBone *curbone = ED_armature_ebone_find_name(arm->edbo, pchan->name);
+ float delta[3], new_tail[3], premat[3][3], new_pose[4][4];
+
+ /* Current orientation matrix. */
+ sub_v3_v3v3(delta, curbone->tail, curbone->head);
+ vec_roll_to_mat3(delta, curbone->roll, premat);
+
+ /* New location and orientation. */
+ mul_m4_m4m3(new_pose, delta_mat, premat);
+ mul_v3_m4v3(new_pose[3], delta_mat, curbone->head);
+ mul_v3_m4v3(new_tail, delta_mat, curbone->tail);
+
+ applyarmature_set_edit_position(curbone, new_pose, new_tail, r_new_arm_mat);
+}
+
+/* Data about parent position for Apply To Selected mode. */
+typedef struct ApplyArmature_ParentState {
+ Bone *bone;
+
+ /* New rest position of the bone with scale included. */
+ float new_rest_mat[4][4];
+ /* New arm_mat of the bone == new_rest_mat without scale. */
+ float new_arm_mat[4][4];
+} ApplyArmature_ParentState;
+
+/* Recursive walk for Apply To Selected mode; pstate NULL unless child of an applied bone. */
+static void applyarmature_process_selected_rec(bArmature *arm,
+ bPose *pose,
+ bPose *pose_eval,
+ Bone *bone,
+ ListBase *selected,
+ ApplyArmature_ParentState *pstate)
+{
+ bPoseChannel *pchan = BKE_pose_channel_find_name(pose, bone->name);
+ const bPoseChannel *pchan_eval = BKE_pose_channel_find_name(pose_eval, bone->name);
+
+ if (!pchan || !pchan_eval)
+ return;
+
+ ApplyArmature_ParentState new_pstate = {.bone = bone};
+
+ if (BLI_findptr(selected, pchan, offsetof(CollectionPointerLink, ptr.data))) {
+ /* SELECTED BONE: Snap to final pose transform minus unapplied parent effects.
+ *
+ * I.e. bone position with accumulated parent effects but no local
+ * transformation will match the original final pose_mat.
+ *
+ * Pose channels are reset as expected.
+ */
+ EditBone *curbone = ED_armature_ebone_find_name(arm->edbo, pchan->name);
+ BoneParentTransform invparent;
+ float new_tail[3];
+
+ if (pchan->parent) {
+ BoneParentTransform old_bpt, new_bpt;
+ float offs_bone[4][4];
+
+ /* Parent effects on the bone transform that have to be removed. */
+ BKE_bone_offset_matrix_get(bone, offs_bone);
+ BKE_bone_parent_transform_calc_from_matrices(
+ bone->flag, offs_bone, bone->parent->arm_mat, pchan_eval->parent->pose_mat, &old_bpt);
+
+ /* Applied parent effects that have to be kept, if any. */
+ float(*new_parent_pose)[4] = pstate ? pstate->new_rest_mat : bone->parent->arm_mat;
+ BKE_bone_parent_transform_calc_from_matrices(
+ bone->flag, offs_bone, bone->parent->arm_mat, new_parent_pose, &new_bpt);
+
+ BKE_bone_parent_transform_invert(&old_bpt);
+ BKE_bone_parent_transform_combine(&new_bpt, &old_bpt, &invparent);
+ }
+ else {
+ BKE_bone_parent_transform_clear(&invparent);
+ }
+
+ /* Apply change without inherited unapplied parent transformations. */
+ BKE_bone_parent_transform_apply(&invparent, pchan_eval->pose_mat, new_pstate.new_rest_mat);
+
+ copy_v3_fl3(new_tail, 0.0, bone->length, 0.0);
+ mul_m4_v3(new_pstate.new_rest_mat, new_tail);
+
+ applyarmature_set_edit_position(
+ curbone, new_pstate.new_rest_mat, new_tail, new_pstate.new_arm_mat);
+ applyarmature_transfer_properties(curbone, pchan, pchan_eval);
+
+ pstate = &new_pstate;
+ }
+ else if (pstate) {
+ /* UNSELECTED CHILD OF SELECTED: Include applied parent effects.
+ *
+ * The inherited transform of applied (selected) bones is baked
+ * into the rest pose so that the final bone position doesn't
+ * change.
+ *
+ * Pose channels are not changed, with the exception of the inherited
+ * applied parent scale being baked into the location pose channel.
+ */
+ BoneParentTransform bpt;
+ float offs_bone[4][4], delta[4][4], old_chan_loc[3];
+
+ /* Include applied parent effects. */
+ BKE_bone_offset_matrix_get(bone, offs_bone);
+ BKE_bone_parent_transform_calc_from_matrices(
+ bone->flag, offs_bone, pstate->bone->arm_mat, pstate->new_rest_mat, &bpt);
+
+ unit_m4(new_pstate.new_rest_mat);
+ BKE_bone_parent_transform_apply(&bpt, new_pstate.new_rest_mat, new_pstate.new_rest_mat);
+
+ /* Bone location channel in pose space relative to bone head. */
+ mul_v3_mat3_m4v3(old_chan_loc, bpt.loc_mat, pchan_eval->loc);
+
+ /* Apply the change to the rest bone position. */
+ invert_m4_m4(delta, bone->arm_mat);
+ mul_m4_m4m4(delta, new_pstate.new_rest_mat, delta);
+
+ applyarmature_adjust_edit_position(arm, pchan, delta, new_pstate.new_arm_mat);
+
+ /* Location pose channel has to be updated, because it is affected
+ * by parent scaling, and the rest pose has no scale by definition. */
+ if (!(bone->flag & BONE_CONNECTED) && !is_zero_v3(old_chan_loc)) {
+ float inv_parent_arm[4][4];
+
+ /* Compute the channel coordinate space matrices for the new rest state. */
+ invert_m4_m4(inv_parent_arm, pstate->new_arm_mat);
+ mul_m4_m4m4(offs_bone, inv_parent_arm, new_pstate.new_arm_mat);
+ BKE_bone_parent_transform_calc_from_matrices(
+ bone->flag, offs_bone, pstate->new_arm_mat, pstate->new_arm_mat, &bpt);
+
+ /* Re-apply the location to keep the final effect. */
+ invert_m4(bpt.loc_mat);
+ mul_v3_mat3_m4v3(pchan->loc, bpt.loc_mat, old_chan_loc);
+ }
+
+ pstate = &new_pstate;
+ }
+
+ for (Bone *child = bone->childbase.first; child; child = child->next) {
+ applyarmature_process_selected_rec(arm, pose, pose_eval, child, selected, pstate);
+ }
+}
+
/* set the current pose as the restpose */
static int apply_armature_pose2bones_exec(bContext *C, wmOperator *op)
{
@@ -99,7 +325,9 @@ static int apply_armature_pose2bones_exec(bContext *C, wmOperator *op)
bArmature *arm = BKE_armature_from_object(ob);
bPose *pose;
bPoseChannel *pchan;
- EditBone *curbone;
+ ListBase selected_bones;
+
+ const bool use_selected = RNA_boolean_get(op->ptr, "selected");
/* don't check if editmode (should be done by caller) */
if (ob->type != OB_ARMATURE) {
@@ -119,80 +347,37 @@ static int apply_armature_pose2bones_exec(bContext *C, wmOperator *op)
"transforms stored are relative to the old rest pose");
}
+ /* Find selected bones before switching to edit mode. */
+ if (use_selected) {
+ CTX_data_selected_pose_bones(C, &selected_bones);
+
+ if (!selected_bones.first) {
+ return OPERATOR_CANCELLED;
+ }
+ }
+
/* Get editbones of active armature to alter */
ED_armature_to_edit(arm);
/* get pose of active object and move it out of posemode */
pose = ob->pose;
- for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
- const bPoseChannel *pchan_eval = BKE_pose_channel_find_name(ob_eval->pose, pchan->name);
- curbone = ED_armature_ebone_find_name(arm->edbo, pchan->name);
-
- /* simply copy the head/tail values from pchan over to curbone */
- copy_v3_v3(curbone->head, pchan_eval->pose_head);
- copy_v3_v3(curbone->tail, pchan_eval->pose_tail);
-
- /* fix roll:
- * 1. find auto-calculated roll value for this bone now
- * 2. remove this from the 'visual' y-rotation
- */
- {
- float premat[3][3], imat[3][3], pmat[3][3], tmat[3][3];
- float delta[3], eul[3];
-
- /* obtain new auto y-rotation */
- sub_v3_v3v3(delta, curbone->tail, curbone->head);
- vec_roll_to_mat3(delta, 0.0f, premat);
- invert_m3_m3(imat, premat);
-
- /* get pchan 'visual' matrix */
- copy_m3_m4(pmat, pchan_eval->pose_mat);
-
- /* remove auto from visual and get euler rotation */
- mul_m3_m3m3(tmat, imat, pmat);
- mat3_to_eul(eul, tmat);
-
- /* just use this euler-y as new roll value */
- curbone->roll = eul[1];
+ if (use_selected) {
+ /* The selected only mode requires a recursive walk to handle parent-child relations. */
+ for (Bone *bone = arm->bonebase.first; bone; bone = bone->next) {
+ applyarmature_process_selected_rec(arm, pose, ob_eval->pose, bone, &selected_bones, NULL);
}
- /* combine pose and rest values for bendy bone settings,
- * then clear the pchan values (so we don't get a double-up)
- */
- if (pchan->bone->segments > 1) {
- /* combine rest/pose values */
- curbone->curve_in_x += pchan_eval->curve_in_x;
- curbone->curve_in_y += pchan_eval->curve_in_y;
- curbone->curve_out_x += pchan_eval->curve_out_x;
- curbone->curve_out_y += pchan_eval->curve_out_y;
- curbone->roll1 += pchan_eval->roll1;
- curbone->roll2 += pchan_eval->roll2;
- curbone->ease1 += pchan_eval->ease1;
- curbone->ease2 += pchan_eval->ease2;
- curbone->scale_in_x *= pchan_eval->scale_in_x;
- curbone->scale_in_y *= pchan_eval->scale_in_y;
- curbone->scale_out_x *= pchan_eval->scale_out_x;
- curbone->scale_out_y *= pchan_eval->scale_out_y;
-
- /* reset pose values */
- pchan->curve_in_x = pchan->curve_out_x = 0.0f;
- pchan->curve_in_y = pchan->curve_out_y = 0.0f;
- pchan->roll1 = pchan->roll2 = 0.0f;
- pchan->ease1 = pchan->ease2 = 0.0f;
- pchan->scale_in_x = pchan->scale_in_y = 1.0f;
- pchan->scale_out_x = pchan->scale_out_y = 1.0f;
- }
-
- /* clear transform values for pchan */
- zero_v3(pchan->loc);
- zero_v3(pchan->eul);
- unit_qt(pchan->quat);
- unit_axis_angle(pchan->rotAxis, &pchan->rotAngle);
- pchan->size[0] = pchan->size[1] = pchan->size[2] = 1.0f;
+ BLI_freelistN(&selected_bones);
+ }
+ else {
+ for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
+ const bPoseChannel *pchan_eval = BKE_pose_channel_find_name(ob_eval->pose, pchan->name);
+ EditBone *curbone = ED_armature_ebone_find_name(arm->edbo, pchan->name);
- /* set anim lock */
- curbone->flag |= BONE_UNKEYED;
+ applyarmature_set_edit_position(curbone, pchan_eval->pose_mat, pchan_eval->pose_tail, NULL);
+ applyarmature_transfer_properties(curbone, pchan, pchan_eval);
+ }
}
/* convert editbones back to bones, and then free the edit-data */
@@ -212,6 +397,17 @@ static int apply_armature_pose2bones_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
+static void apply_armature_pose2bones_ui(bContext *C, wmOperator *op)
+{
+ uiLayout *layout = op->layout;
+ wmWindowManager *wm = CTX_wm_manager(C);
+ PointerRNA ptr;
+
+ RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
+
+ uiItemR(layout, &ptr, "selected", 0, NULL, ICON_NONE);
+}
+
void POSE_OT_armature_apply(wmOperatorType *ot)
{
/* identifiers */
@@ -222,9 +418,16 @@ void POSE_OT_armature_apply(wmOperatorType *ot)
/* callbacks */
ot->exec = apply_armature_pose2bones_exec;
ot->poll = ED_operator_posemode;
+ ot->ui = apply_armature_pose2bones_ui;
/* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_USE_EVAL_DATA;
+
+ RNA_def_boolean(ot->srna,
+ "selected",
+ false,
+ "Selected Only",
+ "Only apply the selected bones (with propagation to children)");
}
/* set the current pose as the restpose */
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index a787b45c13c..65f502d5cd2 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -5551,6 +5551,8 @@ static int add_vertex_exec(bContext *C, wmOperator *op)
}
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+
DEG_id_tag_update(obedit->data, 0);
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index 463c2144276..9ef0657ae83 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -314,7 +314,7 @@ static int gpencil_paintmode_toggle_exec(bContext *C, wmOperator *op)
BKE_paint_ensure(ts, (Paint **)&ts->gp_paint);
Paint *paint = &ts->gp_paint->paint;
/* if not exist, create a new one */
- if (paint->brush == NULL) {
+ if ((paint->brush == NULL) || (paint->brush->gpencil_settings == NULL)) {
BKE_brush_gpencil_presets(C);
}
BKE_paint_toolslots_brush_validate(bmain, &ts->gp_paint->paint);
diff --git a/source/blender/editors/gpencil/gpencil_merge.c b/source/blender/editors/gpencil/gpencil_merge.c
index 9d3c2a6e271..93d8555e014 100644
--- a/source/blender/editors/gpencil/gpencil_merge.c
+++ b/source/blender/editors/gpencil/gpencil_merge.c
@@ -110,7 +110,7 @@ static bGPDstroke *gpencil_prepare_stroke(bContext *C, wmOperator *op, int totpo
Paint *paint = &ts->gp_paint->paint;
/* if not exist, create a new one */
- if (paint->brush == NULL) {
+ if ((paint->brush == NULL) || (paint->brush->gpencil_settings == NULL)) {
/* create new brushes */
BKE_brush_gpencil_presets(C);
}
diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c
index b1b29356060..cd1ebc91fbb 100644
--- a/source/blender/editors/gpencil/gpencil_paint.c
+++ b/source/blender/editors/gpencil/gpencil_paint.c
@@ -1819,7 +1819,7 @@ static void gp_init_drawing_brush(bContext *C, tGPsdata *p)
Paint *paint = &ts->gp_paint->paint;
bool changed = false;
/* if not exist, create a new one */
- if (paint->brush == NULL) {
+ if ((paint->brush == NULL) || (paint->brush->gpencil_settings == NULL)) {
/* create new brushes */
BKE_brush_gpencil_presets(C);
changed = true;
diff --git a/source/blender/editors/gpencil/gpencil_primitive.c b/source/blender/editors/gpencil/gpencil_primitive.c
index 08fee2bb393..bff17bf5078 100644
--- a/source/blender/editors/gpencil/gpencil_primitive.c
+++ b/source/blender/editors/gpencil/gpencil_primitive.c
@@ -314,7 +314,7 @@ static void gp_primitive_set_initdata(bContext *C, tGPDprimitive *tgpi)
/* if brush doesn't exist, create a new one */
Paint *paint = &ts->gp_paint->paint;
/* if not exist, create a new one */
- if (paint->brush == NULL) {
+ if ((paint->brush == NULL) || (paint->brush->gpencil_settings == NULL)) {
/* create new brushes */
BKE_brush_gpencil_presets(C);
}
diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c
index 129bd01574c..93a80f0fcf8 100644
--- a/source/blender/editors/gpencil/gpencil_utils.c
+++ b/source/blender/editors/gpencil/gpencil_utils.c
@@ -1387,7 +1387,7 @@ void ED_gpencil_add_defaults(bContext *C, Object *ob)
BKE_paint_ensure(ts, (Paint **)&ts->gp_paint);
Paint *paint = &ts->gp_paint->paint;
/* if not exist, create a new one */
- if (paint->brush == NULL) {
+ if ((paint->brush == NULL) || (paint->brush->gpencil_settings == NULL)) {
/* create new brushes */
BKE_brush_gpencil_presets(C);
}
diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h
index 6342a8b26d9..cd68981dee3 100644
--- a/source/blender/editors/include/ED_anim_api.h
+++ b/source/blender/editors/include/ED_anim_api.h
@@ -403,7 +403,8 @@ typedef enum eAnimFilter_Flags {
/* -------------- Channel Defines -------------- */
/* channel heights */
-#define ACHANNEL_FIRST_TOP(ac) (-0.4f * (ac)->yscale_fac * U.widget_unit)
+#define ACHANNEL_FIRST_TOP(ac) \
+ (UI_view2d_scale_get_y(&(ac)->ar->v2d) * -UI_SCRUBBING_MARGIN_Y - ACHANNEL_SKIP)
#define ACHANNEL_HEIGHT(ac) (0.8f * (ac)->yscale_fac * U.widget_unit)
#define ACHANNEL_SKIP (0.1f * U.widget_unit)
#define ACHANNEL_STEP(ac) (ACHANNEL_HEIGHT(ac) + ACHANNEL_SKIP)
@@ -420,14 +421,15 @@ typedef enum eAnimFilter_Flags {
/* -------------- NLA Channel Defines -------------- */
/* NLA channel heights */
-#define NLACHANNEL_FIRST_TOP(snla) (-0.4f * U.widget_unit)
+#define NLACHANNEL_FIRST_TOP(ac) \
+ (UI_view2d_scale_get_y(&(ac)->ar->v2d) * -UI_SCRUBBING_MARGIN_Y - NLACHANNEL_SKIP)
#define NLACHANNEL_HEIGHT(snla) \
((snla && (snla->flag & SNLA_NOSTRIPCURVES)) ? (0.8f * U.widget_unit) : (1.2f * U.widget_unit))
#define NLACHANNEL_SKIP (0.1f * U.widget_unit)
#define NLACHANNEL_STEP(snla) (NLACHANNEL_HEIGHT(snla) + NLACHANNEL_SKIP)
/* Additional offset to give some room at the end. */
-#define NLACHANNEL_TOT_HEIGHT(snla, item_amount) \
- (-NLACHANNEL_FIRST_TOP(snla) + NLACHANNEL_STEP(snla) * (item_amount + 1))
+#define NLACHANNEL_TOT_HEIGHT(ac, item_amount) \
+ (-NLACHANNEL_FIRST_TOP(ac) + NLACHANNEL_STEP(((SpaceNla *)(ac)->sl)) * (item_amount + 1))
/* channel widths */
#define NLACHANNEL_NAMEWIDTH (10 * U.widget_unit)
diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h
index ce8521a1f6a..c6d25e6f988 100644
--- a/source/blender/editors/include/ED_mesh.h
+++ b/source/blender/editors/include/ED_mesh.h
@@ -163,7 +163,10 @@ bool EDBM_backbuf_circle_init(struct ViewContext *vc, short xs, short ys, short
struct BMVert *EDBM_vert_find_nearest_ex(struct ViewContext *vc,
float *r_dist,
const bool use_select_bias,
- bool use_cycle);
+ bool use_cycle,
+ struct Base **bases,
+ uint bases_len,
+ uint *r_base_index);
struct BMVert *EDBM_vert_find_nearest(struct ViewContext *vc, float *r_dist);
struct BMEdge *EDBM_edge_find_nearest_ex(struct ViewContext *vc,
@@ -171,7 +174,10 @@ struct BMEdge *EDBM_edge_find_nearest_ex(struct ViewContext *vc,
float *r_dist_center,
const bool use_select_bias,
const bool use_cycle,
- struct BMEdge **r_eed_zbuf);
+ struct BMEdge **r_eed_zbuf,
+ struct Base **bases,
+ uint bases_len,
+ uint *r_base_index);
struct BMEdge *EDBM_edge_find_nearest(struct ViewContext *vc, float *r_dist);
struct BMFace *EDBM_face_find_nearest_ex(struct ViewContext *vc,
@@ -179,7 +185,10 @@ struct BMFace *EDBM_face_find_nearest_ex(struct ViewContext *vc,
float *r_dist_center,
const bool use_select_bias,
const bool use_cycle,
- struct BMFace **r_efa_zbuf);
+ struct BMFace **r_efa_zbuf,
+ struct Base **bases,
+ uint bases_len,
+ uint *r_base_index);
struct BMFace *EDBM_face_find_nearest(struct ViewContext *vc, float *r_dist);
bool EDBM_unified_findnearest(struct ViewContext *vc,
@@ -230,6 +239,7 @@ void em_setup_viewcontext(struct bContext *C, struct ViewContext *vc); /* rename
bool EDBM_mesh_deselect_all_multi_ex(struct Base **bases, const uint bases_len);
bool EDBM_mesh_deselect_all_multi(struct bContext *C);
+/* Only use for modes that don't support multi-edit-modes (painting). */
extern unsigned int bm_vertoffs, bm_solidoffs, bm_wireoffs;
/* editmesh_preselect_edgering.c */
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index 264eb6abdf1..a7a95a4a659 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -87,9 +87,12 @@ void ED_region_panels_ex(const struct bContext *C,
void ED_region_panels(const struct bContext *C, struct ARegion *ar);
void ED_region_panels_layout_ex(const struct bContext *C,
struct ARegion *ar,
+ struct ListBase *paneltypes,
const char *contexts[],
int contextnr,
- const bool vertical);
+ const bool vertical,
+ const char *category_override);
+
void ED_region_panels_layout(const struct bContext *C, struct ARegion *ar);
void ED_region_panels_draw(const struct bContext *C, struct ARegion *ar);
@@ -440,8 +443,9 @@ enum {
ED_KEYMAP_ANIMATION = (1 << 6),
ED_KEYMAP_FRAMES = (1 << 7),
ED_KEYMAP_HEADER = (1 << 8),
- ED_KEYMAP_GPENCIL = (1 << 9),
- ED_KEYMAP_FOOTER = (1 << 10),
+ ED_KEYMAP_FOOTER = (1 << 9),
+ ED_KEYMAP_GPENCIL = (1 << 10),
+ ED_KEYMAP_NAVBAR = (1 << 11),
};
/* SCREEN_OT_space_context_cycle direction */
diff --git a/source/blender/editors/include/ED_time_scrub_ui.h b/source/blender/editors/include/ED_time_scrub_ui.h
new file mode 100644
index 00000000000..a2e3098e949
--- /dev/null
+++ b/source/blender/editors/include/ED_time_scrub_ui.h
@@ -0,0 +1,43 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2019 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup editors
+ */
+
+#ifndef __ED_SCRUBBING_H__
+#define __ED_SCRUBBING_H__
+
+struct View2DGrid;
+struct bContext;
+struct bDopeSheet;
+struct wmEvent;
+
+void ED_scrubbing_draw(const struct ARegion *ar,
+ const struct Scene *scene,
+ bool display_seconds,
+ bool discrete_frames);
+
+bool ED_event_in_scrubbing_region(const struct ARegion *ar, const struct wmEvent *event);
+
+void ED_channel_search_draw(const struct bContext *C,
+ struct ARegion *ar,
+ struct bDopeSheet *dopesheet);
+
+#endif /* __ED_SCRUBBING_H__ */
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index fd51419a3ee..3503d38ad92 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -730,4 +730,9 @@ void ED_view3d_gizmo_mesh_preselect_get_active(struct bContext *C,
struct Base **r_base,
struct BMElem **r_ele);
+/* space_view3d.c */
+void ED_view3d_buttons_region_layout_ex(const struct bContext *C,
+ struct ARegion *ar,
+ const char *category_override);
+
#endif /* __ED_VIEW3D_H__ */
diff --git a/source/blender/editors/include/UI_icons.h b/source/blender/editors/include/UI_icons.h
index b4d345a3344..9ee9e952856 100644
--- a/source/blender/editors/include/UI_icons.h
+++ b/source/blender/editors/include/UI_icons.h
@@ -24,6 +24,9 @@
/* Note: this is included multiple times with different #defines for DEF_ICON. */
/* Auto define more specific types for places that do not need the distinction. */
+#ifndef DEF_ICON_SCENE
+# define DEF_ICON_SCENE DEF_ICON
+#endif
#ifndef DEF_ICON_COLLECTION
# define DEF_ICON_COLLECTION DEF_ICON
#endif
@@ -133,8 +136,8 @@ DEF_ICON_SHADING(MATERIAL)
DEF_ICON_SHADING(TEXTURE)
DEF_ICON(ANIM)
DEF_ICON_SHADING(WORLD)
-DEF_ICON(SCENE)
-DEF_ICON(OUTPUT)
+DEF_ICON_SCENE(SCENE)
+DEF_ICON_SCENE(OUTPUT)
DEF_ICON_BLANK(145)
DEF_ICON_BLANK(146)
DEF_ICON(SCRIPT)
@@ -142,7 +145,7 @@ DEF_ICON_MODIFIER(PARTICLES)
DEF_ICON_MODIFIER(PHYSICS)
DEF_ICON_OBJECT_DATA(SPEAKER)
DEF_ICON_BLANK(151)
-DEF_ICON(TOOL_SETTINGS)
+DEF_ICON_SCENE(TOOL_SETTINGS)
DEF_ICON_MODIFIER(SHADERFX)
DEF_ICON_MODIFIER(MODIFIER)
DEF_ICON_BLANK(155)
@@ -211,8 +214,8 @@ DEF_ICON(TRACKING_REFINE_FORWARDS)
DEF_ICON_BLANK(77b)
/* DATA */
-DEF_ICON(SCENE_DATA)
-DEF_ICON(RENDERLAYERS)
+DEF_ICON_SCENE(SCENE_DATA)
+DEF_ICON_SCENE(RENDERLAYERS)
DEF_ICON_SHADING(WORLD_DATA)
DEF_ICON_OBJECT(OBJECT_DATA)
DEF_ICON_OBJECT_DATA(MESH_DATA)
@@ -243,8 +246,8 @@ DEF_ICON_SHADING(BRUSH_DATA)
DEF_ICON_SHADING(IMAGE_DATA)
DEF_ICON(FILE)
DEF_ICON(FCURVE)
-DEF_ICON(FONT_DATA)
-DEF_ICON(RENDER_RESULT)
+DEF_ICON_OBJECT_DATA(FONT_DATA)
+DEF_ICON_SCENE(RENDER_RESULT)
DEF_ICON_OBJECT_DATA(SURFACE_DATA)
DEF_ICON_OBJECT_DATA(EMPTY_DATA)
DEF_ICON(PRESET)
@@ -320,7 +323,7 @@ DEF_ICON(RESTRICT_SELECT_ON)
DEF_ICON(RESTRICT_SELECT_OFF)
DEF_ICON(RESTRICT_RENDER_ON)
DEF_ICON(RESTRICT_RENDER_OFF)
-DEF_ICON_BLANK(330)
+DEF_ICON(RESTRICT_INSTANCED_OFF)
/* OUTLINER */
DEF_ICON_OBJECT_DATA(OUTLINER_DATA_EMPTY)
@@ -334,7 +337,7 @@ DEF_ICON_OBJECT_DATA(OUTLINER_DATA_ARMATURE)
DEF_ICON_OBJECT_DATA(OUTLINER_DATA_FONT)
DEF_ICON_OBJECT_DATA(OUTLINER_DATA_SURFACE)
DEF_ICON_OBJECT_DATA(OUTLINER_DATA_SPEAKER)
-DEF_ICON_BLANK(344)
+DEF_ICON_OBJECT_DATA(OUTLINER_DATA_LIGHTPROBE)
DEF_ICON_BLANK(345)
DEF_ICON_OBJECT_DATA(OUTLINER_DATA_GREASEPENCIL)
DEF_ICON(GP_SELECT_POINTS)
@@ -348,7 +351,7 @@ DEF_ICON(ONIONSKIN_OFF)
DEF_ICON(ONIONSKIN_ON)
DEF_ICON(RESTRICT_VIEW_ON)
DEF_ICON(RESTRICT_VIEW_OFF)
-DEF_ICON_BLANK(353)
+DEF_ICON(RESTRICT_INSTANCED_ON)
/* PRIMITIVES */
DEF_ICON(MESH_PLANE)
@@ -456,11 +459,11 @@ DEF_ICON_BLANK(707)
DEF_ICON_BLANK(708)
DEF_ICON_BLANK(709)
DEF_ICON_BLANK(710)
-DEF_ICON_BLANK(711)
-DEF_ICON_BLANK(712)
-DEF_ICON_BLANK(713)
-DEF_ICON_BLANK(714)
-DEF_ICON_BLANK(715)
+DEF_ICON(SELECT_SET)
+DEF_ICON(SELECT_EXTEND)
+DEF_ICON(SELECT_SUBTRACT)
+DEF_ICON(SELECT_INTERSECT)
+DEF_ICON(SELECT_DIFFERENCE)
/* EMPTY */
DEF_ICON(ALIGN_LEFT)
@@ -708,7 +711,7 @@ DEF_ICON_BLANK(240)
DEF_ICON_BLANK(241)
DEF_ICON_BLANK(242)
DEF_ICON_BLANK(243)
-DEF_ICON_BLANK(244)
+DEF_ICON(GIZMO)
DEF_ICON(ORIENTATION_CURSOR)
DEF_ICON(NORMALS_VERTEX)
DEF_ICON(NORMALS_FACE)
@@ -1022,6 +1025,7 @@ DEF_ICON_COLOR(EVENT_RETURN)
#undef DEF_ICON
#undef DEF_ICON_ERROR
+#undef DEF_ICON_SCENE
#undef DEF_ICON_COLLECTION
#undef DEF_ICON_OBJECT
#undef DEF_ICON_OBJECT_DATA
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 18960853011..14d681ee817 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -228,6 +228,7 @@ enum {
#define UI_PANEL_WIDTH 340
#define UI_COMPACT_PANEL_WIDTH 160
+#define UI_SIDEBAR_PANEL_WIDTH 220
#define UI_NAVIGATION_REGION_WIDTH UI_COMPACT_PANEL_WIDTH
#define UI_NARROW_NAVIGATION_REGION_WIDTH 100
@@ -594,9 +595,16 @@ struct uiLayout *UI_pie_menu_layout(struct uiPieMenu *pie);
typedef uiBlock *(*uiBlockCreateFunc)(struct bContext *C, struct ARegion *ar, void *arg1);
typedef void (*uiBlockCancelFunc)(struct bContext *C, void *arg1);
-void UI_popup_block_invoke(struct bContext *C, uiBlockCreateFunc func, void *arg);
-void UI_popup_block_invoke_ex(
- struct bContext *C, uiBlockCreateFunc func, void *arg, const char *opname, int opcontext);
+void UI_popup_block_invoke(struct bContext *C,
+ uiBlockCreateFunc func,
+ void *arg,
+ void (*arg_free)(void *arg));
+void UI_popup_block_invoke_ex(struct bContext *C,
+ uiBlockCreateFunc func,
+ void *arg,
+ void (*arg_free)(void *arg),
+ const char *opname,
+ int opcontext);
void UI_popup_block_ex(struct bContext *C,
uiBlockCreateFunc func,
uiBlockHandleFunc popup_func,
@@ -641,6 +649,7 @@ enum {
UI_BLOCK_THEME_STYLE_POPUP = 1,
};
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_free(const struct bContext *C, uiBlock *block);
diff --git a/source/blender/editors/include/UI_interface_icons.h b/source/blender/editors/include/UI_interface_icons.h
index 5666421c27f..1f15fa3bd4d 100644
--- a/source/blender/editors/include/UI_interface_icons.h
+++ b/source/blender/editors/include/UI_interface_icons.h
@@ -52,8 +52,11 @@ typedef struct IconFile {
* Resizable Icons for Blender
*/
void UI_icons_init(void);
+void UI_icons_reload_internal_textures(void);
+
int UI_icon_get_width(int icon_id);
int UI_icon_get_height(int icon_id);
+bool UI_icon_get_theme_color(int icon_id, unsigned char color[4]);
void UI_id_icon_render(const struct bContext *C,
struct Scene *scene,
@@ -64,16 +67,17 @@ int UI_preview_render_size(enum eIconSizes size);
void UI_icon_draw(float x, float y, int icon_id);
void UI_icon_draw_alpha(float x, float y, int icon_id, float alpha);
-void UI_icon_draw_preview(float x, float y, int icon_id);
-void UI_icon_draw_preview_aspect(float x, float y, int icon_id, float aspect);
-void UI_icon_draw_preview_aspect_size(
- float x, float y, int icon_id, float aspect, float alpha, int size);
-
-void UI_icon_draw_aspect(
- float x, float y, int icon_id, float aspect, float alpha, const char mono_color[4]);
-void UI_icon_draw_aspect_color(
- float x, float y, int icon_id, float aspect, const float rgb[3], const char mono_color[4]);
-void UI_icon_draw_size(float x, float y, int size, int icon_id, float alpha);
+void UI_icon_draw_preview(float x, float y, int icon_id, float aspect, float alpha, int size);
+
+void UI_icon_draw_ex(float x,
+ float y,
+ int icon_id,
+ float aspect,
+ float alpha,
+ float desaturate,
+ const char mono_color[4],
+ const bool mono_border);
+
void UI_icon_draw_desaturate(float x,
float y,
int icon_id,
@@ -81,6 +85,7 @@ void UI_icon_draw_desaturate(float x,
float alpha,
float desaturate,
const char mono_color[4]);
+
void UI_icons_free(void);
void UI_icons_free_drawinfo(void *drawinfo);
diff --git a/source/blender/editors/include/UI_resources.h b/source/blender/editors/include/UI_resources.h
index af94889a1bb..7abc27c5b37 100644
--- a/source/blender/editors/include/UI_resources.h
+++ b/source/blender/editors/include/UI_resources.h
@@ -105,6 +105,7 @@ typedef enum ThemeColorID {
TH_FACE_DOT,
TH_FACEDOT_SIZE,
TH_CFRAME,
+ TH_SCRUBBING_BACKGROUND,
TH_TIME_KEYFRAME,
TH_TIME_GP_KEYFRAME,
TH_NURB_ULINE,
@@ -261,12 +262,15 @@ typedef enum ThemeColorID {
TH_ANIM_INACTIVE, /* no active action */
TH_ANIM_PREVIEW_RANGE, /* preview range overlay */
+ TH_ICON_SCENE,
TH_ICON_COLLECTION,
TH_ICON_OBJECT,
TH_ICON_OBJECT_DATA,
TH_ICON_MODIFIER,
TH_ICON_SHADING,
+ TH_SCROLL_TEXT,
+
TH_NLA_TWEAK, /* 'tweaking' track in NLA */
TH_NLA_TWEAK_DUPLI, /* error/warning flag for other strips referencing dupli strip */
@@ -380,7 +384,7 @@ void UI_GetThemeColorType3ubv(int colorid, int spacetype, unsigned char col[3]);
void UI_GetThemeColorType4ubv(int colorid, int spacetype, unsigned char col[4]);
// get theme color for coloring monochrome icons
-bool UI_GetIconThemeColor4fv(int colorid, float col[4]);
+bool UI_GetIconThemeColor4ubv(int colorid, unsigned char col[4]);
// shade a 3 byte color (same as UI_GetColorPtrBlendShade3ubv with 0.0 factor)
void UI_GetColorPtrShade3ubv(const unsigned char cp1[3], unsigned char col[3], int offset);
diff --git a/source/blender/editors/include/UI_view2d.h b/source/blender/editors/include/UI_view2d.h
index 064951d40ed..d03d4b1b4f5 100644
--- a/source/blender/editors/include/UI_view2d.h
+++ b/source/blender/editors/include/UI_view2d.h
@@ -63,9 +63,9 @@ enum eView2D_CommonViewTypes {
/* scroller area */
#define V2D_SCROLL_HEIGHT (0.45f * U.widget_unit)
#define V2D_SCROLL_WIDTH (0.45f * U.widget_unit)
-/* For scrollers with scale markings (text written onto them) */
-#define V2D_SCROLL_HEIGHT_TEXT (0.79f * U.widget_unit)
-#define V2D_SCROLL_WIDTH_TEXT (0.79f * U.widget_unit)
+/* For scrollers with scale handlers */
+#define V2D_SCROLL_HEIGHT_HANDLES (0.6f * U.widget_unit)
+#define V2D_SCROLL_WIDTH_HANDLES (0.6f * U.widget_unit)
/* scroller 'handles' hotspot radius for mouse */
#define V2D_SCROLLER_HANDLE_SIZE (0.6f * U.widget_unit)
@@ -258,6 +258,8 @@ void UI_view2d_smooth_view(struct bContext *C,
struct ARegion *ar,
const struct rctf *cur,
const int smooth_viewtx);
+
#define UI_MARKER_MARGIN_Y (42 * UI_DPI_FAC)
+#define UI_SCRUBBING_MARGIN_Y (23 * UI_DPI_FAC)
#endif /* __UI_VIEW2D_H__ */
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 42f4b4495c3..7c60ac75df8 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -3235,6 +3235,11 @@ uiBlock *UI_block_begin(const bContext *C, ARegion *region, const char *name, sh
return block;
}
+char UI_block_emboss_get(uiBlock *block)
+{
+ return block->dt;
+}
+
void UI_block_emboss_set(uiBlock *block, char dt)
{
block->dt = dt;
diff --git a/source/blender/editors/interface/interface_anim.c b/source/blender/editors/interface/interface_anim.c
index b9de504f3b2..e34d67b6996 100644
--- a/source/blender/editors/interface/interface_anim.c
+++ b/source/blender/editors/interface/interface_anim.c
@@ -82,6 +82,11 @@ void ui_but_anim_flag(uiBut *but, float cfra)
if (fcu) {
if (!driven) {
+ /* Empty curves are ignored by the animation evaluation system. */
+ if (fcu->totvert == 0) {
+ return;
+ }
+
but->flag |= UI_BUT_ANIMATED;
/* T41525 - When the active action is a NLA strip being edited,
diff --git a/source/blender/editors/interface/interface_context_menu.c b/source/blender/editors/interface/interface_context_menu.c
index 748d6e6c183..0055349d4be 100644
--- a/source/blender/editors/interface/interface_context_menu.c
+++ b/source/blender/editors/interface/interface_context_menu.c
@@ -58,30 +58,90 @@
/** \name Button Context Menu
* \{ */
-static void but_shortcut_name_func(bContext *C, void *arg1, int UNUSED(event))
+static IDProperty *shortcut_property_from_rna(bContext *C, uiBut *but)
{
- uiBut *but = (uiBut *)arg1;
+ /* Compute data path from context to property. */
+ const char *member_id = WM_context_member_from_ptr(C, &but->rnapoin);
+ const char *data_path = RNA_path_from_ID_to_struct(&but->rnapoin);
+ const char *member_id_data_path = member_id;
+
+ if (data_path) {
+ member_id_data_path = BLI_sprintfN("%s.%s", member_id, data_path);
+ MEM_freeN((void *)data_path);
+ }
- if (but->optype) {
- char shortcut_str[128];
+ const char *prop_id = RNA_property_identifier(but->rnaprop);
+ const char *final_data_path = BLI_sprintfN("%s.%s", member_id_data_path, prop_id);
- IDProperty *prop = (but->opptr) ? but->opptr->data : NULL;
+ if (member_id != member_id_data_path) {
+ MEM_freeN((void *)member_id_data_path);
+ }
+
+ /* Create ID property of data path, to pass to the operator. */
+ IDProperty *prop;
+ IDPropertyTemplate val = {0};
+ prop = IDP_New(IDP_GROUP, &val, __func__);
+ IDP_AddToGroup(prop, IDP_NewString(final_data_path, "data_path", strlen(final_data_path) + 1));
+
+ MEM_freeN((void *)final_data_path);
+
+ return prop;
+}
- /* complex code to change name of button */
- if (WM_key_event_operator_string(C,
- but->optype->idname,
- but->opcontext,
- prop,
- true,
- shortcut_str,
- sizeof(shortcut_str))) {
- ui_but_add_shortcut(but, shortcut_str, true);
+static const char *shortcut_get_operator_property(bContext *C, uiBut *but, IDProperty **prop)
+{
+ if (but->optype) {
+ /* Operator */
+ *prop = (but->opptr) ? IDP_CopyProperty(but->opptr->data) : NULL;
+ return but->optype->idname;
+ }
+ else if (but->rnaprop) {
+ if (RNA_property_type(but->rnaprop) == PROP_BOOLEAN) {
+ /* Boolean */
+ *prop = shortcut_property_from_rna(C, but);
+ return "WM_OT_context_toggle";
}
- else {
- /* simply strip the shortcut */
- ui_but_add_shortcut(but, NULL, true);
+ else if (RNA_property_type(but->rnaprop) == PROP_ENUM) {
+ /* Enum */
+ *prop = shortcut_property_from_rna(C, but);
+ return "WM_OT_context_menu_enum";
}
}
+
+ *prop = NULL;
+ return NULL;
+}
+
+static void shortcut_free_operator_property(IDProperty *prop)
+{
+ if (prop) {
+ IDP_FreeProperty(prop);
+ MEM_freeN(prop);
+ }
+}
+
+static void but_shortcut_name_func(bContext *C, void *arg1, int UNUSED(event))
+{
+ uiBut *but = (uiBut *)arg1;
+ char shortcut_str[128];
+
+ IDProperty *prop;
+ const char *idname = shortcut_get_operator_property(C, but, &prop);
+ if (idname == NULL) {
+ return;
+ }
+
+ /* complex code to change name of button */
+ if (WM_key_event_operator_string(
+ C, idname, but->opcontext, prop, true, shortcut_str, sizeof(shortcut_str))) {
+ ui_but_add_shortcut(but, shortcut_str, true);
+ }
+ else {
+ /* simply strip the shortcut */
+ ui_but_add_shortcut(but, NULL, true);
+ }
+
+ shortcut_free_operator_property(prop);
}
static uiBlock *menu_change_shortcut(bContext *C, ARegion *ar, void *arg)
@@ -94,15 +154,18 @@ static uiBlock *menu_change_shortcut(bContext *C, ARegion *ar, void *arg)
PointerRNA ptr;
uiLayout *layout;
uiStyle *style = UI_style_get_dpi();
- IDProperty *prop = (but->opptr) ? but->opptr->data : NULL;
+ IDProperty *prop;
+ const char *idname = shortcut_get_operator_property(C, but, &prop);
kmi = WM_key_event_operator(C,
- but->optype->idname,
+ idname,
but->opcontext,
prop,
EVT_TYPE_MASK_HOTKEY_INCLUDE,
EVT_TYPE_MASK_HOTKEY_EXCLUDE,
&km);
+ U.runtime.is_dirty = true;
+
BLI_assert(kmi != NULL);
RNA_pointer_create(&wm->id, &RNA_KeyMapItem, kmi, &ptr);
@@ -118,6 +181,8 @@ static uiBlock *menu_change_shortcut(bContext *C, ARegion *ar, void *arg)
UI_block_bounds_set_popup(block, 6, (const int[2]){-50, 26});
+ shortcut_free_operator_property(prop);
+
return block;
}
@@ -135,25 +200,24 @@ static uiBlock *menu_add_shortcut(bContext *C, ARegion *ar, void *arg)
PointerRNA ptr;
uiLayout *layout;
uiStyle *style = UI_style_get_dpi();
- IDProperty *prop = (but->opptr) ? but->opptr->data : NULL;
int kmi_id;
+ IDProperty *prop;
+ const char *idname = shortcut_get_operator_property(C, but, &prop);
/* XXX this guess_opname can potentially return a different keymap
* than being found on adding later... */
- km = WM_keymap_guess_opname(C, but->optype->idname);
- kmi = WM_keymap_add_item(km, but->optype->idname, AKEY, KM_PRESS, 0, 0);
+ km = WM_keymap_guess_opname(C, idname);
+ kmi = WM_keymap_add_item(km, idname, AKEY, KM_PRESS, 0, 0);
kmi_id = kmi->id;
- /* copy properties, prop can be NULL for reset */
- if (prop) {
- prop = IDP_CopyProperty(prop);
- }
+ /* This takes ownership of prop, or prop can be NULL for reset. */
WM_keymap_item_properties_reset(kmi, prop);
/* update and get pointers again */
WM_keyconfig_update(wm);
+ U.runtime.is_dirty = true;
- km = WM_keymap_guess_opname(C, but->optype->idname);
+ km = WM_keymap_guess_opname(C, idname);
kmi = WM_keymap_item_find_id(km, kmi_id);
RNA_pointer_create(&wm->id, &RNA_KeyMapItem, kmi, &ptr);
@@ -171,6 +235,7 @@ static uiBlock *menu_add_shortcut(bContext *C, ARegion *ar, void *arg)
#ifdef USE_KEYMAP_ADD_HACK
g_kmi_id_hack = kmi_id;
#endif
+
return block;
}
@@ -179,20 +244,21 @@ static void menu_add_shortcut_cancel(struct bContext *C, void *arg1)
uiBut *but = (uiBut *)arg1;
wmKeyMap *km;
wmKeyMapItem *kmi;
-#ifndef USE_KEYMAP_ADD_HACK
- IDProperty *prop;
-#endif
int kmi_id;
+ IDProperty *prop;
+ const char *idname = shortcut_get_operator_property(C, but, &prop);
+
#ifdef USE_KEYMAP_ADD_HACK
- km = WM_keymap_guess_opname(C, but->optype->idname);
+ km = WM_keymap_guess_opname(C, idname);
kmi_id = g_kmi_id_hack;
UNUSED_VARS(but);
#else
- prop = (but->opptr) ? but->opptr->data : NULL;
- kmi_id = WM_key_event_operator_id(C, but->optype->idname, but->opcontext, prop, true, &km);
+ kmi_id = WM_key_event_operator_id(C, idname, but->opcontext, prop, true, &km);
#endif
+ shortcut_free_operator_property(prop);
+
kmi = WM_keymap_item_find_id(km, kmi_id);
WM_keymap_remove_item(km, kmi);
}
@@ -200,7 +266,7 @@ static void menu_add_shortcut_cancel(struct bContext *C, void *arg1)
static void popup_change_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg2))
{
uiBut *but = (uiBut *)arg1;
- UI_popup_block_invoke(C, menu_change_shortcut, but);
+ UI_popup_block_invoke(C, menu_change_shortcut, but, NULL);
}
static void remove_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg2))
@@ -208,10 +274,11 @@ static void remove_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg2))
uiBut *but = (uiBut *)arg1;
wmKeyMap *km;
wmKeyMapItem *kmi;
- IDProperty *prop = (but->opptr) ? but->opptr->data : NULL;
+ IDProperty *prop;
+ const char *idname = shortcut_get_operator_property(C, but, &prop);
kmi = WM_key_event_operator(C,
- but->optype->idname,
+ idname,
but->opcontext,
prop,
EVT_TYPE_MASK_HOTKEY_INCLUDE,
@@ -220,7 +287,9 @@ static void remove_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg2))
BLI_assert(kmi != NULL);
WM_keymap_remove_item(km, kmi);
+ U.runtime.is_dirty = true;
+ shortcut_free_operator_property(prop);
but_shortcut_name_func(C, but, 0);
}
@@ -323,6 +392,7 @@ static void popup_user_menu_add_or_replace_func(bContext *C, void *arg1, void *U
{
uiBut *but = arg1;
bUserMenu *um = ED_screen_user_menu_ensure(C);
+ U.runtime.is_dirty = true;
ui_but_user_menu_add(C, but, um);
}
@@ -330,6 +400,7 @@ static void popup_user_menu_remove_func(bContext *UNUSED(C), void *arg1, void *a
{
bUserMenu *um = arg1;
bUserMenuItem *umi = arg2;
+ U.runtime.is_dirty = true;
ED_screen_user_menu_item_remove(&um->items, umi);
}
@@ -890,16 +961,18 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but)
uiItemS(layout);
}
- /* Operator buttons */
- if (but->optype) {
+ /* Shortcut menu */
+ IDProperty *prop;
+ const char *idname = shortcut_get_operator_property(C, but, &prop);
+ if (idname != NULL) {
uiBlock *block = uiLayoutGetBlock(layout);
uiBut *but2;
- IDProperty *prop = (but->opptr) ? but->opptr->data : NULL;
int w = uiLayoutGetWidth(layout);
wmKeyMap *km;
+
/* We want to know if this op has a shortcut, be it hotkey or not. */
wmKeyMapItem *kmi = WM_key_event_operator(
- C, but->optype->idname, but->opcontext, prop, EVT_TYPE_MASK_ALL, 0, &km);
+ C, idname, but->opcontext, prop, EVT_TYPE_MASK_ALL, 0, &km);
/* We do have a shortcut, but only keyboard ones are editable that way... */
if (kmi) {
@@ -971,7 +1044,7 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but)
}
}
/* only show 'assign' if there's a suitable key map for it to go in */
- else if (WM_keymap_guess_opname(C, but->optype->idname)) {
+ else if (WM_keymap_guess_opname(C, idname)) {
but2 = uiDefIconTextBut(block,
UI_BTYPE_BUT,
0,
@@ -990,6 +1063,8 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but)
UI_but_func_set(but2, popup_add_shortcut_func, but, NULL);
}
+ shortcut_free_operator_property(prop);
+
/* Set the operator pointer for python access */
uiLayoutSetContextFromBut(layout, but);
@@ -1108,6 +1183,9 @@ void ui_popup_context_menu_for_panel(bContext *C, ARegion *ar, Panel *pa)
if (!any_item_visible) {
return;
}
+ if (pa->type->parent != NULL) {
+ return;
+ }
RNA_pointer_create(&sc->id, &RNA_Panel, pa, &ptr);
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 111dfe01319..e4adf757c80 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -551,6 +551,32 @@ static bool ui_but_dragedit_update_mval(uiHandleButtonData *data, int mx)
return true;
}
+static void ui_but_update_preferences_dirty(uiBut *but)
+{
+ /* Not very elegant, but ensures preference changes force re-save. */
+ bool tag = false;
+ if (but->rnaprop) {
+ if (but->rnapoin.data == &U) {
+ /* Exclude navigation from setting dirty. */
+ extern PropertyRNA rna_Preferences_active_section;
+ if (!ELEM(but->rnaprop, &rna_Preferences_active_section)) {
+ tag = true;
+ }
+ }
+ else {
+ StructRNA *base = RNA_struct_base(but->rnapoin.type);
+ if (ELEM(base, &RNA_AddonPreferences, &RNA_KeyConfigPreferences)) {
+ tag = true;
+ }
+ }
+ }
+
+ if (tag) {
+ U.runtime.is_dirty = true;
+ WM_main_add_notifier(NC_WINDOW, NULL);
+ }
+}
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -1334,6 +1360,9 @@ static bool ui_drag_toggle_set_xy_xy(
if (do_check) {
ui_but_update_edited(but);
}
+ if (U.runtime.is_dirty == false) {
+ ui_but_update_preferences_dirty(but);
+ }
changed = true;
}
}
@@ -3769,7 +3798,7 @@ static void ui_block_open_begin(bContext *C, uiBut *but, uiHandleButtonData *dat
}
if (func || handlefunc) {
- data->menu = ui_popup_block_create(C, data->region, but, func, handlefunc, arg);
+ data->menu = ui_popup_block_create(C, data->region, but, func, handlefunc, arg, NULL);
if (but->block->handle) {
data->menu->popup = but->block->handle->popup;
}
@@ -5622,6 +5651,13 @@ static int ui_do_but_UNITVEC(
}
}
}
+ else if (event->type == ESCKEY || event->type == RIGHTMOUSE) {
+ if (event->val == KM_PRESS) {
+ data->cancel = true;
+ data->escapecancel = true;
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ }
else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
button_activate_state(C, but, BUTTON_STATE_EXIT);
}
@@ -7566,6 +7602,10 @@ static void button_activate_exit(
if (block->flag & UI_BLOCK_POPUP_MEMORY) {
ui_popup_menu_memory_set(block, but);
}
+
+ if (U.runtime.is_dirty == false) {
+ ui_but_update_preferences_dirty(but);
+ }
}
/* disable tooltips until mousemove + last active flag */
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index 7e295f83390..e53e9694617 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -37,6 +37,7 @@
#include "BLI_utildefines.h"
#include "BLI_fileops_types.h"
#include "BLI_math_vector.h"
+#include "BLI_math_color_blend.h"
#include "DNA_brush_types.h"
#include "DNA_curve_types.h"
@@ -83,6 +84,7 @@
# define ICON_GRID_COLS 26
# define ICON_GRID_ROWS 30
+# define ICON_MONO_BORDER_OUTSET 2
# define ICON_GRID_MARGIN 10
# define ICON_GRID_W 32
# define ICON_GRID_H 32
@@ -138,7 +140,8 @@ typedef struct DrawInfo {
} DrawInfo;
typedef struct IconTexture {
- GLuint id;
+ GLuint id[2];
+ int num_textures;
int w;
int h;
float invw;
@@ -154,12 +157,13 @@ typedef struct IconType {
/* static here to cache results of icon directory scan, so it's not
* scanning the filesystem each time the menu is drawn */
static struct ListBase iconfilelist = {NULL, NULL};
-static IconTexture icongltex = {0, 0, 0, 0.0f, 0.0f};
+static IconTexture icongltex = {{0, 0}, 0, 0, 0, 0.0f, 0.0f};
#ifndef WITH_HEADLESS
static const IconType icontypes[] = {
# define DEF_ICON(name) {ICON_TYPE_MONO_TEXTURE, 0},
+# define DEF_ICON_SCENE(name) {ICON_TYPE_MONO_TEXTURE, TH_ICON_SCENE},
# define DEF_ICON_COLLECTION(name) {ICON_TYPE_MONO_TEXTURE, TH_ICON_COLLECTION},
# define DEF_ICON_OBJECT(name) {ICON_TYPE_MONO_TEXTURE, TH_ICON_OBJECT},
# define DEF_ICON_OBJECT_DATA(name) {ICON_TYPE_MONO_TEXTURE, TH_ICON_OBJECT_DATA},
@@ -713,38 +717,146 @@ static void icon_verify_datatoc(IconImage *iimg)
}
}
-static void init_internal_icons(void)
+static ImBuf *create_mono_icon_with_border(ImBuf *buf,
+ int resolution_divider,
+ float border_intensity)
{
- // bTheme *btheme = UI_GetTheme();
- ImBuf *b16buf = NULL, *b32buf = NULL;
- int x, y;
+ ImBuf *result = IMB_dupImBuf(buf);
+ const float border_sharpness = 16.0 / (resolution_divider * resolution_divider);
-# if 0 // temp disabled
- if ((btheme != NULL) && btheme->tui.iconfile[0]) {
- char *icondir = BKE_appdir_folder_id(BLENDER_DATAFILES, "icons");
- char iconfilestr[FILE_MAX];
+ float blurred_alpha_buffer[(ICON_GRID_W + 2 * ICON_MONO_BORDER_OUTSET) *
+ (ICON_GRID_H + 2 * ICON_MONO_BORDER_OUTSET)];
+ const int icon_width = (ICON_GRID_W + 2 * ICON_MONO_BORDER_OUTSET) / resolution_divider;
+ const int icon_height = (ICON_GRID_W + 2 * ICON_MONO_BORDER_OUTSET) / resolution_divider;
- if (icondir) {
- BLI_join_dirfile(iconfilestr, sizeof(iconfilestr), icondir, btheme->tui.iconfile);
+ for (int y = 0; y < ICON_GRID_ROWS; y++) {
+ for (int x = 0; x < ICON_GRID_COLS; x++) {
+ IconType icontype = icontypes[y * ICON_GRID_COLS + x];
+ if (icontype.type != ICON_TYPE_MONO_TEXTURE) {
+ continue;
+ }
- /* if the image is missing bbuf will just be NULL */
- bbuf = IMB_loadiffname(iconfilestr, IB_rect, NULL);
+ int sx = x * (ICON_GRID_W + ICON_GRID_MARGIN) + ICON_GRID_MARGIN - ICON_MONO_BORDER_OUTSET;
+ int sy = y * (ICON_GRID_H + ICON_GRID_MARGIN) + ICON_GRID_MARGIN - ICON_MONO_BORDER_OUTSET;
+ sx = sx / resolution_divider;
+ sy = sy / resolution_divider;
+
+ /* blur the alpha channel and store it in blurred_alpha_buffer */
+ int blur_size = 2 / resolution_divider;
+ for (int bx = 0; bx < icon_width; bx++) {
+ const int asx = MAX2(bx - blur_size, 0);
+ const int aex = MIN2(bx + blur_size + 1, icon_width);
+ for (int by = 0; by < icon_height; by++) {
+ const int asy = MAX2(by - blur_size, 0);
+ const int aey = MIN2(by + blur_size + 1, icon_height);
+
+ // blur alpha channel
+ const int write_offset = by * (ICON_GRID_W + 2 * ICON_MONO_BORDER_OUTSET) + bx;
+ float alpha_accum = 0.0;
+ unsigned int alpha_samples = 0;
+ for (int ax = asx; ax < aex; ax++) {
+ for (int ay = asy; ay < aey; ay++) {
+ const int offset_read = (sy + ay) * buf->x + (sx + ax);
+ unsigned int color_read = buf->rect[offset_read];
+ const float alpha_read = ((color_read & 0xff000000) >> 24) / 255.0;
+ alpha_accum += alpha_read;
+ alpha_samples += 1;
+ }
+ }
+ blurred_alpha_buffer[write_offset] = alpha_accum / alpha_samples;
+ }
+ }
- if (bbuf && (bbuf->x < ICON_IMAGE_W || bbuf->y < ICON_IMAGE_H)) {
- printf(
- "\n***WARNING***\n"
- "Icons file '%s' too small.\n"
- "Using built-in Icons instead\n",
- iconfilestr);
- IMB_freeImBuf(bbuf);
- bbuf = NULL;
+ /* apply blurred alpha */
+ for (int bx = 0; bx < icon_width; bx++) {
+ for (int by = 0; by < icon_height; by++) {
+ const int blurred_alpha_offset = by * (ICON_GRID_W + 2 * ICON_MONO_BORDER_OUTSET) + bx;
+ const int offset_write = (sy + by) * buf->x + (sx + bx);
+ const float blurred_alpha = blurred_alpha_buffer[blurred_alpha_offset];
+ float border_srgb[4] = {
+ 0, 0, 0, MIN2(1.0, blurred_alpha * border_sharpness) * border_intensity};
+
+ const unsigned int color_read = buf->rect[offset_write];
+ const unsigned char *orig_color = (unsigned char *)&color_read;
+
+ float border_rgba[4];
+ float orig_rgba[4];
+ float dest_rgba[4];
+ float dest_srgb[4];
+
+ srgb_to_linearrgb_v4(border_rgba, border_srgb);
+ srgb_to_linearrgb_uchar4(orig_rgba, orig_color);
+ blend_color_interpolate_float(dest_rgba, orig_rgba, border_rgba, 1.0 - orig_rgba[3]);
+ linearrgb_to_srgb_v4(dest_srgb, dest_rgba);
+
+ unsigned int alpha_mask = ((unsigned int)(dest_srgb[3] * 255)) << 24;
+ unsigned int cpack = rgb_to_cpack(dest_srgb[0], dest_srgb[1], dest_srgb[2]) | alpha_mask;
+ result->rect[offset_write] = cpack;
+ }
}
}
- else {
- printf("%s: 'icons' data path not found, continuing\n", __func__);
+ }
+ return result;
+}
+
+/* Generate the mipmap levels for the icon textures
+ * During creation the source16 ImBuf will be freed to reduce memory overhead
+ * A new ImBuf will be returned that needs is owned by the caller.
+ *
+ * FIXME: Mipmap levels are generated until the width of the image is 1, which
+ * are too many levels than that are needed.*/
+static ImBuf *create_mono_icon_mipmaps(ImBuf *source32, ImBuf *source16, int level)
+{
+ if (level == 0) {
+ glTexImage2D(GL_TEXTURE_2D,
+ level,
+ GL_RGBA8,
+ source32->x,
+ source32->y,
+ 0,
+ GL_RGBA,
+ GL_UNSIGNED_BYTE,
+ source32->rect);
+ return create_mono_icon_mipmaps(source32, source16, level + 1);
+ }
+ else {
+ glTexImage2D(GL_TEXTURE_2D,
+ level,
+ GL_RGBA8,
+ source16->x,
+ source16->y,
+ 0,
+ GL_RGBA,
+ GL_UNSIGNED_BYTE,
+ source16->rect);
+ if (source16->x > 1) {
+ ImBuf *nbuf = IMB_onehalf(source16);
+ IMB_freeImBuf(source16);
+ source16 = create_mono_icon_mipmaps(source32, nbuf, level + 1);
}
+ return source16;
}
-# endif
+}
+
+static void free_icons_textures(void)
+{
+ if (icongltex.num_textures > 0) {
+ glDeleteTextures(icongltex.num_textures, icongltex.id);
+ icongltex.id[0] = 0;
+ icongltex.id[1] = 0;
+ icongltex.num_textures = 0;
+ }
+}
+
+/* Reload the textures for internal icons.
+ * This function will release the previous textures. */
+void UI_icons_reload_internal_textures(void)
+{
+ bTheme *btheme = UI_GetTheme();
+ ImBuf *b16buf = NULL, *b32buf = NULL, *b16buf_border = NULL, *b32buf_border = NULL;
+ const float icon_border_intensity = btheme->tui.icon_border_intensity;
+ bool need_icons_with_border = icon_border_intensity > 0.0f;
+
if (b16buf == NULL) {
b16buf = IMB_ibImageFromMemory((const uchar *)datatoc_blender_icons16_png,
datatoc_blender_icons16_png_size,
@@ -753,6 +865,10 @@ static void init_internal_icons(void)
"<blender icons>");
}
if (b16buf) {
+ if (need_icons_with_border) {
+ b16buf_border = create_mono_icon_with_border(b16buf, 2, icon_border_intensity);
+ IMB_premultiply_alpha(b16buf_border);
+ }
IMB_premultiply_alpha(b16buf);
}
@@ -764,88 +880,97 @@ static void init_internal_icons(void)
"<blender icons>");
}
if (b32buf) {
+ if (need_icons_with_border) {
+ b32buf_border = create_mono_icon_with_border(b32buf, 1, icon_border_intensity);
+ IMB_premultiply_alpha(b32buf_border);
+ }
IMB_premultiply_alpha(b32buf);
}
if (b16buf && b32buf) {
/* Free existing texture if any. */
- if (icongltex.id) {
- glDeleteTextures(1, &icongltex.id);
- icongltex.id = 0;
- }
+ free_icons_textures();
/* Allocate OpenGL texture. */
- glGenTextures(1, &icongltex.id);
-
- if (icongltex.id) {
- int level = 2;
+ icongltex.num_textures = need_icons_with_border ? 2 : 1;
+ glGenTextures(icongltex.num_textures, icongltex.id);
+ if (icongltex.id[0]) {
icongltex.w = b32buf->x;
icongltex.h = b32buf->y;
icongltex.invw = 1.0f / b32buf->x;
icongltex.invh = 1.0f / b32buf->y;
- glBindTexture(GL_TEXTURE_2D, icongltex.id);
-
- glTexImage2D(GL_TEXTURE_2D,
- 0,
- GL_RGBA8,
- b32buf->x,
- b32buf->y,
- 0,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- b32buf->rect);
- glTexImage2D(GL_TEXTURE_2D,
- 1,
- GL_RGBA8,
- b16buf->x,
- b16buf->y,
- 0,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- b16buf->rect);
-
- while (b16buf->x > 1) {
- ImBuf *nbuf = IMB_onehalf(b16buf);
- glTexImage2D(GL_TEXTURE_2D,
- level,
- GL_RGBA8,
- nbuf->x,
- nbuf->y,
- 0,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- nbuf->rect);
- level++;
- IMB_freeImBuf(b16buf);
- b16buf = nbuf;
- }
-
+ glBindTexture(GL_TEXTURE_2D, icongltex.id[0]);
+ b16buf = create_mono_icon_mipmaps(b32buf, b16buf, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ }
+ if (need_icons_with_border && icongltex.id[1]) {
+ glBindTexture(GL_TEXTURE_2D, icongltex.id[1]);
+ b16buf_border = create_mono_icon_mipmaps(b32buf_border, b16buf_border, 0);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
}
+ }
- /* Define icons. */
- for (y = 0; y < ICON_GRID_ROWS; y++) {
- /* Row W has monochrome icons. */
- for (x = 0; x < ICON_GRID_COLS; x++) {
- IconType icontype = icontypes[y * ICON_GRID_COLS + x];
- if (!ELEM(icontype.type, ICON_TYPE_COLOR_TEXTURE, ICON_TYPE_MONO_TEXTURE)) {
- continue;
- }
+ IMB_freeImBuf(b16buf);
+ IMB_freeImBuf(b32buf);
+ IMB_freeImBuf(b16buf_border);
+ IMB_freeImBuf(b32buf_border);
+}
+
+static void init_internal_icons(void)
+{
+ int x, y;
+
+# if 0 // temp disabled
+ if ((btheme != NULL) && btheme->tui.iconfile[0]) {
+ char *icondir = BKE_appdir_folder_id(BLENDER_DATAFILES, "icons");
+ char iconfilestr[FILE_MAX];
+
+ if (icondir) {
+ BLI_join_dirfile(iconfilestr, sizeof(iconfilestr), icondir, btheme->tui.iconfile);
+
+ /* if the image is missing bbuf will just be NULL */
+ bbuf = IMB_loadiffname(iconfilestr, IB_rect, NULL);
- def_internal_icon(b32buf,
- BIFICONID_FIRST + y * ICON_GRID_COLS + x,
- x * (ICON_GRID_W + ICON_GRID_MARGIN) + ICON_GRID_MARGIN,
- y * (ICON_GRID_H + ICON_GRID_MARGIN) + ICON_GRID_MARGIN,
- ICON_GRID_W,
- icontype.type,
- icontype.theme_color);
+ if (bbuf && (bbuf->x < ICON_IMAGE_W || bbuf->y < ICON_IMAGE_H)) {
+ printf(
+ "\n***WARNING***\n"
+ "Icons file '%s' too small.\n"
+ "Using built-in Icons instead\n",
+ iconfilestr);
+ IMB_freeImBuf(bbuf);
+ bbuf = NULL;
}
}
+ else {
+ printf("%s: 'icons' data path not found, continuing\n", __func__);
+ }
+ }
+# endif
+
+ /* Define icons. */
+ for (y = 0; y < ICON_GRID_ROWS; y++) {
+ /* Row W has monochrome icons. */
+ for (x = 0; x < ICON_GRID_COLS; x++) {
+ IconType icontype = icontypes[y * ICON_GRID_COLS + x];
+ if (!ELEM(icontype.type, ICON_TYPE_COLOR_TEXTURE, ICON_TYPE_MONO_TEXTURE)) {
+ continue;
+ }
+
+ def_internal_icon(NULL,
+ BIFICONID_FIRST + y * ICON_GRID_COLS + x,
+ x * (ICON_GRID_W + ICON_GRID_MARGIN) + ICON_GRID_MARGIN,
+ y * (ICON_GRID_H + ICON_GRID_MARGIN) + ICON_GRID_MARGIN,
+ ICON_GRID_W,
+ icontype.type,
+ icontype.theme_color);
+ }
}
def_internal_vicon(ICON_SMALL_TRI_RIGHT_VEC, vicon_small_tri_right_draw);
@@ -882,9 +1007,6 @@ static void init_internal_icons(void)
def_internal_vicon(ICON_COLORSET_18_VEC, vicon_colorset_draw_18);
def_internal_vicon(ICON_COLORSET_19_VEC, vicon_colorset_draw_19);
def_internal_vicon(ICON_COLORSET_20_VEC, vicon_colorset_draw_20);
-
- IMB_freeImBuf(b16buf);
- IMB_freeImBuf(b32buf);
}
# endif /* WITH_HEADLESS */
@@ -990,11 +1112,7 @@ ListBase *UI_iconfile_list(void)
void UI_icons_free(void)
{
#ifndef WITH_HEADLESS
- if (icongltex.id) {
- glDeleteTextures(1, &icongltex.id);
- icongltex.id = 0;
- }
-
+ free_icons_textures();
free_iconfile_list(&iconfilelist);
BKE_icons_free();
#endif
@@ -1104,10 +1222,22 @@ int UI_icon_get_height(int icon_id)
return 0;
}
+bool UI_icon_get_theme_color(int icon_id, uchar color[4])
+{
+ Icon *icon = BKE_icon_get(icon_id);
+ if (icon == NULL) {
+ return false;
+ }
+
+ DrawInfo *di = icon_ensure_drawinfo(icon);
+ return UI_GetIconThemeColor4ubv(di->data.texture.theme_color, color);
+}
+
void UI_icons_init()
{
#ifndef WITH_HEADLESS
init_iconfile_list(&iconfilelist);
+ UI_icons_reload_internal_textures();
init_internal_icons();
init_brush_icons();
init_event_icons();
@@ -1348,7 +1478,6 @@ static void icon_draw_rect(float x,
int rh,
uint *rect,
float alpha,
- const float rgb[3],
const float desaturate)
{
ImBuf *ima = NULL;
@@ -1366,12 +1495,6 @@ static void icon_draw_rect(float x,
/* modulate color */
float col[4] = {1.0f, 1.0f, 1.0f, alpha};
- if (rgb) {
- col[0] = rgb[0];
- col[1] = rgb[1];
- col[2] = rgb[2];
- }
-
/* rect contains image in 'rendersize', we only scale if needed */
if (rw != w || rh != h) {
/* preserve aspect ratio and center */
@@ -1439,12 +1562,17 @@ typedef struct IconDrawCall {
float color[4];
} IconDrawCall;
-static struct {
+typedef struct IconTextureDrawCall {
IconDrawCall drawcall_cache[ICON_DRAW_CACHE_SIZE];
int calls; /* Number of calls batched together */
+} IconTextureDrawCall;
+
+static struct {
+ IconTextureDrawCall normal;
+ IconTextureDrawCall border;
bool enabled;
float mat[4][4];
-} g_icon_draw_cache = {{{{0}}}};
+} g_icon_draw_cache = {{{{{0}}}}};
void UI_icon_draw_cache_begin(void)
{
@@ -1452,19 +1580,15 @@ void UI_icon_draw_cache_begin(void)
g_icon_draw_cache.enabled = true;
}
-static void icon_draw_cache_flush_ex(void)
+static void icon_draw_cache_texture_flush_ex(GLuint texture,
+ IconTextureDrawCall *texture_draw_calls)
{
- if (g_icon_draw_cache.calls == 0) {
+ if (texture_draw_calls->calls == 0) {
return;
}
- /* We need to flush widget base first to ensure correct ordering. */
- UI_widgetbase_draw_cache_flush();
-
- GPU_blend_set_func(GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
-
glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, icongltex.id);
+ glBindTexture(GL_TEXTURE_2D, texture);
GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_IMAGE_MULTI_RECT_COLOR);
GPU_shader_bind(shader);
@@ -1473,16 +1597,43 @@ static void icon_draw_cache_flush_ex(void)
int data_loc = GPU_shader_get_uniform_ensure(shader, "calls_data[0]");
glUniform1i(img_loc, 0);
- glUniform4fv(data_loc, ICON_DRAW_CACHE_SIZE * 3, (float *)g_icon_draw_cache.drawcall_cache);
+ glUniform4fv(data_loc, ICON_DRAW_CACHE_SIZE * 3, (float *)texture_draw_calls->drawcall_cache);
- GPU_draw_primitive(GPU_PRIM_TRIS, 6 * g_icon_draw_cache.calls);
+ GPU_draw_primitive(GPU_PRIM_TRIS, 6 * texture_draw_calls->calls);
glBindTexture(GL_TEXTURE_2D, 0);
- g_icon_draw_cache.calls = 0;
+ texture_draw_calls->calls = 0;
+}
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+static void icon_draw_cache_flush_ex(bool only_full_caches)
+{
+ bool should_draw = false;
+ if (only_full_caches) {
+ should_draw = g_icon_draw_cache.normal.calls == ICON_DRAW_CACHE_SIZE ||
+ g_icon_draw_cache.border.calls == ICON_DRAW_CACHE_SIZE;
+ }
+ else {
+ should_draw = g_icon_draw_cache.normal.calls || g_icon_draw_cache.border.calls;
+ }
+
+ if (should_draw) {
+ /* We need to flush widget base first to ensure correct ordering. */
+ UI_widgetbase_draw_cache_flush();
+
+ GPU_blend_set_func(GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+
+ if (!only_full_caches || g_icon_draw_cache.normal.calls == ICON_DRAW_CACHE_SIZE) {
+ icon_draw_cache_texture_flush_ex(icongltex.id[0], &g_icon_draw_cache.normal);
+ }
+
+ if (!only_full_caches || g_icon_draw_cache.border.calls == ICON_DRAW_CACHE_SIZE) {
+ icon_draw_cache_texture_flush_ex(icongltex.id[1], &g_icon_draw_cache.border);
+ }
+
+ GPU_blend_set_func_separate(
+ GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ }
}
void UI_icon_draw_cache_end(void)
@@ -1491,12 +1642,12 @@ void UI_icon_draw_cache_end(void)
g_icon_draw_cache.enabled = false;
/* Don't change blend state if it's not needed. */
- if (g_icon_draw_cache.calls == 0) {
+ if (g_icon_draw_cache.border.calls == 0 && g_icon_draw_cache.normal.calls == 0) {
return;
}
GPU_blend(true);
- icon_draw_cache_flush_ex();
+ icon_draw_cache_flush_ex(false);
GPU_blend(false);
}
@@ -1509,14 +1660,18 @@ static void icon_draw_texture_cached(float x,
int UNUSED(iw),
int ih,
float alpha,
- const float rgb[3])
+ const float rgb[3],
+ bool with_border)
{
float mvp[4][4];
GPU_matrix_model_view_projection_get(mvp);
- IconDrawCall *call = &g_icon_draw_cache.drawcall_cache[g_icon_draw_cache.calls];
- g_icon_draw_cache.calls++;
+ IconTextureDrawCall *texture_call = with_border ? &g_icon_draw_cache.border :
+ &g_icon_draw_cache.normal;
+
+ IconDrawCall *call = &texture_call->drawcall_cache[texture_call->calls];
+ texture_call->calls++;
/* Manual mat4*vec2 */
call->pos.xmin = x * mvp[0][0] + y * mvp[1][0] + mvp[3][0];
@@ -1536,8 +1691,8 @@ static void icon_draw_texture_cached(float x,
copy_v4_fl(call->color, alpha);
}
- if (g_icon_draw_cache.calls == ICON_DRAW_CACHE_SIZE) {
- icon_draw_cache_flush_ex();
+ if (texture_call->calls == ICON_DRAW_CACHE_SIZE) {
+ icon_draw_cache_flush_ex(true);
}
}
@@ -1550,10 +1705,11 @@ static void icon_draw_texture(float x,
int iw,
int ih,
float alpha,
- const float rgb[3])
+ const float rgb[3],
+ bool with_border)
{
if (g_icon_draw_cache.enabled) {
- icon_draw_texture_cached(x, y, w, h, ix, iy, iw, ih, alpha, rgb);
+ icon_draw_texture_cached(x, y, w, h, ix, iy, iw, ih, alpha, rgb, with_border);
return;
}
@@ -1570,7 +1726,7 @@ static void icon_draw_texture(float x,
y2 = (iy + ih) * icongltex.invh;
glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, icongltex.id);
+ glBindTexture(GL_TEXTURE_2D, with_border ? icongltex.id[1] : icongltex.id[0]);
GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_IMAGE_RECT_COLOR);
GPU_shader_bind(shader);
@@ -1614,11 +1770,11 @@ static void icon_draw_size(float x,
int icon_id,
float aspect,
float alpha,
- const float rgb[3],
enum eIconSizes size,
int draw_size,
const float desaturate,
- const char mono_rgba[4])
+ const char mono_rgba[4],
+ const bool mono_border)
{
bTheme *btheme = UI_GetTheme();
Icon *icon = NULL;
@@ -1675,7 +1831,7 @@ static void icon_draw_size(float x,
GPU_blend_set_func_separate(
GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- icon_draw_rect(x, y, w, h, aspect, w, h, ibuf->rect, alpha, rgb, desaturate);
+ icon_draw_rect(x, y, w, h, aspect, w, h, ibuf->rect, alpha, desaturate);
GPU_blend_set_func_separate(
GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
}
@@ -1695,36 +1851,42 @@ static void icon_draw_size(float x,
di->data.texture.w,
di->data.texture.h,
alpha,
- rgb);
+ NULL,
+ false);
}
else if (di->type == ICON_TYPE_MONO_TEXTURE) {
- /* icon that matches text color, assumed to be white */
+ /* Monochrome icon that uses text or theme color. */
+ bool with_border = mono_border && (btheme->tui.icon_border_intensity > 0.0f);
float color[4];
- if (!UI_GetIconThemeColor4fv(di->data.texture.theme_color, color)) {
- if (mono_rgba) {
- rgba_uchar_to_float(color, (const uchar *)mono_rgba);
- }
- else {
- UI_GetThemeColor4fv(TH_TEXT, color);
- }
+ if (mono_rgba) {
+ rgba_uchar_to_float(color, (const uchar *)mono_rgba);
}
-
- if (rgb) {
- mul_v3_v3(color, rgb);
+ else {
+ UI_GetThemeColor4fv(TH_TEXT, color);
}
mul_v4_fl(color, alpha);
- icon_draw_texture(x,
- y,
- (float)w,
- (float)h,
- di->data.texture.x,
- di->data.texture.y,
- di->data.texture.w,
- di->data.texture.h,
+ float border_outset = 0.0;
+ unsigned int border_texel = 0;
+#ifndef WITH_HEADLESS
+ if (with_border) {
+ const float scale = (float)ICON_GRID_W / (float)ICON_DEFAULT_WIDTH;
+ border_texel = ICON_MONO_BORDER_OUTSET;
+ border_outset = ICON_MONO_BORDER_OUTSET / (scale * aspect);
+ }
+#endif
+ icon_draw_texture(x - border_outset,
+ y - border_outset,
+ (float)w + 2 * border_outset,
+ (float)h + 2 * border_outset,
+ di->data.texture.x - border_texel,
+ di->data.texture.y - border_texel,
+ di->data.texture.w + 2 * border_texel,
+ di->data.texture.h + 2 * border_texel,
color[3],
- color);
+ color,
+ with_border);
}
else if (di->type == ICON_TYPE_BUFFER) {
@@ -1738,7 +1900,7 @@ static void icon_draw_size(float x,
return;
}
- icon_draw_rect(x, y, w, h, aspect, iimg->w, iimg->h, iimg->rect, alpha, rgb, desaturate);
+ icon_draw_rect(x, y, w, h, aspect, iimg->w, iimg->h, iimg->rect, alpha, desaturate);
}
else if (di->type == ICON_TYPE_PREVIEW) {
PreviewImage *pi = (icon->id_type != 0) ? BKE_previewimg_id_ensure((ID *)icon->obj) :
@@ -1755,7 +1917,7 @@ static void icon_draw_size(float x,
GPU_blend_set_func_separate(
GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
icon_draw_rect(
- x, y, w, h, aspect, pi->w[size], pi->h[size], pi->rect[size], alpha, rgb, desaturate);
+ x, y, w, h, aspect, pi->w[size], pi->h[size], pi->rect[size], alpha, desaturate);
GPU_blend_set_func_separate(
GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
}
@@ -2057,7 +2219,7 @@ int UI_idcode_icon_get(const int idcode)
case ID_PC:
return ICON_CURVE_BEZCURVE; /* TODO! this would need its own icon! */
case ID_LP:
- return ICON_LIGHTPROBE_CUBEMAP;
+ return ICON_OUTLINER_DATA_LIGHTPROBE;
case ID_SCE:
return ICON_SCENE_DATA;
case ID_SPK:
@@ -2077,71 +2239,40 @@ int UI_idcode_icon_get(const int idcode)
}
}
-static void icon_draw_at_size(float x,
- float y,
- int icon_id,
- float aspect,
- float alpha,
- enum eIconSizes size,
- const float desaturate,
- const char mono_color[4])
-{
- int draw_size = get_draw_size(size);
- icon_draw_size(x, y, icon_id, aspect, alpha, NULL, size, draw_size, desaturate, mono_color);
-}
-
-void UI_icon_draw_aspect(
- float x, float y, int icon_id, float aspect, float alpha, const char mono_color[4])
-{
- icon_draw_at_size(x, y, icon_id, aspect, alpha, ICON_SIZE_ICON, 0.0f, mono_color);
-}
-
-void UI_icon_draw_aspect_color(
- float x, float y, int icon_id, float aspect, const float rgb[3], const char mono_color[4])
-{
- int draw_size = get_draw_size(ICON_SIZE_ICON);
- icon_draw_size(x, y, icon_id, aspect, 1.0f, rgb, ICON_SIZE_ICON, draw_size, false, mono_color);
-}
-
-void UI_icon_draw_desaturate(float x,
- float y,
- int icon_id,
- float aspect,
- float alpha,
- float desaturate,
- const char mono_color[4])
-{
- icon_draw_at_size(x, y, icon_id, aspect, alpha, ICON_SIZE_ICON, desaturate, mono_color);
-}
-
/* draws icon with dpi scale factor */
void UI_icon_draw(float x, float y, int icon_id)
{
- UI_icon_draw_aspect(x, y, icon_id, 1.0f / UI_DPI_FAC, 1.0f, NULL);
+ UI_icon_draw_ex(x, y, icon_id, U.inv_dpi_fac, 1.0f, 0.0f, NULL, false);
}
void UI_icon_draw_alpha(float x, float y, int icon_id, float alpha)
{
- UI_icon_draw_aspect(x, y, icon_id, 1.0f / UI_DPI_FAC, alpha, NULL);
-}
-
-void UI_icon_draw_size(float x, float y, int size, int icon_id, float alpha)
-{
- icon_draw_size(x, y, icon_id, 1.0f, alpha, NULL, ICON_SIZE_ICON, size, false, NULL);
+ UI_icon_draw_ex(x, y, icon_id, U.inv_dpi_fac, alpha, 0.0f, NULL, false);
}
-void UI_icon_draw_preview(float x, float y, int icon_id)
+void UI_icon_draw_preview(float x, float y, int icon_id, float aspect, float alpha, int size)
{
- icon_draw_at_size(x, y, icon_id, 1.0f, 1.0f, ICON_SIZE_PREVIEW, false, NULL);
+ icon_draw_size(x, y, icon_id, aspect, alpha, ICON_SIZE_PREVIEW, size, false, NULL, false);
}
-void UI_icon_draw_preview_aspect(float x, float y, int icon_id, float aspect)
+void UI_icon_draw_ex(float x,
+ float y,
+ int icon_id,
+ float aspect,
+ float alpha,
+ float desaturate,
+ const char mono_color[4],
+ const bool mono_border)
{
- icon_draw_at_size(x, y, icon_id, aspect, 1.0f, ICON_SIZE_PREVIEW, false, NULL);
-}
-
-void UI_icon_draw_preview_aspect_size(
- float x, float y, int icon_id, float aspect, float alpha, int size)
-{
- icon_draw_size(x, y, icon_id, aspect, alpha, NULL, ICON_SIZE_PREVIEW, size, false, NULL);
+ int draw_size = get_draw_size(ICON_SIZE_ICON);
+ icon_draw_size(x,
+ y,
+ icon_id,
+ aspect,
+ alpha,
+ ICON_SIZE_ICON,
+ draw_size,
+ desaturate,
+ mono_color,
+ mono_border);
}
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 4af7fdd779f..33288df15ba 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -539,13 +539,12 @@ struct uiKeyNavLock {
typedef uiBlock *(*uiBlockHandleCreateFunc)(struct bContext *C,
struct uiPopupBlockHandle *handle,
void *arg1);
-typedef void (*uiBlockHandleFreeFunc)(struct uiPopupBlockHandle *handle, void *arg1);
struct uiPopupBlockCreate {
uiBlockCreateFunc create_func;
uiBlockHandleCreateFunc handle_create_func;
- uiBlockHandleFreeFunc free_func;
void *arg;
+ void (*arg_free)(void *arg);
int event_xy[2];
@@ -662,7 +661,8 @@ uiPopupBlockHandle *ui_popup_block_create(struct bContext *C,
uiBut *but,
uiBlockCreateFunc create_func,
uiBlockHandleCreateFunc handle_create_func,
- void *arg);
+ void *arg,
+ void (*arg_free)(void *arg));
uiPopupBlockHandle *ui_popup_menu_create(struct bContext *C,
struct ARegion *butregion,
uiBut *but,
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 15e507483ad..37ef0948dee 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -764,7 +764,8 @@ static void ui_item_enum_expand_elem_exec(uiLayout *layout,
if (RNA_property_flag(prop) & PROP_ENUM_FLAG) {
/* If this is set, assert since we're clobbering someone elses callback. */
- BLI_assert(but->func == NULL);
+ /* Buttons get their block's func by default, so we cannot assert in that case either. */
+ BLI_assert(ELEM(but->func, NULL, block->func));
UI_but_func_set(but, ui_item_enum_expand_handle, but, POINTER_FROM_INT(value));
}
diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index 87e58a4b3b5..46b1279643e 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -258,43 +258,16 @@ static void panels_collapse_all(ScrArea *sa, ARegion *ar, const Panel *from_pa)
}
}
-static void ui_panel_copy_offset(Panel *pa, Panel *papar)
-{
- /* with respect to sizes... papar is parent */
-
- pa->ofsx = papar->ofsx;
- pa->ofsy = papar->ofsy + papar->sizey - pa->sizey;
-}
-
-/**
- * XXX Disabled paneltab handling for now. Old 2.4x feature,
- * *DO NOT* confuse it with new tool tabs in 2.70. ;)
- * See also T41704.
- */
-/* #define UI_USE_PANELTAB */
-
Panel *UI_panel_find_by_type(ListBase *lb, PanelType *pt)
{
Panel *pa;
const char *idname = pt->idname;
-#ifdef UI_USE_PANELTAB
- const char *tabname = pt->idname;
- for (pa = lb->first; pa; pa = pa->next) {
- if (STREQLEN(pa->panelname, idname, sizeof(pa->panelname))) {
- if (STREQLEN(pa->tabname, tabname, sizeof(pa->tabname))) {
- return pa;
- }
- }
- }
-#else
for (pa = lb->first; pa; pa = pa->next) {
if (STREQLEN(pa->panelname, idname, sizeof(pa->panelname))) {
return pa;
}
}
-#endif
-
return NULL;
}
@@ -307,10 +280,6 @@ Panel *UI_panel_begin(
Panel *palast, *panext;
const char *drawname = CTX_IFACE_(pt->translation_context, pt->label);
const char *idname = pt->idname;
-#ifdef UI_USE_PANELTAB
- const char *tabname = pt->idname;
- const char *hookname = NULL;
-#endif
const bool newpanel = (pa == NULL);
int align = panel_aligned(sa, ar);
@@ -341,28 +310,6 @@ Panel *UI_panel_begin(
pa->runtime_flag |= PNL_NEW_ADDED;
BLI_addtail(lb, pa);
-
-#ifdef UI_USE_PANELTAB
- BLI_strncpy(pa->tabname, tabname, sizeof(pa->tabname));
-
- /* make new Panel tabbed? */
- if (hookname) {
- Panel *patab;
- for (patab = lb->first; patab; patab = patab->next) {
- if ((patab->runtime_flag & PNL_ACTIVE) && patab->paneltab == NULL) {
- if (STREQLEN(hookname, patab->panelname, sizeof(patab->panelname))) {
- if (STREQLEN(tabname, patab->tabname, sizeof(patab->tabname))) {
- pa->paneltab = patab;
- ui_panel_copy_offset(pa, patab);
- break;
- }
- }
- }
- }
- }
-#else
- BLI_strncpy(pa->tabname, idname, sizeof(pa->tabname));
-#endif
}
/* Do not allow closed panels without headers! Else user could get "disappeared" UI! */
@@ -411,9 +358,6 @@ Panel *UI_panel_begin(
*r_open = false;
- if (pa->paneltab) {
- return pa;
- }
if (pa->flag & PNL_CLOSED) {
return pa;
}
@@ -706,9 +650,6 @@ void ui_draw_aligned_panel(uiStyle *style,
* can't be dragged. This may be changed in future. */
show_background);
- if (panel->paneltab) {
- return;
- }
if (panel->type && (panel->type->flag & PNL_NO_HEADER)) {
return;
}
@@ -765,12 +706,14 @@ void ui_draw_aligned_panel(uiStyle *style,
panel_title_color_get(show_background, col_title);
GPU_blend(true);
- UI_icon_draw_aspect(headrect.xmax - ((PNL_ICON * 2.2f) / block->aspect),
- headrect.ymin + (5.0f / block->aspect),
- (panel->flag & PNL_PIN) ? ICON_PINNED : ICON_UNPINNED,
- (block->aspect / UI_DPI_FAC),
- 1.0f,
- (const char *)col_title);
+ UI_icon_draw_ex(headrect.xmax - ((PNL_ICON * 2.2f) / block->aspect),
+ headrect.ymin + (5.0f / block->aspect),
+ (panel->flag & PNL_PIN) ? ICON_PINNED : ICON_UNPINNED,
+ (block->aspect * U.inv_dpi_fac),
+ 1.0f,
+ 0.0f,
+ (const char *)col_title,
+ false);
GPU_blend(false);
}
@@ -934,12 +877,6 @@ static int get_panel_real_ofsy(Panel *pa)
if (pa->flag & PNL_CLOSEDY) {
return pa->ofsy + pa->sizey;
}
- else if (pa->paneltab && (pa->paneltab->flag & PNL_CLOSEDY)) {
- return pa->ofsy + pa->sizey;
- }
- else if (pa->paneltab) {
- return pa->paneltab->ofsy;
- }
else {
return pa->ofsy;
}
@@ -950,9 +887,6 @@ static int get_panel_real_ofsx(Panel *pa)
if (pa->flag & PNL_CLOSEDX) {
return pa->ofsx + get_panel_header(pa);
}
- else if (pa->paneltab && (pa->paneltab->flag & PNL_CLOSEDX)) {
- return pa->ofsx + get_panel_header(pa);
- }
else {
return pa->ofsx + pa->sizex;
}
@@ -1067,7 +1001,7 @@ static bool uiAlignPanelStep(ScrArea *sa, ARegion *ar, const float fac, const bo
/* count active, not tabbed panels */
for (pa = ar->panels.first; pa; pa = pa->next) {
- if ((pa->runtime_flag & PNL_ACTIVE) && pa->paneltab == NULL) {
+ if (pa->runtime_flag & PNL_ACTIVE) {
tot++;
}
}
@@ -1078,7 +1012,7 @@ static bool uiAlignPanelStep(ScrArea *sa, ARegion *ar, const float fac, const bo
/* extra; change close direction? */
for (pa = ar->panels.first; pa; pa = pa->next) {
- if ((pa->runtime_flag & PNL_ACTIVE) && pa->paneltab == NULL) {
+ if (pa->runtime_flag & PNL_ACTIVE) {
if ((pa->flag & PNL_CLOSEDX) && (align == BUT_VERTICAL)) {
pa->flag ^= PNL_CLOSED;
}
@@ -1093,7 +1027,7 @@ static bool uiAlignPanelStep(ScrArea *sa, ARegion *ar, const float fac, const bo
ps = panelsort;
for (pa = ar->panels.first; pa; pa = pa->next) {
- if ((pa->runtime_flag & PNL_ACTIVE) && pa->paneltab == NULL) {
+ if (pa->runtime_flag & PNL_ACTIVE) {
ps->pa = MEM_dupallocN(pa);
ps->orig = pa;
ps++;
@@ -1160,9 +1094,6 @@ static bool uiAlignPanelStep(ScrArea *sa, ARegion *ar, const float fac, const bo
/* set locations for tabbed and sub panels */
for (pa = ar->panels.first; pa; pa = pa->next) {
if (pa->runtime_flag & PNL_ACTIVE) {
- if (pa->paneltab) {
- ui_panel_copy_offset(pa, pa->paneltab);
- }
if (pa->children.first) {
align_sub_panels(pa);
}
@@ -1265,7 +1196,7 @@ void UI_panels_end(const bContext *C, ARegion *ar, int *r_x, int *r_y)
{
ScrArea *sa = CTX_wm_area(C);
uiBlock *block;
- Panel *panot, *panew, *patest, *pa, *firstpa;
+ Panel *pa, *firstpa;
/* offset contents */
for (block = ar->uiblocks.first; block; block = block->next) {
@@ -1274,31 +1205,6 @@ void UI_panels_end(const bContext *C, ARegion *ar, int *r_x, int *r_y)
}
}
- /* consistency; are panels not made, whilst they have tabs */
- for (panot = ar->panels.first; panot; panot = panot->next) {
- if ((panot->runtime_flag & PNL_ACTIVE) == 0) { /* not made */
-
- for (panew = ar->panels.first; panew; panew = panew->next) {
- if ((panew->runtime_flag & PNL_ACTIVE)) {
- if (panew->paneltab == panot) { /* panew is tab in notmade pa */
- break;
- }
- }
- }
- /* now panew can become the new parent, check all other tabs */
- if (panew) {
- for (patest = ar->panels.first; patest; patest = patest->next) {
- if (patest->paneltab == panot) {
- patest->paneltab = panew;
- }
- }
- panot->paneltab = panew;
- panew->paneltab = NULL;
- ED_region_tag_redraw(ar); /* the buttons panew were not made */
- }
- }
- }
-
/* re-align, possibly with animation */
if (panels_need_realign(sa, ar, &pa)) {
if (pa) {
@@ -1380,7 +1286,7 @@ static void check_panel_overlap(ARegion *ar, Panel *panel)
for (pa = ar->panels.first; pa; pa = pa->next) {
pa->flag &= ~PNL_OVERLAP;
if (panel && (pa != panel)) {
- if (pa->paneltab == NULL && (pa->runtime_flag & PNL_ACTIVE)) {
+ if (pa->runtime_flag & PNL_ACTIVE) {
float safex = 0.2, safey = 0.2;
if (pa->flag & PNL_CLOSEDX) {
@@ -1623,11 +1529,11 @@ static void ui_handle_panel_header(
{
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = CTX_wm_region(C);
- Panel *pa;
#ifdef USE_PIN_HIDDEN
- const bool show_pin = UI_panel_category_is_visible(ar) && (block->panel->flag & PNL_PIN);
+ const bool show_pin = UI_panel_category_is_visible(ar) && (block->panel->type->parent == NULL) &&
+ (block->panel->flag & PNL_PIN);
#else
- const bool show_pin = UI_panel_category_is_visible(ar);
+ const bool show_pin = UI_panel_category_is_visible(ar) && (block->panel->type->parent == NULL);
#endif
const bool is_subpanel = (block->panel->type && block->panel->type->parent);
const bool show_drag = !is_subpanel;
@@ -1658,8 +1564,10 @@ static void ui_handle_panel_header(
button = 1;
}
else if (ELEM(event, 0, RETKEY, LEFTMOUSE) && shift) {
- block->panel->flag ^= PNL_PIN;
- button = 2;
+ if (block->panel->type->parent == NULL) {
+ block->panel->flag ^= PNL_PIN;
+ button = 2;
+ }
}
else if (block->panel->flag & PNL_CLOSEDX) {
if (my >= block->rect.ymax) {
@@ -1720,17 +1628,6 @@ static void ui_handle_panel_header(
ui_panel_drag_collapse_handler_add(C, true);
}
}
-
- for (pa = ar->panels.first; pa; pa = pa->next) {
- if (pa->paneltab == block->panel) {
- if (block->panel->flag & PNL_CLOSED) {
- pa->flag |= PNL_CLOSED;
- }
- else {
- pa->flag &= ~PNL_CLOSED;
- }
- }
- }
}
if (align) {
@@ -2067,7 +1964,11 @@ void UI_panel_category_draw_all(ARegion *ar, const char *category_id_active)
ui_fontscale(&fstyle_points, aspect / (U.pixelsize * 1.1f));
BLF_size(fontid, fstyle_points, U.dpi);
- BLI_assert(UI_panel_category_is_visible(ar));
+ /* Check the region type supports categories to avoid an assert
+ * for showing 3D view panels in the properties space. */
+ if ((1 << ar->regiontype) & RGN_TYPE_HAS_CATEGORY_MASK) {
+ BLI_assert(UI_panel_category_is_visible(ar));
+ }
/* calculate tab rect's and check if we need to scale down */
for (pc_dyn = ar->panels_category.first; pc_dyn; pc_dyn = pc_dyn->next) {
@@ -2378,7 +2279,7 @@ int ui_handler_panel_region(bContext *C,
/* checks for mouse position inside */
pa = block->panel;
- if (!pa || pa->paneltab != NULL) {
+ if (!pa) {
continue;
}
/* XXX - accessed freed panels when scripts reload, need to fix. */
diff --git a/source/blender/editors/interface/interface_region_menu_pie.c b/source/blender/editors/interface/interface_region_menu_pie.c
index dcbbde259f2..330a9d48ff4 100644
--- a/source/blender/editors/interface/interface_region_menu_pie.c
+++ b/source/blender/editors/interface/interface_region_menu_pie.c
@@ -208,7 +208,7 @@ void UI_pie_menu_end(bContext *C, uiPieMenu *pie)
wmWindow *window = CTX_wm_window(C);
uiPopupBlockHandle *menu;
- menu = ui_popup_block_create(C, NULL, NULL, NULL, ui_block_func_PIE, pie);
+ menu = ui_popup_block_create(C, NULL, NULL, NULL, ui_block_func_PIE, pie, NULL);
menu->popup = true;
menu->towardstime = PIL_check_seconds_timer();
diff --git a/source/blender/editors/interface/interface_region_menu_popup.c b/source/blender/editors/interface/interface_region_menu_popup.c
index b97cbcdfef5..ab3a86ec9e1 100644
--- a/source/blender/editors/interface/interface_region_menu_popup.c
+++ b/source/blender/editors/interface/interface_region_menu_popup.c
@@ -351,7 +351,7 @@ uiPopupBlockHandle *ui_popup_menu_create(
pup->menu_func = menu_func;
pup->menu_arg = arg;
- handle = ui_popup_block_create(C, butregion, but, NULL, ui_block_func_POPUP, pup);
+ handle = ui_popup_block_create(C, butregion, but, NULL, ui_block_func_POPUP, pup, NULL);
if (!but) {
handle->popup = true;
@@ -463,7 +463,7 @@ void UI_popup_menu_end(bContext *C, uiPopupMenu *pup)
butregion = pup->butregion;
}
- menu = ui_popup_block_create(C, butregion, but, NULL, ui_block_func_POPUP, pup);
+ menu = ui_popup_block_create(C, butregion, but, NULL, ui_block_func_POPUP, pup, NULL);
menu->popup = true;
UI_popup_handlers_add(C, &window->modalhandlers, menu, 0);
@@ -581,13 +581,17 @@ int UI_popup_menu_invoke(bContext *C, const char *idname, ReportList *reports)
/** \name Popup Block API
* \{ */
-void UI_popup_block_invoke_ex(
- bContext *C, uiBlockCreateFunc func, void *arg, const char *opname, int opcontext)
+void UI_popup_block_invoke_ex(bContext *C,
+ uiBlockCreateFunc func,
+ void *arg,
+ void (*arg_free)(void *arg),
+ const char *opname,
+ int opcontext)
{
wmWindow *window = CTX_wm_window(C);
uiPopupBlockHandle *handle;
- handle = ui_popup_block_create(C, NULL, NULL, func, NULL, arg);
+ handle = ui_popup_block_create(C, NULL, NULL, func, NULL, arg, arg_free);
handle->popup = true;
handle->can_refresh = true;
handle->optype = (opname) ? WM_operatortype_find(opname, 0) : NULL;
@@ -598,9 +602,12 @@ void UI_popup_block_invoke_ex(
WM_event_add_mousemove(C);
}
-void UI_popup_block_invoke(bContext *C, uiBlockCreateFunc func, void *arg)
+void UI_popup_block_invoke(bContext *C,
+ uiBlockCreateFunc func,
+ void *arg,
+ void (*arg_free)(void *arg))
{
- UI_popup_block_invoke_ex(C, func, arg, NULL, WM_OP_INVOKE_DEFAULT);
+ UI_popup_block_invoke_ex(C, func, arg, arg_free, NULL, WM_OP_INVOKE_DEFAULT);
}
void UI_popup_block_ex(bContext *C,
@@ -613,7 +620,7 @@ void UI_popup_block_ex(bContext *C,
wmWindow *window = CTX_wm_window(C);
uiPopupBlockHandle *handle;
- handle = ui_popup_block_create(C, NULL, NULL, func, NULL, arg);
+ handle = ui_popup_block_create(C, NULL, NULL, func, NULL, arg, NULL);
handle->popup = true;
handle->retvalue = 1;
handle->can_refresh = true;
@@ -635,7 +642,7 @@ void uiPupBlockOperator(bContext *C, uiBlockCreateFunc func, wmOperator *op, int
wmWindow *window = CTX_wm_window(C);
uiPopupBlockHandle *handle;
- handle = ui_popup_block_create(C, NULL, NULL, func, NULL, op);
+ handle = ui_popup_block_create(C, NULL, NULL, func, NULL, op, NULL);
handle->popup = 1;
handle->retvalue = 1;
handle->can_refresh = true;
diff --git a/source/blender/editors/interface/interface_region_popover.c b/source/blender/editors/interface/interface_region_popover.c
index f149ccd626c..22c62ecd6f7 100644
--- a/source/blender/editors/interface/interface_region_popover.c
+++ b/source/blender/editors/interface/interface_region_popover.c
@@ -244,7 +244,7 @@ static uiBlock *ui_block_func_POPOVER(bContext *C, uiPopupBlockHandle *handle, v
return block;
}
-static void ui_block_free_func_POPOVER(uiPopupBlockHandle *UNUSED(handle), void *arg_pup)
+static void ui_block_free_func_POPOVER(void *arg_pup)
{
uiPopover *pup = arg_pup;
if (pup->keymap != NULL) {
@@ -282,8 +282,8 @@ uiPopupBlockHandle *ui_popover_panel_create(
/* Create popup block. */
uiPopupBlockHandle *handle;
- handle = ui_popup_block_create(C, butregion, but, NULL, ui_block_func_POPOVER, pup);
- handle->popup_create_vars.free_func = ui_block_free_func_POPOVER;
+ handle = ui_popup_block_create(
+ C, butregion, but, NULL, ui_block_func_POPOVER, pup, ui_block_free_func_POPOVER);
handle->can_refresh = true;
/* Add handlers. If attached to a button, the button will already
@@ -386,8 +386,8 @@ void UI_popover_end(bContext *C, uiPopover *pup, wmKeyMap *keymap)
WM_event_set_keymap_handler_post_callback(pup->keymap_handler, popover_keymap_fn, pup);
}
- handle = ui_popup_block_create(C, NULL, NULL, NULL, ui_block_func_POPOVER, pup);
- handle->popup_create_vars.free_func = ui_block_free_func_POPOVER;
+ handle = ui_popup_block_create(
+ C, NULL, NULL, NULL, ui_block_func_POPOVER, pup, ui_block_free_func_POPOVER);
/* Add handlers. */
UI_popup_handlers_add(C, &window->modalhandlers, handle, 0);
diff --git a/source/blender/editors/interface/interface_region_popup.c b/source/blender/editors/interface/interface_region_popup.c
index c4bcd7074d8..bd87439ca9e 100644
--- a/source/blender/editors/interface/interface_region_popup.c
+++ b/source/blender/editors/interface/interface_region_popup.c
@@ -748,7 +748,8 @@ uiPopupBlockHandle *ui_popup_block_create(bContext *C,
uiBut *but,
uiBlockCreateFunc create_func,
uiBlockHandleCreateFunc handle_create_func,
- void *arg)
+ void *arg,
+ void (*arg_free)(void *arg))
{
wmWindow *window = CTX_wm_window(C);
uiBut *activebut = UI_context_active_but_get(C);
@@ -775,6 +776,7 @@ uiPopupBlockHandle *ui_popup_block_create(bContext *C,
handle->popup_create_vars.create_func = create_func;
handle->popup_create_vars.handle_create_func = handle_create_func;
handle->popup_create_vars.arg = arg;
+ handle->popup_create_vars.arg_free = arg_free;
handle->popup_create_vars.but = but;
handle->popup_create_vars.butregion = but ? butregion : NULL;
copy_v2_v2_int(handle->popup_create_vars.event_xy, &window->eventstate->x);
@@ -820,8 +822,8 @@ void ui_popup_block_free(bContext *C, uiPopupBlockHandle *handle)
}
}
- if (handle->popup_create_vars.free_func) {
- handle->popup_create_vars.free_func(handle, handle->popup_create_vars.arg);
+ if (handle->popup_create_vars.arg_free) {
+ handle->popup_create_vars.arg_free(handle->popup_create_vars.arg);
}
ui_popup_block_remove(C, handle);
diff --git a/source/blender/editors/interface/interface_region_tooltip.c b/source/blender/editors/interface/interface_region_tooltip.c
index 4a9c7b689c1..5b205de21b8 100644
--- a/source/blender/editors/interface/interface_region_tooltip.c
+++ b/source/blender/editors/interface/interface_region_tooltip.c
@@ -891,11 +891,11 @@ static uiTooltipData *ui_tooltip_data_from_gizmo(bContext *C, wmGizmo *gz)
} gzop_actions[] = {
{
.part = gz->highlight_part,
- .prefix = use_drag ? TIP_("Click") : NULL,
+ .prefix = use_drag ? CTX_TIP_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Click") : NULL,
},
{
.part = use_drag ? gz->drag_part : -1,
- .prefix = use_drag ? TIP_("Drag") : NULL,
+ .prefix = use_drag ? CTX_TIP_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Drag") : NULL,
},
};
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index e96141eaa05..9e91505f5e8 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -4042,6 +4042,11 @@ static uiBlock *curvemap_brush_tools_func(bContext *C, ARegion *ar, void *cumap_
return curvemap_tools_func(C, ar, cumap_v, false, UICURVE_FUNC_RESET_NEG);
}
+static uiBlock *curvemap_brush_tools_negslope_func(bContext *C, ARegion *ar, void *cumap_v)
+{
+ return curvemap_tools_func(C, ar, cumap_v, false, UICURVE_FUNC_RESET_POS);
+}
+
static void curvemap_buttons_redraw(bContext *C, void *UNUSED(arg1), void *UNUSED(arg2))
{
ED_region_tag_redraw(CTX_wm_region(C));
@@ -4217,7 +4222,19 @@ static void curvemap_buttons_layout(uiLayout *layout,
TIP_("Zoom out"));
UI_but_func_set(bt, curvemap_buttons_zoom_out, cumap, NULL);
- if (brush) {
+ if (brush && neg_slope) {
+ bt = uiDefIconBlockBut(block,
+ curvemap_brush_tools_negslope_func,
+ cumap,
+ 0,
+ ICON_DOWNARROW_HLT,
+ 0,
+ 0,
+ dx,
+ dx,
+ TIP_("Tools"));
+ }
+ else if (brush) {
bt = uiDefIconBlockBut(block,
curvemap_brush_tools_func,
cumap,
@@ -6744,12 +6761,17 @@ int uiTemplateRecentFiles(uiLayout *layout, int rows)
for (recent = G.recent_files.first, i = 0; (i < rows) && (recent); recent = recent->next, i++) {
const char *filename = BLI_path_basename(recent->filepath);
- uiItemStringO(layout,
- filename,
- BLO_has_bfile_extension(filename) ? ICON_FILE_BLEND : ICON_FILE_BACKUP,
- "WM_OT_open_mainfile",
- "filepath",
- recent->filepath);
+ PointerRNA ptr;
+ uiItemFullO(layout,
+ "WM_OT_open_mainfile",
+ filename,
+ BLO_has_bfile_extension(filename) ? ICON_FILE_BLEND : ICON_FILE_BACKUP,
+ NULL,
+ WM_OP_INVOKE_DEFAULT,
+ 0,
+ &ptr);
+ RNA_string_set(&ptr, "filepath", recent->filepath);
+ RNA_boolean_set(&ptr, "display_file_selector", false);
}
return i;
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index a9cd2f9cee1..594793371ae 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -1421,7 +1421,7 @@ static void widget_draw_preview(BIFIconID icon, float alpha, const rcti *rect)
int x = rect->xmin + w / 2 - size / 2;
int y = rect->ymin + h / 2 - size / 2;
- UI_icon_draw_preview_aspect_size(x, y, icon, 1.0f, alpha, size);
+ UI_icon_draw_preview(x, y, icon, 1.0f, alpha, size);
}
}
@@ -1450,7 +1450,7 @@ static void widget_draw_icon(
return;
}
- aspect = but->block->aspect / UI_DPI_FAC;
+ aspect = but->block->aspect * U.inv_dpi_fac;
height = ICON_DEFAULT_HEIGHT / aspect;
/* calculate blend color */
@@ -1506,18 +1506,27 @@ static void widget_draw_icon(
ys = (int)(ys + 0.1f);
}
+ /* Get theme color. */
+ char color[4] = {mono_color[0], mono_color[1], mono_color[2], mono_color[3]};
+ bool has_theme = UI_icon_get_theme_color(icon, (uchar *)color);
+
/* to indicate draggable */
if (but->dragpoin && (but->flag & UI_ACTIVE)) {
- float rgb[3] = {1.25f, 1.25f, 1.25f};
- UI_icon_draw_aspect_color(xs, ys, icon, aspect, rgb, mono_color);
+ UI_icon_draw_ex(xs, ys, icon, aspect, 1.25f, 0.0f, color, has_theme);
+ }
+ else if ((but->flag & (UI_ACTIVE | UI_SELECT | UI_SELECT_DRAW))) {
+ UI_icon_draw_ex(xs, ys, icon, aspect, alpha, 0.0f, color, has_theme);
}
- else if ((but->flag & (UI_ACTIVE | UI_SELECT | UI_SELECT_DRAW)) || !UI_but_is_tool(but)) {
- UI_icon_draw_aspect(xs, ys, icon, aspect, alpha, mono_color);
+ else if (!UI_but_is_tool(but)) {
+ if (has_theme) {
+ alpha *= 0.8f;
+ }
+ UI_icon_draw_ex(xs, ys, icon, aspect, alpha, 0.0f, color, has_theme);
}
else {
const bTheme *btheme = UI_GetTheme();
- UI_icon_draw_desaturate(
- xs, ys, icon, aspect, alpha, 1.0 - btheme->tui.icon_saturation, mono_color);
+ const float desaturate = 1.0 - btheme->tui.icon_saturation;
+ UI_icon_draw_ex(xs, ys, icon, aspect, alpha, desaturate, color, has_theme);
}
}
@@ -1528,7 +1537,7 @@ static void widget_draw_submenu_tria(const uiBut *but,
const rcti *rect,
const uiWidgetColors *wcol)
{
- const float aspect = but->block->aspect / UI_DPI_FAC;
+ const float aspect = but->block->aspect * U.inv_dpi_fac;
const int tria_height = (int)(ICON_DEFAULT_HEIGHT / aspect);
const int tria_width = (int)(ICON_DEFAULT_WIDTH / aspect) - 2 * U.pixelsize;
const int xs = rect->xmax - tria_width;
@@ -1584,7 +1593,8 @@ static void ui_text_clip_right_ex(const uiFontStyle *fstyle,
BLI_assert(str[0]);
/* If the trailing ellipsis takes more than 20% of all available width, just cut the string
- * (as using the ellipsis would remove even more useful chars, and we cannot show much already!).
+ * (as using the ellipsis would remove even more useful chars, and we cannot show much
+ * already!).
*/
if (sep_strwidth / okwidth > 0.2f) {
l_end = BLF_width_to_strlen(fstyle->uifont_id, str, max_len, okwidth, &tmp);
@@ -1699,7 +1709,8 @@ float UI_text_clip_middle_ex(const uiFontStyle *fstyle,
/* Corner case, the str already takes all available mem,
* and the ellipsis chars would actually add more chars.
* Better to just trim one or two letters to the right in this case...
- * Note: with a single-char ellipsis, this should never happen! But better be safe here...
+ * Note: with a single-char ellipsis, this should never happen! But better be safe
+ * here...
*/
ui_text_clip_right_ex(
fstyle, str, max_len, okwidth, sep, sep_len, sep_strwidth, &final_lpart_len);
@@ -2346,7 +2357,7 @@ static void widget_draw_text_icon(const uiFontStyle *fstyle,
const BIFIconID icon = widget_icon_id(but);
int icon_size_init = is_tool ? ICON_DEFAULT_HEIGHT_TOOLBAR : ICON_DEFAULT_HEIGHT;
- const float icon_size = icon_size_init / (but->block->aspect / UI_DPI_FAC);
+ const float icon_size = icon_size_init / (but->block->aspect * U.inv_dpi_fac);
const float icon_padding = 2 * UI_DPI_FAC;
#ifdef USE_UI_TOOLBAR_HACK
@@ -3494,8 +3505,11 @@ void UI_draw_widget_scroll(uiWidgetColors *wcol, const rcti *rect, const rcti *s
wcol->item[3] = 255;
if (horizontal) {
- shape_preset_init_scroll_circle(&wtb.tria1, slider, 0.6f, 'l');
- shape_preset_init_scroll_circle(&wtb.tria2, slider, 0.6f, 'r');
+ rcti slider_inset = *slider;
+ slider_inset.xmin += 0.05 * U.widget_unit;
+ slider_inset.xmax -= 0.05 * U.widget_unit;
+ shape_preset_init_scroll_circle(&wtb.tria1, &slider_inset, 0.6f, 'l');
+ shape_preset_init_scroll_circle(&wtb.tria2, &slider_inset, 0.6f, 'r');
}
else {
shape_preset_init_scroll_circle(&wtb.tria1, slider, 0.6f, 'b');
@@ -4631,6 +4645,9 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
break;
case UI_BTYPE_COLORBAND:
+ /* do not draw right to edge of rect */
+ rect->xmin += (0.25f * UI_UNIT_X);
+ rect->xmax -= (0.3f * UI_UNIT_X);
ui_draw_but_COLORBAND(but, &tui->wcol_regular, rect);
break;
@@ -4655,6 +4672,9 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
break;
case UI_BTYPE_CURVE:
+ /* do not draw right to edge of rect */
+ rect->xmin += (0.2f * UI_UNIT_X);
+ rect->xmax -= (0.2f * UI_UNIT_X);
ui_draw_but_CURVE(ar, but, &tui->wcol_regular, rect);
break;
@@ -5198,7 +5218,7 @@ void ui_draw_menu_item(
GPU_blend(true);
/* XXX scale weak get from fstyle? */
- UI_icon_draw_aspect(xs, ys, iconid, aspect, 1.0f, wt->wcol.text);
+ UI_icon_draw_ex(xs, ys, iconid, aspect, 1.0f, 0.0f, wt->wcol.text, false);
GPU_blend(false);
}
}
diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c
index 8ed7dd87e9f..14fad2f3072 100644
--- a/source/blender/editors/interface/resources.c
+++ b/source/blender/editors/interface/resources.c
@@ -309,6 +309,9 @@ const uchar *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colorid)
case TH_GRID:
cp = ts->grid;
break;
+ case TH_SCRUBBING_BACKGROUND:
+ cp = ts->scrubbing_background;
+ break;
case TH_VIEW_OVERLAY:
cp = ts->view_overlay;
break;
@@ -865,6 +868,9 @@ const uchar *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colorid)
cp = btheme->tui.gizmo_b;
break;
+ case TH_ICON_SCENE:
+ cp = btheme->tui.icon_scene;
+ break;
case TH_ICON_COLLECTION:
cp = btheme->tui.icon_collection;
break;
@@ -881,6 +887,10 @@ const uchar *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colorid)
cp = btheme->tui.icon_shading;
break;
+ case TH_SCROLL_TEXT:
+ cp = btheme->tui.wcol_scroll.text;
+ break;
+
case TH_INFO_SELECTED:
cp = ts->info_selected;
break;
@@ -1347,7 +1357,7 @@ void UI_GetThemeColorType4ubv(int colorid, int spacetype, uchar col[4])
col[3] = cp[3];
}
-bool UI_GetIconThemeColor4fv(int colorid, float col[4])
+bool UI_GetIconThemeColor4ubv(int colorid, uchar col[4])
{
if (colorid == 0) {
return false;
@@ -1357,17 +1367,15 @@ bool UI_GetIconThemeColor4fv(int colorid, float col[4])
* to stay monochrome and out of the way except a few places where it
* is important to communicate different data types. */
if (!((theme_spacetype == SPACE_OUTLINER && theme_regionid == RGN_TYPE_WINDOW) ||
- (theme_spacetype == SPACE_PROPERTIES && theme_regionid == RGN_TYPE_NAV_BAR) ||
- (theme_regionid == RGN_TYPE_TEMPORARY))) {
+ (theme_spacetype == SPACE_PROPERTIES && theme_regionid == RGN_TYPE_NAV_BAR))) {
return false;
}
- const uchar *cp;
- cp = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
- col[0] = ((float)cp[0]) / 255.0f;
- col[1] = ((float)cp[1]) / 255.0f;
- col[2] = ((float)cp[2]) / 255.0f;
- col[3] = ((float)cp[3]) / 255.0f;
+ const uchar *cp = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
+ col[0] = cp[0];
+ col[1] = cp[1];
+ col[2] = cp[2];
+ col[3] = cp[3];
return true;
}
diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c
index 9de7a33b757..f2d4faff479 100644
--- a/source/blender/editors/interface/view2d.c
+++ b/source/blender/editors/interface/view2d.c
@@ -138,7 +138,7 @@ static void view2d_masks(View2D *v2d, bool check_scrollers, const rcti *mask_scr
if (check_scrollers) {
/* check size if hiding flag is set: */
if (v2d->scroll & V2D_SCROLL_HORIZONTAL_HIDE) {
- if (!(v2d->scroll & V2D_SCROLL_SCALE_HORIZONTAL)) {
+ if (!(v2d->scroll & V2D_SCROLL_HORIZONTAL_HANDLES)) {
if (BLI_rctf_size_x(&v2d->tot) > BLI_rctf_size_x(&v2d->cur)) {
v2d->scroll &= ~V2D_SCROLL_HORIZONTAL_FULLR;
}
@@ -148,7 +148,7 @@ static void view2d_masks(View2D *v2d, bool check_scrollers, const rcti *mask_scr
}
}
if (v2d->scroll & V2D_SCROLL_VERTICAL_HIDE) {
- if (!(v2d->scroll & V2D_SCROLL_SCALE_VERTICAL)) {
+ if (!(v2d->scroll & V2D_SCROLL_VERTICAL_HANDLES)) {
if (BLI_rctf_size_y(&v2d->tot) + 0.01f > BLI_rctf_size_y(&v2d->cur)) {
v2d->scroll &= ~V2D_SCROLL_VERTICAL_FULLR;
}
@@ -166,10 +166,11 @@ static void view2d_masks(View2D *v2d, bool check_scrollers, const rcti *mask_scr
* - if they overlap, they must not occupy the corners (which are reserved for other widgets)
*/
if (scroll) {
- const int scroll_width = (v2d->scroll & V2D_SCROLL_SCALE_VERTICAL) ? V2D_SCROLL_WIDTH_TEXT :
- V2D_SCROLL_WIDTH;
- const int scroll_height = (v2d->scroll & V2D_SCROLL_SCALE_HORIZONTAL) ?
- V2D_SCROLL_HEIGHT_TEXT :
+ const int scroll_width = (v2d->scroll & V2D_SCROLL_VERTICAL_HANDLES) ?
+ V2D_SCROLL_WIDTH_HANDLES :
+ V2D_SCROLL_WIDTH;
+ const int scroll_height = (v2d->scroll & V2D_SCROLL_HORIZONTAL_HANDLES) ?
+ V2D_SCROLL_HEIGHT_HANDLES :
V2D_SCROLL_HEIGHT;
/* vertical scroller */
@@ -185,6 +186,13 @@ static void view2d_masks(View2D *v2d, bool check_scrollers, const rcti *mask_scr
v2d->vert.xmin = v2d->vert.xmax - scroll_width;
}
+ /* Currently, all regions that have vertical scale handles,
+ * also have the scrubbing area at the top.
+ * So the scrollbar has to move down a bit. */
+ if (scroll & V2D_SCROLL_VERTICAL_HANDLES) {
+ v2d->vert.ymax -= UI_SCRUBBING_MARGIN_Y;
+ }
+
/* horizontal scroller */
if (scroll & (V2D_SCROLL_BOTTOM)) {
/* on bottom edge of region */
@@ -1589,7 +1597,7 @@ void UI_view2d_scrollers_draw(View2D *v2d, View2DScrollers *vs)
* (workaround to make sure that button windows don't show these,
* and only the time-grids with their zoomability can do so)
*/
- if ((v2d->keepzoom & V2D_LOCKZOOM_X) == 0 && (v2d->scroll & V2D_SCROLL_SCALE_HORIZONTAL) &&
+ if ((v2d->keepzoom & V2D_LOCKZOOM_X) == 0 && (v2d->scroll & V2D_SCROLL_HORIZONTAL_HANDLES) &&
(BLI_rcti_size_x(&slider) > V2D_SCROLLER_HANDLE_SIZE)) {
state |= UI_SCROLL_ARROWS;
}
@@ -1623,7 +1631,7 @@ void UI_view2d_scrollers_draw(View2D *v2d, View2DScrollers *vs)
* (workaround to make sure that button windows don't show these,
* and only the time-grids with their zoomability can do so)
*/
- if ((v2d->keepzoom & V2D_LOCKZOOM_Y) == 0 && (v2d->scroll & V2D_SCROLL_SCALE_VERTICAL) &&
+ if ((v2d->keepzoom & V2D_LOCKZOOM_Y) == 0 && (v2d->scroll & V2D_SCROLL_VERTICAL_HANDLES) &&
(BLI_rcti_size_y(&slider) > V2D_SCROLLER_HANDLE_SIZE)) {
state |= UI_SCROLL_ARROWS;
}
diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c
index ab8d1cf9bf6..68ee38bc99f 100644
--- a/source/blender/editors/interface/view2d_ops.c
+++ b/source/blender/editors/interface/view2d_ops.c
@@ -2032,8 +2032,8 @@ static int scroller_activate_invoke(bContext *C, wmOperator *op, const wmEvent *
* NOTE: see view2d.c for latest conditions, and keep this in sync with that
*/
if (ELEM(vsm->zone, SCROLLHANDLE_MIN, SCROLLHANDLE_MAX)) {
- if (((vsm->scroller == 'h') && (v2d->scroll & V2D_SCROLL_SCALE_HORIZONTAL) == 0) ||
- ((vsm->scroller == 'v') && (v2d->scroll & V2D_SCROLL_SCALE_VERTICAL) == 0)) {
+ if (((vsm->scroller == 'h') && (v2d->scroll & V2D_SCROLL_HORIZONTAL_HANDLES) == 0) ||
+ ((vsm->scroller == 'v') && (v2d->scroll & V2D_SCROLL_VERTICAL_HANDLES) == 0)) {
/* switch to bar (i.e. no scaling gets handled) */
vsm->zone = SCROLLHANDLE_BAR;
}
diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c
index c0f3b1f8338..1f825c0bb31 100644
--- a/source/blender/editors/mask/mask_ops.c
+++ b/source/blender/editors/mask/mask_ops.c
@@ -1992,9 +1992,9 @@ static int mask_hide_view_clear_exec(bContext *C, wmOperator *op)
for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
- if (masklay->restrictflag & OB_RESTRICT_VIEW) {
+ if (masklay->restrictflag & OB_RESTRICT_VIEWPORT) {
ED_mask_layer_select_set(masklay, select);
- masklay->restrictflag &= ~OB_RESTRICT_VIEW;
+ masklay->restrictflag &= ~OB_RESTRICT_VIEWPORT;
changed = true;
}
}
@@ -2045,7 +2045,7 @@ static int mask_hide_view_set_exec(bContext *C, wmOperator *op)
if (ED_mask_layer_select_check(masklay)) {
ED_mask_layer_select_set(masklay, false);
- masklay->restrictflag |= OB_RESTRICT_VIEW;
+ masklay->restrictflag |= OB_RESTRICT_VIEWPORT;
changed = true;
if (masklay == BKE_mask_layer_active(mask)) {
BKE_mask_layer_active_set(mask, NULL);
@@ -2054,7 +2054,7 @@ static int mask_hide_view_set_exec(bContext *C, wmOperator *op)
}
else {
if (!ED_mask_layer_select_check(masklay)) {
- masklay->restrictflag |= OB_RESTRICT_VIEW;
+ masklay->restrictflag |= OB_RESTRICT_VIEWPORT;
changed = true;
if (masklay == BKE_mask_layer_active(mask)) {
BKE_mask_layer_active_set(mask, NULL);
diff --git a/source/blender/editors/mesh/CMakeLists.txt b/source/blender/editors/mesh/CMakeLists.txt
index 57bf67e825e..9a779db4812 100644
--- a/source/blender/editors/mesh/CMakeLists.txt
+++ b/source/blender/editors/mesh/CMakeLists.txt
@@ -23,6 +23,7 @@ set(INC
../../blentranslation
../../bmesh
../../depsgraph
+ ../../draw
../../gpu
../../imbuf
../../makesdna
diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c
index 990250792a1..fdbcc3449b2 100644
--- a/source/blender/editors/mesh/editface.c
+++ b/source/blender/editors/mesh/editface.c
@@ -461,13 +461,13 @@ bool do_paintface_box_select(ViewContext *vc, const rcti *rect, int sel_op)
}
else {
MPoly *mpoly;
- uint *rt;
+ uint *rt, *buf, buf_len;
int a, index;
char *selar = MEM_callocN(me->totpoly + 1, "selar");
- uint buf_len;
- uint *buf = ED_view3d_select_id_read_rect(vc, rect, &buf_len);
+ ED_view3d_select_id_validate(vc);
+ buf = ED_view3d_select_id_read_rect(vc, rect, &buf_len);
rt = buf;
diff --git a/source/blender/editors/mesh/editmesh_bevel.c b/source/blender/editors/mesh/editmesh_bevel.c
index f5810d9ff61..1cd4e95314b 100644
--- a/source/blender/editors/mesh/editmesh_bevel.c
+++ b/source/blender/editors/mesh/editmesh_bevel.c
@@ -907,7 +907,8 @@ void MESH_OT_bevel(wmOperatorType *ot)
/* identifiers */
ot->name = "Bevel";
- ot->description = "Cut into selected items at an angle to create flat or rounded bevel or chamfer";
+ ot->description =
+ "Cut into selected items at an angle to create flat or rounded bevel or chamfer";
ot->idname = "MESH_OT_bevel";
/* api callbacks */
diff --git a/source/blender/editors/mesh/editmesh_extrude.c b/source/blender/editors/mesh/editmesh_extrude.c
index 82cff8363f8..0da4d20c6b5 100644
--- a/source/blender/editors/mesh/editmesh_extrude.c
+++ b/source/blender/editors/mesh/editmesh_extrude.c
@@ -36,6 +36,7 @@
#include "RNA_access.h"
#include "WM_types.h"
+#include "WM_api.h"
#include "ED_mesh.h"
#include "ED_screen.h"
@@ -860,6 +861,9 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, const w
EDBM_mesh_normals_update(vc.em);
EDBM_update_generic(vc.em, true, true);
+
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
}
MEM_freeN(objects);
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index cc0c2f5bbe4..e45c15b3e53 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -2811,6 +2811,7 @@ wmKeyMap *knifetool_modal_keymap(wmKeyConfig *keyconf)
{KNF_MODAL_CUT_THROUGH_TOGGLE, "CUT_THROUGH_TOGGLE", 0, "Toggle Cut Through", ""},
{KNF_MODAL_NEW_CUT, "NEW_CUT", 0, "End Current Cut", ""},
{KNF_MODAL_ADD_CUT, "ADD_CUT", 0, "Add Cut", ""},
+ {KNF_MODAL_ADD_CUT_CLOSED, "ADD_CUT_CLOSED", 0, "Add Cut Closed", ""},
{KNF_MODAL_PANNING, "PANNING", 0, "Panning", ""},
{0, NULL, 0, NULL, NULL},
};
diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c
index 528235e693a..59355890428 100644
--- a/source/blender/editors/mesh/editmesh_loopcut.c
+++ b/source/blender/editors/mesh/editmesh_loopcut.c
@@ -79,11 +79,11 @@ typedef struct RingSelOpData {
Depsgraph *depsgraph;
- Object **objects;
- uint objects_len;
+ Base **bases;
+ uint bases_len;
/* These values switch objects based on the object under the cursor. */
- uint ob_index;
+ uint base_index;
Object *ob;
BMEditMesh *em;
BMEdge *eed;
@@ -111,8 +111,8 @@ static void edgering_select(RingSelOpData *lcd)
}
if (!lcd->extend) {
- for (uint ob_index = 0; ob_index < lcd->objects_len; ob_index++) {
- Object *ob_iter = lcd->objects[ob_index];
+ for (uint base_index = 0; base_index < lcd->bases_len; base_index++) {
+ Object *ob_iter = lcd->bases[base_index]->object;
BMEditMesh *em = BKE_editmesh_from_object(ob_iter);
EDBM_flag_disable_all(em, BM_ELEM_SELECT);
DEG_id_tag_update(ob_iter->data, ID_RECALC_SELECT);
@@ -252,7 +252,7 @@ static void ringsel_exit(bContext *UNUSED(C), wmOperator *op)
EDBM_preselect_edgering_destroy(lcd->presel_edgering);
- MEM_freeN(lcd->objects);
+ MEM_freeN(lcd->bases);
ED_region_tag_redraw(lcd->ar);
@@ -307,21 +307,21 @@ static void ringcut_cancel(bContext *C, wmOperator *op)
}
static void loopcut_update_edge(RingSelOpData *lcd,
- uint ob_index,
+ uint base_index,
BMEdge *e,
const int previewlines)
{
if (e != lcd->eed) {
lcd->eed = e;
lcd->ob = lcd->vc.obedit;
- lcd->ob_index = ob_index;
+ lcd->base_index = base_index;
lcd->em = lcd->vc.em;
ringsel_find_edge(lcd, previewlines);
}
else if (e == NULL) {
lcd->ob = NULL;
lcd->em = NULL;
- lcd->ob_index = UINT_MAX;
+ lcd->base_index = UINT_MAX;
}
}
@@ -331,27 +331,26 @@ static void loopcut_mouse_move(RingSelOpData *lcd, const int previewlines)
Object *ob;
BMEdge *eed;
float dist;
- int ob_index;
+ int base_index;
} best = {
.dist = ED_view3d_select_dist_px(),
};
- for (uint ob_index = 0; ob_index < lcd->objects_len; ob_index++) {
- Object *ob_iter = lcd->objects[ob_index];
- ED_view3d_viewcontext_init_object(&lcd->vc, ob_iter);
- BMEdge *eed_test = EDBM_edge_find_nearest_ex(&lcd->vc, &best.dist, NULL, false, false, NULL);
- if (eed_test) {
- best.ob = ob_iter;
- best.eed = eed_test;
- best.ob_index = ob_index;
- }
+ uint base_index;
+ BMEdge *eed_test = EDBM_edge_find_nearest_ex(
+ &lcd->vc, &best.dist, NULL, false, false, NULL, lcd->bases, lcd->bases_len, &base_index);
+
+ if (eed_test) {
+ best.ob = lcd->bases[base_index]->object;
+ best.eed = eed_test;
+ best.base_index = base_index;
}
if (best.eed) {
ED_view3d_viewcontext_init_object(&lcd->vc, best.ob);
}
- loopcut_update_edge(lcd, best.ob_index, best.eed, previewlines);
+ loopcut_update_edge(lcd, best.base_index, best.eed, previewlines);
}
/* called by both init() and exec() */
@@ -361,22 +360,22 @@ static int loopcut_init(bContext *C, wmOperator *op, const wmEvent *event)
/* Use for redo - intentionally wrap int to uint. */
const struct {
- uint ob_index;
+ uint base_index;
uint e_index;
} exec_data = {
- .ob_index = (uint)RNA_int_get(op->ptr, "object_index"),
+ .base_index = (uint)RNA_int_get(op->ptr, "object_index"),
.e_index = (uint)RNA_int_get(op->ptr, "edge_index"),
};
ViewLayer *view_layer = CTX_data_view_layer(C);
- uint objects_len;
- Object **objects = BKE_view_layer_array_from_objects_in_edit_mode(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ uint bases_len;
+ Base **bases = BKE_view_layer_array_from_bases_in_edit_mode(
+ view_layer, CTX_wm_view3d(C), &bases_len);
if (is_interactive) {
- for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- Object *ob_iter = objects[ob_index];
+ for (uint base_index = 0; base_index < bases_len; base_index++) {
+ Object *ob_iter = bases[base_index]->object;
if (modifiers_isDeformedByLattice(ob_iter) || modifiers_isDeformedByArmature(ob_iter)) {
BKE_report(
op->reports, RPT_WARNING, "Loop cut does not work well on deformed edit mesh display");
@@ -390,12 +389,12 @@ static int loopcut_init(bContext *C, wmOperator *op, const wmEvent *event)
/* for re-execution, check edge index is in range before we setup ringsel */
bool ok = true;
if (is_interactive == false) {
- if (exec_data.ob_index >= objects_len) {
+ if (exec_data.base_index >= bases_len) {
return OPERATOR_CANCELLED;
ok = false;
}
else {
- Object *ob_iter = objects[exec_data.ob_index];
+ Object *ob_iter = bases[exec_data.base_index]->object;
BMEditMesh *em = BKE_editmesh_from_object(ob_iter);
if (exec_data.e_index >= em->bm->totedge) {
ok = false;
@@ -404,7 +403,7 @@ static int loopcut_init(bContext *C, wmOperator *op, const wmEvent *event)
}
if (!ok || !ringsel_init(C, op, true)) {
- MEM_freeN(objects);
+ MEM_freeN(bases);
return OPERATOR_CANCELLED;
}
@@ -416,8 +415,8 @@ static int loopcut_init(bContext *C, wmOperator *op, const wmEvent *event)
RingSelOpData *lcd = op->customdata;
- lcd->objects = objects;
- lcd->objects_len = objects_len;
+ lcd->bases = bases;
+ lcd->bases_len = bases_len;
if (is_interactive) {
copy_v2_v2_int(lcd->vc.mval, event->mval);
@@ -425,13 +424,13 @@ static int loopcut_init(bContext *C, wmOperator *op, const wmEvent *event)
}
else {
- Object *ob_iter = objects[exec_data.ob_index];
+ Object *ob_iter = bases[exec_data.base_index]->object;
ED_view3d_viewcontext_init_object(&lcd->vc, ob_iter);
BMEdge *e;
BM_mesh_elem_table_ensure(lcd->vc.em->bm, BM_EDGE);
e = BM_edge_at_index(lcd->vc.em->bm, exec_data.e_index);
- loopcut_update_edge(lcd, exec_data.ob_index, e, 0);
+ loopcut_update_edge(lcd, exec_data.base_index, e, 0);
}
#ifdef USE_LOOPSLIDE_HACK
@@ -503,7 +502,7 @@ static int loopcut_finish(RingSelOpData *lcd, bContext *C, wmOperator *op)
if (lcd->eed) {
/* set for redo */
BM_mesh_elem_index_ensure(lcd->em->bm, BM_EDGE);
- RNA_int_set(op->ptr, "object_index", lcd->ob_index);
+ RNA_int_set(op->ptr, "object_index", lcd->base_index);
RNA_int_set(op->ptr, "edge_index", BM_elem_index_get(lcd->eed));
/* execute */
diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c
index 9df03a81762..5344537e2d1 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.c
@@ -67,6 +67,8 @@
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
+#include "DRW_engine.h"
+
#include "mesh_intern.h" /* own include */
/* use bmesh operator flags for a few operators */
@@ -196,7 +198,87 @@ void EDBM_automerge(Scene *scene, Object *obedit, bool update, const char hflag)
/** \name Back-Buffer OpenGL Selection
* \{ */
-/* set in drawobject.c ... for colorindices */
+struct EDBMBaseOffset {
+ uint face;
+ uint edge;
+ uint vert;
+};
+
+static struct EDBMBaseOffset *base_array_index_offsets = NULL;
+
+static void edbm_select_pick_cache_alloc(uint bases_len)
+{
+ BLI_assert(base_array_index_offsets == NULL);
+ base_array_index_offsets = MEM_mallocN(sizeof(struct EDBMBaseOffset) * bases_len, __func__);
+}
+
+static void edbm_select_pick_cache_free(void)
+{
+ MEM_SAFE_FREE(base_array_index_offsets);
+}
+
+static bool check_ob_drawface_dot(short select_mode, View3D *vd, char dt)
+{
+ if ((select_mode & SCE_SELECT_FACE) == 0) {
+ return false;
+ }
+
+ /* if its drawing textures with zbuf sel, then don't draw dots */
+ if (dt == OB_TEXTURE && vd->shading.type == OB_TEXTURE) {
+ return false;
+ }
+
+ return true;
+}
+
+static void edbm_select_pick_draw_bases(ViewContext *vc,
+ Base **bases,
+ uint bases_len,
+ short select_mode)
+{
+ Scene *scene_eval = (Scene *)DEG_get_evaluated_id(vc->depsgraph, &vc->scene->id);
+ DRW_framebuffer_select_id_setup(vc->ar, true);
+
+ uint offset = 0;
+ for (uint base_index = 0; base_index < bases_len; base_index++) {
+ Object *ob_eval = DEG_get_evaluated_object(vc->depsgraph, bases[base_index]->object);
+ struct EDBMBaseOffset *base_ofs = &base_array_index_offsets[base_index];
+
+ bool draw_facedot = check_ob_drawface_dot(select_mode, vc->v3d, ob_eval->dt);
+
+ DRW_draw_select_id_object(scene_eval,
+ vc->rv3d,
+ ob_eval,
+ select_mode,
+ draw_facedot,
+ offset,
+ &base_ofs->vert,
+ &base_ofs->edge,
+ &base_ofs->face);
+
+ offset = base_ofs->vert;
+ }
+
+ DRW_framebuffer_select_id_release(vc->ar);
+}
+
+static uint edbm_select_pick_base_index_find(uint bases_len, uint elem_index, uint *r_offset)
+{
+ *r_offset = 0;
+ uint base_index = 0;
+ for (; base_index < bases_len; base_index++) {
+ struct EDBMBaseOffset *base_ofs = &base_array_index_offsets[base_index];
+ if (base_ofs->vert > elem_index) {
+ break;
+ }
+ *r_offset = base_ofs->vert;
+ }
+
+ *r_offset += 1;
+ return base_index;
+}
+
+/* set in view3d_draw_legacy.c ... for colorindices */
unsigned int bm_solidoffs = 0, bm_wireoffs = 0, bm_vertoffs = 0;
/* facilities for box select and circle select */
@@ -217,6 +299,7 @@ bool EDBM_backbuf_border_init(ViewContext *vc, short xmin, short ymin, short xma
return false;
}
+ ED_view3d_select_id_validate(vc);
buf = ED_view3d_select_id_read(vc, xmin, ymin, xmax, ymax, &buf_len);
if ((buf == NULL) || (bm_vertoffs == 0)) {
return false;
@@ -303,6 +386,7 @@ bool EDBM_backbuf_border_mask_init(ViewContext *vc,
return false;
}
+ ED_view3d_select_id_validate(vc);
buf = ED_view3d_select_id_read(vc, xmin, ymin, xmax, ymax, &buf_len);
if ((buf == NULL) || (bm_vertoffs == 0)) {
return false;
@@ -354,6 +438,8 @@ bool EDBM_backbuf_circle_init(ViewContext *vc, short xs, short ys, short rads)
xmax = xs + rads;
ymin = ys - rads;
ymax = ys + rads;
+
+ ED_view3d_select_id_validate(vc);
buf = ED_view3d_select_id_read(vc, xmin, ymin, xmax, ymax, NULL);
if ((buf == NULL) || (bm_vertoffs == 0)) {
return false;
@@ -470,29 +556,46 @@ static void findnearestvert__doClosest(void *userData,
BMVert *EDBM_vert_find_nearest_ex(ViewContext *vc,
float *r_dist,
const bool use_select_bias,
- bool use_cycle)
+ bool use_cycle,
+ Base **bases,
+ uint bases_len,
+ uint *r_base_index)
{
- BMesh *bm = vc->em->bm;
+ uint base_index = 0;
if (!XRAY_FLAG_ENABLED(vc->v3d)) {
uint dist_px = (uint)ED_view3d_backbuf_sample_size_clamp(vc->ar, *r_dist);
- unsigned int index;
+ uint index, offset;
BMVert *eve;
/* No afterqueue (yet), so we check it now, otherwise the bm_xxxofs indices are bad. */
{
- FAKE_SELECT_MODE_BEGIN (vc, fake_select_mode, select_mode, SCE_SELECT_VERTEX)
- ;
- ED_view3d_select_id_validate_with_select_mode(vc, select_mode);
+ FAKE_SELECT_MODE_BEGIN(vc, fake_select_mode, select_mode, SCE_SELECT_VERTEX);
+
+ edbm_select_pick_cache_alloc(bases_len);
+ edbm_select_pick_draw_bases(vc, bases, bases_len, select_mode);
+
+ index = ED_view3d_select_id_read_nearest(vc, vc->mval, 1, UINT_MAX, &dist_px);
+
+ if (index) {
+ base_index = edbm_select_pick_base_index_find(bases_len, index, &offset);
+ ED_view3d_viewcontext_init_object(vc, bases[base_index]->object);
+ eve = BM_vert_at_index_find_or_table(vc->em->bm, index - offset);
+ }
+ else {
+ eve = NULL;
+ }
- index = ED_view3d_select_id_read_nearest(vc, vc->mval, bm_wireoffs, 0xFFFFFF, &dist_px);
- eve = index ? BM_vert_at_index_find_or_table(bm, index - 1) : NULL;
+ edbm_select_pick_cache_free();
FAKE_SELECT_MODE_END(vc, fake_select_mode);
}
if (eve) {
if (dist_px < *r_dist) {
+ if (r_base_index) {
+ *r_base_index = base_index;
+ }
*r_dist = dist_px;
return eve;
}
@@ -509,7 +612,7 @@ BMVert *EDBM_vert_find_nearest_ex(ViewContext *vc,
if ((use_cycle == false) ||
(prev_select_elem &&
- (prev_select_elem != BM_vert_at_index_find_or_table(bm, prev_select_index)))) {
+ (prev_select_elem != BM_vert_at_index_find_or_table(vc->em->bm, prev_select_index)))) {
prev_select_index = 0;
prev_select_elem = NULL;
}
@@ -518,14 +621,26 @@ BMVert *EDBM_vert_find_nearest_ex(ViewContext *vc,
data.mval_fl[1] = vc->mval[1];
data.use_select_bias = use_select_bias;
data.use_cycle = use_cycle;
- data.hit.dist = data.hit_cycle.dist = data.hit.dist_bias = data.hit_cycle.dist_bias = *r_dist;
data.cycle_index_prev = prev_select_index;
- ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
- mesh_foreachScreenVert(vc, findnearestvert__doClosest, &data, clip_flag);
+ for (; base_index < bases_len; base_index++) {
+ Base *base_iter = bases[base_index];
+ ED_view3d_viewcontext_init_object(vc, base_iter->object);
+ data.hit.dist = data.hit_cycle.dist = data.hit.dist_bias = data.hit_cycle.dist_bias =
+ *r_dist;
- hit = (data.use_cycle && data.hit_cycle.vert) ? &data.hit_cycle : &data.hit;
- *r_dist = hit->dist;
+ ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
+ mesh_foreachScreenVert(vc, findnearestvert__doClosest, &data, clip_flag);
+
+ hit = (data.use_cycle && data.hit_cycle.vert) ? &data.hit_cycle : &data.hit;
+
+ if (hit->dist < *r_dist) {
+ if (r_base_index) {
+ *r_base_index = base_index;
+ }
+ *r_dist = hit->dist;
+ }
+ }
prev_select_elem = hit->vert;
prev_select_index = hit->index;
@@ -536,7 +651,8 @@ BMVert *EDBM_vert_find_nearest_ex(ViewContext *vc,
BMVert *EDBM_vert_find_nearest(ViewContext *vc, float *r_dist)
{
- return EDBM_vert_find_nearest_ex(vc, r_dist, false, false);
+ Base *base = BKE_view_layer_base_find(vc->view_layer, vc->obact);
+ return EDBM_vert_find_nearest_ex(vc, r_dist, false, false, &base, 1, NULL);
}
/* find the distance to the edge we already have */
@@ -659,23 +775,37 @@ BMEdge *EDBM_edge_find_nearest_ex(ViewContext *vc,
float *r_dist_center,
const bool use_select_bias,
const bool use_cycle,
- BMEdge **r_eed_zbuf)
+ BMEdge **r_eed_zbuf,
+ Base **bases,
+ uint bases_len,
+ uint *r_base_index)
{
- BMesh *bm = vc->em->bm;
+ uint base_index = 0;
if (!XRAY_FLAG_ENABLED(vc->v3d)) {
uint dist_px = (uint)ED_view3d_backbuf_sample_size_clamp(vc->ar, *r_dist);
- unsigned int index;
+ uint index, offset;
BMEdge *eed;
/* No afterqueue (yet), so we check it now, otherwise the bm_xxxofs indices are bad. */
{
- FAKE_SELECT_MODE_BEGIN (vc, fake_select_mode, select_mode, SCE_SELECT_EDGE)
- ;
- ED_view3d_select_id_validate_with_select_mode(vc, select_mode);
+ FAKE_SELECT_MODE_BEGIN(vc, fake_select_mode, select_mode, SCE_SELECT_EDGE);
+
+ edbm_select_pick_cache_alloc(bases_len);
+ edbm_select_pick_draw_bases(vc, bases, bases_len, select_mode);
+
+ index = ED_view3d_select_id_read_nearest(vc, vc->mval, 1, UINT_MAX, &dist_px);
- index = ED_view3d_select_id_read_nearest(vc, vc->mval, bm_solidoffs, bm_wireoffs, &dist_px);
- eed = index ? BM_edge_at_index_find_or_table(bm, index - 1) : NULL;
+ if (index) {
+ base_index = edbm_select_pick_base_index_find(bases_len, index, &offset);
+ ED_view3d_viewcontext_init_object(vc, bases[base_index]->object);
+ eed = BM_edge_at_index_find_or_table(vc->em->bm, index - offset);
+ }
+ else {
+ eed = NULL;
+ }
+
+ edbm_select_pick_cache_free();
FAKE_SELECT_MODE_END(vc, fake_select_mode);
}
@@ -704,6 +834,9 @@ BMEdge *EDBM_edge_find_nearest_ex(ViewContext *vc,
if (eed) {
if (dist_px < *r_dist) {
+ if (r_base_index) {
+ *r_base_index = base_index;
+ }
*r_dist = dist_px;
return eed;
}
@@ -721,7 +854,7 @@ BMEdge *EDBM_edge_find_nearest_ex(ViewContext *vc,
if ((use_cycle == false) ||
(prev_select_elem &&
- (prev_select_elem != BM_edge_at_index_find_or_table(bm, prev_select_index)))) {
+ (prev_select_elem != BM_edge_at_index_find_or_table(vc->em->bm, prev_select_index)))) {
prev_select_index = 0;
prev_select_elem = NULL;
}
@@ -731,14 +864,27 @@ BMEdge *EDBM_edge_find_nearest_ex(ViewContext *vc,
data.mval_fl[1] = vc->mval[1];
data.use_select_bias = use_select_bias;
data.use_cycle = use_cycle;
- data.hit.dist = data.hit_cycle.dist = data.hit.dist_bias = data.hit_cycle.dist_bias = *r_dist;
data.cycle_index_prev = prev_select_index;
- ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
- mesh_foreachScreenEdge(vc, find_nearest_edge__doClosest, &data, clip_flag);
+ for (; base_index < bases_len; base_index++) {
+ Base *base_iter = bases[base_index];
+ ED_view3d_viewcontext_init_object(vc, base_iter->object);
+ data.hit.dist = data.hit_cycle.dist = data.hit.dist_bias = data.hit_cycle.dist_bias =
+ *r_dist;
+
+ ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
+ mesh_foreachScreenEdge(vc, find_nearest_edge__doClosest, &data, clip_flag);
+
+ hit = (data.use_cycle && data.hit_cycle.edge) ? &data.hit_cycle : &data.hit;
+
+ if (hit->dist < *r_dist) {
+ if (r_base_index) {
+ *r_base_index = base_index;
+ }
+ *r_dist = hit->dist;
+ }
+ }
- hit = (data.use_cycle && data.hit_cycle.edge) ? &data.hit_cycle : &data.hit;
- *r_dist = hit->dist;
if (r_dist_center) {
*r_dist_center = hit->dist_center;
}
@@ -752,7 +898,8 @@ BMEdge *EDBM_edge_find_nearest_ex(ViewContext *vc,
BMEdge *EDBM_edge_find_nearest(ViewContext *vc, float *r_dist)
{
- return EDBM_edge_find_nearest_ex(vc, r_dist, NULL, false, false, NULL);
+ Base *base = BKE_view_layer_base_find(vc->view_layer, vc->obact);
+ return EDBM_edge_find_nearest_ex(vc, r_dist, NULL, false, false, NULL, &base, 1, NULL);
}
/* find the distance to the face we already have */
@@ -832,22 +979,36 @@ BMFace *EDBM_face_find_nearest_ex(ViewContext *vc,
float *r_dist_center,
const bool use_select_bias,
const bool use_cycle,
- BMFace **r_efa_zbuf)
+ BMFace **r_efa_zbuf,
+ Base **bases,
+ uint bases_len,
+ uint *r_base_index)
{
- BMesh *bm = vc->em->bm;
+ uint base_index = 0;
if (!XRAY_FLAG_ENABLED(vc->v3d)) {
float dist_test = 0.0f;
- unsigned int index;
+ uint index, offset;
BMFace *efa;
{
- FAKE_SELECT_MODE_BEGIN (vc, fake_select_mode, select_mode, SCE_SELECT_FACE)
- ;
- ED_view3d_select_id_validate_with_select_mode(vc, select_mode);
+ FAKE_SELECT_MODE_BEGIN(vc, fake_select_mode, select_mode, SCE_SELECT_FACE);
+
+ edbm_select_pick_cache_alloc(bases_len);
+ edbm_select_pick_draw_bases(vc, bases, bases_len, select_mode);
index = ED_view3d_select_id_sample(vc, vc->mval[0], vc->mval[1]);
- efa = index ? BM_face_at_index_find_or_table(bm, index - 1) : NULL;
+
+ if (index) {
+ base_index = edbm_select_pick_base_index_find(bases_len, index, &offset);
+ ED_view3d_viewcontext_init_object(vc, bases[base_index]->object);
+ efa = BM_face_at_index_find_or_table(vc->em->bm, index - offset);
+ }
+ else {
+ efa = NULL;
+ }
+
+ edbm_select_pick_cache_free();
FAKE_SELECT_MODE_END(vc, fake_select_mode);
}
@@ -876,6 +1037,9 @@ BMFace *EDBM_face_find_nearest_ex(ViewContext *vc,
if (efa) {
if (dist_test < *r_dist) {
+ if (r_base_index) {
+ *r_base_index = base_index;
+ }
*r_dist = dist_test;
return efa;
}
@@ -892,7 +1056,7 @@ BMFace *EDBM_face_find_nearest_ex(ViewContext *vc,
if ((use_cycle == false) ||
(prev_select_elem &&
- (prev_select_elem != BM_face_at_index_find_or_table(bm, prev_select_index)))) {
+ (prev_select_elem != BM_face_at_index_find_or_table(vc->em->bm, prev_select_index)))) {
prev_select_index = 0;
prev_select_elem = NULL;
}
@@ -901,14 +1065,28 @@ BMFace *EDBM_face_find_nearest_ex(ViewContext *vc,
data.mval_fl[1] = vc->mval[1];
data.use_select_bias = use_select_bias;
data.use_cycle = use_cycle;
- data.hit.dist = data.hit_cycle.dist = data.hit.dist_bias = data.hit_cycle.dist_bias = *r_dist;
data.cycle_index_prev = prev_select_index;
- ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
- mesh_foreachScreenFace(vc, findnearestface__doClosest, &data, clip_flag);
+ for (; base_index < bases_len; base_index++) {
+ Base *base_iter = bases[base_index];
+ ED_view3d_viewcontext_init_object(vc, base_iter->object);
+
+ data.hit.dist = data.hit_cycle.dist = data.hit.dist_bias = data.hit_cycle.dist_bias =
+ *r_dist;
+
+ ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
+ mesh_foreachScreenFace(vc, findnearestface__doClosest, &data, clip_flag);
+
+ hit = (data.use_cycle && data.hit_cycle.face) ? &data.hit_cycle : &data.hit;
+
+ if (hit->dist < *r_dist) {
+ if (r_base_index) {
+ *r_base_index = base_index;
+ }
+ *r_dist = hit->dist;
+ }
+ }
- hit = (data.use_cycle && data.hit_cycle.face) ? &data.hit_cycle : &data.hit;
- *r_dist = hit->dist;
if (r_dist_center) {
*r_dist_center = hit->dist;
}
@@ -922,7 +1100,8 @@ BMFace *EDBM_face_find_nearest_ex(ViewContext *vc,
BMFace *EDBM_face_find_nearest(ViewContext *vc, float *r_dist)
{
- return EDBM_face_find_nearest_ex(vc, r_dist, NULL, false, false, NULL);
+ Base *base = BKE_view_layer_base_find(vc->view_layer, vc->obact);
+ return EDBM_face_find_nearest_ex(vc, r_dist, NULL, false, false, NULL, &base, 1, NULL);
}
#undef FIND_NEAR_SELECT_BIAS
@@ -965,75 +1144,64 @@ static bool unified_findnearest(ViewContext *vc,
} f, f_zbuf;
} hit = {{NULL}};
- /* TODO(campbell): perform selection as one pass
- * instead of many smaller passes (which doesn't work for zbuf occlusion). */
-
/* no afterqueue (yet), so we check it now, otherwise the em_xxxofs indices are bad */
+ short selectmode = vc->scene->toolsettings->selectmode;
- if ((dist > 0.0f) && em->selectmode & SCE_SELECT_FACE) {
+ if ((dist > 0.0f) && (selectmode & SCE_SELECT_FACE)) {
float dist_center = 0.0f;
float *dist_center_p = (em->selectmode & (SCE_SELECT_EDGE | SCE_SELECT_VERTEX)) ?
&dist_center :
NULL;
- for (uint base_index = 0; base_index < bases_len; base_index++) {
- Base *base_iter = bases[base_index];
- Object *obedit = base_iter->object;
- ED_view3d_viewcontext_init_object(vc, obedit);
- BLI_assert(vc->em->selectmode == em->selectmode);
- BMFace *efa_zbuf = NULL;
- BMFace *efa_test = EDBM_face_find_nearest_ex(
- vc, &dist, dist_center_p, true, use_cycle, &efa_zbuf);
- if (efa_test && dist_center_p) {
- dist = min_ff(dist_margin, dist_center);
- }
- if (efa_test) {
- hit.f.base_index = base_index;
- hit.f.ele = efa_test;
- }
- if (efa_zbuf) {
- hit.f_zbuf.base_index = base_index;
- hit.f_zbuf.ele = efa_zbuf;
- }
- } /* bases */
+ uint base_index = 0;
+ BMFace *efa_zbuf = NULL;
+ BMFace *efa_test = EDBM_face_find_nearest_ex(
+ vc, &dist, dist_center_p, true, use_cycle, &efa_zbuf, bases, bases_len, &base_index);
+
+ if (efa_test && dist_center_p) {
+ dist = min_ff(dist_margin, dist_center);
+ }
+ if (efa_test) {
+ hit.f.base_index = base_index;
+ hit.f.ele = efa_test;
+ }
+ if (efa_zbuf) {
+ hit.f_zbuf.base_index = base_index;
+ hit.f_zbuf.ele = efa_zbuf;
+ }
}
- if ((dist > 0.0f) && (em->selectmode & SCE_SELECT_EDGE)) {
+ if ((dist > 0.0f) && (selectmode & SCE_SELECT_EDGE)) {
float dist_center = 0.0f;
float *dist_center_p = (em->selectmode & SCE_SELECT_VERTEX) ? &dist_center : NULL;
- for (uint base_index = 0; base_index < bases_len; base_index++) {
- Base *base_iter = bases[base_index];
- Object *obedit = base_iter->object;
- ED_view3d_viewcontext_init_object(vc, obedit);
- BMEdge *eed_zbuf = NULL;
- BMEdge *eed_test = EDBM_edge_find_nearest_ex(
- vc, &dist, dist_center_p, true, use_cycle, &eed_zbuf);
- if (eed_test && dist_center_p) {
- dist = min_ff(dist_margin, dist_center);
- }
- if (eed_test) {
- hit.e.base_index = base_index;
- hit.e.ele = eed_test;
- }
- if (eed_zbuf) {
- hit.e_zbuf.base_index = base_index;
- hit.e_zbuf.ele = eed_zbuf;
- }
- } /* bases */
+ uint base_index = 0;
+ BMEdge *eed_zbuf = NULL;
+ BMEdge *eed_test = EDBM_edge_find_nearest_ex(
+ vc, &dist, dist_center_p, true, use_cycle, &eed_zbuf, bases, bases_len, &base_index);
+
+ if (eed_test && dist_center_p) {
+ dist = min_ff(dist_margin, dist_center);
+ }
+ if (eed_test) {
+ hit.e.base_index = base_index;
+ hit.e.ele = eed_test;
+ }
+ if (eed_zbuf) {
+ hit.e_zbuf.base_index = base_index;
+ hit.e_zbuf.ele = eed_zbuf;
+ }
}
- if ((dist > 0.0f) && em->selectmode & SCE_SELECT_VERTEX) {
- for (uint base_index = 0; base_index < bases_len; base_index++) {
- Base *base_iter = bases[base_index];
- Object *obedit = base_iter->object;
- ED_view3d_viewcontext_init_object(vc, obedit);
- BMVert *eve_test = EDBM_vert_find_nearest_ex(vc, &dist, true, use_cycle);
- if (eve_test) {
- hit.v.base_index = base_index;
- hit.v.ele = eve_test;
- }
- } /* bases */
+ if ((dist > 0.0f) && (selectmode & SCE_SELECT_VERTEX)) {
+ uint base_index = 0;
+ BMVert *eve_test = EDBM_vert_find_nearest_ex(
+ vc, &dist, true, use_cycle, bases, bases_len, &base_index);
+
+ if (eve_test) {
+ hit.v.base_index = base_index;
+ hit.v.ele = eve_test;
+ }
}
/* return only one of 3 pointers, for frontbuffer redraws */
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index 2181bf01583..331be744932 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -1124,7 +1124,7 @@ static int edbm_mark_sharp_exec(bContext *C, wmOperator *op)
BMEditMesh *em = BKE_editmesh_from_object(obedit);
BMesh *bm = em->bm;
- if (bm->totedgesel == 0) {
+ if ((use_verts && bm->totvertsel == 0) || (!use_verts && bm->totedgesel == 0)) {
continue;
}
@@ -8955,7 +8955,6 @@ void MESH_OT_smoothen_normals(struct wmOperatorType *ot)
static int edbm_mod_weighted_strength_exec(bContext *C, wmOperator *op)
{
- Scene *scene = CTX_data_scene(C);
Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = BKE_editmesh_from_object(obedit);
BMesh *bm = em->bm;
@@ -8974,7 +8973,7 @@ static int edbm_mod_weighted_strength_exec(bContext *C, wmOperator *op)
const int cd_prop_int_offset = CustomData_get_n_offset(
&bm->pdata, CD_PROP_INT, cd_prop_int_index);
- const int face_strength = scene->toolsettings->face_strength;
+ const int face_strength = RNA_enum_get(op->ptr, "face_strength");
const bool set = RNA_boolean_get(op->ptr, "set");
BM_mesh_elem_index_ensure(bm, BM_FACE);
@@ -9003,6 +9002,13 @@ static int edbm_mod_weighted_strength_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
+static const EnumPropertyItem prop_mesh_face_strength_types[] = {
+ {FACE_STRENGTH_WEAK, "WEAK", 0, "Weak", ""},
+ {FACE_STRENGTH_MEDIUM, "MEDIUM", 0, "Medium", ""},
+ {FACE_STRENGTH_STRONG, "STRONG", 0, "Strong", ""},
+ {0, NULL, 0, NULL, NULL},
+};
+
void MESH_OT_mod_weighted_strength(struct wmOperatorType *ot)
{
/* identifiers */
@@ -9018,5 +9024,12 @@ void MESH_OT_mod_weighted_strength(struct wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
ot->prop = RNA_def_boolean(ot->srna, "set", 0, "Set value", "Set Value of faces");
- RNA_def_property_flag(ot->prop, PROP_HIDDEN);
+
+ ot->prop = RNA_def_enum(
+ ot->srna,
+ "face_strength",
+ prop_mesh_face_strength_types,
+ FACE_STRENGTH_MEDIUM,
+ "Face Strength",
+ "Strength to use for assigning or selecting face influence for weighted normal modifier");
}
diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c
index c32fef42d27..e29cfa6b6e0 100644
--- a/source/blender/editors/mesh/meshtools.c
+++ b/source/blender/editors/mesh/meshtools.c
@@ -1109,13 +1109,11 @@ bool ED_mesh_pick_face(bContext *C, Object *ob, const int mval[2], uint dist_px,
}
ED_view3d_viewcontext_init(C, &vc);
+ ED_view3d_select_id_validate(&vc);
if (dist_px) {
/* sample rect to increase chances of selecting, so that when clicking
* on an edge in the backbuf, we can still select a face */
-
- ED_view3d_select_id_validate(&vc);
-
*r_index = ED_view3d_select_id_read_nearest(&vc, mval, 1, me->totpoly + 1, &dist_px);
}
else {
@@ -1291,14 +1289,12 @@ bool ED_mesh_pick_vert(
}
ED_view3d_viewcontext_init(C, &vc);
+ ED_view3d_select_id_validate(&vc);
if (use_zbuf) {
if (dist_px > 0) {
/* sample rect to increase chances of selecting, so that when clicking
* on an face in the backbuf, we can still select a vert */
-
- ED_view3d_select_id_validate(&vc);
-
*r_index = ED_view3d_select_id_read_nearest(&vc, mval, 1, me->totvert + 1, &dist_px);
}
else {
diff --git a/source/blender/editors/metaball/mball_edit.c b/source/blender/editors/metaball/mball_edit.c
index 54143822b61..18ff7ae1a5e 100644
--- a/source/blender/editors/metaball/mball_edit.c
+++ b/source/blender/editors/metaball/mball_edit.c
@@ -738,7 +738,7 @@ bool ED_mball_select_pick(bContext *C, const int mval[2], bool extend, bool dese
}
const uint hit_object = hitresult & 0xFFFF;
- if (vc.obedit->select_id != hit_object) {
+ if (vc.obedit->runtime.select_id != hit_object) {
continue;
}
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index f8a13579732..f8760f93f2f 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -161,6 +161,18 @@ static EnumPropertyItem lightprobe_type_items[] = {
{0, NULL, 0, NULL, NULL},
};
+enum ObjectAlign {
+ ALIGN_WORLD,
+ ALIGN_VIEW,
+ ALIGN_CURSOR,
+} ALIGN_OPTIONS;
+
+static const EnumPropertyItem align_options[] = {
+ {ALIGN_WORLD, "WORLD", 0, "World", "Align the new object to the world"},
+ {ALIGN_VIEW, "VIEW", 0, "View", "Align the new object to the view"},
+ {ALIGN_CURSOR, "CURSOR", 0, "3D Cursor", "Use the 3D cursor orientation for the new object"},
+ {0, NULL, 0, NULL, NULL}};
+
/************************** Exported *****************************/
void ED_object_location_from_view(bContext *C, float loc[3])
@@ -291,16 +303,15 @@ void ED_object_add_generic_props(wmOperatorType *ot, bool do_editmode)
{
PropertyRNA *prop;
- /* note: this property gets hidden for add-camera operator */
- prop = RNA_def_boolean(
- ot->srna, "view_align", 0, "Align to View", "Align the new object to the view");
- RNA_def_property_update_runtime(prop, view_align_update);
-
if (do_editmode) {
prop = RNA_def_boolean(
ot->srna, "enter_editmode", 0, "Enter Editmode", "Enter editmode when adding this object");
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
}
+ /* note: this property gets hidden for add-camera operator */
+ prop = RNA_def_enum(
+ ot->srna, "align", align_options, ALIGN_WORLD, "Align", "The alignment of the new object");
+ RNA_def_property_update_runtime(prop, view_align_update);
prop = RNA_def_float_vector_xyz(ot->srna,
"location",
@@ -392,23 +403,42 @@ bool ED_object_add_generic_get_opts(bContext *C,
rot = _rot;
}
+ prop = RNA_struct_find_property(op->ptr, "align");
+ int alignment = RNA_property_enum_get(op->ptr, prop);
+ bool alignment_set = RNA_property_is_set(op->ptr, prop);
+
if (RNA_struct_property_is_set(op->ptr, "rotation")) {
*is_view_aligned = false;
}
- else if (RNA_struct_property_is_set(op->ptr, "view_align")) {
- *is_view_aligned = RNA_boolean_get(op->ptr, "view_align");
+ else if (alignment_set) {
+ *is_view_aligned = alignment == ALIGN_VIEW;
}
else {
*is_view_aligned = (U.flag & USER_ADD_VIEWALIGNED) != 0;
- RNA_boolean_set(op->ptr, "view_align", *is_view_aligned);
+ if (*is_view_aligned) {
+ RNA_property_enum_set(op->ptr, prop, ALIGN_VIEW);
+ alignment = ALIGN_VIEW;
+ }
+ else if (U.flag & USER_ADD_CURSORALIGNED) {
+ RNA_property_enum_set(op->ptr, prop, ALIGN_CURSOR);
+ alignment = ALIGN_CURSOR;
+ }
}
- if (*is_view_aligned) {
- ED_object_rotation_from_view(C, rot, view_align_axis);
- RNA_float_set_array(op->ptr, "rotation", rot);
- }
- else {
- RNA_float_get_array(op->ptr, "rotation", rot);
+ switch (alignment) {
+ case ALIGN_WORLD:
+ RNA_float_get_array(op->ptr, "rotation", rot);
+ break;
+ case ALIGN_VIEW:
+ ED_object_rotation_from_view(C, rot, view_align_axis);
+ RNA_float_set_array(op->ptr, "rotation", rot);
+ break;
+ case ALIGN_CURSOR: {
+ const Scene *scene = CTX_data_scene(C);
+ copy_v3_v3(rot, scene->cursor.rotation_euler);
+ RNA_float_set_array(op->ptr, "rotation", rot);
+ break;
+ }
}
}
@@ -690,7 +720,7 @@ static int object_camera_add_exec(bContext *C, wmOperator *op)
float loc[3], rot[3];
/* force view align for cameras */
- RNA_boolean_set(op->ptr, "view_align", true);
+ RNA_enum_set(op->ptr, "align", ALIGN_VIEW);
if (!ED_object_add_generic_get_opts(
C, op, 'Z', loc, rot, &enter_editmode, &local_view_bits, NULL)) {
@@ -732,7 +762,7 @@ void OBJECT_OT_camera_add(wmOperatorType *ot)
ED_object_add_generic_props(ot, true);
/* hide this for cameras, default */
- prop = RNA_struct_type_find_property(ot->srna, "view_align");
+ prop = RNA_struct_type_find_property(ot->srna, "align");
RNA_def_property_flag(prop, PROP_HIDDEN);
}
@@ -1176,7 +1206,6 @@ static const char *get_light_defname(int type)
static int object_light_add_exec(bContext *C, wmOperator *op)
{
- Scene *scene = CTX_data_scene(C);
Object *ob;
Light *la;
int type = RNA_enum_get(op->ptr, "type");
@@ -1207,9 +1236,8 @@ static int object_light_add_exec(bContext *C, wmOperator *op)
la = (Light *)ob->data;
la->type = type;
- if (BKE_scene_uses_cycles(scene)) {
- ED_node_shader_default(C, &la->id);
- la->use_nodes = true;
+ if (type == LA_SUN) {
+ la->energy = 1.0f;
}
return OPERATOR_FINISHED;
@@ -1656,7 +1684,7 @@ static void make_object_duplilist_real(
for (dob = lb_duplis->first; dob; dob = dob->next) {
Object *ob_src = DEG_get_original_object(dob->ob);
- Object *ob_dst = ID_NEW_SET(dob->ob, BKE_object_copy(bmain, ob_src));
+ Object *ob_dst = ID_NEW_SET(ob_src, BKE_object_copy(bmain, ob_src));
Base *base_dst;
/* font duplis can have a totcol without material, we get them from parent
@@ -2481,7 +2509,7 @@ static int add_named_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- basen->object->restrictflag &= ~OB_RESTRICT_VIEW;
+ basen->object->restrictflag &= ~OB_RESTRICT_VIEWPORT;
if (event) {
ARegion *ar = CTX_wm_region(C);
diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c
index 5ae757cac56..da95db92332 100644
--- a/source/blender/editors/object/object_bake_api.c
+++ b/source/blender/editors/object/object_bake_api.c
@@ -277,7 +277,8 @@ static bool write_internal_bake_pixels(Image *image,
RE_bake_margin(ibuf, mask_buffer, margin);
}
- ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID | IB_BITMAPDIRTY;
+ ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
+ BKE_image_mark_dirty(image, ibuf);
if (ibuf->rect_float) {
ibuf->userflags |= IB_RECT_INVALID;
diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c
index 078135f46ff..abdf64af595 100644
--- a/source/blender/editors/object/object_constraint.c
+++ b/source/blender/editors/object/object_constraint.c
@@ -2025,8 +2025,8 @@ static const EnumPropertyItem *object_constraint_add_itemf(bContext *UNUSED(C),
EnumPropertyItem *object_constraint_items = NULL;
int totitem = 0;
- while(item->identifier) {
- if((item->value != CONSTRAINT_TYPE_KINEMATIC) && (item->value != CONSTRAINT_TYPE_SPLINEIK)) {
+ while (item->identifier) {
+ if ((item->value != CONSTRAINT_TYPE_KINEMATIC) && (item->value != CONSTRAINT_TYPE_SPLINEIK)) {
RNA_enum_item_add(&object_constraint_items, &totitem, item);
}
item++;
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index 795e1dd66a5..9fba0d89c4a 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -314,7 +314,7 @@ void ED_collection_hide_menu_draw(const bContext *C, uiLayout *layout)
continue;
}
- if (lc->collection->flag & COLLECTION_RESTRICT_VIEW) {
+ if (lc->collection->flag & COLLECTION_RESTRICT_VIEWPORT) {
continue;
}
@@ -722,7 +722,7 @@ static bool editmode_toggle_poll(bContext *C)
}
/* if hidden but in edit mode, we still display */
- if ((ob->restrictflag & OB_RESTRICT_VIEW) && !(ob->mode & OB_MODE_EDIT)) {
+ if ((ob->restrictflag & OB_RESTRICT_VIEWPORT) && !(ob->mode & OB_MODE_EDIT)) {
return 0;
}
diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c
index 09bcc0a3058..1e85c895f71 100644
--- a/source/blender/editors/render/render_internal.c
+++ b/source/blender/editors/render/render_internal.c
@@ -356,7 +356,7 @@ static int screen_render_exec(bContext *C, wmOperator *op)
/* cleanup sequencer caches before starting user triggered render.
* otherwise, invalidated cache entries can make their way into
- * the output rendering. We can't put that into RE_BlenderFrame,
+ * the output rendering. We can't put that into RE_RenderFrame,
* since sequence rendering can call that recursively... (peter) */
BKE_sequencer_cache_cleanup(scene);
@@ -364,18 +364,17 @@ static int screen_render_exec(bContext *C, wmOperator *op)
BLI_threaded_malloc_begin();
if (is_animation) {
- RE_BlenderAnim(re,
- mainp,
- scene,
- single_layer,
- camera_override,
- scene->r.sfra,
- scene->r.efra,
- scene->r.frame_step);
+ RE_RenderAnim(re,
+ mainp,
+ scene,
+ single_layer,
+ camera_override,
+ scene->r.sfra,
+ scene->r.efra,
+ scene->r.frame_step);
}
else {
- RE_BlenderFrame(
- re, mainp, scene, single_layer, camera_override, scene->r.cfra, is_write_still);
+ RE_RenderFrame(re, mainp, scene, single_layer, camera_override, scene->r.cfra, is_write_still);
}
BLI_threaded_malloc_end();
@@ -671,23 +670,23 @@ static void render_startjob(void *rjv, short *stop, short *do_update, float *pro
RE_SetReports(rj->re, rj->reports);
if (rj->anim) {
- RE_BlenderAnim(rj->re,
+ RE_RenderAnim(rj->re,
+ rj->main,
+ rj->scene,
+ rj->single_layer,
+ rj->camera_override,
+ rj->scene->r.sfra,
+ rj->scene->r.efra,
+ rj->scene->r.frame_step);
+ }
+ else {
+ RE_RenderFrame(rj->re,
rj->main,
rj->scene,
rj->single_layer,
rj->camera_override,
- rj->scene->r.sfra,
- rj->scene->r.efra,
- rj->scene->r.frame_step);
- }
- else {
- RE_BlenderFrame(rj->re,
- rj->main,
- rj->scene,
- rj->single_layer,
- rj->camera_override,
- rj->scene->r.cfra,
- rj->write_still);
+ rj->scene->r.cfra,
+ rj->write_still);
}
RE_SetReports(rj->re, NULL);
@@ -976,7 +975,7 @@ static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *even
/* cleanup sequencer caches before starting user triggered render.
* otherwise, invalidated cache entries can make their way into
- * the output rendering. We can't put that into RE_BlenderFrame,
+ * the output rendering. We can't put that into RE_RenderFrame,
* since sequence rendering can call that recursively... (peter) */
BKE_sequencer_cache_cleanup(scene);
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index 64f20a4a348..e082e961b45 100644
--- a/source/blender/editors/render/render_preview.c
+++ b/source/blender/editors/render/render_preview.c
@@ -270,7 +270,7 @@ static const char *preview_collection_name(const char pr_type)
case MA_FLUID:
return "Fluid";
case MA_SPHERE_A:
- return "World Shader Ball";
+ return "World Sphere";
case MA_LAMP:
return "Lamp";
case MA_SKY:
@@ -437,7 +437,14 @@ static Scene *preview_prepare_scene(
sce->world->horb = 0.05f;
}
- set_preview_visibility(sce, view_layer, mat->pr_type, sp->pr_method);
+ if (sp->pr_method == PR_ICON_RENDER && sp->pr_main == G_pr_main_grease_pencil) {
+ /* For grease pencil, always use sphere for icon renders. */
+ set_preview_visibility(sce, view_layer, MA_SPHERE_A, sp->pr_method);
+ }
+ else {
+ /* Use specified preview shape for both preview panel and icon previews. */
+ set_preview_visibility(sce, view_layer, mat->pr_type, sp->pr_method);
+ }
if (sp->pr_method != PR_ICON_RENDER) {
if (mat->nodetree && sp->pr_method == PR_NODE_RENDER) {
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index 8c73f4cd649..c2f9beb5d78 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -50,6 +50,7 @@
#include "ED_screen.h"
#include "ED_screen_types.h"
#include "ED_space_api.h"
+#include "ED_time_scrub_ui.h"
#include "GPU_immediate.h"
#include "GPU_immediate_util.h"
@@ -202,7 +203,7 @@ static void area_draw_azone_fullscreen(short x1, short y1, short x2, short y2, f
alpha = min_ff(alpha, 0.75f);
- UI_icon_draw_aspect(x, y, ICON_FULLSCREEN_EXIT, 0.7f / UI_DPI_FAC, alpha, NULL);
+ UI_icon_draw_ex(x, y, ICON_FULLSCREEN_EXIT, 0.7f * U.inv_dpi_fac, 0.0f, alpha, NULL, false);
/* debug drawing :
* The click_rect is the same as defined in fullscreen_click_rcti_init
@@ -1058,11 +1059,11 @@ static void region_azones_scrollbars_initialize(ScrArea *sa, ARegion *ar)
{
const View2D *v2d = &ar->v2d;
- if ((v2d->scroll & V2D_SCROLL_VERTICAL) && ((v2d->scroll & V2D_SCROLL_SCALE_VERTICAL) == 0)) {
+ if ((v2d->scroll & V2D_SCROLL_VERTICAL) && ((v2d->scroll & V2D_SCROLL_VERTICAL_HANDLES) == 0)) {
region_azone_scrollbar_initialize(sa, ar, AZ_SCROLL_VERT);
}
if ((v2d->scroll & V2D_SCROLL_HORIZONTAL) &&
- ((v2d->scroll & V2D_SCROLL_SCALE_HORIZONTAL) == 0)) {
+ ((v2d->scroll & V2D_SCROLL_HORIZONTAL_HANDLES) == 0)) {
region_azone_scrollbar_initialize(sa, ar, AZ_SCROLL_HOR);
}
}
@@ -1604,14 +1605,19 @@ static void ed_default_handlers(
wmKeyMap *keymap = WM_keymap_ensure(wm->defaultconf, "View2D", 0, 0);
WM_event_add_keymap_handler(handlers, keymap);
}
- if (flag & ED_KEYMAP_MARKERS) {
+ if (flag & ED_KEYMAP_ANIMATION) {
+ wmKeyMap *keymap;
+
/* time-markers */
- wmKeyMap *keymap = WM_keymap_ensure(wm->defaultconf, "Markers", 0, 0);
+ keymap = WM_keymap_ensure(wm->defaultconf, "Markers", 0, 0);
WM_event_add_keymap_handler_poll(handlers, keymap, event_in_markers_region);
- }
- if (flag & ED_KEYMAP_ANIMATION) {
+
+ /* time-scrubbing */
+ keymap = WM_keymap_ensure(wm->defaultconf, "Scrubbing", 0, 0);
+ WM_event_add_keymap_handler_poll(handlers, keymap, ED_event_in_scrubbing_region);
+
/* frame changing and timeline operators (for time spaces) */
- wmKeyMap *keymap = WM_keymap_ensure(wm->defaultconf, "Animation", 0, 0);
+ keymap = WM_keymap_ensure(wm->defaultconf, "Animation", 0, 0);
WM_event_add_keymap_handler(handlers, keymap);
}
if (flag & ED_KEYMAP_FRAMES) {
@@ -1621,14 +1627,19 @@ static void ed_default_handlers(
}
if (flag & ED_KEYMAP_HEADER) {
/* standard keymap for headers regions */
- wmKeyMap *keymap = WM_keymap_ensure(wm->defaultconf, "Header", 0, 0);
+ wmKeyMap *keymap = WM_keymap_ensure(wm->defaultconf, "Region Context Menu", 0, 0);
WM_event_add_keymap_handler(handlers, keymap);
}
if (flag & ED_KEYMAP_FOOTER) {
/* standard keymap for footer regions */
- wmKeyMap *keymap = WM_keymap_ensure(wm->defaultconf, "Footer", 0, 0);
+ wmKeyMap *keymap = WM_keymap_ensure(wm->defaultconf, "Region Context Menu", 0, 0);
WM_event_add_keymap_handler(handlers, keymap);
}
+ if (flag & ED_KEYMAP_NAVBAR) {
+ /* standard keymap for Navigation bar regions */
+ wmKeyMap *keymap = WM_keymap_ensure(wm->defaultconf, "Region Context Menu", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
+ }
/* Keep last because of LMB/RMB handling, see: T57527. */
if (flag & ED_KEYMAP_GPENCIL) {
@@ -2289,34 +2300,62 @@ static void ed_panel_draw(const bContext *C,
* Matching against any of these strings will draw the panel.
* Can be NULL to skip context checks.
*/
-void ED_region_panels_layout_ex(
- const bContext *C, ARegion *ar, const char *contexts[], int contextnr, const bool vertical)
+void ED_region_panels_layout_ex(const bContext *C,
+ ARegion *ar,
+ ListBase *paneltypes,
+ const char *contexts[],
+ int contextnr,
+ const bool vertical,
+ const char *category_override)
{
+ /* collect panels to draw */
+ WorkSpace *workspace = CTX_wm_workspace(C);
+ LinkNode *panel_types_stack = NULL;
+ for (PanelType *pt = paneltypes->last; pt; pt = pt->prev) {
+ /* Only draw top level panels. */
+ if (pt->parent) {
+ continue;
+ }
+
+ if (category_override) {
+ if (!STREQ(pt->category, category_override)) {
+ continue;
+ }
+ }
+
+ /* verify context */
+ if (contexts && pt->context[0] && !streq_array_any(pt->context, contexts)) {
+ continue;
+ }
+
+ /* If we're tagged, only use compatible. */
+ if (pt->owner_id[0] && BKE_workspace_owner_id_check(workspace, pt->owner_id) == false) {
+ continue;
+ }
+
+ /* draw panel */
+ if (pt->draw && (!pt->poll || pt->poll(C, pt))) {
+ BLI_linklist_prepend_alloca(&panel_types_stack, pt);
+ }
+ }
+
ar->runtime.category = NULL;
- const WorkSpace *workspace = CTX_wm_workspace(C);
ScrArea *sa = CTX_wm_area(C);
- PanelType *pt;
View2D *v2d = &ar->v2d;
int x, y, w, em;
- bool is_context_new = 0;
- int scroll;
/* XXX, should use some better check? */
/* For now also has hardcoded check for clip editor until it supports actual toolbar. */
- bool use_category_tabs = ((1 << ar->regiontype) & RGN_TYPE_HAS_CATEGORY_MASK) ||
- (ar->regiontype == RGN_TYPE_TOOLS && sa->spacetype == SPACE_CLIP);
+ bool use_category_tabs = (category_override == NULL) &&
+ ((((1 << ar->regiontype) & RGN_TYPE_HAS_CATEGORY_MASK) ||
+ (ar->regiontype == RGN_TYPE_TOOLS && sa->spacetype == SPACE_CLIP)));
/* offset panels for small vertical tab area */
const char *category = NULL;
const int category_tabs_width = UI_PANEL_CATEGORY_MARGIN_WIDTH;
int margin_x = 0;
const bool region_layout_based = ar->flag & RGN_FLAG_DYNAMIC_SIZE;
-
- BLI_SMALLSTACK_DECLARE(pt_stack, PanelType *);
-
- if (contextnr != -1) {
- is_context_new = UI_view2d_tab_set(v2d, contextnr);
- }
+ const bool is_context_new = (contextnr != -1) ? UI_view2d_tab_set(v2d, contextnr) : false;
/* before setting the view */
if (vertical) {
@@ -2334,45 +2373,21 @@ void ED_region_panels_layout_ex(
v2d->scroll |= (V2D_SCROLL_BOTTOM);
v2d->scroll &= ~(V2D_SCROLL_RIGHT);
}
-
- scroll = v2d->scroll;
-
- /* collect panels to draw */
- for (pt = ar->type->paneltypes.last; pt; pt = pt->prev) {
- /* Only draw top level panels. */
- if (pt->parent) {
- continue;
- }
-
- /* verify context */
- if (contexts && pt->context[0] && !streq_array_any(pt->context, contexts)) {
- continue;
- }
-
- /* If we're tagged, only use compatible. */
- if (pt->owner_id[0] && BKE_workspace_owner_id_check(workspace, pt->owner_id) == false) {
- continue;
- }
-
- /* draw panel */
- if (pt->draw && (!pt->poll || pt->poll(C, pt))) {
- BLI_SMALLSTACK_PUSH(pt_stack, pt);
- }
- }
+ const int scroll = v2d->scroll;
/* collect categories */
if (use_category_tabs) {
UI_panel_category_clear_all(ar);
/* gather unique categories */
- BLI_SMALLSTACK_ITER_BEGIN (pt_stack, pt) {
+ for (LinkNode *pt_link = panel_types_stack; pt_link; pt_link = pt_link->next) {
+ PanelType *pt = pt_link->link;
if (pt->category[0]) {
if (!UI_panel_category_find(ar, pt->category)) {
UI_panel_category_add(ar, pt->category);
}
}
}
- BLI_SMALLSTACK_ITER_END;
if (!UI_panel_category_is_visible(ar)) {
use_category_tabs = false;
@@ -2400,7 +2415,8 @@ void ED_region_panels_layout_ex(
/* set view2d view matrix - UI_block_begin() stores it */
UI_view2d_view_ortho(v2d);
- BLI_SMALLSTACK_ITER_BEGIN (pt_stack, pt) {
+ for (LinkNode *pt_link = panel_types_stack; pt_link; pt_link = pt_link->next) {
+ PanelType *pt = pt_link->link;
Panel *panel = UI_panel_find_by_type(&ar->panels, pt);
if (use_category_tabs && pt->category[0] && !STREQ(category, pt->category)) {
@@ -2411,7 +2427,6 @@ void ED_region_panels_layout_ex(
ed_panel_draw(C, sa, ar, &ar->panels, pt, panel, w, em, vertical);
}
- BLI_SMALLSTACK_ITER_END;
/* align panels and return size */
UI_panels_end(C, ar, &x, &y);
@@ -2482,9 +2497,11 @@ void ED_region_panels_layout_ex(
ar->runtime.category = category;
}
}
+
void ED_region_panels_layout(const bContext *C, ARegion *ar)
{
- ED_region_panels_layout_ex(C, ar, NULL, -1, true);
+ bool vertical = true;
+ ED_region_panels_layout_ex(C, ar, &ar->type->paneltypes, NULL, -1, vertical, NULL);
}
void ED_region_panels_draw(const bContext *C, ARegion *ar)
@@ -2533,7 +2550,7 @@ void ED_region_panels_ex(
const bContext *C, ARegion *ar, const char *contexts[], int contextnr, const bool vertical)
{
/* TODO: remove? */
- ED_region_panels_layout_ex(C, ar, contexts, contextnr, vertical);
+ ED_region_panels_layout_ex(C, ar, &ar->type->paneltypes, contexts, contextnr, vertical, NULL);
ED_region_panels_draw(C, ar);
}
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 61fa05f243f..af90bbc9975 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -67,7 +67,6 @@
#include "WM_types.h"
#include "DEG_depsgraph.h"
-#include "DEG_depsgraph_query.h"
#include "ED_anim_api.h"
#include "ED_armature.h"
@@ -343,7 +342,7 @@ bool ED_operator_console_active(bContext *C)
static bool ed_object_hidden(Object *ob)
{
/* if hidden but in edit mode, we still display, can happen with animation */
- return ((ob->restrictflag & OB_RESTRICT_VIEW) && !(ob->mode & OB_MODE_EDIT));
+ return ((ob->restrictflag & OB_RESTRICT_VIEWPORT) && !(ob->mode & OB_MODE_EDIT));
}
bool ED_operator_object_active(bContext *C)
@@ -632,24 +631,6 @@ static bool screen_active_editable(bContext *C)
return 0;
}
-static ARegion *screen_find_region_type(bContext *C, int type)
-{
- ARegion *ar = CTX_wm_region(C);
-
- /* find the header region
- * - try context first, but upon failing, search all regions in area...
- */
- if ((ar == NULL) || (ar->regiontype != type)) {
- ScrArea *sa = CTX_wm_area(C);
- ar = BKE_area_find_region_type(sa, type);
- }
- else {
- ar = NULL;
- }
-
- return ar;
-}
-
/** \} */
/* -------------------------------------------------------------------- */
@@ -2771,7 +2752,7 @@ static int frame_offset_exec(bContext *C, wmOperator *op)
areas_do_frame_follow(C, false);
- BKE_sound_update_and_seek(bmain, CTX_data_depsgraph(C));
+ BKE_sound_seek_scene(bmain, scene);
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
@@ -2833,7 +2814,7 @@ static int frame_jump_exec(bContext *C, wmOperator *op)
areas_do_frame_follow(C, true);
- BKE_sound_update_and_seek(bmain, CTX_data_depsgraph(C));
+ BKE_sound_seek_scene(bmain, scene);
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
}
@@ -2949,7 +2930,7 @@ static int keyframe_jump_exec(bContext *C, wmOperator *op)
else {
areas_do_frame_follow(C, true);
- BKE_sound_update_and_seek(bmain, CTX_data_depsgraph(C));
+ BKE_sound_seek_scene(bmain, scene);
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
@@ -3016,7 +2997,7 @@ static int marker_jump_exec(bContext *C, wmOperator *op)
areas_do_frame_follow(C, true);
- BKE_sound_update_and_seek(bmain, CTX_data_depsgraph(C));
+ BKE_sound_seek_scene(bmain, scene);
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
@@ -3956,10 +3937,10 @@ static void SCREEN_OT_header_toggle_menus(wmOperatorType *ot)
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Header Tools Operator
+/** \name Region Context Menu Operator (Header/Footer/Navbar)
* \{ */
-static bool header_context_menu_poll(bContext *C)
+static bool screen_region_context_menu_poll(bContext *C)
{
ScrArea *sa = CTX_wm_area(C);
return (sa && sa->spacetype != SPACE_STATUSBAR);
@@ -4009,89 +3990,17 @@ void ED_screens_header_tools_menu_create(bContext *C, uiLayout *layout, void *UN
}
}
-static int header_context_menu_invoke(bContext *C,
- wmOperator *UNUSED(op),
- const wmEvent *UNUSED(event))
-{
- uiPopupMenu *pup;
- uiLayout *layout;
-
- pup = UI_popup_menu_begin(C, IFACE_("Header"), ICON_NONE);
- layout = UI_popup_menu_layout(pup);
-
- ED_screens_header_tools_menu_create(C, layout, NULL);
-
- UI_popup_menu_end(C, pup);
-
- return OPERATOR_INTERFACE;
-}
-
-static void SCREEN_OT_header_context_menu(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name = "Header Context Menu";
- ot->description = "Display header region context menu";
- ot->idname = "SCREEN_OT_header_context_menu";
-
- /* api callbacks */
- ot->poll = header_context_menu_poll;
- ot->invoke = header_context_menu_invoke;
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Footer Toggle Operator
- * \{ */
-
-static int footer_exec(bContext *C, wmOperator *UNUSED(op))
-{
- ARegion *ar = screen_find_region_type(C, RGN_TYPE_FOOTER);
-
- if (ar == NULL) {
- return OPERATOR_CANCELLED;
- }
-
- ar->flag ^= RGN_FLAG_HIDDEN;
-
- ED_area_tag_redraw(CTX_wm_area(C));
-
- WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL);
-
- return OPERATOR_FINISHED;
-}
-
-static void SCREEN_OT_footer(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name = "Toggle Footer";
- ot->description = "Toggle footer display";
- ot->idname = "SCREEN_OT_footer";
-
- /* api callbacks */
- ot->exec = footer_exec;
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Footer Tools Operator
- * \{ */
-
-static bool footer_context_menu_poll(bContext *C)
-{
- ScrArea *sa = CTX_wm_area(C);
- return sa;
-}
-
void ED_screens_footer_tools_menu_create(bContext *C, uiLayout *layout, void *UNUSED(arg))
{
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = CTX_wm_region(C);
const char *but_flip_str = (ar->alignment == RGN_ALIGN_TOP) ? IFACE_("Flip to Bottom") :
IFACE_("Flip to Top");
-
- uiItemO(layout, IFACE_("Toggle Footer"), ICON_NONE, "SCREEN_OT_footer");
+ {
+ PointerRNA ptr;
+ RNA_pointer_create((ID *)CTX_wm_screen(C), &RNA_Space, sa->spacedata.first, &ptr);
+ uiItemR(layout, &ptr, "show_region_footer", 0, IFACE_("Show Footer"), ICON_NONE);
+ }
/* default is WM_OP_INVOKE_REGION_WIN, which we don't want here. */
uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_DEFAULT);
@@ -4108,51 +4017,58 @@ void ED_screens_footer_tools_menu_create(bContext *C, uiLayout *layout, void *UN
}
}
-static int footer_context_menu_invoke(bContext *C,
+void ED_screens_navigation_bar_tools_menu_create(bContext *C, uiLayout *layout, void *UNUSED(arg))
+{
+ const ARegion *ar = CTX_wm_region(C);
+ const char *but_flip_str = (ar->alignment == RGN_ALIGN_LEFT) ? IFACE_("Flip to Right") :
+ IFACE_("Flip to Left");
+
+ /* default is WM_OP_INVOKE_REGION_WIN, which we don't want here. */
+ uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_DEFAULT);
+
+ uiItemO(layout, but_flip_str, ICON_NONE, "SCREEN_OT_region_flip");
+}
+
+static int screen_context_menu_invoke(bContext *C,
wmOperator *UNUSED(op),
const wmEvent *UNUSED(event))
{
uiPopupMenu *pup;
uiLayout *layout;
+ const ARegion *ar = CTX_wm_region(C);
- pup = UI_popup_menu_begin(C, IFACE_("Footer"), ICON_NONE);
- layout = UI_popup_menu_layout(pup);
-
- ED_screens_footer_tools_menu_create(C, layout, NULL);
-
- UI_popup_menu_end(C, pup);
+ if (ELEM(ar->regiontype, RGN_TYPE_HEADER, RGN_TYPE_TOOL_HEADER)) {
+ pup = UI_popup_menu_begin(C, IFACE_("Header"), ICON_NONE);
+ layout = UI_popup_menu_layout(pup);
+ ED_screens_header_tools_menu_create(C, layout, NULL);
+ UI_popup_menu_end(C, pup);
+ }
+ else if (ar->regiontype == RGN_TYPE_FOOTER) {
+ pup = UI_popup_menu_begin(C, IFACE_("Footer"), ICON_NONE);
+ layout = UI_popup_menu_layout(pup);
+ ED_screens_footer_tools_menu_create(C, layout, NULL);
+ UI_popup_menu_end(C, pup);
+ }
+ else if (ar->regiontype == RGN_TYPE_NAV_BAR) {
+ pup = UI_popup_menu_begin(C, IFACE_("Navigation Bar"), ICON_NONE);
+ layout = UI_popup_menu_layout(pup);
+ ED_screens_navigation_bar_tools_menu_create(C, layout, NULL);
+ UI_popup_menu_end(C, pup);
+ }
return OPERATOR_INTERFACE;
}
-static void SCREEN_OT_footer_context_menu(wmOperatorType *ot)
+static void SCREEN_OT_region_context_menu(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Footer Context Menu";
- ot->description = "Display footer region context menu";
- ot->idname = "SCREEN_OT_footer_context_menu";
+ ot->name = "Region Context Menu";
+ ot->description = "Display region context menu";
+ ot->idname = "SCREEN_OT_region_context_menu";
/* api callbacks */
- ot->poll = footer_context_menu_poll;
- ot->invoke = footer_context_menu_invoke;
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Navigation Bar Tools Menu
- * \{ */
-
-void ED_screens_navigation_bar_tools_menu_create(bContext *C, uiLayout *layout, void *UNUSED(arg))
-{
- const ARegion *ar = CTX_wm_region(C);
- const char *but_flip_str = (ar->alignment == RGN_ALIGN_LEFT) ? IFACE_("Flip to Right") :
- IFACE_("Flip to Left");
-
- /* default is WM_OP_INVOKE_REGION_WIN, which we don't want here. */
- uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_DEFAULT);
-
- uiItemO(layout, but_flip_str, ICON_NONE, "SCREEN_OT_region_flip");
+ ot->poll = screen_region_context_menu_poll;
+ ot->invoke = screen_context_menu_invoke;
}
/** \} */
@@ -4288,8 +4204,7 @@ static int screen_animation_step(bContext *C, wmOperator *UNUSED(op), const wmEv
if (screen->animtimer && screen->animtimer == event->customdata) {
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
+ struct Depsgraph *depsgraph = CTX_data_depsgraph(C);
wmTimer *wt = screen->animtimer;
ScreenAnimData *sad = wt->customdata;
wmWindowManager *wm = CTX_wm_manager(C);
@@ -4310,7 +4225,7 @@ static int screen_animation_step(bContext *C, wmOperator *UNUSED(op), const wmEv
}
if ((scene->audio.flag & AUDIO_SYNC) && (sad->flag & ANIMPLAY_FLAG_REVERSE) == false &&
- isfinite(time = BKE_sound_sync_scene(scene_eval))) {
+ isfinite(time = BKE_sound_sync_scene(scene))) {
double newfra = (double)time * FPS;
/* give some space here to avoid jumps */
@@ -4403,7 +4318,7 @@ static int screen_animation_step(bContext *C, wmOperator *UNUSED(op), const wmEv
}
if (sad->flag & ANIMPLAY_FLAG_JUMPED) {
- BKE_sound_update_and_seek(bmain, depsgraph);
+ BKE_sound_seek_scene(bmain, scene);
#ifdef PROFILE_AUDIO_SYNCH
old_frame = CFRA;
#endif
@@ -4525,12 +4440,11 @@ int ED_screen_animation_play(bContext *C, int sync, int mode)
{
bScreen *screen = CTX_wm_screen(C);
Scene *scene = CTX_data_scene(C);
- Scene *scene_eval = DEG_get_evaluated_scene(CTX_data_depsgraph(C));
if (ED_screen_animation_playing(CTX_wm_manager(C))) {
/* stop playback now */
ED_screen_animation_timer(C, 0, 0, 0, 0);
- BKE_sound_stop_scene(scene_eval);
+ BKE_sound_stop_scene(scene);
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
}
@@ -4539,7 +4453,7 @@ int ED_screen_animation_play(bContext *C, int sync, int mode)
int refresh = SPACE_ACTION;
if (mode == 1) { /* XXX only play audio forwards!? */
- BKE_sound_play_scene(scene_eval);
+ BKE_sound_play_scene(scene);
}
ED_screen_animation_timer(C, screen->redraws_flag, refresh, sync, mode);
@@ -5302,9 +5216,7 @@ void ED_operatortypes_screen(void)
WM_operatortype_append(SCREEN_OT_region_scale);
WM_operatortype_append(SCREEN_OT_region_flip);
WM_operatortype_append(SCREEN_OT_header_toggle_menus);
- WM_operatortype_append(SCREEN_OT_header_context_menu);
- WM_operatortype_append(SCREEN_OT_footer);
- WM_operatortype_append(SCREEN_OT_footer_context_menu);
+ WM_operatortype_append(SCREEN_OT_region_context_menu);
WM_operatortype_append(SCREEN_OT_screen_set);
WM_operatortype_append(SCREEN_OT_screen_full_area);
WM_operatortype_append(SCREEN_OT_back_to_previous);
diff --git a/source/blender/editors/screen/workspace_edit.c b/source/blender/editors/screen/workspace_edit.c
index 2dfa05cf6b0..863e3a15120 100644
--- a/source/blender/editors/screen/workspace_edit.c
+++ b/source/blender/editors/screen/workspace_edit.c
@@ -373,13 +373,15 @@ static int workspace_append_activate_exec(bContext *C, wmOperator *op)
&bmain->workspaces, idname, offsetof(ID, name) + 2);
BLI_assert(appended_workspace != NULL);
- /* Reorder to last position. */
- BKE_id_reorder(&bmain->workspaces, &appended_workspace->id, NULL, true);
+ if (appended_workspace) {
+ /* Reorder to last position. */
+ BKE_id_reorder(&bmain->workspaces, &appended_workspace->id, NULL, true);
- /* Changing workspace changes context. Do delayed! */
- WM_event_add_notifier(C, NC_SCREEN | ND_WORKSPACE_SET, appended_workspace);
+ /* Changing workspace changes context. Do delayed! */
+ WM_event_add_notifier(C, NC_SCREEN | ND_WORKSPACE_SET, appended_workspace);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
+ }
}
return OPERATOR_CANCELLED;
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index 5a45f4946f2..f7a589350f9 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -47,6 +47,7 @@
#include "BKE_colorband.h"
#include "BKE_context.h"
#include "BKE_brush.h"
+#include "BKE_image.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_mesh.h"
@@ -154,7 +155,7 @@ void ED_imapaint_dirty_region(Image *ima, ImBuf *ibuf, int x, int y, int w, int
}
}
- ibuf->userflags |= IB_BITMAPDIRTY;
+ BKE_image_mark_dirty(ima, ibuf);
if (tmpibuf) {
IMB_freeImBuf(tmpibuf);
diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c
index 0340a4989e1..d7553d18d3b 100644
--- a/source/blender/editors/sculpt_paint/paint_image_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_image_proj.c
@@ -1837,7 +1837,7 @@ static int project_paint_undo_subtiles(const TileInfo *tinf, int tx, int ty)
false);
}
- pjIma->ibuf->userflags |= IB_BITMAPDIRTY;
+ BKE_image_mark_dirty(pjIma->ima, pjIma->ibuf);
/* tile ready, publish */
if (tinf->lock) {
BLI_spin_lock(tinf->lock);
@@ -6394,7 +6394,7 @@ static const EnumPropertyItem layer_type_items[] = {
{0, NULL, 0, NULL, NULL},
};
-static Image *proj_paint_image_create(wmOperator *op, Main *bmain)
+static Image *proj_paint_image_create(wmOperator *op, Main *bmain, bool is_data)
{
Image *ima;
float color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
@@ -6417,6 +6417,11 @@ static Image *proj_paint_image_create(wmOperator *op, Main *bmain)
ima = BKE_image_add_generated(
bmain, width, height, imagename, alpha ? 32 : 24, use_float, gen_type, color, false);
+ if (is_data) {
+ STRNCPY(ima->colorspace_settings.name,
+ IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_DATA));
+ }
+
return ima;
}
@@ -6487,6 +6492,7 @@ static bool proj_paint_add_slot(bContext *C, wmOperator *op)
if (ma) {
Main *bmain = CTX_data_main(C);
int type = RNA_enum_get(op->ptr, "type");
+ bool is_data = (type > LAYER_BASE_COLOR);
bNode *imanode;
bNodeTree *ntree = ma->nodetree;
@@ -6501,7 +6507,7 @@ static bool proj_paint_add_slot(bContext *C, wmOperator *op)
/* try to add an image node */
imanode = nodeAddStaticNode(C, ntree, SH_NODE_TEX_IMAGE);
- ima = proj_paint_image_create(op, bmain);
+ ima = proj_paint_image_create(op, bmain, is_data);
imanode->id = &ima->id;
nodeSetActive(ntree, imanode);
@@ -6553,12 +6559,6 @@ static bool proj_paint_add_slot(bContext *C, wmOperator *op)
}
}
- if (type > LAYER_BASE_COLOR) {
- /* This is a "non color data" image */
- NodeTexImage *tex = imanode->storage;
- tex->color_space = SHD_COLORSPACE_NONE;
- }
-
/* Check if the socket in already connected to something */
bNodeLink *link = in_sock ? in_sock->link : NULL;
if (in_sock != NULL && link == NULL) {
diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c
index 6d003820723..84b4a130183 100644
--- a/source/blender/editors/sculpt_paint/paint_utils.c
+++ b/source/blender/editors/sculpt_paint/paint_utils.c
@@ -389,6 +389,7 @@ static int imapaint_pick_face(ViewContext *vc,
}
/* sample only on the exact position */
+ ED_view3d_select_id_validate(vc);
*r_index = ED_view3d_select_id_sample(vc, mval[0], mval[1]);
if ((*r_index) == 0 || (*r_index) > (unsigned int)totpoly) {
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 c1c2964156f..c904bf2005b 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c
@@ -161,7 +161,7 @@ void PAINT_OT_weight_from_bones(wmOperatorType *ot)
ot->poll = weight_from_bones_poll;
/* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_USE_EVAL_DATA;
/* properties */
ot->prop = RNA_def_enum(
@@ -880,7 +880,7 @@ void PAINT_OT_weight_gradient(wmOperatorType *ot)
ot->cancel = WM_gesture_straightline_cancel;
/* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_USE_EVAL_DATA;
prop = RNA_def_enum(ot->srna, "type", gradient_types, 0, "Type", "");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
diff --git a/source/blender/editors/sound/CMakeLists.txt b/source/blender/editors/sound/CMakeLists.txt
index 7f4b5a45aa3..c2a88041a85 100644
--- a/source/blender/editors/sound/CMakeLists.txt
+++ b/source/blender/editors/sound/CMakeLists.txt
@@ -19,7 +19,6 @@ set(INC
../include
../../blenkernel
../../blenlib
- ../../depsgraph
../../makesdna
../../makesrna
../../windowmanager
diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c
index 8ac49e447fe..25c05e2d1d0 100644
--- a/source/blender/editors/sound/sound_ops.c
+++ b/source/blender/editors/sound/sound_ops.c
@@ -62,8 +62,6 @@
# include <AUD_Special.h>
#endif
-#include "DEG_depsgraph_query.h"
-
#include "ED_sound.h"
#include "ED_util.h"
@@ -90,6 +88,7 @@ static int sound_open_exec(bContext *C, wmOperator *op)
bSound *sound;
PropertyPointerRNA *pprop;
PointerRNA idptr;
+ AUD_SoundInfo info;
Main *bmain = CTX_data_main(C);
RNA_string_get(op->ptr, "filepath", path);
@@ -99,8 +98,29 @@ static int sound_open_exec(bContext *C, wmOperator *op)
sound_open_init(C, op);
}
+ if (sound->playback_handle == NULL) {
+ if (op->customdata) {
+ MEM_freeN(op->customdata);
+ }
+ BKE_id_free(bmain, sound);
+ BKE_report(op->reports, RPT_ERROR, "Unsupported audio format");
+ return OPERATOR_CANCELLED;
+ }
+
+ info = AUD_getInfo(sound->playback_handle);
+
+ if (info.specs.channels == AUD_CHANNELS_INVALID) {
+ BKE_id_free(bmain, sound);
+ if (op->customdata) {
+ MEM_freeN(op->customdata);
+ }
+ BKE_report(op->reports, RPT_ERROR, "Unsupported audio format");
+ return OPERATOR_CANCELLED;
+ }
+
if (RNA_boolean_get(op->ptr, "mono")) {
sound->flags |= SOUND_FLAGS_MONO;
+ BKE_sound_load(bmain, sound);
}
if (RNA_boolean_get(op->ptr, "cache")) {
@@ -120,8 +140,6 @@ static int sound_open_exec(bContext *C, wmOperator *op)
RNA_property_update(C, &pprop->ptr, pprop->prop);
}
- DEG_relations_tag_update(bmain);
-
MEM_freeN(op->customdata);
return OPERATOR_FINISHED;
}
@@ -343,9 +361,8 @@ static int sound_mixdown_exec(bContext *C, wmOperator *op)
#ifdef WITH_AUDASPACE
char path[FILE_MAX];
char filename[FILE_MAX];
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
- Main *bmain = CTX_data_main(C);
+ Scene *scene;
+ Main *bmain;
int split;
int bitrate, accuracy;
@@ -363,20 +380,18 @@ static int sound_mixdown_exec(bContext *C, wmOperator *op)
container = RNA_enum_get(op->ptr, "container");
codec = RNA_enum_get(op->ptr, "codec");
split = RNA_boolean_get(op->ptr, "split_channels");
- specs.channels = scene_eval->r.ffcodecdata.audio_channels;
- specs.rate = scene_eval->r.ffcodecdata.audio_mixrate;
+ scene = CTX_data_scene(C);
+ bmain = CTX_data_main(C);
+ specs.channels = scene->r.ffcodecdata.audio_channels;
+ specs.rate = scene->r.ffcodecdata.audio_mixrate;
BLI_strncpy(filename, path, sizeof(filename));
BLI_path_abs(filename, BKE_main_blendfile_path(bmain));
- const double fps = (((double)scene_eval->r.frs_sec) / (double)scene_eval->r.frs_sec_base);
- const int start_frame = scene_eval->r.sfra;
- const int end_frame = scene_eval->r.efra;
-
if (split) {
- result = AUD_mixdown_per_channel(scene_eval->sound_scene,
- start_frame * specs.rate / fps,
- (end_frame - start_frame + 1) * specs.rate / fps,
+ result = AUD_mixdown_per_channel(scene->sound_scene,
+ SFRA * specs.rate / FPS,
+ (EFRA - SFRA + 1) * specs.rate / FPS,
accuracy,
filename,
specs,
@@ -385,9 +400,9 @@ static int sound_mixdown_exec(bContext *C, wmOperator *op)
bitrate);
}
else {
- result = AUD_mixdown(scene_eval->sound_scene,
- start_frame * specs.rate / fps,
- (end_frame - start_frame + 1) * specs.rate / fps,
+ result = AUD_mixdown(scene->sound_scene,
+ SFRA * specs.rate / FPS,
+ (EFRA - SFRA + 1) * specs.rate / FPS,
accuracy,
filename,
specs,
@@ -396,7 +411,7 @@ static int sound_mixdown_exec(bContext *C, wmOperator *op)
bitrate);
}
- BKE_sound_reset_scene_specs(scene_eval);
+ BKE_sound_reset_scene_specs(scene);
if (result) {
BKE_report(op->reports, RPT_ERROR, result);
diff --git a/source/blender/editors/space_action/action_draw.c b/source/blender/editors/space_action/action_draw.c
index 2a6ae93fc99..f32207fe08b 100644
--- a/source/blender/editors/space_action/action_draw.c
+++ b/source/blender/editors/space_action/action_draw.c
@@ -411,7 +411,7 @@ void timeline_draw_cache(SpaceAction *saction, Object *ob, Scene *scene)
}
GPU_matrix_push();
- GPU_matrix_translate_2f(0.0, (float)V2D_SCROLL_HEIGHT_TEXT + yoffs);
+ GPU_matrix_translate_2f(0.0, (float)V2D_SCROLL_HEIGHT_HANDLES + yoffs);
GPU_matrix_scale_2f(1.0, cache_draw_height);
switch (pid->type) {
diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c
index 8ecd25bda76..1371305487e 100644
--- a/source/blender/editors/space_action/action_select.c
+++ b/source/blender/editors/space_action/action_select.c
@@ -47,6 +47,7 @@
#include "BKE_gpencil.h"
#include "UI_view2d.h"
+#include "UI_interface.h"
#include "ED_anim_api.h"
#include "ED_gpencil.h"
diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c
index 5ac6297e108..972f19bb643 100644
--- a/source/blender/editors/space_action/space_action.c
+++ b/source/blender/editors/space_action/space_action.c
@@ -45,6 +45,7 @@
#include "WM_types.h"
#include "WM_message.h"
+#include "UI_interface.h"
#include "UI_resources.h"
#include "UI_view2d.h"
@@ -52,6 +53,7 @@
#include "ED_screen.h"
#include "ED_anim_api.h"
#include "ED_markers.h"
+#include "ED_time_scrub_ui.h"
#include "action_intern.h" /* own include */
#include "GPU_framebuffer.h"
@@ -69,7 +71,7 @@ static SpaceLink *action_new(const ScrArea *sa, const Scene *scene)
saction->autosnap = SACTSNAP_FRAME;
saction->mode = SACTCONT_DOPESHEET;
saction->mode_prev = SACTCONT_DOPESHEET;
- saction->flag = SACTION_SHOW_INTERPOLATION;
+ saction->flag = SACTION_SHOW_INTERPOLATION | SACTION_SHOW_MARKER_LINES;
saction->ads.filterflag |= ADS_FILTER_SUMMARY;
@@ -125,7 +127,7 @@ static SpaceLink *action_new(const ScrArea *sa, const Scene *scene)
ar->v2d.minzoom = 0.01f;
ar->v2d.maxzoom = 50;
- ar->v2d.scroll = (V2D_SCROLL_BOTTOM | V2D_SCROLL_SCALE_HORIZONTAL);
+ ar->v2d.scroll = (V2D_SCROLL_BOTTOM | V2D_SCROLL_HORIZONTAL_HANDLES);
ar->v2d.scroll |= (V2D_SCROLL_RIGHT);
ar->v2d.keepzoom = V2D_LOCKZOOM_Y;
ar->v2d.keepofs = V2D_KEEPOFS_Y;
@@ -234,20 +236,13 @@ static void action_main_region_draw(const bContext *C, ARegion *ar)
/* reset view matrix */
UI_view2d_view_restore(C);
+ /* scrubbing region */
+ ED_scrubbing_draw(ar, scene, saction->flag & SACTION_DRAWTIME, true);
+
/* scrollers */
scrollers = UI_view2d_scrollers_calc(v2d, NULL);
UI_view2d_scrollers_draw(v2d, scrollers);
UI_view2d_scrollers_free(scrollers);
-
- /* frame numbers */
- UI_view2d_draw_scale_x__discrete_frames_or_seconds(
- ar, v2d, &v2d->hor, scene, saction->flag & SACTION_DRAWTIME, TH_TEXT);
-
- /* draw current frame number-indicator on top of scrollers */
- if ((saction->flag & SACTION_NODRAWCFRANUM) == 0) {
- UI_view2d_view_orthoSpecial(ar, v2d, 1);
- ANIM_draw_cfra_number(C, v2d, cfra_flag);
- }
}
/* add handlers, stuff you only do once or on area/region changes */
@@ -285,6 +280,9 @@ static void action_channel_region_draw(const bContext *C, ARegion *ar)
draw_channel_names((bContext *)C, &ac, ar);
}
+ /* channel filter next to scrubbing area */
+ ED_channel_search_draw(C, ar, ac.ads);
+
/* reset view matrix */
UI_view2d_view_restore(C);
@@ -869,7 +867,7 @@ void ED_spacetype_action(void)
art->draw = action_main_region_draw;
art->listener = action_main_region_listener;
art->message_subscribe = saction_main_region_message_subscribe;
- art->keymapflag = ED_KEYMAP_VIEW2D | ED_KEYMAP_MARKERS | ED_KEYMAP_ANIMATION | ED_KEYMAP_FRAMES;
+ art->keymapflag = ED_KEYMAP_VIEW2D | ED_KEYMAP_ANIMATION | ED_KEYMAP_FRAMES;
BLI_addhead(&st->regiontypes, art);
@@ -901,7 +899,7 @@ void ED_spacetype_action(void)
/* regions: UI buttons */
art = MEM_callocN(sizeof(ARegionType), "spacetype action region");
art->regionid = RGN_TYPE_UI;
- art->prefsizex = 200;
+ art->prefsizex = UI_SIDEBAR_PANEL_WIDTH;
art->keymapflag = ED_KEYMAP_UI;
art->listener = action_region_listener;
art->init = action_buttons_area_init;
diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c
index 577f7a7af8a..fde8b8f85f8 100644
--- a/source/blender/editors/space_buttons/buttons_context.c
+++ b/source/blender/editors/space_buttons/buttons_context.c
@@ -785,8 +785,11 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
SpaceProperties *sbuts = CTX_wm_space_properties(C);
ButsContextPath *path = sbuts ? sbuts->path : NULL;
- /* A zero sized path will be set for 'BCONTEXT_TOOL'. */
- if (!path || !path->len) {
+ if (sbuts->mainb == BCONTEXT_TOOL) {
+ return 0;
+ }
+
+ if (!path) {
return 0;
}
diff --git a/source/blender/editors/space_buttons/buttons_ops.c b/source/blender/editors/space_buttons/buttons_ops.c
index fe4ed0209bf..500efe4bb4d 100644
--- a/source/blender/editors/space_buttons/buttons_ops.c
+++ b/source/blender/editors/space_buttons/buttons_ops.c
@@ -56,15 +56,10 @@
static int context_menu_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
{
- const ARegion *ar = CTX_wm_region(C);
uiPopupMenu *pup = UI_popup_menu_begin(C, IFACE_("Context Menu"), ICON_NONE);
uiLayout *layout = UI_popup_menu_layout(pup);
uiItemM(layout, "INFO_MT_area", NULL, ICON_NONE);
- if (ar->regiontype == RGN_TYPE_NAV_BAR) {
- ED_screens_navigation_bar_tools_menu_create(C, layout, NULL);
- }
-
UI_popup_menu_end(C, pup);
return OPERATOR_INTERFACE;
diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c
index f9244049d54..9b0150d731d 100644
--- a/source/blender/editors/space_buttons/space_buttons.c
+++ b/source/blender/editors/space_buttons/space_buttons.c
@@ -34,6 +34,7 @@
#include "ED_space_api.h"
#include "ED_screen.h"
+#include "ED_view3d.h" /* To draw toolbar UI. */
#include "WM_api.h"
#include "WM_types.h"
@@ -198,105 +199,7 @@ static void buttons_main_region_layout_properties(const bContext *C,
}
const bool vertical = true;
- ED_region_panels_layout_ex(C, ar, contexts, sbuts->mainb, vertical);
-}
-
-static void buttons_main_region_layout_tool(const bContext *C, ARegion *ar)
-{
- const enum eContextObjectMode mode = CTX_data_mode_enum(C);
-
- const char *contexts_base[5] = {NULL};
- contexts_base[0] = ".active_tool";
- const char **contexts = &contexts_base[1];
-
- /* Hard coded to 3D view. */
- {
- switch (mode) {
- case CTX_MODE_EDIT_MESH:
- ARRAY_SET_ITEMS(contexts, ".mesh_edit");
- break;
- case CTX_MODE_EDIT_CURVE:
- ARRAY_SET_ITEMS(contexts, ".curve_edit");
- break;
- case CTX_MODE_EDIT_SURFACE:
- ARRAY_SET_ITEMS(contexts, ".curve_edit");
- break;
- case CTX_MODE_EDIT_TEXT:
- ARRAY_SET_ITEMS(contexts, ".text_edit");
- break;
- case CTX_MODE_EDIT_ARMATURE:
- ARRAY_SET_ITEMS(contexts, ".armature_edit");
- break;
- case CTX_MODE_EDIT_METABALL:
- ARRAY_SET_ITEMS(contexts, ".mball_edit");
- break;
- case CTX_MODE_EDIT_LATTICE:
- ARRAY_SET_ITEMS(contexts, ".lattice_edit");
- break;
- case CTX_MODE_POSE:
- ARRAY_SET_ITEMS(contexts, ".posemode");
- break;
- case CTX_MODE_SCULPT:
- ARRAY_SET_ITEMS(contexts, ".paint_common", ".sculpt_mode");
- break;
- case CTX_MODE_PAINT_WEIGHT:
- ARRAY_SET_ITEMS(contexts, ".paint_common", ".weightpaint");
- break;
- case CTX_MODE_PAINT_VERTEX:
- ARRAY_SET_ITEMS(contexts, ".paint_common", ".vertexpaint");
- break;
- case CTX_MODE_PAINT_TEXTURE:
- ARRAY_SET_ITEMS(contexts, ".paint_common", ".imagepaint");
- break;
- case CTX_MODE_PARTICLE:
- ARRAY_SET_ITEMS(contexts, ".paint_common", ".particlemode");
- break;
- case CTX_MODE_OBJECT:
- ARRAY_SET_ITEMS(contexts, ".objectmode");
- break;
- case CTX_MODE_PAINT_GPENCIL:
- ARRAY_SET_ITEMS(contexts, ".greasepencil_paint");
- break;
- case CTX_MODE_SCULPT_GPENCIL:
- ARRAY_SET_ITEMS(contexts, ".greasepencil_sculpt");
- break;
- case CTX_MODE_WEIGHT_GPENCIL:
- ARRAY_SET_ITEMS(contexts, ".greasepencil_weight");
- break;
- default:
- break;
- }
- }
-
- /* for grease pencil we don't use tool system yet, so we need check outside
- * workspace->tools_space_type because this value is not available
- */
- switch (mode) {
- case CTX_MODE_PAINT_GPENCIL:
- ARRAY_SET_ITEMS(contexts, ".greasepencil_paint");
- break;
- case CTX_MODE_SCULPT_GPENCIL:
- ARRAY_SET_ITEMS(contexts, ".greasepencil_sculpt");
- break;
- case CTX_MODE_WEIGHT_GPENCIL:
- ARRAY_SET_ITEMS(contexts, ".greasepencil_weight");
- break;
- case CTX_MODE_EDIT_GPENCIL:
- ARRAY_SET_ITEMS(contexts, ".greasepencil_edit");
- break;
- default:
- break;
- }
-
- int i = 0;
- while (contexts_base[i]) {
- i++;
- }
- BLI_assert(i < ARRAY_SIZE(contexts_base));
- contexts_base[i] = ".workspace";
-
- const bool vertical = true;
- ED_region_panels_layout_ex(C, ar, contexts_base, -1, vertical);
+ ED_region_panels_layout_ex(C, ar, &ar->type->paneltypes, contexts, sbuts->mainb, vertical, NULL);
}
static void buttons_main_region_layout(const bContext *C, ARegion *ar)
@@ -305,7 +208,7 @@ static void buttons_main_region_layout(const bContext *C, ARegion *ar)
SpaceProperties *sbuts = CTX_wm_space_properties(C);
if (sbuts->mainb == BCONTEXT_TOOL) {
- buttons_main_region_layout_tool(C, ar);
+ ED_view3d_buttons_region_layout_ex(C, ar, "Tool");
}
else {
buttons_main_region_layout_properties(C, sbuts, ar);
@@ -400,9 +303,6 @@ static void buttons_header_region_message_subscribe(const bContext *UNUSED(C),
static void buttons_navigation_bar_region_init(wmWindowManager *wm, ARegion *ar)
{
- wmKeyMap *keymap = WM_keymap_ensure(wm->defaultconf, "Property Editor", SPACE_PROPERTIES, 0);
- WM_event_add_keymap_handler(&ar->handlers, keymap);
-
ar->flag |= RGN_FLAG_PREFSIZE_OR_HIDDEN;
ED_region_panels_init(wm, ar);
@@ -749,7 +649,7 @@ void ED_spacetype_buttons(void)
art->regionid = RGN_TYPE_NAV_BAR;
art->prefsizex = AREAMINX - 3; /* XXX Works and looks best,
* should we update AREAMINX accordingly? */
- art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_FRAMES;
+ art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_FRAMES | ED_KEYMAP_NAVBAR;
art->init = buttons_navigation_bar_region_init;
art->draw = buttons_navigation_bar_region_draw;
art->message_subscribe = buttons_navigation_bar_region_message_subscribe;
diff --git a/source/blender/editors/space_clip/clip_intern.h b/source/blender/editors/space_clip/clip_intern.h
index 70dc1caf36f..081515ca4bc 100644
--- a/source/blender/editors/space_clip/clip_intern.h
+++ b/source/blender/editors/space_clip/clip_intern.h
@@ -35,7 +35,7 @@ struct bContext;
struct wmOperatorType;
/* channel heights */
-#define CHANNEL_FIRST (-0.8f * U.widget_unit)
+#define CHANNEL_FIRST (-UI_SCRUBBING_MARGIN_Y - CHANNEL_HEIGHT_HALF - CHANNEL_SKIP)
#define CHANNEL_HEIGHT (0.8f * U.widget_unit)
#define CHANNEL_HEIGHT_HALF (0.4f * U.widget_unit)
#define CHANNEL_SKIP (0.1f * U.widget_unit)
diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c
index 8b3f221f3a5..a6b1db1aa83 100644
--- a/source/blender/editors/space_clip/clip_ops.c
+++ b/source/blender/editors/space_clip/clip_ops.c
@@ -955,10 +955,10 @@ static bool change_frame_poll(bContext *C)
{
/* prevent changes during render */
if (G.is_rendering) {
- return 0;
+ return false;
}
-
- return ED_space_clip_poll(C);
+ SpaceClip *space_clip = CTX_wm_space_clip(C);
+ return space_clip != NULL;
}
static void change_frame_apply(bContext *C, wmOperator *op)
@@ -971,7 +971,7 @@ static void change_frame_apply(bContext *C, wmOperator *op)
SUBFRA = 0.0f;
/* do updates */
- BKE_sound_update_and_seek(CTX_data_main(C), CTX_data_depsgraph(C));
+ BKE_sound_seek_scene(CTX_data_main(C), scene);
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
}
diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c
index 5364c4bc3ca..13d190e6861 100644
--- a/source/blender/editors/space_clip/space_clip.c
+++ b/source/blender/editors/space_clip/space_clip.c
@@ -47,6 +47,7 @@
#include "ED_mask.h"
#include "ED_space_api.h"
#include "ED_screen.h"
+#include "ED_time_scrub_ui.h"
#include "ED_select_utils.h"
#include "ED_clip.h"
#include "ED_transform.h"
@@ -94,7 +95,7 @@ static void init_preview_region(const Scene *scene,
ar->v2d.minzoom = 0.01f;
ar->v2d.maxzoom = 50;
- ar->v2d.scroll = (V2D_SCROLL_BOTTOM | V2D_SCROLL_SCALE_HORIZONTAL);
+ ar->v2d.scroll = (V2D_SCROLL_BOTTOM | V2D_SCROLL_HORIZONTAL_HANDLES);
ar->v2d.scroll |= (V2D_SCROLL_RIGHT);
ar->v2d.keepzoom = V2D_LOCKZOOM_Y;
ar->v2d.keepofs = V2D_KEEPOFS_Y;
@@ -115,8 +116,8 @@ static void init_preview_region(const Scene *scene,
ar->v2d.max[0] = MAXFRAMEF;
ar->v2d.max[1] = FLT_MAX;
- ar->v2d.scroll = (V2D_SCROLL_BOTTOM | V2D_SCROLL_SCALE_HORIZONTAL);
- ar->v2d.scroll |= (V2D_SCROLL_LEFT | V2D_SCROLL_SCALE_VERTICAL);
+ ar->v2d.scroll = (V2D_SCROLL_BOTTOM | V2D_SCROLL_HORIZONTAL_HANDLES);
+ ar->v2d.scroll |= (V2D_SCROLL_RIGHT | V2D_SCROLL_VERTICAL_HANDLES);
ar->v2d.minzoom = 0.0f;
ar->v2d.maxzoom = 0.0f;
@@ -249,7 +250,7 @@ static SpaceLink *clip_new(const ScrArea *sa, const Scene *scene)
sc->zoom = 1.0f;
sc->path_length = 20;
sc->scopes.track_preview_height = 120;
- sc->around = V3D_AROUND_LOCAL_ORIGINS;
+ sc->around = V3D_AROUND_CENTER_MEDIAN;
/* header */
ar = MEM_callocN(sizeof(ARegion), "header for clip");
@@ -1001,9 +1002,13 @@ static void clip_preview_region_init(wmWindowManager *wm, ARegion *ar)
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy);
/* own keymap */
+
keymap = WM_keymap_ensure(wm->defaultconf, "Clip", SPACE_CLIP, 0);
WM_event_add_keymap_handler_v2d_mask(&ar->handlers, keymap);
+ keymap = WM_keymap_ensure(wm->defaultconf, "Clip Scrubbing", SPACE_CLIP, RGN_TYPE_PREVIEW);
+ WM_event_add_keymap_handler_poll(&ar->handlers, keymap, ED_event_in_scrubbing_region);
+
keymap = WM_keymap_ensure(wm->defaultconf, "Clip Graph Editor", SPACE_CLIP, 0);
WM_event_add_keymap_handler_v2d_mask(&ar->handlers, keymap);
@@ -1041,22 +1046,24 @@ static void graph_region_draw(const bContext *C, ARegion *ar)
/* reset view matrix */
UI_view2d_view_restore(C);
+ /* time-scrubbing */
+ ED_scrubbing_draw(ar, scene, sc->flag & SC_SHOW_SECONDS, true);
+
/* scrollers */
scrollers = UI_view2d_scrollers_calc(v2d, NULL);
UI_view2d_scrollers_draw(v2d, scrollers);
UI_view2d_scrollers_free(scrollers);
/* scale indicators */
- UI_view2d_draw_scale_x__discrete_frames_or_seconds(
- ar, v2d, &v2d->hor, scene, sc->flag & SC_SHOW_SECONDS, TH_TEXT);
- UI_view2d_draw_scale_y__values(ar, v2d, &v2d->vert, TH_TEXT);
-
- /* current frame indicator */
- if (sc->flag & SC_SHOW_SECONDS) {
- cfra_flag |= DRAWCFRA_UNIT_SECONDS;
+ {
+ rcti rect;
+ BLI_rcti_init(&rect,
+ 0,
+ 15 * UI_DPI_FAC,
+ 15 * UI_DPI_FAC,
+ UI_DPI_FAC * ar->sizey - UI_SCRUBBING_MARGIN_Y);
+ UI_view2d_draw_scale_y__values(ar, v2d, &rect, TH_TEXT);
}
- UI_view2d_view_orthoSpecial(ar, v2d, 1);
- ANIM_draw_cfra_number(C, v2d, cfra_flag);
}
static void dopesheet_region_draw(const bContext *C, ARegion *ar)
@@ -1093,18 +1100,13 @@ static void dopesheet_region_draw(const bContext *C, ARegion *ar)
/* reset view matrix */
UI_view2d_view_restore(C);
+ /* time-scrubbing */
+ ED_scrubbing_draw(ar, scene, sc->flag & SC_SHOW_SECONDS, true);
+
/* scrollers */
scrollers = UI_view2d_scrollers_calc(v2d, NULL);
UI_view2d_scrollers_draw(v2d, scrollers);
UI_view2d_scrollers_free(scrollers);
-
- /* frame numbers */
- UI_view2d_draw_scale_x__discrete_frames_or_seconds(
- ar, v2d, &v2d->hor, scene, sc->flag & SC_SHOW_SECONDS, TH_TEXT);
-
- /* current frame number indicator */
- UI_view2d_view_orthoSpecial(ar, v2d, 1);
- ANIM_draw_cfra_number(C, v2d, cfra_flag);
}
static void clip_preview_region_draw(const bContext *C, ARegion *ar)
diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c
index 441e65cefe4..b51baafbcf5 100644
--- a/source/blender/editors/space_clip/tracking_ops.c
+++ b/source/blender/editors/space_clip/tracking_ops.c
@@ -1299,6 +1299,12 @@ void CLIP_OT_hide_tracks_clear(wmOperatorType *ot)
/********************** frame jump operator *********************/
+static bool frame_jump_poll(bContext *C)
+{
+ SpaceClip *space_clip = CTX_wm_space_clip(C);
+ return space_clip != NULL;
+}
+
static int frame_jump_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
@@ -1350,7 +1356,7 @@ static int frame_jump_exec(bContext *C, wmOperator *op)
if (CFRA != sc->user.framenr) {
CFRA = sc->user.framenr;
- BKE_sound_update_and_seek(CTX_data_main(C), CTX_data_depsgraph(C));
+ BKE_sound_seek_scene(CTX_data_main(C), scene);
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
}
@@ -1377,7 +1383,7 @@ void CLIP_OT_frame_jump(wmOperatorType *ot)
/* api callbacks */
ot->exec = frame_jump_exec;
- ot->poll = ED_space_clip_poll;
+ ot->poll = frame_jump_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c
index bb8680682d2..6b3baa1e766 100644
--- a/source/blender/editors/space_file/file_draw.c
+++ b/source/blender/editors/space_file/file_draw.c
@@ -478,7 +478,7 @@ static void file_draw_preview(uiBlock *block,
GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
if (icon) {
- UI_icon_draw_aspect((float)xco, (float)yco, icon, icon_aspect, 1.0f, NULL);
+ UI_icon_draw_ex((float)xco, (float)yco, icon, icon_aspect, 1.0f, 0.0f, NULL, false);
}
/* border */
diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c
index 674735f3e1d..5ac7ff72aed 100644
--- a/source/blender/editors/space_file/file_ops.c
+++ b/source/blender/editors/space_file/file_ops.c
@@ -1011,7 +1011,7 @@ static int bookmark_cleanup_exec(bContext *C, wmOperator *UNUSED(op))
BLI_make_file_string(
"/", name, BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE);
fsmenu_write_file(fsmenu, name);
- fsmenu_refresh_bookmarks_status(fsmenu);
+ fsmenu_refresh_bookmarks_status(CTX_wm_manager(C), fsmenu);
ED_area_tag_refresh(sa);
ED_area_tag_redraw(sa);
}
@@ -1567,6 +1567,9 @@ static int file_refresh_exec(bContext *C, wmOperator *UNUSED(unused))
/* refresh system directory menu */
fsmenu_refresh_system_category(fsmenu);
+ /* Update bookmarks 'valid' state. */
+ fsmenu_refresh_bookmarks_status(wm, fsmenu);
+
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/space_file/fsmenu.c b/source/blender/editors/space_file/fsmenu.c
index 38423a87447..b50c37baae6 100644
--- a/source/blender/editors/space_file/fsmenu.c
+++ b/source/blender/editors/space_file/fsmenu.c
@@ -44,6 +44,9 @@
# include "BLI_winstuff.h"
#endif
+#include "WM_api.h"
+#include "WM_types.h"
+
#ifdef __APPLE__
# include <Carbon/Carbon.h>
#endif /* __APPLE__ */
@@ -721,31 +724,59 @@ void fsmenu_refresh_system_category(struct FSMenu *fsmenu)
fsmenu_read_system(fsmenu, true);
}
-void fsmenu_refresh_bookmarks_status(struct FSMenu *fsmenu)
+static void fsmenu_free_ex(FSMenu **fsmenu)
{
- int categories[] = {
- FS_CATEGORY_SYSTEM, FS_CATEGORY_SYSTEM_BOOKMARKS, FS_CATEGORY_BOOKMARKS, FS_CATEGORY_RECENT};
- int i;
-
- for (i = sizeof(categories) / sizeof(*categories); i--;) {
- FSMenuEntry *fsm_iter = ED_fsmenu_get_category(fsmenu, categories[i]);
- for (; fsm_iter; fsm_iter = fsm_iter->next) {
- fsmenu_entry_refresh_valid(fsm_iter);
- }
+ if (*fsmenu != NULL) {
+ fsmenu_free_category(*fsmenu, FS_CATEGORY_SYSTEM);
+ fsmenu_free_category(*fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS);
+ fsmenu_free_category(*fsmenu, FS_CATEGORY_BOOKMARKS);
+ fsmenu_free_category(*fsmenu, FS_CATEGORY_RECENT);
+ MEM_freeN(*fsmenu);
}
+
+ *fsmenu = NULL;
}
void fsmenu_free(void)
{
- if (g_fsmenu) {
- fsmenu_free_category(g_fsmenu, FS_CATEGORY_SYSTEM);
- fsmenu_free_category(g_fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS);
- fsmenu_free_category(g_fsmenu, FS_CATEGORY_BOOKMARKS);
- fsmenu_free_category(g_fsmenu, FS_CATEGORY_RECENT);
- MEM_freeN(g_fsmenu);
+ fsmenu_free_ex(&g_fsmenu);
+}
+
+static void fsmenu_copy_category(struct FSMenu *fsmenu_dst,
+ struct FSMenu *fsmenu_src,
+ const FSMenuCategory category)
+{
+ FSMenuEntry *fsm_dst_prev = NULL, *fsm_dst_head = NULL;
+ FSMenuEntry *fsm_src_iter = ED_fsmenu_get_category(fsmenu_src, category);
+
+ for (; fsm_src_iter != NULL; fsm_src_iter = fsm_src_iter->next) {
+ FSMenuEntry *fsm_dst = MEM_dupallocN(fsm_src_iter);
+ if (fsm_dst->path != NULL) {
+ fsm_dst->path = MEM_dupallocN(fsm_dst->path);
+ }
+
+ if (fsm_dst_prev != NULL) {
+ fsm_dst_prev->next = fsm_dst;
+ }
+ else {
+ fsm_dst_head = fsm_dst;
+ }
+ fsm_dst_prev = fsm_dst;
}
- g_fsmenu = NULL;
+ ED_fsmenu_set_category(fsmenu_dst, category, fsm_dst_head);
+}
+
+static FSMenu *fsmenu_copy(FSMenu *fsmenu)
+{
+ FSMenu *fsmenu_copy = MEM_dupallocN(fsmenu);
+
+ fsmenu_copy_category(fsmenu_copy, fsmenu_copy, FS_CATEGORY_SYSTEM);
+ fsmenu_copy_category(fsmenu_copy, fsmenu_copy, FS_CATEGORY_SYSTEM_BOOKMARKS);
+ fsmenu_copy_category(fsmenu_copy, fsmenu_copy, FS_CATEGORY_BOOKMARKS);
+ fsmenu_copy_category(fsmenu_copy, fsmenu_copy, FS_CATEGORY_RECENT);
+
+ return fsmenu_copy;
}
int fsmenu_get_active_indices(struct FSMenu *fsmenu, enum FSMenuCategory category, const char *dir)
@@ -761,3 +792,99 @@ int fsmenu_get_active_indices(struct FSMenu *fsmenu, enum FSMenuCategory categor
return -1;
}
+
+/* Thanks to some bookmarks sometimes being network drives that can have tens of seconds of delay
+ * before being defined as unreachable by the OS, we need to validate the bookmarks in an async
+ * job...
+ */
+static void fsmenu_bookmark_validate_job_startjob(void *fsmenuv,
+ short *stop,
+ short *do_update,
+ float *UNUSED(progress))
+{
+ FSMenu *fsmenu = fsmenuv;
+
+ int categories[] = {
+ FS_CATEGORY_SYSTEM, FS_CATEGORY_SYSTEM_BOOKMARKS, FS_CATEGORY_BOOKMARKS, FS_CATEGORY_RECENT};
+
+ for (size_t i = ARRAY_SIZE(categories); i--;) {
+ FSMenuEntry *fsm_iter = ED_fsmenu_get_category(fsmenu, categories[i]);
+ for (; fsm_iter; fsm_iter = fsm_iter->next) {
+ if (*stop) {
+ return;
+ }
+ /* Note that we do not really need atomics primitives or thread locks here, since this only
+ * sets one short, which is assumed to be 'atomic'-enough for us here. */
+ fsmenu_entry_refresh_valid(fsm_iter);
+ *do_update = true;
+ }
+ }
+}
+
+static void fsmenu_bookmark_validate_job_update(void *fsmenuv)
+{
+ FSMenu *fsmenu_job = fsmenuv;
+
+ int categories[] = {
+ FS_CATEGORY_SYSTEM, FS_CATEGORY_SYSTEM_BOOKMARKS, FS_CATEGORY_BOOKMARKS, FS_CATEGORY_RECENT};
+
+ for (size_t i = ARRAY_SIZE(categories); i--;) {
+ FSMenuEntry *fsm_iter_src = ED_fsmenu_get_category(fsmenu_job, categories[i]);
+ FSMenuEntry *fsm_iter_dst = ED_fsmenu_get_category(ED_fsmenu_get(), categories[i]);
+ for (; fsm_iter_dst != NULL; fsm_iter_dst = fsm_iter_dst->next) {
+ while (fsm_iter_src != NULL && !STREQ(fsm_iter_dst->path, fsm_iter_src->path)) {
+ fsm_iter_src = fsm_iter_src->next;
+ }
+ if (fsm_iter_src == NULL) {
+ return;
+ }
+ fsm_iter_dst->valid = fsm_iter_src->valid;
+ }
+ }
+}
+
+static void fsmenu_bookmark_validate_job_end(void *fsmenuv)
+{
+ /* In case there would be some dangling update... */
+ fsmenu_bookmark_validate_job_update(fsmenuv);
+}
+
+static void fsmenu_bookmark_validate_job_free(void *fsmenuv)
+{
+ FSMenu *fsmenu = fsmenuv;
+ fsmenu_free_ex(&fsmenu);
+}
+
+static void fsmenu_bookmark_validate_job_start(wmWindowManager *wm)
+{
+ wmJob *wm_job;
+ FSMenu *fsmenu_job = fsmenu_copy(g_fsmenu);
+
+ /* setup job */
+ wm_job = WM_jobs_get(
+ wm, wm->winactive, wm, "Validating Bookmarks...", 0, WM_JOB_TYPE_FSMENU_BOOKMARK_VALIDATE);
+ WM_jobs_customdata_set(wm_job, fsmenu_job, fsmenu_bookmark_validate_job_free);
+ WM_jobs_timer(wm_job, 0.01, NC_SPACE | ND_SPACE_FILE_LIST, NC_SPACE | ND_SPACE_FILE_LIST);
+ WM_jobs_callbacks(wm_job,
+ fsmenu_bookmark_validate_job_startjob,
+ NULL,
+ fsmenu_bookmark_validate_job_update,
+ fsmenu_bookmark_validate_job_end);
+
+ /* start the job */
+ WM_jobs_start(wm, wm_job);
+}
+
+static void fsmenu_bookmark_validate_job_stop(wmWindowManager *wm)
+{
+ WM_jobs_kill_type(wm, wm, WM_JOB_TYPE_FSMENU_BOOKMARK_VALIDATE);
+}
+
+void fsmenu_refresh_bookmarks_status(wmWindowManager *wm, FSMenu *fsmenu)
+{
+ BLI_assert(fsmenu == ED_fsmenu_get());
+ UNUSED_VARS_NDEBUG(fsmenu);
+
+ fsmenu_bookmark_validate_job_stop(wm);
+ fsmenu_bookmark_validate_job_start(wm);
+}
diff --git a/source/blender/editors/space_file/fsmenu.h b/source/blender/editors/space_file/fsmenu.h
index cb0dccf0499..d9850cb855d 100644
--- a/source/blender/editors/space_file/fsmenu.h
+++ b/source/blender/editors/space_file/fsmenu.h
@@ -68,7 +68,7 @@ void fsmenu_free(void);
void fsmenu_refresh_system_category(struct FSMenu *fsmenu);
/** Refresh 'valid' status of all menu entries */
-void fsmenu_refresh_bookmarks_status(struct FSMenu *fsmenu);
+void fsmenu_refresh_bookmarks_status(struct wmWindowManager *wm, struct FSMenu *fsmenu);
/** Get active index based on given directory. */
int fsmenu_get_active_indices(struct FSMenu *fsmenu,
diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c
index 4629f33d210..1fd878e4662 100644
--- a/source/blender/editors/space_file/space_file.c
+++ b/source/blender/editors/space_file/space_file.c
@@ -83,7 +83,6 @@ static SpaceLink *file_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scen
BLI_addtail(&sfile->regionbase, ar);
ar->regiontype = RGN_TYPE_TOOL_PROPS;
ar->alignment = RGN_ALIGN_BOTTOM | RGN_SPLIT_PREV;
- ar->flag |= RGN_FLAG_DYNAMIC_SIZE;
/* ui list region */
ar = MEM_callocN(sizeof(ARegion), "ui region for file");
@@ -143,18 +142,16 @@ static void file_free(SpaceLink *sl)
}
/* spacetype; init callback, area size changes, screen set, etc */
-static void file_init(wmWindowManager *UNUSED(wm), ScrArea *sa)
+static void file_init(wmWindowManager *wm, ScrArea *sa)
{
SpaceFile *sfile = (SpaceFile *)sa->spacedata.first;
+ struct FSMenu *fsmenu = ED_fsmenu_get();
/* refresh system directory list */
- fsmenu_refresh_system_category(ED_fsmenu_get());
+ fsmenu_refresh_system_category(fsmenu);
- /* Update bookmarks 'valid' state.
- * Done here, because it seems BLI_is_dir() can have huge impact on performances
- * in some cases, on win systems... See T43684.
- */
- fsmenu_refresh_bookmarks_status(ED_fsmenu_get());
+ /* Update bookmarks 'valid' state. */
+ fsmenu_refresh_bookmarks_status(wm, fsmenu);
if (sfile->layout) {
sfile->layout->dirty = true;
diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c
index 0954538e430..c5f8c32ec7a 100644
--- a/source/blender/editors/space_graph/graph_edit.c
+++ b/source/blender/editors/space_graph/graph_edit.c
@@ -2820,6 +2820,7 @@ void GRAPH_OT_fmodifier_add(wmOperatorType *ot)
/* id-props */
prop = RNA_def_enum(ot->srna, "type", rna_enum_fmodifier_type_items, 0, "Type", "");
+ RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_ACTION);
RNA_def_enum_funcs(prop, graph_fmodifier_itemf);
ot->prop = prop;
diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c
index 054a1e3d8ee..5c7035a4c04 100644
--- a/source/blender/editors/space_graph/graph_ops.c
+++ b/source/blender/editors/space_graph/graph_ops.c
@@ -105,7 +105,7 @@ static void graphview_cursor_apply(bContext *C, wmOperator *op)
}
SUBFRA = 0.0f;
- BKE_sound_update_and_seek(bmain, CTX_data_depsgraph(C));
+ BKE_sound_seek_scene(bmain, scene);
}
/* set the cursor value */
diff --git a/source/blender/editors/space_graph/graph_select.c b/source/blender/editors/space_graph/graph_select.c
index 13a42f091f6..5ea07c56286 100644
--- a/source/blender/editors/space_graph/graph_select.c
+++ b/source/blender/editors/space_graph/graph_select.c
@@ -1141,7 +1141,7 @@ typedef enum eGraphVertIndex {
/* Tolerance for absolute radius (in pixels) of the vert from the cursor to use */
// TODO: perhaps this should depend a bit on the size that the user set the vertices to be?
-#define GVERTSEL_TOL 10
+#define GVERTSEL_TOL (10 * U.pixelsize)
/* ....... */
diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c
index 390ea0cf00b..4e131c653f8 100644
--- a/source/blender/editors/space_graph/space_graph.c
+++ b/source/blender/editors/space_graph/space_graph.c
@@ -42,6 +42,7 @@
#include "ED_screen.h"
#include "ED_anim_api.h"
#include "ED_markers.h"
+#include "ED_time_scrub_ui.h"
#include "GPU_immediate.h"
#include "GPU_state.h"
@@ -57,6 +58,7 @@
#include "UI_resources.h"
#include "UI_view2d.h"
+#include "UI_interface.h"
#include "graph_intern.h" // own include
@@ -79,7 +81,7 @@ static SpaceLink *graph_new(const ScrArea *UNUSED(sa), const Scene *scene)
/* settings for making it easier by default to just see what you're interested in tweaking */
sipo->ads->filterflag |= ADS_FILTER_ONLYSEL;
- sipo->flag |= SIPO_SELVHANDLESONLY;
+ sipo->flag |= SIPO_SELVHANDLESONLY | SIPO_MARKER_LINES;
/* header */
ar = MEM_callocN(sizeof(ARegion), "header for graphedit");
@@ -124,8 +126,8 @@ static SpaceLink *graph_new(const ScrArea *UNUSED(sa), const Scene *scene)
ar->v2d.max[0] = MAXFRAMEF;
ar->v2d.max[1] = FLT_MAX;
- ar->v2d.scroll = (V2D_SCROLL_BOTTOM | V2D_SCROLL_SCALE_HORIZONTAL);
- ar->v2d.scroll |= (V2D_SCROLL_LEFT | V2D_SCROLL_SCALE_VERTICAL);
+ ar->v2d.scroll = (V2D_SCROLL_BOTTOM | V2D_SCROLL_HORIZONTAL_HANDLES);
+ ar->v2d.scroll |= (V2D_SCROLL_RIGHT | V2D_SCROLL_VERTICAL_HANDLES);
ar->v2d.keeptot = 0;
@@ -291,12 +293,14 @@ static void graph_main_region_draw(const bContext *C, ARegion *ar)
}
/* markers */
- UI_view2d_view_orthoSpecial(ar, v2d, 1);
- int marker_draw_flag = DRAW_MARKERS_MARGIN;
- if (sipo->flag & SIPO_MARKER_LINES) {
- marker_draw_flag |= DRAW_MARKERS_LINES;
+ if (sipo->mode != SIPO_MODE_DRIVERS) {
+ UI_view2d_view_orthoSpecial(ar, v2d, 1);
+ int marker_draw_flag = DRAW_MARKERS_MARGIN;
+ if (sipo->flag & SIPO_MARKER_LINES) {
+ marker_draw_flag |= DRAW_MARKERS_LINES;
+ }
+ ED_markers_draw(C, marker_draw_flag);
}
- ED_markers_draw(C, marker_draw_flag);
/* preview range */
UI_view2d_view_ortho(v2d);
@@ -309,6 +313,9 @@ static void graph_main_region_draw(const bContext *C, ARegion *ar)
/* reset view matrix */
UI_view2d_view_restore(C);
+ /* time-scrubbing */
+ ED_scrubbing_draw(ar, scene, display_seconds, false);
+
/* scrollers */
// FIXME: args for scrollers depend on the type of data being shown...
scrollers = UI_view2d_scrollers_calc(v2d, NULL);
@@ -316,13 +323,14 @@ static void graph_main_region_draw(const bContext *C, ARegion *ar)
UI_view2d_scrollers_free(scrollers);
/* scale numbers */
- UI_view2d_draw_scale_x__frames_or_seconds(ar, v2d, &v2d->hor, scene, display_seconds, TH_TEXT);
- UI_view2d_draw_scale_y__values(ar, v2d, &v2d->vert, TH_TEXT);
-
- /* draw current frame number-indicator on top of scrollers */
- if ((sipo->mode != SIPO_MODE_DRIVERS) && ((sipo->flag & SIPO_NODRAWCFRANUM) == 0)) {
- UI_view2d_view_orthoSpecial(ar, v2d, 1);
- ANIM_draw_cfra_number(C, v2d, cfra_flag);
+ {
+ rcti rect;
+ BLI_rcti_init(&rect,
+ 0,
+ 15 * UI_DPI_FAC,
+ 15 * UI_DPI_FAC,
+ UI_DPI_FAC * ar->sizey - UI_SCRUBBING_MARGIN_Y);
+ UI_view2d_draw_scale_y__values(ar, v2d, &rect, TH_SCROLL_TEXT);
}
}
@@ -367,6 +375,9 @@ static void graph_channel_region_draw(const bContext *C, ARegion *ar)
graph_draw_channel_names((bContext *)C, &ac, ar);
}
+ /* channel filter next to scrubbing area */
+ ED_channel_search_draw(C, ar, ac.ads);
+
/* reset view matrix */
UI_view2d_view_restore(C);
@@ -849,7 +860,7 @@ void ED_spacetype_ipo(void)
art->draw = graph_main_region_draw;
art->listener = graph_region_listener;
art->message_subscribe = graph_region_message_subscribe;
- art->keymapflag = ED_KEYMAP_VIEW2D | ED_KEYMAP_MARKERS | ED_KEYMAP_ANIMATION | ED_KEYMAP_FRAMES;
+ art->keymapflag = ED_KEYMAP_VIEW2D | ED_KEYMAP_ANIMATION | ED_KEYMAP_FRAMES;
BLI_addhead(&st->regiontypes, art);
@@ -880,7 +891,7 @@ void ED_spacetype_ipo(void)
/* regions: UI buttons */
art = MEM_callocN(sizeof(ARegionType), "spacetype graphedit region");
art->regionid = RGN_TYPE_UI;
- art->prefsizex = 200;
+ art->prefsizex = UI_SIDEBAR_PANEL_WIDTH;
art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_FRAMES;
art->listener = graph_region_listener;
art->init = graph_buttons_region_init;
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index 0710ecf3bd6..c317cb26cb7 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -2494,7 +2494,8 @@ static int image_invert_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- ibuf->userflags |= IB_BITMAPDIRTY | IB_DISPLAY_BUFFER_INVALID;
+ ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
+ BKE_image_mark_dirty(ima, ibuf);
if (ibuf->mipmap[0]) {
ibuf->userflags |= IB_MIPMAP_INVALID;
@@ -3542,7 +3543,7 @@ static void change_frame_apply(bContext *C, wmOperator *op)
SUBFRA = 0.0f;
/* do updates */
- BKE_sound_update_and_seek(CTX_data_main(C), CTX_data_depsgraph(C));
+ BKE_sound_seek_scene(CTX_data_main(C), scene);
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
}
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index 3b2386d94e6..cbe655fc9ae 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -567,7 +567,8 @@ static void image_main_region_draw(const bContext *C, ARegion *ar)
Object *obedit = CTX_data_edit_object(C);
Depsgraph *depsgraph = CTX_data_depsgraph(C);
Mask *mask = NULL;
- bool curve = false;
+ bool show_uvedit = false;
+ bool show_curve = false;
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
View2D *v2d = &ar->v2d;
@@ -609,13 +610,13 @@ static void image_main_region_draw(const bContext *C, ARegion *ar)
/* check for mask (delay draw) */
if (ED_space_image_show_uvedit(sima, obedit)) {
- /* pass */
+ show_uvedit = true;
}
else if (sima->mode == SI_MODE_MASK) {
mask = ED_space_image_get_mask(sima);
}
else if (ED_space_image_paint_curve(C)) {
- curve = true;
+ show_curve = true;
}
ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW);
@@ -669,12 +670,9 @@ static void image_main_region_draw(const bContext *C, ARegion *ar)
false,
NULL,
C);
-
- UI_view2d_view_ortho(v2d);
- ED_image_draw_cursor(ar, sima->cursor);
- UI_view2d_view_restore(C);
}
- else if (curve) {
+
+ if (show_uvedit || mask || show_curve) {
UI_view2d_view_ortho(v2d);
ED_image_draw_cursor(ar, sima->cursor);
UI_view2d_view_restore(C);
@@ -764,7 +762,7 @@ static void image_buttons_region_layout(const bContext *C, ARegion *ar)
}
const bool vertical = true;
- ED_region_panels_layout_ex(C, ar, contexts_base, -1, vertical);
+ ED_region_panels_layout_ex(C, ar, &ar->type->paneltypes, contexts_base, -1, vertical, NULL);
}
static void image_buttons_region_draw(const bContext *C, ARegion *ar)
@@ -1035,7 +1033,7 @@ void ED_spacetype_image(void)
/* regions: listview/buttons/scopes */
art = MEM_callocN(sizeof(ARegionType), "spacetype image region");
art->regionid = RGN_TYPE_UI;
- art->prefsizex = 220; // XXX
+ art->prefsizex = UI_SIDEBAR_PANEL_WIDTH;
art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_FRAMES;
art->listener = image_buttons_region_listener;
art->message_subscribe = ED_area_do_mgs_subscribe_for_tool_ui;
diff --git a/source/blender/editors/space_info/info_ops.c b/source/blender/editors/space_info/info_ops.c
index 171d8505222..bf43e493cc5 100644
--- a/source/blender/editors/space_info/info_ops.c
+++ b/source/blender/editors/space_info/info_ops.c
@@ -160,19 +160,11 @@ static int pack_all_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(ev
{
Main *bmain = CTX_data_main(C);
Image *ima;
- ImBuf *ibuf;
// first check for dirty images
for (ima = bmain->images.first; ima; ima = ima->id.next) {
- if (BKE_image_has_loaded_ibuf(ima)) { /* XXX FIX */
- ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
-
- if (ibuf && (ibuf->userflags & IB_BITMAPDIRTY)) {
- BKE_image_release_ibuf(ima, ibuf, NULL);
- break;
- }
-
- BKE_image_release_ibuf(ima, ibuf, NULL);
+ if (BKE_image_is_dirty(ima)) {
+ break;
}
}
diff --git a/source/blender/editors/space_nla/nla_channels.c b/source/blender/editors/space_nla/nla_channels.c
index 3e4eb6af098..e5c116e85de 100644
--- a/source/blender/editors/space_nla/nla_channels.c
+++ b/source/blender/editors/space_nla/nla_channels.c
@@ -52,6 +52,8 @@
#include "WM_api.h"
#include "WM_types.h"
+#include "UI_interface.h"
+
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
@@ -389,7 +391,7 @@ static int nlachannels_mouseclick_invoke(bContext *C, wmOperator *op, const wmEv
UI_view2d_listview_view_to_cell(NLACHANNEL_NAMEWIDTH,
NLACHANNEL_STEP(snla),
0,
- NLACHANNEL_FIRST_TOP(snla),
+ NLACHANNEL_FIRST_TOP(&ac),
x,
y,
NULL,
diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c
index b821a246dc5..68cbfd76331 100644
--- a/source/blender/editors/space_nla/nla_draw.c
+++ b/source/blender/editors/space_nla/nla_draw.c
@@ -689,11 +689,11 @@ void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *ar)
* - offset of NLACHANNEL_HEIGHT*2 is added to the height of the channels, as first is for
* start of list offset, and the second is as a correction for the scrollers.
*/
- int height = NLACHANNEL_TOT_HEIGHT(snla, items);
+ int height = NLACHANNEL_TOT_HEIGHT(ac, items);
v2d->tot.ymin = -height;
/* loop through channels, and set up drawing depending on their type */
- float ymax = NLACHANNEL_FIRST_TOP(snla);
+ float ymax = NLACHANNEL_FIRST_TOP(ac);
for (bAnimListElem *ale = anim_data.first; ale; ale = ale->next, ymax -= NLACHANNEL_STEP(snla)) {
float ymin = ymax - NLACHANNEL_HEIGHT(snla);
@@ -822,7 +822,7 @@ void draw_nla_channel_list(const bContext *C, bAnimContext *ac, ARegion *ar)
* - offset of NLACHANNEL_HEIGHT*2 is added to the height of the channels, as first is for
* start of list offset, and the second is as a correction for the scrollers.
*/
- int height = NLACHANNEL_TOT_HEIGHT(snla, items);
+ int height = NLACHANNEL_TOT_HEIGHT(ac, items);
v2d->tot.ymin = -height;
/* need to do a view-sync here, so that the keys area doesn't jump around
@@ -832,7 +832,7 @@ void draw_nla_channel_list(const bContext *C, bAnimContext *ac, ARegion *ar)
/* draw channels */
{ /* first pass: just the standard GL-drawing for backdrop + text */
size_t channel_index = 0;
- float ymax = NLACHANNEL_FIRST_TOP(snla);
+ float ymax = NLACHANNEL_FIRST_TOP(ac);
for (ale = anim_data.first; ale;
ale = ale->next, ymax -= NLACHANNEL_STEP(snla), channel_index++) {
@@ -849,7 +849,7 @@ void draw_nla_channel_list(const bContext *C, bAnimContext *ac, ARegion *ar)
{ /* second pass: UI widgets */
uiBlock *block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
size_t channel_index = 0;
- float ymax = NLACHANNEL_FIRST_TOP(snla);
+ float ymax = NLACHANNEL_FIRST_TOP(ac);
/* set blending again, as may not be set in previous step */
GPU_blend_set_func_separate(
diff --git a/source/blender/editors/space_nla/nla_edit.c b/source/blender/editors/space_nla/nla_edit.c
index 07853e5850a..acb3d913114 100644
--- a/source/blender/editors/space_nla/nla_edit.c
+++ b/source/blender/editors/space_nla/nla_edit.c
@@ -429,7 +429,7 @@ static bool nla_channels_get_selected_extents(bAnimContext *ac, float *min, floa
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* loop through all channels, finding the first one that's selected */
- float ymax = NLACHANNEL_FIRST_TOP(snla);
+ float ymax = NLACHANNEL_FIRST_TOP(ac);
for (ale = anim_data.first; ale; ale = ale->next, ymax -= NLACHANNEL_STEP(snla)) {
const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
@@ -2446,6 +2446,7 @@ void NLA_OT_fmodifier_add(wmOperatorType *ot)
/* id-props */
ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_fmodifier_type_items, 0, "Type", "");
+ RNA_def_property_translation_context(ot->prop, BLT_I18NCONTEXT_ID_ACTION);
RNA_def_enum_funcs(ot->prop, nla_fmodifier_itemf);
RNA_def_boolean(ot->srna,
diff --git a/source/blender/editors/space_nla/nla_select.c b/source/blender/editors/space_nla/nla_select.c
index accd82525f5..0de9acfec25 100644
--- a/source/blender/editors/space_nla/nla_select.c
+++ b/source/blender/editors/space_nla/nla_select.c
@@ -47,6 +47,7 @@
#include "WM_types.h"
#include "UI_view2d.h"
+#include "UI_interface.h"
#include "nla_intern.h" // own include
@@ -542,7 +543,7 @@ static void mouse_nla_strips(
* (i.e a row in the list) where keyframe was */
UI_view2d_region_to_view(v2d, mval[0], mval[1], &x, &y);
UI_view2d_listview_view_to_cell(
- 0, NLACHANNEL_STEP(snla), 0, NLACHANNEL_FIRST_TOP(snla), x, y, NULL, &channel_index);
+ 0, NLACHANNEL_STEP(snla), 0, NLACHANNEL_FIRST_TOP(ac), x, y, NULL, &channel_index);
/* x-range to check is +/- 7 (in screen/region-space) on either side of mouse click
* (that is the size of keyframe icons, so user should be expecting similar tolerances)
diff --git a/source/blender/editors/space_nla/space_nla.c b/source/blender/editors/space_nla/space_nla.c
index ba660945d32..4b7dfe5d653 100644
--- a/source/blender/editors/space_nla/space_nla.c
+++ b/source/blender/editors/space_nla/space_nla.c
@@ -40,6 +40,7 @@
#include "ED_anim_api.h"
#include "ED_markers.h"
#include "ED_screen.h"
+#include "ED_time_scrub_ui.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -47,6 +48,7 @@
#include "RNA_access.h"
+#include "UI_interface.h"
#include "UI_resources.h"
#include "UI_view2d.h"
@@ -69,6 +71,7 @@ static SpaceLink *nla_new(const ScrArea *sa, const Scene *scene)
/* set auto-snapping settings */
snla->autosnap = SACTSNAP_FRAME;
+ snla->flag = SNLA_SHOW_MARKER_LINES;
/* header */
ar = MEM_callocN(sizeof(ARegion), "header for nla");
@@ -116,7 +119,7 @@ static SpaceLink *nla_new(const ScrArea *sa, const Scene *scene)
ar->v2d.minzoom = 0.01f;
ar->v2d.maxzoom = 50;
- ar->v2d.scroll = (V2D_SCROLL_BOTTOM | V2D_SCROLL_SCALE_HORIZONTAL);
+ ar->v2d.scroll = (V2D_SCROLL_BOTTOM | V2D_SCROLL_HORIZONTAL_HANDLES);
ar->v2d.scroll |= (V2D_SCROLL_RIGHT);
ar->v2d.keepzoom = V2D_LOCKZOOM_Y;
ar->v2d.keepofs = V2D_KEEPOFS_Y;
@@ -201,6 +204,9 @@ static void nla_channel_region_draw(const bContext *C, ARegion *ar)
draw_nla_channel_list(C, &ac, ar);
}
+ /* channel filter next to scrubbing area */
+ ED_channel_search_draw(C, ar, ac.ads);
+
/* reset view matrix */
UI_view2d_view_restore(C);
@@ -284,20 +290,12 @@ static void nla_main_region_draw(const bContext *C, ARegion *ar)
/* reset view matrix */
UI_view2d_view_restore(C);
+ ED_scrubbing_draw(ar, scene, snla->flag & SNLA_DRAWTIME, true);
+
/* scrollers */
scrollers = UI_view2d_scrollers_calc(v2d, NULL);
UI_view2d_scrollers_draw(v2d, scrollers);
UI_view2d_scrollers_free(scrollers);
-
- /* frame numbers */
- UI_view2d_draw_scale_x__discrete_frames_or_seconds(
- ar, v2d, &v2d->hor, scene, snla->flag & SNLA_DRAWTIME, TH_TEXT);
-
- /* draw current frame number-indicator on top of scrollers */
- if ((snla->flag & SNLA_NODRAWCFRANUM) == 0) {
- UI_view2d_view_orthoSpecial(ar, v2d, 1);
- ANIM_draw_cfra_number(C, v2d, cfra_flag);
- }
}
/* add handlers, stuff you only do once or on area/region changes */
@@ -614,7 +612,7 @@ void ED_spacetype_nla(void)
art->draw = nla_main_region_draw;
art->listener = nla_main_region_listener;
art->message_subscribe = nla_main_region_message_subscribe;
- art->keymapflag = ED_KEYMAP_VIEW2D | ED_KEYMAP_MARKERS | ED_KEYMAP_ANIMATION | ED_KEYMAP_FRAMES;
+ art->keymapflag = ED_KEYMAP_VIEW2D | ED_KEYMAP_ANIMATION | ED_KEYMAP_FRAMES;
BLI_addhead(&st->regiontypes, art);
@@ -645,7 +643,7 @@ void ED_spacetype_nla(void)
/* regions: UI buttons */
art = MEM_callocN(sizeof(ARegionType), "spacetype nla region");
art->regionid = RGN_TYPE_UI;
- art->prefsizex = 200;
+ art->prefsizex = UI_SIDEBAR_PANEL_WIDTH;
art->keymapflag = ED_KEYMAP_UI;
art->listener = nla_region_listener;
art->init = nla_buttons_region_init;
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index 447fea8098c..bf6ec961a5d 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -708,6 +708,11 @@ static void node_buts_image_user(uiLayout *layout,
col = uiLayoutColumn(layout, false);
uiItemR(col, ptr, "layer", 0, NULL, ICON_NONE);
}
+
+ uiLayout *split = uiLayoutSplit(layout, 0.5f, true);
+ PointerRNA colorspace_settings_ptr = RNA_pointer_get(imaptr, "colorspace_settings");
+ uiItemL(split, IFACE_("Color Space"), ICON_NONE);
+ uiItemR(split, &colorspace_settings_ptr, "name", 0, "", ICON_NONE);
}
static void node_shader_buts_mapping(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
@@ -782,7 +787,6 @@ static void node_shader_buts_tex_image(uiLayout *layout, bContext *C, PointerRNA
NULL,
UI_TEMPLATE_ID_FILTER_ALL,
false);
- uiItemR(layout, ptr, "color_space", 0, "", ICON_NONE);
uiItemR(layout, ptr, "interpolation", 0, "", ICON_NONE);
uiItemR(layout, ptr, "projection", 0, "", ICON_NONE);
@@ -820,11 +824,10 @@ static void node_shader_buts_tex_environment(uiLayout *layout, bContext *C, Poin
UI_TEMPLATE_ID_FILTER_ALL,
false);
- node_buts_image_user(layout, C, &iuserptr, &imaptr, &iuserptr, false);
-
- uiItemR(layout, ptr, "color_space", 0, "", ICON_NONE);
uiItemR(layout, ptr, "interpolation", 0, "", ICON_NONE);
uiItemR(layout, ptr, "projection", 0, "", ICON_NONE);
+
+ node_buts_image_user(layout, C, &iuserptr, &imaptr, &iuserptr, false);
}
static void node_shader_buts_tex_environment_ex(uiLayout *layout, bContext *C, PointerRNA *ptr)
@@ -875,7 +878,6 @@ static void node_shader_buts_tex_environment_ex(uiLayout *layout, bContext *C, P
uiTemplateImageInfo(layout, C, ima, iuserptr.data);
}
- uiItemR(layout, ptr, "color_space", 0, IFACE_("Color Space"), ICON_NONE);
uiItemR(layout, ptr, "interpolation", 0, IFACE_("Interpolation"), ICON_NONE);
uiItemR(layout, ptr, "projection", 0, IFACE_("Projection"), ICON_NONE);
}
diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c
index 3e73cc52c52..fb34d9dc459 100644
--- a/source/blender/editors/space_node/node_edit.c
+++ b/source/blender/editors/space_node/node_edit.c
@@ -453,13 +453,8 @@ void ED_node_shader_default(const bContext *C, ID *id)
output_type = SH_NODE_OUTPUT_LIGHT;
shader_type = SH_NODE_EMISSION;
- copy_v3_v3(color, &la->r);
- if (la->type == LA_LOCAL || la->type == LA_SPOT || la->type == LA_AREA) {
- strength = 100.0f;
- }
- else {
- strength = 1.0f;
- }
+ copy_v3_fl3(color, 1.0f, 1.0f, 1.0f);
+ strength = 1.0f;
break;
}
default:
diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c
index b52d1d3b78f..aab328249fe 100644
--- a/source/blender/editors/space_node/node_select.c
+++ b/source/blender/editors/space_node/node_select.c
@@ -429,19 +429,24 @@ void node_select_single(bContext *C, bNode *node)
WM_event_add_notifier(C, NC_NODE | NA_SELECTED, NULL);
}
-static int node_mouse_select(Main *bmain,
- SpaceNode *snode,
- ARegion *ar,
+static int node_mouse_select(bContext *C,
const int mval[2],
const bool extend,
const bool socket_select,
- const bool deselect_all)
+ const bool deselect_all,
+ const bool wait_to_deselect_others)
{
+ Main *bmain = CTX_data_main(C);
+ SpaceNode *snode = CTX_wm_space_node(C);
+ ARegion *ar = CTX_wm_region(C);
bNode *node, *tnode;
bNodeSocket *sock = NULL;
bNodeSocket *tsock;
float cursor[2];
- bool selected = false;
+ int ret_value = OPERATOR_CANCELLED;
+
+ /* Waiting to deselect others is only allowed for basic selection. */
+ BLI_assert(!(extend || socket_select) || !wait_to_deselect_others);
/* get mouse coordinates in view2d space */
UI_view2d_region_to_view(&ar->v2d, mval[0], mval[1], &cursor[0], &cursor[1]);
@@ -449,89 +454,104 @@ static int node_mouse_select(Main *bmain,
/* first do socket selection, these generally overlap with nodes. */
if (socket_select) {
if (node_find_indicated_socket(snode, &node, &sock, cursor, SOCK_IN)) {
- node_socket_toggle(node, sock, 1);
- selected = true;
+ /* NOTE: SOCK_IN does not take into account the extend case...
+ * This feature is not really used anyway currently? */
+ node_socket_toggle(node, sock, true);
+ ret_value = OPERATOR_FINISHED;
}
else if (node_find_indicated_socket(snode, &node, &sock, cursor, SOCK_OUT)) {
if (sock->flag & SELECT) {
if (extend) {
- node_socket_deselect(node, sock, 1);
+ node_socket_deselect(node, sock, true);
}
else {
- selected = true;
+ ret_value = OPERATOR_FINISHED;
}
}
else {
- /* only allow one selected output per node, for sensible linking.
- * allows selecting outputs from different nodes though. */
+ /* Only allow one selected output per node, for sensible linking.
+ * Allow selecting outputs from different nodes though, if extend is true. */
if (node) {
for (tsock = node->outputs.first; tsock; tsock = tsock->next) {
- node_socket_deselect(node, tsock, 1);
+ if (tsock == sock) {
+ continue;
+ }
+ node_socket_deselect(node, tsock, true);
}
}
- if (extend) {
- /* only allow one selected output per node, for sensible linking.
- * allows selecting outputs from different nodes though. */
- for (tsock = node->outputs.first; tsock; tsock = tsock->next) {
- if (tsock != sock) {
- node_socket_deselect(node, tsock, 1);
+ if (!extend) {
+ for (tnode = snode->edittree->nodes.first; tnode; tnode = tnode->next) {
+ if (tnode == node) {
+ continue;
+ }
+ for (tsock = tnode->outputs.first; tsock; tsock = tsock->next) {
+ node_socket_deselect(tnode, tsock, true);
}
}
}
node_socket_select(node, sock);
- selected = true;
+ ret_value = OPERATOR_FINISHED;
}
}
}
if (!sock) {
- if (extend) {
- /* find the closest visible node */
- node = node_under_mouse_select(snode->edittree, cursor[0], cursor[1]);
+ /* find the closest visible node */
+ node = node_under_mouse_select(snode->edittree, (int)cursor[0], (int)cursor[1]);
- if (node) {
- if ((node->flag & SELECT) && (node->flag & NODE_ACTIVE) == 0) {
- /* if node is selected but not active make it active */
- ED_node_set_active(bmain, snode->edittree, node);
- }
- else {
+ if (extend) {
+ if (node != NULL) {
+ /* If node is selected but not active, we want to make it active,
+ * but not toggle (deselect) it. */
+ if (!((node->flag & SELECT) && (node->flag & NODE_ACTIVE) == 0)) {
node_toggle(node);
- ED_node_set_active(bmain, snode->edittree, node);
}
- selected = true;
+ ret_value = OPERATOR_FINISHED;
}
}
- else {
- /* find the closest visible node */
- node = node_under_mouse_select(snode->edittree, cursor[0], cursor[1]);
+ else if (deselect_all && node == NULL) {
+ /* Deselect in empty space. */
+ for (tnode = snode->edittree->nodes.first; tnode; tnode = tnode->next) {
+ nodeSetSelected(tnode, false);
+ }
+ ret_value = OPERATOR_FINISHED;
+ }
+ else if (node != NULL) {
+ /* When clicking on an already selected node, we want to wait to deselect
+ * others and allow the user to start moving the node without that. */
+ if (wait_to_deselect_others && (node->flag & SELECT)) {
+ ret_value = OPERATOR_RUNNING_MODAL;
+ }
+ else {
+ nodeSetSelected(node, true);
- if (node != NULL || deselect_all) {
for (tnode = snode->edittree->nodes.first; tnode; tnode = tnode->next) {
- nodeSetSelected(tnode, false);
- }
- selected = true;
- if (node != NULL) {
- nodeSetSelected(node, true);
- ED_node_set_active(bmain, snode->edittree, node);
+ if (tnode != node) {
+ nodeSetSelected(tnode, false);
+ }
}
+
+ ret_value = OPERATOR_FINISHED;
}
}
}
/* update node order */
- if (selected) {
+ if (ret_value != OPERATOR_CANCELLED) {
+ if (node != NULL && ret_value != OPERATOR_RUNNING_MODAL) {
+ ED_node_set_active(bmain, snode->edittree, node);
+ }
ED_node_set_active_viewer_key(snode);
ED_node_sort(snode->edittree);
+
+ WM_event_add_notifier(C, NC_NODE | NA_SELECTED, NULL);
}
- return selected;
+ return ret_value;
}
static int node_select_exec(bContext *C, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
- SpaceNode *snode = CTX_wm_space_node(C);
- ARegion *ar = CTX_wm_region(C);
int mval[2];
/* get settings from RNA properties for operator */
@@ -544,17 +564,70 @@ static int node_select_exec(bContext *C, wmOperator *op)
const bool deselect_all = RNA_boolean_get(op->ptr, "deselect_all");
/* perform the select */
- if (node_mouse_select(bmain, snode, ar, mval, extend, socket_select, deselect_all)) {
- /* send notifiers */
- WM_event_add_notifier(C, NC_NODE | NA_SELECTED, NULL);
+ const int ret_value = node_mouse_select(C, mval, extend, socket_select, deselect_all, false);
- /* allow tweak event to work too */
- return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH;
+ /* allow tweak event to work too */
+ return ret_value | OPERATOR_PASS_THROUGH;
+}
+
+static int node_select_modal(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ const short init_event_type = (short)POINTER_AS_INT(op->customdata);
+
+ /* get settings from RNA properties for operator */
+ int mval[2];
+ mval[0] = RNA_int_get(op->ptr, "mouse_x");
+ mval[1] = RNA_int_get(op->ptr, "mouse_y");
+
+ const bool extend = RNA_boolean_get(op->ptr, "extend");
+ /* always do socket_select when extending selection. */
+ const bool socket_select = extend || RNA_boolean_get(op->ptr, "socket_select");
+ const bool deselect_all = RNA_boolean_get(op->ptr, "deselect_all");
+
+ /* These cases are never modal. */
+ if (extend || socket_select) {
+ return node_select_exec(C, op);
}
- else {
- /* allow tweak event to work too */
- return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
+
+ if (init_event_type == 0) {
+ if (event->val == KM_PRESS) {
+ const int ret_value = node_mouse_select(C, mval, extend, socket_select, deselect_all, true);
+
+ op->customdata = POINTER_FROM_INT((int)event->type);
+ if (ret_value & OPERATOR_RUNNING_MODAL) {
+ WM_event_add_modal_handler(C, op);
+ }
+ 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.
+ */
+ return node_select_exec(C, op);
+ }
}
+ else if (event->type == init_event_type && event->val == KM_RELEASE) {
+ const int ret_value = node_mouse_select(C, mval, extend, socket_select, deselect_all, false);
+ return ret_value | OPERATOR_PASS_THROUGH;
+ }
+ else if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) {
+ const int dx = mval[0] - event->mval[0];
+ const int dy = mval[1] - event->mval[1];
+ const float tweak_threshold = U.tweak_threshold * U.dpi_fac;
+ /* If user moves mouse more than defined threshold, we consider select operator as
+ * finished. Otherwise, it is still running until we get an 'release' event. In any
+ * case, we pass through event, but select op is not finished yet. */
+ if (abs(dx) + abs(dy) > tweak_threshold) {
+ 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;
+ }
+ }
+
+ return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH;
}
static int node_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
@@ -562,7 +635,9 @@ static int node_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
RNA_int_set(op->ptr, "mouse_x", event->mval[0]);
RNA_int_set(op->ptr, "mouse_y", event->mval[1]);
- return node_select_exec(C, op);
+ op->customdata = POINTER_FROM_INT(0);
+
+ return node_select_modal(C, op, event);
}
void NODE_OT_select(wmOperatorType *ot)
@@ -575,6 +650,7 @@ void NODE_OT_select(wmOperatorType *ot)
/* api callbacks */
ot->invoke = node_select_invoke;
ot->exec = node_select_exec;
+ ot->modal = node_select_modal;
ot->poll = ED_operator_node_active;
/* flags */
@@ -1186,7 +1262,7 @@ static uiBlock *node_find_menu(bContext *C, ARegion *ar, void *arg_op)
static int node_find_node_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- UI_popup_block_invoke(C, node_find_menu, op);
+ UI_popup_block_invoke(C, node_find_menu, op, NULL);
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c
index 2152bb9847a..2351d437294 100644
--- a/source/blender/editors/space_node/space_node.c
+++ b/source/blender/editors/space_node/space_node.c
@@ -998,7 +998,7 @@ void ED_spacetype_node(void)
/* regions: listview/buttons */
art = MEM_callocN(sizeof(ARegionType), "spacetype node region");
art->regionid = RGN_TYPE_UI;
- art->prefsizex = 180; // XXX
+ art->prefsizex = UI_SIDEBAR_PANEL_WIDTH;
art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_FRAMES;
art->listener = node_region_listener;
art->init = node_buttons_region_init;
diff --git a/source/blender/editors/space_outliner/outliner_collections.c b/source/blender/editors/space_outliner/outliner_collections.c
index 6da42ecb3c0..21e54a29fb9 100644
--- a/source/blender/editors/space_outliner/outliner_collections.c
+++ b/source/blender/editors/space_outliner/outliner_collections.c
@@ -855,7 +855,7 @@ static int collection_view_layer_exec(bContext *C, wmOperator *op)
void OUTLINER_OT_collection_exclude_set(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Set Exclude";
+ ot->name = "Disable from View Layer";
ot->idname = "OUTLINER_OT_collection_exclude_set";
ot->description = "Exclude collection from the active view layer";
@@ -870,7 +870,7 @@ void OUTLINER_OT_collection_exclude_set(wmOperatorType *ot)
void OUTLINER_OT_collection_exclude_clear(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Clear Exclude";
+ ot->name = "Enable in View Layer";
ot->idname = "OUTLINER_OT_collection_exclude_clear";
ot->description = "Include collection in the active view layer";
@@ -965,8 +965,8 @@ static int collection_isolate_exec(bContext *C, wmOperator *op)
LayerCollection *lc_master = view_layer->layer_collections.first;
for (LayerCollection *lc_iter = lc_master->layer_collections.first; lc_iter;
lc_iter = lc_iter->next) {
- lc_iter->flag |= LAYER_COLLECTION_RESTRICT_VIEW;
- layer_collection_flag_recursive_set(lc_iter, LAYER_COLLECTION_RESTRICT_VIEW);
+ lc_iter->flag |= LAYER_COLLECTION_HIDE;
+ layer_collection_flag_recursive_set(lc_iter, LAYER_COLLECTION_HIDE);
}
}
@@ -1023,12 +1023,12 @@ void OUTLINER_OT_collection_isolate(wmOperatorType *ot)
static bool collection_show_poll(bContext *C)
{
- return collections_view_layer_poll(C, true, LAYER_COLLECTION_RESTRICT_VIEW);
+ return collections_view_layer_poll(C, true, LAYER_COLLECTION_HIDE);
}
static bool collection_hide_poll(bContext *C)
{
- return collections_view_layer_poll(C, false, LAYER_COLLECTION_RESTRICT_VIEW);
+ return collections_view_layer_poll(C, false, LAYER_COLLECTION_HIDE);
}
static bool collection_inside_poll(bContext *C)
@@ -1163,12 +1163,12 @@ static bool collection_flag_poll(bContext *C, bool clear, int flag)
static bool collection_enable_poll(bContext *C)
{
- return collection_flag_poll(C, true, COLLECTION_RESTRICT_VIEW);
+ return collection_flag_poll(C, true, COLLECTION_RESTRICT_VIEWPORT);
}
static bool collection_disable_poll(bContext *C)
{
- return collection_flag_poll(C, false, COLLECTION_RESTRICT_VIEW);
+ return collection_flag_poll(C, false, COLLECTION_RESTRICT_VIEWPORT);
}
static bool collection_enable_render_poll(bContext *C)
@@ -1188,7 +1188,7 @@ static int collection_flag_exec(bContext *C, wmOperator *op)
SpaceOutliner *soops = CTX_wm_space_outliner(C);
const bool is_render = strstr(op->idname, "render");
const bool clear = strstr(op->idname, "show") || strstr(op->idname, "enable");
- int flag = is_render ? COLLECTION_RESTRICT_RENDER : COLLECTION_RESTRICT_VIEW;
+ int flag = is_render ? COLLECTION_RESTRICT_RENDER : COLLECTION_RESTRICT_VIEWPORT;
struct CollectionEditData data = {
.scene = scene,
.soops = soops,
@@ -1215,7 +1215,7 @@ static int collection_flag_exec(bContext *C, wmOperator *op)
/* Make sure (at least for this view layer) the collection is visible. */
if (clear && !is_render) {
- layer_collection->flag &= ~LAYER_COLLECTION_RESTRICT_VIEW;
+ layer_collection->flag &= ~LAYER_COLLECTION_HIDE;
}
}
BLI_gset_free(data.collections_to_edit, NULL);
@@ -1408,8 +1408,8 @@ static int outliner_unhide_all_exec(bContext *C, wmOperator *UNUSED(op))
LayerCollection *lc_master = view_layer->layer_collections.first;
for (LayerCollection *lc_iter = lc_master->layer_collections.first; lc_iter;
lc_iter = lc_iter->next) {
- lc_iter->flag &= ~LAYER_COLLECTION_RESTRICT_VIEW;
- layer_collection_flag_recursive_set(lc_iter, LAYER_COLLECTION_RESTRICT_VIEW);
+ lc_iter->flag &= ~LAYER_COLLECTION_HIDE;
+ layer_collection_flag_recursive_set(lc_iter, LAYER_COLLECTION_HIDE);
}
/* Unhide all objects. */
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index 9d6008ce3a8..6547b46a6e6 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -270,127 +270,413 @@ static void restrictbutton_id_user_toggle(bContext *UNUSED(C), void *poin, void
}
}
-static int base_pushed_state_cb(bContext *UNUSED(C), void *poin)
+static void outliner_object_set_flag_recursive_cb(bContext *C,
+ Base *base,
+ Object *ob,
+ const char *propname)
+{
+ Main *bmain = CTX_data_main(C);
+ wmWindow *win = CTX_wm_window(C);
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ PointerRNA ptr;
+
+ bool extend = (win->eventstate->shift != 0);
+
+ if (!extend) {
+ return;
+ }
+
+ /* Create PointerRNA and PropertyRNA for either Object or Base. */
+ ID *id = ob ? &ob->id : &scene->id;
+ StructRNA *struct_rna = ob ? &RNA_Object : &RNA_ObjectBase;
+ void *data = ob ? (void *)ob : (void *)base;
+
+ RNA_pointer_create(id, struct_rna, data, &ptr);
+ PropertyRNA *base_or_object_prop = RNA_struct_type_find_property(struct_rna, propname);
+ const bool value = RNA_property_boolean_get(&ptr, base_or_object_prop);
+
+ Object *ob_parent = ob ? ob : base->object;
+
+ for (Object *ob_iter = bmain->objects.first; ob_iter; ob_iter = ob_iter->id.next) {
+ if (BKE_object_is_child_recursive(ob_parent, ob_iter)) {
+ if (ob) {
+ RNA_id_pointer_create(&ob_iter->id, &ptr);
+ DEG_id_tag_update(&ob_iter->id, ID_RECALC_COPY_ON_WRITE);
+ }
+ else {
+ Base *base_iter = BKE_view_layer_base_find(view_layer, ob_iter);
+ RNA_pointer_create(&scene->id, &RNA_ObjectBase, base_iter, &ptr);
+ }
+ RNA_property_boolean_set(&ptr, base_or_object_prop, value);
+ }
+ }
+
+ /* We don't call RNA_property_update() due to performance, so we batch update them. */
+ if (ob) {
+ BKE_main_collection_sync_remap(bmain);
+ DEG_relations_tag_update(bmain);
+ }
+ else {
+ BKE_layer_collection_sync(scene, view_layer);
+ DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS);
+ }
+}
+
+/**
+ * Object properties.
+ * */
+static void outliner__object_set_flag_recursive_cb(bContext *C, void *poin, void *poin2)
+{
+ Object *ob = poin;
+ char *propname = poin2;
+ outliner_object_set_flag_recursive_cb(C, NULL, ob, propname);
+}
+
+/**
+ * Base properties.
+ * */
+static void outliner__base_set_flag_recursive_cb(bContext *C, void *poin, void *poin2)
{
Base *base = poin;
- Object *ob = base->object;
+ char *propname = poin2;
+ outliner_object_set_flag_recursive_cb(C, base, NULL, propname);
+}
- const bool is_visible = ((base->flag & BASE_HIDDEN) == 0) &&
- ((ob->restrictflag & OB_RESTRICT_VIEW) == 0);
- return !is_visible;
+/** Create either a RNA_LayerCollection or a RNA_Collection pointer. */
+static void outliner_layer_or_collection_pointer_create(Scene *scene,
+ LayerCollection *layer_collection,
+ Collection *collection,
+ PointerRNA *ptr)
+{
+ if (collection) {
+ RNA_id_pointer_create(&collection->id, ptr);
+ }
+ else {
+ RNA_pointer_create(&scene->id, &RNA_LayerCollection, layer_collection, ptr);
+ }
}
-static void hidebutton_base_flag_cb(bContext *C, void *poin, void *poin2)
+/** Create either a RNA_ObjectBase or a RNA_Object pointer. */
+static void outliner_base_or_object_pointer_create(ViewLayer *view_layer,
+ Collection *collection,
+ Object *ob,
+ PointerRNA *ptr)
{
- wmWindow *win = CTX_wm_window(C);
- Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
- ViewLayer *view_layer = poin;
- Base *base = poin2;
- Object *ob = base->object;
- bool do_disable = (CTX_wm_window(C)->eventstate->alt != 0);
- bool do_isolate = (win->eventstate->ctrl != 0) && !do_disable;
- bool extend = (win->eventstate->shift != 0);
- bool depsgraph_changed = false;
- const bool is_linked = ID_IS_LINKED(ob);
+ if (collection) {
+ RNA_id_pointer_create(&ob->id, ptr);
+ }
+ else {
+ Base *base = BKE_view_layer_base_find(view_layer, ob);
+ RNA_pointer_create(&base->object->id, &RNA_ObjectBase, base, ptr);
+ }
+}
- if (do_disable) {
- if (!is_linked) {
- ob->restrictflag |= OB_RESTRICT_VIEW;
- depsgraph_changed = true;
- }
+/* Note: Collection is only valid when we want to change the collection data, otherwise we get it
+ * from layer collection. Layer collection is valid whenever we are looking at a view layer. */
+static void outliner_collection_set_flag_recursive(Scene *scene,
+ ViewLayer *view_layer,
+ LayerCollection *layer_collection,
+ Collection *collection,
+ PropertyRNA *layer_or_collection_prop,
+ PropertyRNA *base_or_object_prop,
+ const bool value)
+{
+ if (layer_collection && layer_collection->flag & LAYER_COLLECTION_EXCLUDE) {
+ return;
}
- else if (do_isolate) {
- depsgraph_changed = (!is_linked) && ((ob->restrictflag & OB_RESTRICT_VIEW) != 0);
+ PointerRNA ptr;
+ outliner_layer_or_collection_pointer_create(scene, layer_collection, collection, &ptr);
+ RNA_property_boolean_set(&ptr, layer_or_collection_prop, value);
- if (!extend) {
- /* Make only one base visible. */
- for (Base *other = view_layer->object_bases.first; other; other = other->next) {
- other->flag |= BASE_HIDDEN;
- }
+ /* Set the same flag for the nested objects as well. */
+ if (base_or_object_prop) {
+ /* Note: We can't use BKE_collection_object_cache_get()
+ * otherwise we would not take collection exclusion into account. */
+ for (CollectionObject *cob = layer_collection->collection->gobject.first; cob;
+ cob = cob->next) {
- base->flag &= ~BASE_HIDDEN;
- }
- else {
- /* Toggle visibility of one base. */
- base->flag ^= BASE_HIDDEN;
- }
+ outliner_base_or_object_pointer_create(view_layer, collection, cob->ob, &ptr);
+ RNA_property_boolean_set(&ptr, base_or_object_prop, value);
- if (!is_linked) {
- ob->restrictflag &= ~OB_RESTRICT_VIEW;
+ if (collection) {
+ DEG_id_tag_update(&cob->ob->id, ID_RECALC_COPY_ON_WRITE);
+ }
}
}
- else if (ob->restrictflag & OB_RESTRICT_VIEW) {
- if (!is_linked) {
- ob->restrictflag &= ~OB_RESTRICT_VIEW;
- base->flag &= ~BASE_HIDDEN;
+
+ /* Keep going recursively. */
+ ListBase *lb = (layer_collection ? &layer_collection->layer_collections : &collection->children);
+ for (Link *link = lb->first; link; link = link->next) {
+ LayerCollection *layer_collection_iter = layer_collection ? (LayerCollection *)link : NULL;
+ Collection *collection_iter = layer_collection ?
+ (collection ? layer_collection_iter->collection : NULL) :
+ ((CollectionChild *)link)->collection;
+ outliner_collection_set_flag_recursive(scene,
+ view_layer,
+ layer_collection_iter,
+ collection_iter,
+ layer_or_collection_prop,
+ base_or_object_prop,
+ value);
+ }
+
+ if (collection) {
+ DEG_id_tag_update(&collection->id, ID_RECALC_COPY_ON_WRITE);
+ }
+}
+
+/** Check if collection is already isolated.
+ *
+ * A collection is isolated if all its parents and children are "visible".
+ * All the other collections must be "invisible".
+ *
+ * Note: We could/should boost performance by iterating over the tree twice.
+ * First tagging all the children/parent collections, then getting their values and comparing.
+ * To run BKE_collection_has_collection() so many times is silly and slow.
+ */
+static bool outliner_collection_is_isolated(Scene *scene,
+ const LayerCollection *layer_collection_cmp,
+ const Collection *collection_cmp,
+ const bool value_cmp,
+ const PropertyRNA *layer_or_collection_prop,
+ LayerCollection *layer_collection,
+ Collection *collection)
+{
+ PointerRNA ptr;
+ outliner_layer_or_collection_pointer_create(scene, layer_collection, collection, &ptr);
+ const bool value = RNA_property_boolean_get(&ptr, (PropertyRNA *)layer_or_collection_prop);
+ Collection *collection_ensure = collection ? collection : layer_collection->collection;
+ const Collection *collection_ensure_cmp = collection_cmp ? collection_cmp :
+ layer_collection_cmp->collection;
+
+ if (collection_ensure->flag & COLLECTION_IS_MASTER) {
+ }
+ else if (collection_ensure == collection_ensure_cmp) {
+ }
+ else if (BKE_collection_has_collection(collection_ensure, (Collection *)collection_ensure_cmp) ||
+ BKE_collection_has_collection((Collection *)collection_ensure_cmp, collection_ensure)) {
+ /* This collection is either a parent or a child of the collection.
+ * We expect it to be set "visble" already. */
+ if (value != value_cmp) {
+ return false;
}
- depsgraph_changed = true;
}
else {
- base->flag ^= BASE_HIDDEN;
+ /* This collection is neither a parent nor a child of the collection.
+ * We expect it to be "invisble". */
+ if (value == value_cmp) {
+ return false;
+ }
}
- if (depsgraph_changed) {
- BKE_main_collection_sync_remap(bmain);
- DEG_id_tag_update(&ob->id, ID_RECALC_COPY_ON_WRITE);
- DEG_relations_tag_update(bmain);
- WM_main_add_notifier(NC_OBJECT | ND_DRAW, &ob->id);
+ /* Keep going recursively. */
+ ListBase *lb = (layer_collection ? &layer_collection->layer_collections : &collection->children);
+ for (Link *link = lb->first; link; link = link->next) {
+ LayerCollection *layer_collection_iter = layer_collection ? (LayerCollection *)link : NULL;
+ Collection *collection_iter = layer_collection ?
+ (collection ? layer_collection_iter->collection : NULL) :
+ ((CollectionChild *)link)->collection;
+ if (layer_collection_iter && layer_collection_iter->flag & LAYER_COLLECTION_EXCLUDE) {
+ continue;
+ }
+ if (!outliner_collection_is_isolated(scene,
+ layer_collection_cmp,
+ collection_cmp,
+ value_cmp,
+ layer_or_collection_prop,
+ layer_collection_iter,
+ collection_iter)) {
+ return false;
+ }
}
- if (!do_disable) {
- BKE_layer_collection_sync(scene, view_layer);
- DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS);
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
- }
+ return true;
}
-static int layer_collection_pushed_state_cb(bContext *UNUSED(C), void *poin)
+static void outliner_collection_isolate_flag(Scene *scene,
+ ViewLayer *view_layer,
+ LayerCollection *layer_collection,
+ Collection *collection,
+ PropertyRNA *layer_or_collection_prop,
+ const char *propname,
+ const bool value)
{
- LayerCollection *lc = poin;
- Collection *collection = lc->collection;
+ PointerRNA ptr;
+ const bool is_hide = strstr(propname, "hide_") != NULL;
+
+ LayerCollection *top_layer_collection = layer_collection ? view_layer->layer_collections.first :
+ NULL;
+ Collection *top_collection = collection ? scene->master_collection : NULL;
+
+ bool was_isolated = (value == is_hide);
+ was_isolated &= outliner_collection_is_isolated(scene,
+ layer_collection,
+ collection,
+ !is_hide,
+ layer_or_collection_prop,
+ top_layer_collection,
+ top_collection);
+
+ if (was_isolated) {
+ const bool default_value = RNA_property_boolean_get_default(NULL, layer_or_collection_prop);
+ /* Make every collection go back to its default "visibility" state. */
+ outliner_collection_set_flag_recursive(scene,
+ view_layer,
+ top_layer_collection,
+ top_collection,
+ layer_or_collection_prop,
+ NULL,
+ default_value);
+ return;
+ }
- const bool is_visible = ((lc->flag & LAYER_COLLECTION_RESTRICT_VIEW) == 0) &&
- ((collection->flag & COLLECTION_RESTRICT_VIEW) == 0);
- return !is_visible;
+ /* Make every collection "invisible". */
+ outliner_collection_set_flag_recursive(scene,
+ view_layer,
+ top_layer_collection,
+ top_collection,
+ layer_or_collection_prop,
+ NULL,
+ is_hide);
+
+ /* Make this collection and its children collections the only "visible". */
+ outliner_collection_set_flag_recursive(
+ scene, view_layer, layer_collection, collection, layer_or_collection_prop, NULL, !is_hide);
+
+ /* Make this collection direct parents also "visible". */
+ if (layer_collection) {
+ LayerCollection *lc_parent = layer_collection;
+ for (LayerCollection *lc_iter = top_layer_collection->layer_collections.first; lc_iter;
+ lc_iter = lc_iter->next) {
+ if (BKE_layer_collection_has_layer_collection(lc_iter, layer_collection)) {
+ lc_parent = lc_iter;
+ break;
+ }
+ }
+
+ while (lc_parent != layer_collection) {
+ outliner_layer_or_collection_pointer_create(
+ scene, lc_parent, collection ? lc_parent->collection : NULL, &ptr);
+ RNA_property_boolean_set(&ptr, layer_or_collection_prop, !is_hide);
+
+ for (LayerCollection *lc_iter = lc_parent->layer_collections.first; lc_iter;
+ lc_iter = lc_iter->next) {
+ if (BKE_layer_collection_has_layer_collection(lc_iter, layer_collection)) {
+ lc_parent = lc_iter;
+ break;
+ }
+ }
+ }
+ }
+ else {
+ CollectionParent *parent;
+ Collection *child = collection;
+ while ((parent = child->parents.first)) {
+ if (parent->collection->flag & COLLECTION_IS_MASTER) {
+ break;
+ }
+ RNA_id_pointer_create(&parent->collection->id, &ptr);
+ RNA_property_boolean_set(&ptr, layer_or_collection_prop, !is_hide);
+ child = parent->collection;
+ }
+ }
}
-static void hidebutton_layer_collection_flag_cb(bContext *C, void *poin, void *poin2)
+static void outliner_collection_set_flag_recursive_cb(bContext *C,
+ LayerCollection *layer_collection,
+ Collection *collection,
+ const char *propname)
{
Main *bmain = CTX_data_main(C);
wmWindow *win = CTX_wm_window(C);
Scene *scene = CTX_data_scene(C);
- ViewLayer *view_layer = poin;
- LayerCollection *lc = poin2;
- Collection *collection = lc->collection;
- bool do_disable = (win->eventstate->alt != 0);
- bool do_isolate = (win->eventstate->ctrl != 0) && !do_disable;
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ PointerRNA ptr;
+
+ bool do_isolate = (win->eventstate->ctrl != 0);
bool extend = (win->eventstate->shift != 0);
- bool depsgraph_changed = false;
- if (do_disable) {
- if (!ID_IS_LINKED(collection)) {
- collection->flag |= COLLECTION_RESTRICT_VIEW;
- depsgraph_changed = true;
- }
+ if (!ELEM(true, do_isolate, extend)) {
+ return;
+ }
+
+ /* Create PointerRNA and PropertyRNA for either Collection or LayerCollection. */
+ ID *id = collection ? &collection->id : &scene->id;
+ StructRNA *struct_rna = collection ? &RNA_Collection : &RNA_LayerCollection;
+ void *data = collection ? (void *)collection : (void *)layer_collection;
+
+ RNA_pointer_create(id, struct_rna, data, &ptr);
+ outliner_layer_or_collection_pointer_create(scene, layer_collection, collection, &ptr);
+ PropertyRNA *layer_or_collection_prop = RNA_struct_type_find_property(struct_rna, propname);
+ const bool value = RNA_property_boolean_get(&ptr, layer_or_collection_prop);
+
+ PropertyRNA *base_or_object_prop = NULL;
+ if (layer_collection != NULL) {
+ /* If we are toggling Layer collections we still want to change the properties of the base
+ * or the objects. If we have a matching property, toggle it as well, it can be NULL. */
+ struct_rna = collection ? &RNA_Object : &RNA_ObjectBase;
+ base_or_object_prop = RNA_struct_type_find_property(struct_rna, propname);
}
- else if (do_isolate) {
- depsgraph_changed |= BKE_layer_collection_isolate(scene, view_layer, lc, extend);
+
+ if (extend) {
+ outliner_collection_set_flag_recursive(scene,
+ view_layer,
+ layer_collection,
+ collection,
+ layer_or_collection_prop,
+ base_or_object_prop,
+ value);
}
else {
- bool make_visible = ((lc->flag & LAYER_COLLECTION_RESTRICT_VIEW) != 0) ||
- ((collection->flag & COLLECTION_RESTRICT_VIEW) != 0);
- depsgraph_changed |= BKE_layer_collection_set_visible(view_layer, lc, make_visible, extend);
- }
+ outliner_collection_isolate_flag(scene,
+ view_layer,
+ layer_collection,
+ collection,
+ layer_or_collection_prop,
+ propname,
+ value);
+ }
+
+ /* We don't call RNA_property_update() due to performance, so we batch update them. */
+ BKE_main_collection_sync_remap(bmain);
+ DEG_relations_tag_update(bmain);
+}
- BKE_layer_collection_sync(scene, view_layer);
- DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS);
+/**
+ * Layer collection properties called from the ViewLayer mode.
+ * Change the (non-excluded) collection children, and the objects nested to them all.
+ */
+static void view_layer__layer_collection_set_flag_recursive_cb(bContext *C,
+ void *poin,
+ void *poin2)
+{
+ LayerCollection *layer_collection = poin;
+ char *propname = poin2;
+ outliner_collection_set_flag_recursive_cb(C, layer_collection, NULL, propname);
+}
- if (depsgraph_changed) {
- BKE_main_collection_sync_remap(bmain);
- DEG_relations_tag_update(bmain);
- }
- WM_main_add_notifier(NC_SCENE | ND_LAYER_CONTENT, NULL);
+/**
+ * Collection properties called from the ViewLayer mode.
+ * Change the (non-excluded) collection children, and the objects nested to them all.
+ */
+static void view_layer__collection_set_flag_recursive_cb(bContext *C, void *poin, void *poin2)
+{
+ LayerCollection *layer_collection = poin;
+ char *propname = poin2;
+ outliner_collection_set_flag_recursive_cb(
+ C, layer_collection, layer_collection->collection, propname);
+}
+
+/**
+ * Collection properties called from the Scenes mode.
+ * Change the collection children but no objects.
+ */
+static void scenes__collection_set_flag_recursive_cb(bContext *C, void *poin, void *poin2)
+{
+ Collection *collection = poin;
+ char *propname = poin2;
+ outliner_collection_set_flag_recursive_cb(C, NULL, collection, propname);
}
static void namebutton_cb(bContext *C, void *tsep, char *oldname)
@@ -580,7 +866,10 @@ static void outliner_draw_restrictbuts(uiBlock *block,
bool initialized;
PropertyRNA *object_hide_viewport, *object_hide_select, *object_hide_render;
+ PropertyRNA *base_hide_viewport;
PropertyRNA *collection_hide_viewport, *collection_hide_select, *collection_hide_render;
+ PropertyRNA *layer_collection_holdout, *layer_collection_indirect_only,
+ *layer_collection_hide_viewport;
PropertyRNA *modifier_show_viewport, *modifier_show_render;
} props = {false};
@@ -588,16 +877,57 @@ static void outliner_draw_restrictbuts(uiBlock *block,
props.object_hide_viewport = RNA_struct_type_find_property(&RNA_Object, "hide_viewport");
props.object_hide_select = RNA_struct_type_find_property(&RNA_Object, "hide_select");
props.object_hide_render = RNA_struct_type_find_property(&RNA_Object, "hide_render");
- props.collection_hide_select = RNA_struct_type_find_property(&RNA_Collection, "hide_select");
+ props.base_hide_viewport = RNA_struct_type_find_property(&RNA_ObjectBase, "hide_viewport");
props.collection_hide_viewport = RNA_struct_type_find_property(&RNA_Collection,
"hide_viewport");
+ props.collection_hide_select = RNA_struct_type_find_property(&RNA_Collection, "hide_select");
props.collection_hide_render = RNA_struct_type_find_property(&RNA_Collection, "hide_render");
+ props.layer_collection_holdout = RNA_struct_type_find_property(&RNA_LayerCollection,
+ "holdout");
+ props.layer_collection_indirect_only = RNA_struct_type_find_property(&RNA_LayerCollection,
+ "indirect_only");
+ props.layer_collection_hide_viewport = RNA_struct_type_find_property(&RNA_LayerCollection,
+ "hide_viewport");
props.modifier_show_viewport = RNA_struct_type_find_property(&RNA_Modifier, "show_viewport");
props.modifier_show_render = RNA_struct_type_find_property(&RNA_Modifier, "show_render");
props.initialized = true;
}
+ struct {
+ int select;
+ int hide;
+ int viewport;
+ int render;
+ int indirect_only;
+ int holdout;
+ } restrict_offsets = {0};
+ int restrict_column_offset = 0;
+
+ /* This will determine the order of drawing from RIGHT to LEFT. */
+ if (soops->outlinevis == SO_VIEW_LAYER) {
+ if (soops->show_restrict_flags & SO_RESTRICT_INDIRECT_ONLY) {
+ restrict_offsets.indirect_only = (++restrict_column_offset) * UI_UNIT_X + V2D_SCROLL_WIDTH;
+ }
+ if (soops->show_restrict_flags & SO_RESTRICT_HOLDOUT) {
+ restrict_offsets.holdout = (++restrict_column_offset) * UI_UNIT_X + V2D_SCROLL_WIDTH;
+ }
+ }
+ if (soops->show_restrict_flags & SO_RESTRICT_RENDER) {
+ restrict_offsets.render = (++restrict_column_offset) * UI_UNIT_X + V2D_SCROLL_WIDTH;
+ }
+ if (soops->show_restrict_flags & SO_RESTRICT_VIEWPORT) {
+ restrict_offsets.viewport = (++restrict_column_offset) * UI_UNIT_X + V2D_SCROLL_WIDTH;
+ }
+ if (soops->show_restrict_flags & SO_RESTRICT_HIDE) {
+ restrict_offsets.hide = (++restrict_column_offset) * UI_UNIT_X + V2D_SCROLL_WIDTH;
+ }
+ if (soops->show_restrict_flags & SO_RESTRICT_SELECT) {
+ restrict_offsets.select = (++restrict_column_offset) * UI_UNIT_X + V2D_SCROLL_WIDTH;
+ }
+ BLI_assert((restrict_column_offset * UI_UNIT_X + V2D_SCROLL_WIDTH) ==
+ outliner_restrict_columns_width(soops));
+
/* Create buttons. */
uiBut *bt;
@@ -605,27 +935,29 @@ static void outliner_draw_restrictbuts(uiBlock *block,
TreeStoreElem *tselem = TREESTORE(te);
if (te->ys + 2 * UI_UNIT_Y >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) {
if (tselem->type == TSE_R_LAYER && (soops->outlinevis == SO_SCENES)) {
- /* View layer render toggle. */
- ViewLayer *layer = te->directdata;
+ if (soops->show_restrict_flags & SO_RESTRICT_RENDER) {
+ /* View layer render toggle. */
+ ViewLayer *layer = te->directdata;
- bt = uiDefIconButBitS(block,
- UI_BTYPE_ICON_TOGGLE_N,
- VIEW_LAYER_RENDER,
- 0,
- ICON_RESTRICT_RENDER_OFF,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX),
- te->ys,
- UI_UNIT_X,
- UI_UNIT_Y,
- &layer->flag,
- 0,
- 0,
- 0,
- 0,
- TIP_("Use view layer for rendering"));
- UI_but_func_set(bt, restrictbutton_r_lay_cb, tselem->id, NULL);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
- UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE);
+ bt = uiDefIconButBitS(block,
+ UI_BTYPE_ICON_TOGGLE_N,
+ VIEW_LAYER_RENDER,
+ 0,
+ ICON_RESTRICT_RENDER_OFF,
+ (int)(ar->v2d.cur.xmax - restrict_offsets.render),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &layer->flag,
+ 0,
+ 0,
+ 0,
+ 0,
+ TIP_("Use view layer for rendering"));
+ UI_but_func_set(bt, restrictbutton_r_lay_cb, tselem->id, NULL);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE);
+ }
}
else if ((tselem->type == 0 && te->idcode == ID_OB) &&
(te->flag & TE_CHILD_NOT_IN_COLLECTION)) {
@@ -634,40 +966,65 @@ static void outliner_draw_restrictbuts(uiBlock *block,
else if (tselem->type == 0 && te->idcode == ID_OB) {
PointerRNA ptr;
Object *ob = (Object *)tselem->id;
- RNA_pointer_create(&ob->id, &RNA_Object, ob, &ptr);
- Base *base = BKE_view_layer_base_find(view_layer, ob);
-
- if (base) {
- int icon = ICON_RESTRICT_VIEW_ON;
- if ((ob->restrictflag & OB_RESTRICT_VIEW) == 0) {
- icon = (base->flag & BASE_HIDDEN) != 0 ? ICON_HIDE_ON : ICON_HIDE_OFF;
+ RNA_id_pointer_create(&ob->id, &ptr);
+
+ if (soops->show_restrict_flags & SO_RESTRICT_HIDE) {
+ Base *base = (te->directdata) ? (Base *)te->directdata :
+ BKE_view_layer_base_find(view_layer, ob);
+ if (base) {
+ PointerRNA base_ptr;
+ RNA_pointer_create(&ob->id, &RNA_ObjectBase, base, &base_ptr);
+ bt = uiDefIconButR_prop(block,
+ UI_BTYPE_ICON_TOGGLE,
+ 0,
+ 0,
+ (int)(ar->v2d.cur.xmax - restrict_offsets.hide),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &base_ptr,
+ props.base_hide_viewport,
+ -1,
+ 0,
+ 0,
+ 0,
+ 0,
+ TIP_("Temporarly hide in viewport\n"
+ "* Shift to set children"));
+ UI_but_func_set(
+ bt, outliner__base_set_flag_recursive_cb, base, (void *)"hide_viewport");
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
}
- bt = uiDefIconBut(block,
- UI_BTYPE_ICON_TOGGLE,
- 0,
- icon,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX),
- te->ys,
- UI_UNIT_X,
- UI_UNIT_Y,
- NULL,
- 0,
- 0,
- 0,
- 0,
- TIP_("Hide object in viewport\n"
- "* Alt to disable for all viewports\n"
- "* Ctrl to isolate visibility"));
- UI_but_func_set(bt, hidebutton_base_flag_cb, view_layer, base);
- UI_but_func_pushed_state_set(bt, base_pushed_state_cb, base);
+ }
+
+ if (soops->show_restrict_flags & SO_RESTRICT_SELECT) {
+ bt = uiDefIconButR_prop(block,
+ UI_BTYPE_ICON_TOGGLE,
+ 0,
+ 0,
+ (int)(ar->v2d.cur.xmax - restrict_offsets.select),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &ptr,
+ props.object_hide_select,
+ -1,
+ 0,
+ 0,
+ -1,
+ -1,
+ TIP_("Disable selection in viewport\n"
+ "* Shift to set children"));
+ UI_but_func_set(bt, outliner__object_set_flag_recursive_cb, ob, (char *)"hide_select");
UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
}
- else {
+
+ if (soops->show_restrict_flags & SO_RESTRICT_VIEWPORT) {
bt = uiDefIconButR_prop(block,
UI_BTYPE_ICON_TOGGLE,
0,
0,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX),
+ (int)(ar->v2d.cur.xmax - restrict_offsets.viewport),
te->ys,
UI_UNIT_X,
UI_UNIT_Y,
@@ -678,256 +1035,320 @@ static void outliner_draw_restrictbuts(uiBlock *block,
0,
-1,
-1,
+ TIP_("Globally disable in viewports\n"
+ "* Shift to set children"));
+ UI_but_func_set(bt, outliner__object_set_flag_recursive_cb, ob, (void *)"hide_viewport");
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ }
+
+ if (soops->show_restrict_flags & SO_RESTRICT_RENDER) {
+ bt = uiDefIconButR_prop(block,
+ UI_BTYPE_ICON_TOGGLE,
+ 0,
+ 0,
+ (int)(ar->v2d.cur.xmax - restrict_offsets.render),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &ptr,
+ props.object_hide_render,
+ -1,
+ 0,
+ 0,
+ -1,
+ -1,
+ TIP_("Globally disable in renders\n"
+ "* Shift to set children"));
+ UI_but_func_set(bt, outliner__object_set_flag_recursive_cb, ob, (char *)"hide_render");
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ }
+ }
+ else if (tselem->type == TSE_MODIFIER) {
+ ModifierData *md = (ModifierData *)te->directdata;
+
+ PointerRNA ptr;
+ RNA_pointer_create(tselem->id, &RNA_Modifier, md, &ptr);
+
+ if (soops->show_restrict_flags & SO_RESTRICT_VIEWPORT) {
+ bt = uiDefIconButR_prop(block,
+ UI_BTYPE_ICON_TOGGLE,
+ 0,
+ 0,
+ (int)(ar->v2d.cur.xmax - restrict_offsets.viewport),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &ptr,
+ props.modifier_show_viewport,
+ -1,
+ 0,
+ 0,
+ -1,
+ -1,
+ NULL);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ }
+
+ if (soops->show_restrict_flags & SO_RESTRICT_RENDER) {
+ bt = uiDefIconButR_prop(block,
+ UI_BTYPE_ICON_TOGGLE,
+ 0,
+ 0,
+ (int)(ar->v2d.cur.xmax - restrict_offsets.render),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &ptr,
+ props.modifier_show_render,
+ -1,
+ 0,
+ 0,
+ -1,
+ -1,
NULL);
UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
}
+ }
+ else if (tselem->type == TSE_POSE_CHANNEL) {
+ bPoseChannel *pchan = (bPoseChannel *)te->directdata;
+ Bone *bone = pchan->bone;
+ Object *ob = (Object *)tselem->id;
- bt = uiDefIconButR_prop(block,
+ if (soops->show_restrict_flags & SO_RESTRICT_VIEWPORT) {
+ bt = uiDefIconButBitI(block,
UI_BTYPE_ICON_TOGGLE,
+ BONE_HIDDEN_P,
0,
- 0,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX),
+ ICON_HIDE_OFF,
+ (int)(ar->v2d.cur.xmax - restrict_offsets.viewport),
te->ys,
UI_UNIT_X,
UI_UNIT_Y,
- &ptr,
- props.object_hide_select,
- -1,
+ &(bone->flag),
+ 0,
0,
0,
- -1,
- -1,
- NULL);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ 0,
+ TIP_("Restrict visibility in the 3D View"));
+ UI_but_func_set(bt, restrictbutton_bone_visibility_cb, ob->data, bone);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE);
+ }
- bt = uiDefIconButR_prop(block,
+ if (soops->show_restrict_flags & SO_RESTRICT_SELECT) {
+ bt = uiDefIconButBitI(block,
UI_BTYPE_ICON_TOGGLE,
+ BONE_UNSELECTABLE,
0,
- 0,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX),
+ ICON_RESTRICT_SELECT_OFF,
+ (int)(ar->v2d.cur.xmax - restrict_offsets.select),
te->ys,
UI_UNIT_X,
UI_UNIT_Y,
- &ptr,
- props.object_hide_render,
- -1,
+ &(bone->flag),
+ 0,
0,
0,
- -1,
- -1,
- NULL);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ 0,
+ TIP_("Restrict selection in the 3D View"));
+ UI_but_func_set(bt, restrictbutton_bone_select_cb, ob->data, bone);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE);
+ }
}
- else if (tselem->type == TSE_MODIFIER) {
- ModifierData *md = (ModifierData *)te->directdata;
-
- PointerRNA ptr;
- RNA_pointer_create(tselem->id, &RNA_Modifier, md, &ptr);
+ else if (tselem->type == TSE_EBONE) {
+ EditBone *ebone = (EditBone *)te->directdata;
- bt = uiDefIconButR_prop(block,
+ if (soops->show_restrict_flags & SO_RESTRICT_VIEWPORT) {
+ bt = uiDefIconButBitI(block,
UI_BTYPE_ICON_TOGGLE,
+ BONE_HIDDEN_A,
0,
- 0,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX),
+ ICON_RESTRICT_VIEW_OFF,
+ (int)(ar->v2d.cur.xmax - restrict_offsets.viewport),
te->ys,
UI_UNIT_X,
UI_UNIT_Y,
- &ptr,
- props.modifier_show_viewport,
- -1,
+ &(ebone->flag),
+ 0,
0,
0,
- -1,
- -1,
- NULL);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ 0,
+ TIP_("Restrict visibility in the 3D View"));
+ UI_but_func_set(bt, restrictbutton_ebone_visibility_cb, NULL, ebone);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE);
+ }
- bt = uiDefIconButR_prop(block,
+ if (soops->show_restrict_flags & SO_RESTRICT_SELECT) {
+ bt = uiDefIconButBitI(block,
UI_BTYPE_ICON_TOGGLE,
+ BONE_UNSELECTABLE,
0,
- 0,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX),
+ ICON_RESTRICT_SELECT_OFF,
+ (int)(ar->v2d.cur.xmax - restrict_offsets.select),
te->ys,
UI_UNIT_X,
UI_UNIT_Y,
- &ptr,
- props.modifier_show_render,
- -1,
+ &(ebone->flag),
0,
0,
- -1,
- -1,
- NULL);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
- }
- else if (tselem->type == TSE_POSE_CHANNEL) {
- bPoseChannel *pchan = (bPoseChannel *)te->directdata;
- Bone *bone = pchan->bone;
- Object *ob = (Object *)tselem->id;
-
- bt = uiDefIconButBitI(block,
- UI_BTYPE_ICON_TOGGLE,
- BONE_HIDDEN_P,
- 0,
- ICON_HIDE_OFF,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX),
- te->ys,
- UI_UNIT_X,
- UI_UNIT_Y,
- &(bone->flag),
- 0,
- 0,
- 0,
- 0,
- TIP_("Restrict/Allow visibility in the 3D View"));
- UI_but_func_set(bt, restrictbutton_bone_visibility_cb, ob->data, bone);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
- UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE);
-
- bt = uiDefIconButBitI(block,
- UI_BTYPE_ICON_TOGGLE,
- BONE_UNSELECTABLE,
- 0,
- ICON_RESTRICT_SELECT_OFF,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX),
- te->ys,
- UI_UNIT_X,
- UI_UNIT_Y,
- &(bone->flag),
- 0,
- 0,
- 0,
- 0,
- TIP_("Restrict/Allow selection in the 3D View"));
- UI_but_func_set(bt, restrictbutton_bone_select_cb, ob->data, bone);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
- UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE);
- }
- else if (tselem->type == TSE_EBONE) {
- EditBone *ebone = (EditBone *)te->directdata;
-
- bt = uiDefIconButBitI(block,
- UI_BTYPE_ICON_TOGGLE,
- BONE_HIDDEN_A,
- 0,
- ICON_RESTRICT_VIEW_OFF,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX),
- te->ys,
- UI_UNIT_X,
- UI_UNIT_Y,
- &(ebone->flag),
- 0,
- 0,
- 0,
- 0,
- TIP_("Restrict/Allow visibility in the 3D View"));
- UI_but_func_set(bt, restrictbutton_ebone_visibility_cb, NULL, ebone);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
- UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE);
-
- bt = uiDefIconButBitI(block,
- UI_BTYPE_ICON_TOGGLE,
- BONE_UNSELECTABLE,
- 0,
- ICON_RESTRICT_SELECT_OFF,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX),
- te->ys,
- UI_UNIT_X,
- UI_UNIT_Y,
- &(ebone->flag),
- 0,
- 0,
- 0,
- 0,
- TIP_("Restrict/Allow selection in the 3D View"));
- UI_but_func_set(bt, restrictbutton_ebone_select_cb, NULL, ebone);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
- UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE);
+ 0,
+ 0,
+ TIP_("Restrict selection in the 3D View"));
+ UI_but_func_set(bt, restrictbutton_ebone_select_cb, NULL, ebone);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE);
+ }
}
else if (tselem->type == TSE_GP_LAYER) {
ID *id = tselem->id;
bGPDlayer *gpl = (bGPDlayer *)te->directdata;
- bt = uiDefIconButBitS(block,
- UI_BTYPE_ICON_TOGGLE,
- GP_LAYER_HIDE,
- 0,
- ICON_HIDE_OFF,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX),
- te->ys,
- UI_UNIT_X,
- UI_UNIT_Y,
- &gpl->flag,
- 0,
- 0,
- 0,
- 0,
- TIP_("Restrict/Allow visibility in the 3D View"));
- UI_but_func_set(bt, restrictbutton_gp_layer_flag_cb, id, gpl);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
- UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE);
-
- bt = uiDefIconButBitS(
- block,
- UI_BTYPE_ICON_TOGGLE,
- GP_LAYER_LOCKED,
- 0,
- ICON_UNLOCKED,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX),
- te->ys,
- UI_UNIT_X,
- UI_UNIT_Y,
- &gpl->flag,
- 0,
- 0,
- 0,
- 0,
- TIP_("Restrict/Allow editing of strokes and keyframes in this layer"));
- UI_but_func_set(bt, restrictbutton_gp_layer_flag_cb, id, gpl);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ if (soops->show_restrict_flags & SO_RESTRICT_VIEWPORT) {
+ bt = uiDefIconButBitS(block,
+ UI_BTYPE_ICON_TOGGLE,
+ GP_LAYER_HIDE,
+ 0,
+ ICON_HIDE_OFF,
+ (int)(ar->v2d.cur.xmax - restrict_offsets.viewport),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &gpl->flag,
+ 0,
+ 0,
+ 0,
+ 0,
+ TIP_("Restrict visibility in the 3D View"));
+ UI_but_func_set(bt, restrictbutton_gp_layer_flag_cb, id, gpl);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE);
+ }
+
+ if (soops->show_restrict_flags & SO_RESTRICT_SELECT) {
+ bt = uiDefIconButBitS(block,
+ UI_BTYPE_ICON_TOGGLE,
+ GP_LAYER_LOCKED,
+ 0,
+ ICON_UNLOCKED,
+ (int)(ar->v2d.cur.xmax - restrict_offsets.select),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &gpl->flag,
+ 0,
+ 0,
+ 0,
+ 0,
+ TIP_("Restrict editing of strokes and keyframes in this layer"));
+ UI_but_func_set(bt, restrictbutton_gp_layer_flag_cb, id, gpl);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ }
}
else if (outliner_is_collection_tree_element(te)) {
- LayerCollection *lc = (tselem->type == TSE_LAYER_COLLECTION) ? te->directdata : NULL;
+ LayerCollection *layer_collection = (tselem->type == TSE_LAYER_COLLECTION) ?
+ te->directdata :
+ NULL;
Collection *collection = outliner_collection_from_tree_element(te);
- if ((!lc || !(lc->flag & LAYER_COLLECTION_EXCLUDE)) &&
+ if ((!layer_collection || !(layer_collection->flag & LAYER_COLLECTION_EXCLUDE)) &&
!(collection->flag & COLLECTION_IS_MASTER)) {
PointerRNA collection_ptr;
RNA_id_pointer_create(&collection->id, &collection_ptr);
- if (lc != NULL) {
- int icon = ICON_RESTRICT_VIEW_ON;
- if ((collection->flag & COLLECTION_RESTRICT_VIEW) == 0) {
- icon = (lc->flag & LAYER_COLLECTION_RESTRICT_VIEW) != 0 ? ICON_HIDE_ON :
- ICON_HIDE_OFF;
+ if (layer_collection != NULL) {
+ PointerRNA layer_collection_ptr;
+ RNA_pointer_create(
+ &scene->id, &RNA_LayerCollection, layer_collection, &layer_collection_ptr);
+
+ if (soops->show_restrict_flags & SO_RESTRICT_HIDE) {
+ bt = uiDefIconButR_prop(block,
+ UI_BTYPE_ICON_TOGGLE,
+ 0,
+ 0,
+ (int)(ar->v2d.cur.xmax - restrict_offsets.hide),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &layer_collection_ptr,
+ props.layer_collection_hide_viewport,
+ -1,
+ 0,
+ 0,
+ 0,
+ 0,
+ TIP_("Temporarily hide in viewport\n"
+ "* Ctrl to isolate collection\n"
+ "* Shift to set inside collections and objects"));
+ UI_but_func_set(bt,
+ view_layer__layer_collection_set_flag_recursive_cb,
+ layer_collection,
+ (char *)"hide_viewport");
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ }
+
+ if (soops->show_restrict_flags & SO_RESTRICT_HOLDOUT) {
+ bt = uiDefIconButR_prop(block,
+ UI_BTYPE_ICON_TOGGLE,
+ 0,
+ 0,
+ (int)(ar->v2d.cur.xmax - restrict_offsets.holdout),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &layer_collection_ptr,
+ props.layer_collection_holdout,
+ -1,
+ 0,
+ 0,
+ 0,
+ 0,
+ TIP_("Mask out objects in collection from view layer\n"
+ "* Ctrl to isolate collection\n"
+ "* Shift to set inside collections"));
+ UI_but_func_set(bt,
+ view_layer__layer_collection_set_flag_recursive_cb,
+ layer_collection,
+ (char *)"holdout");
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ }
+
+ if (soops->show_restrict_flags & SO_RESTRICT_INDIRECT_ONLY) {
+ bt = uiDefIconButR_prop(
+ block,
+ UI_BTYPE_ICON_TOGGLE,
+ 0,
+ (layer_collection->flag & LAYER_COLLECTION_INDIRECT_ONLY) != 0 ? 0 : ICON_REMOVE,
+ (int)(ar->v2d.cur.xmax - restrict_offsets.indirect_only),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &layer_collection_ptr,
+ props.layer_collection_indirect_only,
+ -1,
+ 0,
+ 0,
+ 0,
+ 0,
+ TIP_("Objects in collection only contribute indirectly (through shadows and "
+ "reflections) in the view layer\n"
+ "* Ctrl to isolate collection\n"
+ "* Shift to set inside collections"));
+ UI_but_func_set(bt,
+ view_layer__layer_collection_set_flag_recursive_cb,
+ layer_collection,
+ (char *)"indirect_only");
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
}
- bt = uiDefIconBut(block,
- UI_BTYPE_ICON_TOGGLE,
- 0,
- icon,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX),
- te->ys,
- UI_UNIT_X,
- UI_UNIT_Y,
- NULL,
- 0,
- 0,
- 0,
- 0,
- TIP_("Hide collection in viewport\n"
- "* Alt to disable for all viewports\n"
- "* Ctrl to isolate visibility\n"
- "* Shift to hide inside objects and collections"));
- UI_but_func_set(bt, hidebutton_layer_collection_flag_cb, view_layer, lc);
- UI_but_func_pushed_state_set(bt, layer_collection_pushed_state_cb, lc);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
}
- else {
+
+ if (soops->show_restrict_flags & SO_RESTRICT_VIEWPORT) {
bt = uiDefIconButR_prop(block,
UI_BTYPE_ICON_TOGGLE,
0,
0,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX),
+ (int)(ar->v2d.cur.xmax - restrict_offsets.viewport),
te->ys,
UI_UNIT_X,
UI_UNIT_Y,
@@ -938,45 +1359,87 @@ static void outliner_draw_restrictbuts(uiBlock *block,
0,
0,
0,
- NULL);
+ TIP_("Globally disable in viewports\n"
+ "* Ctrl to isolate collection\n"
+ "* Shift to set inside collections and objects"));
+ if (layer_collection != NULL) {
+ UI_but_func_set(bt,
+ view_layer__collection_set_flag_recursive_cb,
+ layer_collection,
+ (char *)"hide_viewport");
+ }
+ else {
+ UI_but_func_set(bt,
+ scenes__collection_set_flag_recursive_cb,
+ collection,
+ (char *)"hide_viewport");
+ }
UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
}
- bt = uiDefIconButR_prop(block,
- UI_BTYPE_ICON_TOGGLE,
- 0,
- 0,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX),
- te->ys,
- UI_UNIT_X,
- UI_UNIT_Y,
- &collection_ptr,
- props.collection_hide_render,
- -1,
- 0,
- 0,
- 0,
- 0,
- NULL);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ if (soops->show_restrict_flags & SO_RESTRICT_RENDER) {
+ bt = uiDefIconButR_prop(block,
+ UI_BTYPE_ICON_TOGGLE,
+ 0,
+ 0,
+ (int)(ar->v2d.cur.xmax - restrict_offsets.render),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &collection_ptr,
+ props.collection_hide_render,
+ -1,
+ 0,
+ 0,
+ 0,
+ 0,
+ TIP_("Globally disable in renders\n"
+ "* Ctrl to isolate collection\n"
+ "* Shift to set inside collections and objects"));
+ if (layer_collection != NULL) {
+ UI_but_func_set(bt,
+ view_layer__collection_set_flag_recursive_cb,
+ layer_collection,
+ (char *)"hide_render");
+ }
+ else {
+ UI_but_func_set(
+ bt, scenes__collection_set_flag_recursive_cb, collection, (char *)"hide_render");
+ }
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ }
- bt = uiDefIconButR_prop(block,
- UI_BTYPE_ICON_TOGGLE,
- 0,
- 0,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX),
- te->ys,
- UI_UNIT_X,
- UI_UNIT_Y,
- &collection_ptr,
- props.collection_hide_select,
- -1,
- 0,
- 0,
- 0,
- 0,
- NULL);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ if (soops->show_restrict_flags & SO_RESTRICT_SELECT) {
+ bt = uiDefIconButR_prop(block,
+ UI_BTYPE_ICON_TOGGLE,
+ 0,
+ 0,
+ (int)(ar->v2d.cur.xmax - restrict_offsets.select),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &collection_ptr,
+ props.collection_hide_select,
+ -1,
+ 0,
+ 0,
+ 0,
+ 0,
+ TIP_("Disable selection in viewport\n"
+ "* Ctrl to isolate collection\n"
+ "* Shift to set inside collections and objects"));
+ if (layer_collection != NULL) {
+ UI_but_func_set(bt,
+ view_layer__collection_set_flag_recursive_cb,
+ layer_collection,
+ (char *)"hide_select");
+ }
+ else {
+ UI_but_func_set(
+ bt, scenes__collection_set_flag_recursive_cb, collection, (char *)"hide_select");
+ }
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ }
}
}
}
@@ -1005,6 +1468,23 @@ static void outliner_draw_userbuts(uiBlock *block, ARegion *ar, SpaceOutliner *s
but_flag |= UI_BUT_DISABLED;
}
+ BLI_str_format_int_grouped(buf, id->us);
+ bt = uiDefBut(block,
+ UI_BTYPE_BUT,
+ 1,
+ buf,
+ (int)(ar->v2d.cur.xmax - OL_TOG_USER_BUTS_USERS),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0,
+ 0,
+ TIP_("Number of users of this data-block"));
+ UI_but_flag_enable(bt, but_flag);
+
if (id->flag & LIB_FAKEUSER) {
icon = ICON_FILE_TICK;
tip = TIP_("Data-block will be retained using a fake user");
@@ -1018,7 +1498,7 @@ static void outliner_draw_userbuts(uiBlock *block, ARegion *ar, SpaceOutliner *s
LIB_FAKEUSER,
1,
icon,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX),
+ (int)(ar->v2d.cur.xmax - OL_TOG_USER_BUTS_STATUS),
te->ys,
UI_UNIT_X,
UI_UNIT_Y,
@@ -1031,29 +1511,12 @@ static void outliner_draw_userbuts(uiBlock *block, ARegion *ar, SpaceOutliner *s
UI_but_func_set(bt, restrictbutton_id_user_toggle, id, NULL);
UI_but_flag_enable(bt, but_flag);
- BLI_str_format_int_grouped(buf, id->us);
- bt = uiDefBut(block,
- UI_BTYPE_BUT,
- 1,
- buf,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX),
- te->ys,
- UI_UNIT_X,
- UI_UNIT_Y,
- NULL,
- 0.0,
- 0.0,
- 0,
- 0,
- TIP_("Number of users of this data-block"));
- UI_but_flag_enable(bt, but_flag);
-
bt = uiDefButBitS(block,
UI_BTYPE_ICON_TOGGLE,
LIB_FAKEUSER,
1,
(id->flag & LIB_FAKEUSER) ? "F" : " ",
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX),
+ (int)(ar->v2d.cur.xmax - OL_TOG_USER_BUTS_FAKEUSER),
te->ys,
UI_UNIT_X,
UI_UNIT_Y,
@@ -1179,8 +1642,13 @@ static void outliner_draw_rnabuts(
}
}
-static void outliner_buttons(const bContext *C, uiBlock *block, ARegion *ar, TreeElement *te)
+static void outliner_buttons(const bContext *C,
+ uiBlock *block,
+ ARegion *ar,
+ const float restrict_column_width,
+ TreeElement *te)
{
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
uiBut *bt;
TreeStoreElem *tselem;
int spx, dx, len;
@@ -1206,7 +1674,11 @@ static void outliner_buttons(const bContext *C, uiBlock *block, ARegion *ar, Tre
}
spx = te->xs + 1.8f * UI_UNIT_X;
- dx = ar->v2d.cur.xmax - (spx + 3.2f * UI_UNIT_X);
+ if ((tselem->type == TSE_LAYER_COLLECTION) &&
+ (soops->show_restrict_flags & SO_RESTRICT_ENABLE)) {
+ spx += UI_UNIT_X;
+ }
+ dx = ar->v2d.cur.xmax - (spx + restrict_column_width + 0.2f * UI_UNIT_X);
bt = uiDefBut(block,
UI_BTYPE_TEXT,
@@ -1778,6 +2250,60 @@ TreeElementIcon tree_element_get_icon(TreeStoreElem *tselem, TreeElement *te)
return data;
}
+static void tselem_draw_layer_collection_enable_icon(
+ Scene *scene, uiBlock *block, int xmax, float x, float y, TreeElement *te, float alpha)
+{
+ /* Get RNA property (once for speed). */
+ static PropertyRNA *exclude_prop = NULL;
+ if (exclude_prop == NULL) {
+ exclude_prop = RNA_struct_type_find_property(&RNA_LayerCollection, "exclude");
+ }
+
+ if (x >= xmax) {
+ /* Placement of icons, copied from interface_widgets.c. */
+ float aspect = (0.8f * UI_UNIT_Y) / ICON_DEFAULT_HEIGHT;
+ x += 2.0f * aspect;
+ y += 2.0f * aspect;
+
+ /* restrict column clip... it has been coded by simply overdrawing,
+ * doesn't work for buttons */
+ char color[4];
+ int icon = RNA_property_ui_icon(exclude_prop);
+ if (UI_icon_get_theme_color(icon, (uchar *)color)) {
+ UI_icon_draw_ex(x, y, icon, U.inv_dpi_fac, alpha, 0.0f, color, true);
+ }
+ else {
+ UI_icon_draw_ex(x, y, icon, U.inv_dpi_fac, alpha, 0.0f, NULL, false);
+ }
+ }
+ else {
+ LayerCollection *layer_collection = te->directdata;
+ PointerRNA layer_collection_ptr;
+ RNA_pointer_create(&scene->id, &RNA_LayerCollection, layer_collection, &layer_collection_ptr);
+
+ char emboss = UI_block_emboss_get(block);
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
+ uiBut *bt = uiDefIconButR_prop(block,
+ UI_BTYPE_ICON_TOGGLE,
+ 0,
+ 0,
+ x,
+ y,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &layer_collection_ptr,
+ exclude_prop,
+ -1,
+ 0,
+ 0,
+ 0,
+ 0,
+ NULL);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ UI_block_emboss_set(block, emboss);
+ }
+}
+
static void tselem_draw_icon(uiBlock *block,
int xmax,
float x,
@@ -1801,7 +2327,13 @@ static void tselem_draw_icon(uiBlock *block,
/* restrict column clip... it has been coded by simply overdrawing,
* doesn't work for buttons */
- UI_icon_draw_alpha(x, y, data.icon, alpha);
+ char color[4];
+ if (UI_icon_get_theme_color(data.icon, (uchar *)color)) {
+ UI_icon_draw_ex(x, y, data.icon, U.inv_dpi_fac, alpha, 0.0f, color, true);
+ }
+ else {
+ UI_icon_draw_ex(x, y, data.icon, U.inv_dpi_fac, alpha, 0.0f, NULL, false);
+ }
}
else {
uiDefIconBut(block,
@@ -2068,6 +2600,7 @@ static void outliner_draw_tree_element(bContext *C,
bool draw_grayed_out,
int startx,
int *starty,
+ const float restrict_column_width,
TreeElement **te_edit)
{
TreeStoreElem *tselem;
@@ -2090,8 +2623,8 @@ static void outliner_draw_tree_element(bContext *C,
}
/* icons can be ui buts, we don't want it to overlap with restrict */
- if ((soops->flag & SO_HIDE_RESTRICTCOLS) == 0) {
- xmax -= OL_TOGW + UI_UNIT_X;
+ if (restrict_column_width > 0) {
+ xmax -= restrict_column_width + UI_UNIT_X;
}
GPU_blend(true);
@@ -2150,13 +2683,21 @@ static void outliner_draw_tree_element(bContext *C,
rgba_float_args_set(color, 0.85f, 0.85f, 1.0f, alpha);
}
+ /* Checkbox to enable collections. */
+ if ((tselem->type == TSE_LAYER_COLLECTION) &&
+ (soops->show_restrict_flags & SO_RESTRICT_ENABLE)) {
+ tselem_draw_layer_collection_enable_icon(
+ scene, block, xmax, (float)startx + offsx + UI_UNIT_X, (float)*starty, te, 0.8f);
+ offsx += UI_UNIT_X;
+ }
+
/* active circle */
if (active != OL_DRAWSEL_NONE) {
UI_draw_roundbox_corner_set(UI_CNR_ALL);
UI_draw_roundbox_aa(true,
- (float)startx + UI_UNIT_X + 1.0f * ufac,
+ (float)startx + offsx + UI_UNIT_X + 1.0f * ufac,
(float)*starty + 1.0f * ufac,
- (float)startx + 2.0f * UI_UNIT_X - 1.0f * ufac,
+ (float)startx + offsx + 2.0f * UI_UNIT_X - 1.0f * ufac,
(float)*starty + UI_UNIT_Y - 1.0f * ufac,
UI_UNIT_Y / 2.0f - 1.0f * ufac,
color);
@@ -2190,7 +2731,6 @@ static void outliner_draw_tree_element(bContext *C,
offsx += UI_UNIT_X;
/* datatype icon */
-
if (!(ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM, TSE_ID_BASE))) {
tselem_draw_icon(
block, xmax, (float)startx + offsx, (float)*starty, tselem, te, alpha_fac, true);
@@ -2306,6 +2846,7 @@ static void outliner_draw_tree_element(bContext *C,
draw_childs_grayed_out,
startx + UI_UNIT_X,
starty,
+ restrict_column_width,
te_edit);
}
}
@@ -2585,7 +3126,7 @@ static void outliner_draw_tree(bContext *C,
ViewLayer *view_layer,
ARegion *ar,
SpaceOutliner *soops,
- const bool has_restrict_icons,
+ const float restrict_column_width,
TreeElement **te_edit)
{
const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
@@ -2607,8 +3148,8 @@ static void outliner_draw_tree(bContext *C,
/* set scissor so tree elements or lines can't overlap restriction icons */
float scissor[4] = {0};
- if (has_restrict_icons) {
- int mask_x = BLI_rcti_size_x(&ar->v2d.mask) - (int)OL_TOGW + 1;
+ if (restrict_column_width > 0.0f) {
+ int mask_x = BLI_rcti_size_x(&ar->v2d.mask) - (int)restrict_column_width + 1;
CLAMP_MIN(mask_x, 0);
GPU_scissor_get_f(scissor);
@@ -2636,10 +3177,11 @@ static void outliner_draw_tree(bContext *C,
(te->flag & TE_DRAGGING) != 0,
startx,
&starty,
+ restrict_column_width,
te_edit);
}
- if (has_restrict_icons) {
+ if (restrict_column_width > 0.0f) {
/* reset scissor */
GPU_scissor(UNPACK4(scissor));
}
@@ -2694,7 +3236,6 @@ void draw_outliner(const bContext *C)
uiBlock *block;
int sizey = 0, sizex = 0, sizex_rna = 0;
TreeElement *te_edit = NULL;
- bool has_restrict_icons;
outliner_build_tree(mainvar, scene, view_layer, soops, ar); // always
@@ -2704,6 +3245,7 @@ void draw_outliner(const bContext *C)
/* extend size to allow for horizontal scrollbar */
sizey += V2D_SCROLL_HEIGHT;
+ const float restrict_column_width = outliner_restrict_columns_width(soops);
if (soops->outlinevis == SO_DATA_API) {
/* RNA has two columns:
* - column 1 is (max_width + OL_RNA_COL_SPACEX) or
@@ -2719,7 +3261,6 @@ void draw_outliner(const bContext *C)
/* get width of data (for setting 'tot' rect, this is column 1 + column 2 + a bit extra) */
sizex = sizex_rna + OL_RNA_COL_SIZEX + 50;
- has_restrict_icons = false;
}
else {
/* width must take into account restriction columns (if visible)
@@ -2728,13 +3269,8 @@ void draw_outliner(const bContext *C)
// XXX should use outliner_width instead when te->xend will be set correctly...
outliner_rna_width(soops, &soops->tree, &sizex, 0);
- /* constant offset for restriction columns */
- // XXX this isn't that great yet...
- if ((soops->flag & SO_HIDE_RESTRICTCOLS) == 0) {
- sizex += OL_TOGW * 3;
- }
-
- has_restrict_icons = !(soops->flag & SO_HIDE_RESTRICTCOLS);
+ /* Constant offset for restriction columns */
+ sizex += restrict_column_width;
}
/* adds vertical offset */
@@ -2752,7 +3288,7 @@ void draw_outliner(const bContext *C)
outliner_back(ar);
block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
outliner_draw_tree(
- (bContext *)C, block, scene, view_layer, ar, soops, has_restrict_icons, &te_edit);
+ (bContext *)C, block, scene, view_layer, ar, soops, restrict_column_width, &te_edit);
/* Default to no emboss for outliner UI. */
UI_block_emboss_set(block, UI_EMBOSS_NONE);
@@ -2765,20 +3301,20 @@ void draw_outliner(const bContext *C)
outliner_draw_rnabuts(block, ar, soops, sizex_rna, &soops->tree);
UI_block_emboss_set(block, UI_EMBOSS_NONE);
}
- else if ((soops->outlinevis == SO_ID_ORPHANS) && has_restrict_icons) {
+ else if (soops->outlinevis == SO_ID_ORPHANS) {
/* draw user toggle columns */
outliner_draw_userbuts(block, ar, soops, &soops->tree);
}
- else if (has_restrict_icons) {
+ else if (restrict_column_width > 0.0f) {
/* draw restriction columns */
outliner_draw_restrictbuts(block, scene, view_layer, ar, soops, &soops->tree);
}
UI_block_emboss_set(block, UI_EMBOSS);
- /* draw edit buttons if nessecery */
+ /* Draw edit buttons if necessary. */
if (te_edit) {
- outliner_buttons(C, block, ar, te_edit);
+ outliner_buttons(C, block, ar, restrict_column_width, te_edit);
}
UI_block_end(C, block);
diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c
index a943e972cf5..90180c4ea47 100644
--- a/source/blender/editors/space_outliner/outliner_edit.c
+++ b/source/blender/editors/space_outliner/outliner_edit.c
@@ -1025,8 +1025,8 @@ int common_restrict_check(bContext *C, Object *ob)
Object *obedit = CTX_data_edit_object(C);
if (obedit && obedit == ob) {
/* found object is hidden, reset */
- if (ob->restrictflag & OB_RESTRICT_VIEW) {
- ob->restrictflag &= ~OB_RESTRICT_VIEW;
+ if (ob->restrictflag & OB_RESTRICT_VIEWPORT) {
+ ob->restrictflag &= ~OB_RESTRICT_VIEWPORT;
}
/* found object is unselectable, reset */
if (ob->restrictflag & OB_RESTRICT_SELECT) {
diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h
index 8211e3005c7..15489c61230 100644
--- a/source/blender/editors/space_outliner/outliner_intern.h
+++ b/source/blender/editors/space_outliner/outliner_intern.h
@@ -156,11 +156,9 @@ typedef enum {
/* size constants */
#define OL_Y_OFFSET 2
-#define OL_TOG_RESTRICT_SELECTX (UI_UNIT_X * 3.0f + V2D_SCROLL_WIDTH)
-#define OL_TOG_RESTRICT_VIEWX (UI_UNIT_X * 2.0f + V2D_SCROLL_WIDTH)
-#define OL_TOG_RESTRICT_RENDERX (UI_UNIT_X + V2D_SCROLL_WIDTH)
-
-#define OL_TOGW OL_TOG_RESTRICT_SELECTX
+#define OL_TOG_USER_BUTS_USERS (UI_UNIT_X * 2.0f + V2D_SCROLL_WIDTH)
+#define OL_TOG_USER_BUTS_STATUS (UI_UNIT_X * 3.0f + V2D_SCROLL_WIDTH)
+#define OL_TOG_USER_BUTS_FAKEUSER (UI_UNIT_X + V2D_SCROLL_WIDTH)
#define OL_RNA_COLX (UI_UNIT_X * 15)
#define OL_RNA_COL_SIZEX (UI_UNIT_X * 7.5f)
@@ -449,5 +447,6 @@ bool outliner_tree_traverse(const SpaceOutliner *soops,
int filter_tselem_flag,
TreeTraversalFunc func,
void *customdata);
+float outliner_restrict_columns_width(const struct SpaceOutliner *soops);
#endif /* __OUTLINER_INTERN_H__ */
diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c
index 995f41382cd..c6fcf1d8cf7 100644
--- a/source/blender/editors/space_outliner/outliner_select.c
+++ b/source/blender/editors/space_outliner/outliner_select.c
@@ -1271,8 +1271,7 @@ static bool outliner_is_co_within_restrict_columns(const SpaceOutliner *soops,
const ARegion *ar,
float view_co_x)
{
- return ((soops->outlinevis != SO_DATA_API) && !(soops->flag & SO_HIDE_RESTRICTCOLS) &&
- (view_co_x > ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX));
+ return (view_co_x > ar->v2d.cur.xmax - outliner_restrict_columns_width(soops));
}
/**
diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c
index 4e3fd6037bb..80424f021e2 100644
--- a/source/blender/editors/space_outliner/outliner_tree.c
+++ b/source/blender/editors/space_outliner/outliner_tree.c
@@ -302,6 +302,9 @@ static void outliner_add_scene_contents(SpaceOutliner *soops,
tenlay->directdata = view_layer;
}
+ /* World */
+ outliner_add_element(soops, lb, sce->world, te, 0, 0);
+
/* Collections */
ten = outliner_add_element(soops, lb, &sce->id, te, TSE_SCENE_COLLECTION_BASE, 0);
ten->name = IFACE_("Scene Collection");
@@ -1370,6 +1373,12 @@ static void outliner_add_layer_collections_recursive(SpaceOutliner *soops,
const bool show_objects)
{
for (LayerCollection *lc = layer_collections->first; lc; lc = lc->next) {
+ const bool exclude = (lc->flag & LAYER_COLLECTION_EXCLUDE) != 0;
+
+ if (exclude && ((soops->show_restrict_flags & SO_RESTRICT_ENABLE) == 0)) {
+ continue;
+ }
+
ID *id = &lc->collection->id;
TreeElement *ten = outliner_add_element(soops, tree, id, parent_ten, TSE_LAYER_COLLECTION, 0);
@@ -1382,8 +1391,7 @@ static void outliner_add_layer_collections_recursive(SpaceOutliner *soops,
tselem->flag &= ~TSE_CLOSED;
}
- const bool exclude = (lc->flag & LAYER_COLLECTION_EXCLUDE) != 0;
- if (exclude || ((lc->runtime_flag & LAYER_COLLECTION_VISIBLE) == 0)) {
+ if (exclude || (lc->runtime_flag & LAYER_COLLECTION_VISIBLE) == 0) {
ten->flag |= TE_DISABLED;
}
diff --git a/source/blender/editors/space_outliner/outliner_utils.c b/source/blender/editors/space_outliner/outliner_utils.c
index 03d15088380..f57dce97b38 100644
--- a/source/blender/editors/space_outliner/outliner_utils.c
+++ b/source/blender/editors/space_outliner/outliner_utils.c
@@ -31,6 +31,7 @@
#include "ED_armature.h"
#include "UI_interface.h"
+#include "UI_view2d.h"
#include "outliner_intern.h"
@@ -261,3 +262,41 @@ bool outliner_tree_traverse(const SpaceOutliner *soops,
return true;
}
+
+float outliner_restrict_columns_width(const SpaceOutliner *soops)
+{
+ int num_columns = 0;
+
+ switch (soops->outlinevis) {
+ case SO_DATA_API:
+ case SO_SEQUENCE:
+ case SO_LIBRARIES:
+ return 0.0f;
+ case SO_ID_ORPHANS:
+ num_columns = 3;
+ break;
+ case SO_VIEW_LAYER:
+ if (soops->show_restrict_flags & SO_RESTRICT_HOLDOUT) {
+ num_columns++;
+ }
+ if (soops->show_restrict_flags & SO_RESTRICT_INDIRECT_ONLY) {
+ num_columns++;
+ }
+ ATTR_FALLTHROUGH;
+ case SO_SCENES:
+ if (soops->show_restrict_flags & SO_RESTRICT_SELECT) {
+ num_columns++;
+ }
+ if (soops->show_restrict_flags & SO_RESTRICT_HIDE) {
+ num_columns++;
+ }
+ if (soops->show_restrict_flags & SO_RESTRICT_VIEWPORT) {
+ num_columns++;
+ }
+ if (soops->show_restrict_flags & SO_RESTRICT_RENDER) {
+ num_columns++;
+ }
+ break;
+ }
+ return (num_columns * UI_UNIT_X + V2D_SCROLL_WIDTH);
+}
diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c
index a8e3129b5b4..6634edfebee 100644
--- a/source/blender/editors/space_outliner/space_outliner.c
+++ b/source/blender/editors/space_outliner/space_outliner.c
@@ -302,6 +302,7 @@ static SpaceLink *outliner_new(const ScrArea *UNUSED(area), const Scene *UNUSED(
soutliner = MEM_callocN(sizeof(SpaceOutliner), "initoutliner");
soutliner->spacetype = SPACE_OUTLINER;
soutliner->filter_id_type = ID_GR;
+ soutliner->show_restrict_flags = SO_RESTRICT_ENABLE | SO_RESTRICT_SELECT | SO_RESTRICT_HIDE;
/* header */
ar = MEM_callocN(sizeof(ARegion), "header for outliner");
diff --git a/source/blender/editors/space_sequencer/CMakeLists.txt b/source/blender/editors/space_sequencer/CMakeLists.txt
index d57be0c85c3..4668a9cef90 100644
--- a/source/blender/editors/space_sequencer/CMakeLists.txt
+++ b/source/blender/editors/space_sequencer/CMakeLists.txt
@@ -21,7 +21,6 @@ set(INC
../../blenlib
../../blentranslation
../../gpu
- ../../depsgraph
../../imbuf
../../makesdna
../../makesrna
diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c
index 1cad9e4f734..b5bb79fb430 100644
--- a/source/blender/editors/space_sequencer/sequencer_add.c
+++ b/source/blender/editors/space_sequencer/sequencer_add.c
@@ -64,8 +64,6 @@
# include <AUD_Sequence.h>
#endif
-#include "DEG_depsgraph.h"
-
/* own include */
#include "sequencer_intern.h"
@@ -357,7 +355,6 @@ static int sequencer_add_scene_strip_exec(bContext *C, wmOperator *op)
sequencer_add_apply_replace_sel(C, op, seq);
sequencer_add_apply_overlap(C, op, seq);
- DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
return OPERATOR_FINISHED;
@@ -444,7 +441,6 @@ static int sequencer_add_movieclip_strip_exec(bContext *C, wmOperator *op)
sequencer_add_apply_replace_sel(C, op, seq);
sequencer_add_apply_overlap(C, op, seq);
- DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
return OPERATOR_FINISHED;
@@ -531,7 +527,6 @@ static int sequencer_add_mask_strip_exec(bContext *C, wmOperator *op)
sequencer_add_apply_replace_sel(C, op, seq);
sequencer_add_apply_overlap(C, op, seq);
- DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
return OPERATOR_FINISHED;
@@ -646,7 +641,6 @@ static int sequencer_add_generic_strip_exec(bContext *C, wmOperator *op, SeqLoad
BKE_sequencer_sort(scene);
BKE_sequencer_update_muting(ed);
- DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
return OPERATOR_FINISHED;
@@ -974,7 +968,6 @@ static int sequencer_add_image_strip_exec(bContext *C, wmOperator *op)
MEM_freeN(op->customdata);
}
- DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
return OPERATOR_FINISHED;
@@ -1130,7 +1123,6 @@ static int sequencer_add_effect_strip_exec(bContext *C, wmOperator *op)
* it was NOT called in blender 2.4x, but wont hurt */
BKE_sequencer_sort(scene);
- DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c
index 72f186d4c1a..805ec26950a 100644
--- a/source/blender/editors/space_sequencer/sequencer_draw.c
+++ b/source/blender/editors/space_sequencer/sequencer_draw.c
@@ -60,6 +60,7 @@
#include "ED_mask.h"
#include "ED_sequencer.h"
#include "ED_screen.h"
+#include "ED_time_scrub_ui.h"
#include "ED_space_api.h"
#include "BIF_glutil.h"
@@ -259,6 +260,11 @@ static void drawseqwave(View2D *v2d,
return;
}
+ if (!sound->spinlock) {
+ sound->spinlock = MEM_mallocN(sizeof(SpinLock), "sound_spinlock");
+ BLI_spin_init(sound->spinlock);
+ }
+
BLI_spin_lock(sound->spinlock);
if (!sound->waveform) {
if (!(sound->tags & SOUND_TAGS_WAVEFORM_LOADING)) {
@@ -955,7 +961,7 @@ static void draw_seq_strip(const bContext *C,
x1 = seq->startdisp + handsize_clamped;
x2 = seq->enddisp - handsize_clamped;
- float scroller_vert_xoffs = (V2D_SCROLL_WIDTH_TEXT + SEQ_SCROLLER_TEXT_OFFSET) * pixelx;
+ float scroller_vert_xoffs = (V2D_SCROLL_WIDTH_HANDLES + SEQ_SCROLLER_TEXT_OFFSET) * pixelx;
/* info text on the strip */
if (x1 < v2d->cur.xmin + scroller_vert_xoffs) {
@@ -1842,7 +1848,7 @@ static bool draw_cache_view_cb(
color[2] = 0.2f;
stripe_ht = UI_view2d_region_to_view_y(v2d, 4.0f * UI_DPI_FAC * U.pixelsize) -
v2d->cur.ymin;
- stripe_bot = UI_view2d_region_to_view_y(v2d, V2D_SCROLL_HEIGHT_TEXT);
+ stripe_bot = UI_view2d_region_to_view_y(v2d, V2D_SCROLL_HEIGHT_HANDLES);
stripe_top = stripe_bot + stripe_ht;
break;
}
@@ -1916,12 +1922,16 @@ static void draw_cache_view(const bContext *C)
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- float stripe_bot, stripe_top, stripe_offs;
+ float stripe_bot, stripe_top;
+ float stripe_offs = UI_view2d_region_to_view_y(v2d, 1.0f) - v2d->cur.ymin;
float stripe_ht = UI_view2d_region_to_view_y(v2d, 4.0f * UI_DPI_FAC * U.pixelsize) -
v2d->cur.ymin;
+ CLAMP_MAX(stripe_ht, 0.2f);
+ CLAMP_MIN(stripe_offs, stripe_ht / 2);
+
if (scene->ed->cache_flag & SEQ_CACHE_VIEW_FINAL_OUT) {
- stripe_bot = UI_view2d_region_to_view_y(v2d, V2D_SCROLL_HEIGHT_TEXT);
+ stripe_bot = UI_view2d_region_to_view_y(v2d, V2D_SCROLL_HEIGHT_HANDLES);
stripe_top = stripe_bot + stripe_ht;
float bg_color[4] = {1.0f, 0.4f, 0.2f, 0.1f};
@@ -1938,10 +1948,6 @@ static void draw_cache_view(const bContext *C)
continue;
}
- CLAMP_MAX(stripe_ht, 0.2f);
- stripe_offs = UI_view2d_region_to_view_y(v2d, 1.0f) - v2d->cur.ymin;
- CLAMP_MIN(stripe_offs, stripe_ht / 2);
-
stripe_bot = seq->machine + SEQ_STRIP_OFSBOTTOM + stripe_offs;
stripe_top = stripe_bot + stripe_ht;
@@ -2080,19 +2086,22 @@ void draw_timeline_seq(const bContext *C, ARegion *ar)
/* reset view matrix */
UI_view2d_view_restore(C);
+ /* scrubbing region */
+ ED_scrubbing_draw(ar, scene, !(sseq->flag & SEQ_DRAWFRAMES), true);
+
/* scrollers */
scrollers = UI_view2d_scrollers_calc(v2d, NULL);
UI_view2d_scrollers_draw(v2d, scrollers);
UI_view2d_scrollers_free(scrollers);
- /* scale numbers */
- UI_view2d_draw_scale_x__discrete_frames_or_seconds(
- ar, v2d, &v2d->hor, scene, !(sseq->flag & SEQ_DRAWFRAMES), TH_TEXT);
- UI_view2d_draw_scale_y__block(ar, v2d, &v2d->vert, TH_TEXT);
-
- /* draw current frame number-indicator on top of scrollers */
- if ((sseq->flag & SEQ_NO_DRAW_CFRANUM) == 0) {
- UI_view2d_view_orthoSpecial(ar, v2d, 1);
- ANIM_draw_cfra_number(C, v2d, cfra_flag);
+ /* channel numbers */
+ {
+ rcti rect;
+ BLI_rcti_init(&rect,
+ 0,
+ 15 * UI_DPI_FAC,
+ 15 * UI_DPI_FAC,
+ UI_DPI_FAC * ar->sizey - UI_SCRUBBING_MARGIN_Y);
+ UI_view2d_draw_scale_y__block(ar, v2d, &rect, TH_SCROLL_TEXT);
}
}
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index 0f5c02327cc..94437d4871a 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -64,8 +64,6 @@
#include "UI_view2d.h"
#include "UI_interface.h"
-#include "DEG_depsgraph.h"
-
/* own include */
#include "sequencer_intern.h"
@@ -2381,7 +2379,6 @@ static int sequencer_delete_exec(bContext *C, wmOperator *UNUSED(op))
ms = ms->prev;
}
- DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/space_sequencer/sequencer_preview.c b/source/blender/editors/space_sequencer/sequencer_preview.c
index 8a4e8c007f7..546c2a8a9f0 100644
--- a/source/blender/editors/space_sequencer/sequencer_preview.c
+++ b/source/blender/editors/space_sequencer/sequencer_preview.c
@@ -50,7 +50,6 @@ typedef struct PreviewJob {
typedef struct PreviewJobAudio {
struct PreviewJobAudio *next, *prev;
- struct Main *bmain;
bSound *sound;
int lr; /* sample left or right */
int startframe;
@@ -80,9 +79,7 @@ static void preview_startjob(void *data, short *stop, short *do_update, float *p
PreviewJobAudio *preview_next;
bSound *sound = previewjb->sound;
- BKE_sound_load_audio(previewjb->bmain, sound);
BKE_sound_read_waveform(sound, stop);
- BKE_sound_free_audio(sound);
if (*stop || G.is_break) {
BLI_mutex_lock(pj->mutex);
@@ -156,7 +153,6 @@ void sequencer_preview_add_sound(const bContext *C, Sequence *seq)
/* attempt to lock mutex of job here */
- audiojob->bmain = CTX_data_main(C);
audiojob->sound = seq->sound;
BLI_mutex_lock(pj->mutex);
diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c
index 2b0c29a02ad..7a02b1850ae 100644
--- a/source/blender/editors/space_sequencer/space_sequencer.c
+++ b/source/blender/editors/space_sequencer/space_sequencer.c
@@ -157,8 +157,8 @@ static SpaceLink *sequencer_new(const ScrArea *UNUSED(sa), const Scene *scene)
ar->v2d.minzoom = 0.01f;
ar->v2d.maxzoom = 100.0f;
- ar->v2d.scroll |= (V2D_SCROLL_BOTTOM | V2D_SCROLL_SCALE_HORIZONTAL);
- ar->v2d.scroll |= (V2D_SCROLL_LEFT | V2D_SCROLL_SCALE_VERTICAL);
+ ar->v2d.scroll |= (V2D_SCROLL_BOTTOM | V2D_SCROLL_HORIZONTAL_HANDLES);
+ ar->v2d.scroll |= (V2D_SCROLL_RIGHT | V2D_SCROLL_VERTICAL_HANDLES);
ar->v2d.keepzoom = 0;
ar->v2d.keeptot = 0;
ar->v2d.align = V2D_ALIGN_NO_NEG_Y;
@@ -816,7 +816,7 @@ void ED_spacetype_sequencer(void)
art->draw = sequencer_main_region_draw;
art->listener = sequencer_main_region_listener;
art->message_subscribe = sequencer_main_region_message_subscribe;
- art->keymapflag = ED_KEYMAP_VIEW2D | ED_KEYMAP_MARKERS | ED_KEYMAP_FRAMES | ED_KEYMAP_ANIMATION;
+ art->keymapflag = ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES | ED_KEYMAP_ANIMATION;
BLI_addhead(&st->regiontypes, art);
@@ -832,7 +832,7 @@ void ED_spacetype_sequencer(void)
/* regions: listview/buttons */
art = MEM_callocN(sizeof(ARegionType), "spacetype sequencer region");
art->regionid = RGN_TYPE_UI;
- art->prefsizex = 220; // XXX
+ art->prefsizex = UI_SIDEBAR_PANEL_WIDTH;
art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_FRAMES;
art->listener = sequencer_buttons_region_listener;
art->init = sequencer_buttons_region_init;
diff --git a/source/blender/editors/space_text/text_draw.c b/source/blender/editors/space_text/text_draw.c
index 678879018a7..ac1fb4af1c2 100644
--- a/source/blender/editors/space_text/text_draw.c
+++ b/source/blender/editors/space_text/text_draw.c
@@ -1665,12 +1665,14 @@ void draw_text_main(SpaceText *st, ARegion *ar)
immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
+ GPU_line_width(2.0f);
+
float viewport_size[4];
GPU_viewport_size_get_f(viewport_size);
immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
- immUniform1i("colors_len", 0); /* "simple" mode */
- immUniformThemeColor(TH_GRID); /* same color as line number background */
+ immUniform1i("colors_len", 0); /* "simple" mode */
+ immUniformThemeColor3(TH_GRID); /* same color as line number background */
immUniform1f("dash_width", 2.0f);
immUniform1f("dash_factor", 0.5f);
diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c
index d0809ec33fc..a3a438c3220 100644
--- a/source/blender/editors/space_text/text_ops.c
+++ b/source/blender/editors/space_text/text_ops.c
@@ -101,7 +101,7 @@ static char *buf_tabs_to_spaces(const char *in_buf, const int tab_size)
}
/* Allocate output before with extra space for expanded tabs. */
- const int out_size = strlen(in_buf) + num_tabs * (tab_size - 1);
+ const int out_size = strlen(in_buf) + num_tabs * (tab_size - 1) + 1;
char *out_buf = MEM_mallocN(out_size * sizeof(char), __func__);
/* Fill output buffer. */
diff --git a/source/blender/editors/space_topbar/space_topbar.c b/source/blender/editors/space_topbar/space_topbar.c
index 8b290009a97..725a49e417e 100644
--- a/source/blender/editors/space_topbar/space_topbar.c
+++ b/source/blender/editors/space_topbar/space_topbar.c
@@ -213,12 +213,15 @@ static void recent_files_menu_draw(const bContext *UNUSED(C), Menu *menu)
{
struct RecentFile *recent;
uiLayout *layout = menu->layout;
- uiLayoutSetOperatorContext(layout, WM_OP_EXEC_REGION_WIN);
+ uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_DEFAULT);
if (!BLI_listbase_is_empty(&G.recent_files)) {
for (recent = G.recent_files.first; (recent); recent = recent->next) {
const char *file = BLI_path_basename(recent->filepath);
const int icon = BLO_has_bfile_extension(file) ? ICON_FILE_BLEND : ICON_FILE_BACKUP;
- uiItemStringO(layout, file, icon, "WM_OT_open_mainfile", "filepath", recent->filepath);
+ PointerRNA ptr;
+ uiItemFullO(layout, "WM_OT_open_mainfile", file, icon, NULL, WM_OP_INVOKE_DEFAULT, 0, &ptr);
+ RNA_string_set(&ptr, "filepath", recent->filepath);
+ RNA_boolean_set(&ptr, "display_file_selector", false);
}
}
else {
diff --git a/source/blender/editors/space_userpref/space_userpref.c b/source/blender/editors/space_userpref/space_userpref.c
index 2237e8b02bc..4c6f2231cc1 100644
--- a/source/blender/editors/space_userpref/space_userpref.c
+++ b/source/blender/editors/space_userpref/space_userpref.c
@@ -249,7 +249,7 @@ void ED_spacetype_userpref(void)
art->init = userpref_navigation_region_init;
art->draw = userpref_navigation_region_draw;
art->listener = userpref_navigation_region_listener;
- art->keymapflag = ED_KEYMAP_UI;
+ art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_NAVBAR;
BLI_addhead(&st->regiontypes, art);
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index 638c77fc3cb..cc76c151a29 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -41,7 +41,6 @@
#include "GPU_batch.h"
#include "GPU_matrix.h"
#include "GPU_state.h"
-#include "GPU_framebuffer.h"
#include "ED_mesh.h"
@@ -51,8 +50,6 @@
#include "view3d_intern.h" /* bad level include */
-#include "../../draw/intern/draw_cache_impl.h" /* bad level include (temporary) */
-
int view3d_effective_drawtype(const struct View3D *v3d)
{
if (v3d->shading.type == OB_RENDER) {
@@ -61,24 +58,6 @@ int view3d_effective_drawtype(const struct View3D *v3d)
return v3d->shading.type;
}
-static bool check_ob_drawface_dot(Scene *sce, View3D *vd, char dt)
-{
- if ((sce->toolsettings->selectmode & SCE_SELECT_FACE) == 0) {
- return false;
- }
-
- if (G.f & G_FLAG_BACKBUFSEL) {
- return false;
- }
-
- /* if its drawing textures with zbuf sel, then don't draw dots */
- if (dt == OB_TEXTURE && vd->shading.type == OB_TEXTURE) {
- return false;
- }
-
- return true;
-}
-
/* OpenGL Circle Drawing - Tables for Optimized Drawing Speed */
/* 32 values of sin function (still same result!) */
#define CIRCLE_RESOL 32
@@ -138,216 +117,6 @@ bool view3d_camera_border_hack_test = false;
/* ***************** BACKBUF SEL (BBS) ********* */
-/** See #DRW_shgroup_world_clip_planes_from_rv3d, same function for draw manager. */
-static void bbs_world_clip_planes_from_rv3d(GPUBatch *batch, const float world_clip_planes[6][4])
-{
- GPU_batch_uniform_4fv_array(batch, "WorldClipPlanes", 6, world_clip_planes[0]);
-}
-
-static void bbs_mesh_verts(GPUBatch *batch, int offset, const float world_clip_planes[6][4])
-{
- GPU_point_size(UI_GetThemeValuef(TH_VERTEX_SIZE));
-
- const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED :
- GPU_SHADER_CFG_DEFAULT;
- GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_FLAT_SELECT_ID, sh_cfg);
- GPU_batch_uniform_1ui(batch, "offset", offset);
- if (world_clip_planes != NULL) {
- bbs_world_clip_planes_from_rv3d(batch, world_clip_planes);
- }
- GPU_batch_draw(batch);
-}
-
-static void bbs_mesh_wire(GPUBatch *batch, int offset, const float world_clip_planes[6][4])
-{
- GPU_line_width(1.0f);
- glProvokingVertex(GL_FIRST_VERTEX_CONVENTION);
-
- const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED :
- GPU_SHADER_CFG_DEFAULT;
- GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_FLAT_SELECT_ID, sh_cfg);
- GPU_batch_uniform_1ui(batch, "offset", offset);
- if (world_clip_planes != NULL) {
- bbs_world_clip_planes_from_rv3d(batch, world_clip_planes);
- }
- GPU_batch_draw(batch);
-
- glProvokingVertex(GL_LAST_VERTEX_CONVENTION);
-}
-
-/* two options, facecolors or black */
-static void bbs_mesh_face(GPUBatch *batch,
- const bool use_select,
- const float world_clip_planes[6][4])
-{
- if (use_select) {
- const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED :
- GPU_SHADER_CFG_DEFAULT;
- GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_FLAT_SELECT_ID, sh_cfg);
- GPU_batch_uniform_1ui(batch, "offset", 1);
- if (world_clip_planes != NULL) {
- bbs_world_clip_planes_from_rv3d(batch, world_clip_planes);
- }
- GPU_batch_draw(batch);
- }
- else {
- const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED :
- GPU_SHADER_CFG_DEFAULT;
- GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_UNIFORM_SELECT_ID, sh_cfg);
- GPU_batch_uniform_1ui(batch, "id", 0);
- if (world_clip_planes != NULL) {
- bbs_world_clip_planes_from_rv3d(batch, world_clip_planes);
- }
- GPU_batch_draw(batch);
- }
-}
-
-static void bbs_mesh_face_dot(GPUBatch *batch, const float world_clip_planes[6][4])
-{
- const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED :
- GPU_SHADER_CFG_DEFAULT;
- GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_FLAT_SELECT_ID, sh_cfg);
- GPU_batch_uniform_1ui(batch, "offset", 1);
- if (world_clip_planes != NULL) {
- bbs_world_clip_planes_from_rv3d(batch, world_clip_planes);
- }
- GPU_batch_draw(batch);
-}
-
-static void bbs_mesh_solid_verts(Depsgraph *UNUSED(depsgraph),
- Scene *UNUSED(scene),
- Object *ob,
- const float world_clip_planes[6][4])
-{
- Mesh *me = ob->data;
-
- GPUBatch *geom_faces = DRW_mesh_batch_cache_get_triangles_with_select_id(me);
- GPUBatch *geom_verts = DRW_mesh_batch_cache_get_verts_with_select_id(me);
- DRW_mesh_batch_cache_create_requested(ob, me, NULL, false, true);
-
- /* Only draw faces to mask out verts, we don't want their selection ID's. */
- bbs_mesh_face(geom_faces, false, world_clip_planes);
- bbs_mesh_verts(geom_verts, 1, world_clip_planes);
-
- bm_vertoffs = me->totvert + 1;
-}
-
-static void bbs_mesh_solid_faces(Scene *UNUSED(scene),
- Object *ob,
- const float world_clip_planes[6][4])
-{
- Mesh *me = ob->data;
- Mesh *me_orig = DEG_get_original_object(ob)->data;
-
- const bool use_hide = (me_orig->editflag & ME_EDIT_PAINT_FACE_SEL);
- GPUBatch *geom_faces = DRW_mesh_batch_cache_get_triangles_with_select_id(me);
- DRW_mesh_batch_cache_create_requested(ob, me, NULL, false, use_hide);
-
- bbs_mesh_face(geom_faces, true, world_clip_planes);
-}
-
-void draw_object_select_id(Depsgraph *depsgraph,
- Scene *scene,
- View3D *v3d,
- RegionView3D *rv3d,
- Object *ob,
- short select_mode)
-{
- ToolSettings *ts = scene->toolsettings;
- if (select_mode == -1) {
- select_mode = ts->selectmode;
- }
-
- GPU_matrix_mul(ob->obmat);
- GPU_depth_test(true);
-
- const float(*world_clip_planes)[4] = NULL;
- if (rv3d->rflag & RV3D_CLIPPING) {
- ED_view3d_clipping_local(rv3d, ob->obmat);
- world_clip_planes = rv3d->clip_local;
- }
-
- switch (ob->type) {
- case OB_MESH:
- if (ob->mode & OB_MODE_EDIT) {
- Mesh *me = ob->data;
- BMEditMesh *em = me->edit_mesh;
- const bool draw_facedot = check_ob_drawface_dot(scene, v3d, ob->dt);
- const bool use_faceselect = (select_mode & SCE_SELECT_FACE) != 0;
-
- BM_mesh_elem_table_ensure(em->bm, BM_VERT | BM_EDGE | BM_FACE);
-
- GPUBatch *geom_faces, *geom_edges, *geom_verts, *geom_facedots;
- geom_faces = DRW_mesh_batch_cache_get_triangles_with_select_id(me);
- if (select_mode & SCE_SELECT_EDGE) {
- geom_edges = DRW_mesh_batch_cache_get_edges_with_select_id(me);
- }
- if (select_mode & SCE_SELECT_VERTEX) {
- geom_verts = DRW_mesh_batch_cache_get_verts_with_select_id(me);
- }
- if (draw_facedot) {
- geom_facedots = DRW_mesh_batch_cache_get_facedots_with_select_id(me);
- }
- DRW_mesh_batch_cache_create_requested(ob, me, NULL, false, true);
-
- bbs_mesh_face(geom_faces, use_faceselect, world_clip_planes);
-
- if (use_faceselect && draw_facedot) {
- bbs_mesh_face_dot(geom_facedots, world_clip_planes);
- }
-
- if (select_mode & SCE_SELECT_FACE) {
- bm_solidoffs = 1 + em->bm->totface;
- }
- else {
- bm_solidoffs = 1;
- }
-
- ED_view3d_polygon_offset(rv3d, 1.0);
-
- /* we draw edges if edge select mode */
- if (select_mode & SCE_SELECT_EDGE) {
- bbs_mesh_wire(geom_edges, bm_solidoffs, world_clip_planes);
- bm_wireoffs = bm_solidoffs + em->bm->totedge;
- }
- else {
- /* `bm_vertoffs` is calculated from `bm_wireoffs`. (otherwise see T53512) */
- bm_wireoffs = bm_solidoffs;
- }
-
- ED_view3d_polygon_offset(rv3d, 1.1);
-
- /* we draw verts if vert select mode. */
- if (select_mode & SCE_SELECT_VERTEX) {
- bbs_mesh_verts(geom_verts, bm_wireoffs, world_clip_planes);
- bm_vertoffs = bm_wireoffs + em->bm->totvert;
- }
- else {
- bm_vertoffs = bm_wireoffs;
- }
-
- ED_view3d_polygon_offset(rv3d, 0.0);
- }
- else {
- Mesh *me = DEG_get_original_object(ob)->data;
- if ((me->editflag & ME_EDIT_PAINT_VERT_SEL) &&
- /* currently vertex select supports weight paint and vertex paint*/
- ((ob->mode & OB_MODE_WEIGHT_PAINT) || (ob->mode & OB_MODE_VERTEX_PAINT))) {
- bbs_mesh_solid_verts(depsgraph, scene, ob, world_clip_planes);
- }
- else {
- bbs_mesh_solid_faces(scene, ob, world_clip_planes);
- }
- }
- break;
- case OB_CURVE:
- case OB_SURF:
- break;
- }
-
- GPU_matrix_set(rv3d->viewmat);
-}
-
void ED_draw_object_facemap(Depsgraph *depsgraph,
Object *ob,
const float col[4],
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index dbf2160d39b..770172d702b 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -1132,6 +1132,9 @@ static void view3d_header_region_listener(wmWindow *UNUSED(win),
ED_region_tag_redraw(ar);
}
break;
+ case NC_BRUSH:
+ ED_region_tag_redraw(ar);
+ break;
}
/* From topbar, which ones are needed? split per header? */
@@ -1201,9 +1204,106 @@ static void view3d_buttons_region_init(wmWindowManager *wm, ARegion *ar)
WM_event_add_keymap_handler(&ar->handlers, keymap);
}
-static void view3d_buttons_region_draw(const bContext *C, ARegion *ar)
+void ED_view3d_buttons_region_layout_ex(const bContext *C,
+ ARegion *ar,
+ const char *category_override)
{
- ED_region_panels_ex(C, ar, (const char *[]){CTX_data_mode_string(C), NULL}, -1, true);
+ const enum eContextObjectMode mode = CTX_data_mode_enum(C);
+
+ const char *contexts_base[4] = {NULL};
+ contexts_base[0] = CTX_data_mode_string(C);
+
+ const char **contexts = &contexts_base[1];
+
+ switch (mode) {
+ case CTX_MODE_EDIT_MESH:
+ ARRAY_SET_ITEMS(contexts, ".mesh_edit");
+ break;
+ case CTX_MODE_EDIT_CURVE:
+ ARRAY_SET_ITEMS(contexts, ".curve_edit");
+ break;
+ case CTX_MODE_EDIT_SURFACE:
+ ARRAY_SET_ITEMS(contexts, ".curve_edit");
+ break;
+ case CTX_MODE_EDIT_TEXT:
+ ARRAY_SET_ITEMS(contexts, ".text_edit");
+ break;
+ case CTX_MODE_EDIT_ARMATURE:
+ ARRAY_SET_ITEMS(contexts, ".armature_edit");
+ break;
+ case CTX_MODE_EDIT_METABALL:
+ ARRAY_SET_ITEMS(contexts, ".mball_edit");
+ break;
+ case CTX_MODE_EDIT_LATTICE:
+ ARRAY_SET_ITEMS(contexts, ".lattice_edit");
+ break;
+ case CTX_MODE_POSE:
+ ARRAY_SET_ITEMS(contexts, ".posemode");
+ break;
+ case CTX_MODE_SCULPT:
+ ARRAY_SET_ITEMS(contexts, ".paint_common", ".sculpt_mode");
+ break;
+ case CTX_MODE_PAINT_WEIGHT:
+ ARRAY_SET_ITEMS(contexts, ".paint_common", ".weightpaint");
+ break;
+ case CTX_MODE_PAINT_VERTEX:
+ ARRAY_SET_ITEMS(contexts, ".paint_common", ".vertexpaint");
+ break;
+ case CTX_MODE_PAINT_TEXTURE:
+ ARRAY_SET_ITEMS(contexts, ".paint_common", ".imagepaint");
+ break;
+ case CTX_MODE_PARTICLE:
+ ARRAY_SET_ITEMS(contexts, ".paint_common", ".particlemode");
+ break;
+ case CTX_MODE_OBJECT:
+ ARRAY_SET_ITEMS(contexts, ".objectmode");
+ break;
+ case CTX_MODE_PAINT_GPENCIL:
+ ARRAY_SET_ITEMS(contexts, ".greasepencil_paint");
+ break;
+ case CTX_MODE_SCULPT_GPENCIL:
+ ARRAY_SET_ITEMS(contexts, ".greasepencil_sculpt");
+ break;
+ case CTX_MODE_WEIGHT_GPENCIL:
+ ARRAY_SET_ITEMS(contexts, ".greasepencil_weight");
+ break;
+ default:
+ break;
+ }
+
+ switch (mode) {
+ case CTX_MODE_PAINT_GPENCIL:
+ ARRAY_SET_ITEMS(contexts, ".greasepencil_paint");
+ break;
+ case CTX_MODE_SCULPT_GPENCIL:
+ ARRAY_SET_ITEMS(contexts, ".greasepencil_sculpt");
+ break;
+ case CTX_MODE_WEIGHT_GPENCIL:
+ ARRAY_SET_ITEMS(contexts, ".greasepencil_weight");
+ break;
+ case CTX_MODE_EDIT_GPENCIL:
+ ARRAY_SET_ITEMS(contexts, ".greasepencil_edit");
+ break;
+ default:
+ break;
+ }
+
+ ListBase *paneltypes = &ar->type->paneltypes;
+
+ /* Allow drawing 3D view toolbar from non 3D view space type. */
+ if (category_override != NULL) {
+ SpaceType *st = BKE_spacetype_from_id(SPACE_VIEW3D);
+ ARegionType *art = BKE_regiontype_from_id(st, RGN_TYPE_UI);
+ paneltypes = &art->paneltypes;
+ }
+
+ const bool vertical = true;
+ ED_region_panels_layout_ex(C, ar, paneltypes, contexts_base, -1, vertical, category_override);
+}
+
+static void view3d_buttons_region_layout(const bContext *C, ARegion *ar)
+{
+ ED_view3d_buttons_region_layout_ex(C, ar, NULL);
}
static void view3d_buttons_region_listener(wmWindow *UNUSED(win),
@@ -1508,12 +1608,13 @@ void ED_spacetype_view3d(void)
/* regions: listview/buttons */
art = MEM_callocN(sizeof(ARegionType), "spacetype view3d buttons region");
art->regionid = RGN_TYPE_UI;
- art->prefsizex = 180; /* XXX */
+ art->prefsizex = UI_SIDEBAR_PANEL_WIDTH;
art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_FRAMES;
art->listener = view3d_buttons_region_listener;
art->message_subscribe = ED_area_do_mgs_subscribe_for_tool_ui;
art->init = view3d_buttons_region_init;
- art->draw = view3d_buttons_region_draw;
+ art->layout = view3d_buttons_region_layout;
+ art->draw = ED_region_panels_draw;
BLI_addhead(&st->regiontypes, art);
view3d_buttons_register(art);
diff --git a/source/blender/editors/space_view3d/view3d_draw_legacy.c b/source/blender/editors/space_view3d/view3d_draw_legacy.c
index b0cee18f8e3..e0dbe1f6543 100644
--- a/source/blender/editors/space_view3d/view3d_draw_legacy.c
+++ b/source/blender/editors/space_view3d/view3d_draw_legacy.c
@@ -77,6 +77,7 @@
#include "ED_armature.h"
#include "ED_keyframing.h"
#include "ED_gpencil.h"
+#include "ED_mesh.h"
#include "ED_screen.h"
#include "ED_space_api.h"
#include "ED_screen_types.h"
@@ -208,7 +209,16 @@ static void validate_object_select_id(struct Depsgraph *depsgraph,
if (obact_eval && ((obact_eval->base_flag & BASE_VISIBLE) != 0)) {
DRW_framebuffer_select_id_setup(ar, true);
- draw_object_select_id(depsgraph, scene_eval, v3d, rv3d, obact_eval, select_mode);
+ DRW_draw_select_id_object(scene_eval,
+ rv3d,
+ obact_eval,
+ select_mode,
+ false,
+ 0,
+ &bm_vertoffs,
+ &bm_wireoffs,
+ &bm_solidoffs);
+
DRW_framebuffer_select_id_release(ar);
}
@@ -271,10 +281,8 @@ void ED_view3d_backbuf_depth_validate(ViewContext *vc)
}
}
-uint *ED_view3d_select_id_read_rect(ViewContext *vc, const rcti *clip, uint *r_buf_len)
+uint *ED_view3d_select_id_read_rect(ViewContext *UNUSED(vc), const rcti *clip, uint *r_buf_len)
{
- ED_view3d_select_id_validate(vc);
-
uint width = BLI_rcti_size_x(clip);
uint height = BLI_rcti_size_y(clip);
uint buf_len = width * height;
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 6f35c0aa748..9cbf179ab49 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c
@@ -304,15 +304,14 @@ static int gizmo_preselect_edgering_test_select(bContext *C, wmGizmo *gz, const
em_setup_viewcontext(C, &vc);
copy_v2_v2_int(vc.mval, mval);
- for (uint base_index = 0; base_index < gz_ring->bases_len; base_index++) {
- Object *ob_iter = gz_ring->bases[base_index]->object;
- ED_view3d_viewcontext_init_object(&vc, ob_iter);
- BMEdge *eed_test = EDBM_edge_find_nearest_ex(&vc, &best.dist, NULL, false, false, NULL);
- if (eed_test) {
- best.ob = ob_iter;
- best.eed = eed_test;
- best.base_index = base_index;
- }
+ uint base_index;
+ BMEdge *eed_test = EDBM_edge_find_nearest_ex(
+ &vc, &best.dist, NULL, false, false, NULL, gz_ring->bases, gz_ring->bases_len, &base_index);
+
+ if (eed_test) {
+ best.ob = gz_ring->bases[base_index]->object;
+ best.eed = eed_test;
+ best.base_index = base_index;
}
BMesh *bm = NULL;
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index 9075909a6fe..e499672acc1 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -127,13 +127,6 @@ void VIEW3D_OT_fly(struct wmOperatorType *ot);
void VIEW3D_OT_walk(struct wmOperatorType *ot);
/* drawobject.c */
-void draw_object_select_id(struct Depsgraph *depsgraph,
- Scene *scene,
- View3D *v3d,
- RegionView3D *rv3d,
- struct Object *ob,
- short select_mode);
-
int view3d_effective_drawtype(const struct View3D *v3d);
/* view3d_draw.c */
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index 2ce23486476..419ec87eec8 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -57,6 +57,7 @@
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
#include "BKE_global.h"
+#include "BKE_main.h"
#include "BKE_armature.h"
#include "BKE_context.h"
@@ -134,9 +135,6 @@ void ED_view3d_viewcontext_init_object(ViewContext *vc, Object *obact)
if (vc->obedit) {
BLI_assert(BKE_object_is_in_editmode(obact));
vc->obedit = obact;
- /* previous selections are now invalid. */
- vc->v3d->flag |= V3D_INVALID_BACKBUF;
-
if (vc->em) {
vc->em = BKE_editmesh_from_object(vc->obedit);
}
@@ -1170,6 +1168,7 @@ static int view3d_lasso_select_exec(bContext *C, wmOperator *op)
if (mcords) {
view3d_operator_needs_opengl(C);
+ BKE_object_update_select_id(CTX_data_main(C));
/* setup view context for argument to callbacks */
ED_view3d_viewcontext_init(C, &vc);
@@ -1337,7 +1336,7 @@ static Base *object_mouse_select_menu(
if (buffer) {
for (int a = 0; a < hits; a++) {
/* index was converted */
- if (base->object->select_id == (buffer[(4 * a) + 3] & ~0xFFFF0000)) {
+ if (base->object->runtime.select_id == (buffer[(4 * a) + 3] & ~0xFFFF0000)) {
ok = true;
break;
}
@@ -1609,7 +1608,7 @@ static Base *mouse_select_eval_buffer(ViewContext *vc,
else {
/* only exclude active object when it is selected... */
if (BASACT(view_layer) && (BASACT(view_layer)->flag & BASE_SELECTED) && hits > 1) {
- notcol = BASACT(view_layer)->object->select_id;
+ notcol = BASACT(view_layer)->object->runtime.select_id;
}
for (a = 0; a < hits; a++) {
@@ -1623,7 +1622,7 @@ static Base *mouse_select_eval_buffer(ViewContext *vc,
base = FIRSTBASE(view_layer);
while (base) {
if (BASE_SELECTABLE(v3d, base)) {
- if (base->object->select_id == selcol) {
+ if (base->object->runtime.select_id == selcol) {
break;
}
}
@@ -1654,13 +1653,13 @@ static Base *mouse_select_eval_buffer(ViewContext *vc,
if (has_bones) {
/* skip non-bone objects */
if ((buffer[4 * a + 3] & 0xFFFF0000)) {
- if (base->object->select_id == (buffer[(4 * a) + 3] & 0xFFFF)) {
+ if (base->object->runtime.select_id == (buffer[(4 * a) + 3] & 0xFFFF)) {
basact = base;
}
}
}
else {
- if (base->object->select_id == (buffer[(4 * a) + 3] & 0xFFFF)) {
+ if (base->object->runtime.select_id == (buffer[(4 * a) + 3] & 0xFFFF)) {
basact = base;
}
}
@@ -1693,6 +1692,7 @@ Base *ED_view3d_give_base_under_cursor(bContext *C, const int mval[2])
/* setup view context for argument to callbacks */
view3d_operator_needs_opengl(C);
+ BKE_object_update_select_id(CTX_data_main(C));
ED_view3d_viewcontext_init(C, &vc);
@@ -1878,7 +1878,7 @@ static bool ed_object_select_pick(bContext *C,
/* if there's bundles in buffer select bundles first,
* so non-camera elements should be ignored in buffer */
- if (basact->object->select_id != (hitresult & 0xFFFF)) {
+ if (basact->object->runtime.select_id != (hitresult & 0xFFFF)) {
continue;
}
@@ -2129,6 +2129,7 @@ static int view3d_select_exec(bContext *C, wmOperator *op)
RNA_int_get_array(op->ptr, "location", location);
view3d_operator_needs_opengl(C);
+ BKE_object_update_select_id(CTX_data_main(C));
if (object) {
obedit = NULL;
@@ -2355,14 +2356,14 @@ static bool do_paintvert_box_select(ViewContext *vc, const rcti *rect, const eSe
}
else if (use_zbuf) {
MVert *mvert;
- unsigned int *rt;
+ uint *rt, *buf, buf_len;
int a, index;
char *selar;
selar = MEM_callocN(me->totvert + 1, "selar");
- uint buf_len;
- uint *buf = ED_view3d_select_id_read_rect(vc, rect, &buf_len);
+ ED_view3d_select_id_validate(vc);
+ buf = ED_view3d_select_id_read_rect(vc, rect, &buf_len);
rt = buf;
@@ -2652,7 +2653,7 @@ static bool do_meta_box_select(ViewContext *vc, const rcti *rect, const eSelectO
}
const uint hit_object = hitresult & 0xFFFF;
- if (vc->obedit->select_id != hit_object) {
+ if (vc->obedit->runtime.select_id != hit_object) {
continue;
}
@@ -2803,7 +2804,7 @@ static bool do_object_box_select(bContext *C, ViewContext *vc, rcti *rect, const
for (Base *base = vc->view_layer->object_bases.first; base; base = base->next) {
if (BASE_SELECTABLE(v3d, base)) {
- if ((base->object->select_id & 0x0000FFFF) != 0) {
+ if ((base->object->runtime.select_id & 0x0000FFFF) != 0) {
BLI_array_append(bases, base);
}
}
@@ -2893,7 +2894,7 @@ static bool do_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, const e
/* Select the next bone if we're not switching bases. */
if (col + 4 != col_end) {
- if ((base->object->select_id & 0x0000FFFF) != (col[4] & 0x0000FFFF)) {
+ if ((base->object->runtime.select_id & 0x0000FFFF) != (col[4] & 0x0000FFFF)) {
break;
}
if (base->object->pose != NULL) {
@@ -2930,6 +2931,7 @@ static int view3d_box_select_exec(bContext *C, wmOperator *op)
bool changed_multi = false;
view3d_operator_needs_opengl(C);
+ BKE_object_update_select_id(CTX_data_main(C));
/* setup view context for argument to callbacks */
ED_view3d_viewcontext_init(C, &vc);
@@ -3670,6 +3672,7 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op)
if (obedit || BKE_paint_select_elem_test(obact) || (obact && (obact->mode & OB_MODE_POSE))) {
view3d_operator_needs_opengl(C);
+ BKE_object_update_select_id(CTX_data_main(C));
FOREACH_OBJECT_IN_MODE_BEGIN (vc.view_layer, vc.v3d, obact->type, obact->mode, ob_iter) {
ED_view3d_viewcontext_init_object(&vc, ob_iter);
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 81405b55ac2..09f198ff14c 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -4917,8 +4917,7 @@ static void initSnapSpatial(TransInfo *t, float r_snap[3])
}
else if (t->spacetype == SPACE_NODE) {
r_snap[0] = 0.0f;
- r_snap[1] = ED_node_grid_size();
- r_snap[2] = ED_node_grid_size();
+ r_snap[1] = r_snap[2] = ED_node_grid_size();
}
else if (t->spacetype == SPACE_GRAPH) {
r_snap[0] = 0.0f;
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index 50fc1a276b9..b0f720bfdf7 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -383,6 +383,30 @@ typedef struct BoneInitData {
float zwidth;
} BoneInitData;
+typedef struct PoseInitData_Mirror {
+ /** Points to the bone which this info is initialized & restored to.
+ * A NULL value is used to terminate the array. */
+ struct bPoseChannel *pchan;
+ struct {
+ float loc[3];
+ float size[3];
+ union {
+ float eul[3];
+ float quat[4];
+ float axis_angle[4];
+ };
+ float curve_in_x;
+ float curve_out_x;
+ float roll1;
+ float roll2;
+ } orig;
+ /**
+ * An extra offset to apply after mirroring.
+ * Use with #POSE_MIRROR_RELATIVE.
+ */
+ float offset_mtx[4][4];
+} PoseInitData_Mirror;
+
typedef struct TransData {
/** Distance needed to affect element (for Proportionnal Editing). */
float dist;
@@ -501,7 +525,7 @@ typedef struct TransDataContainer {
struct Object *obedit;
/**
- * Use when #T_LOCAL_MATRIX is set.
+ * Store matrix, this avoids having to have duplicate check all over
* Typically: 'obedit->obmat' or 'poseobj->obmat', but may be used elsewhere too.
*/
bool use_local_mat;
@@ -715,10 +739,8 @@ enum {
T_CURSOR = 1 << 5,
/** Transform points, having no rotation/scale. */
T_POINTS = 1 << 6,
- /**
- * Apply matrix #TransDataContainer.matrix, this avoids having to have duplicate check all over
- * that happen to apply to specific modes (edit & pose for eg). */
- T_LOCAL_MATRIX = 1 << 7,
+
+ /* empty slot - (1 << 7) */
/** restrictions flags */
T_NO_CONSTRAINT = 1 << 8,
@@ -892,6 +914,7 @@ void flushTransSeq(TransInfo *t);
void flushTransTracking(TransInfo *t);
void flushTransMasking(TransInfo *t);
void flushTransPaintCurve(TransInfo *t);
+void restoreMirrorPoseBones(TransDataContainer *tc);
void restoreBones(TransDataContainer *tc);
/*********************** transform_gizmo.c ********** */
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 6c1da5ae825..4037fab2b68 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -198,7 +198,10 @@ void sort_trans_data_dist(TransInfo *t)
}
}
-static void sort_trans_data_container(TransDataContainer *tc)
+/**
+ * Make #TD_SELECTED first in the array.
+ */
+static void sort_trans_data_selected_first_container(TransDataContainer *tc)
{
TransData *sel, *unsel;
TransData temp;
@@ -225,10 +228,10 @@ static void sort_trans_data_container(TransDataContainer *tc)
unsel++;
}
}
-static void sort_trans_data(TransInfo *t)
+static void sort_trans_data_selected_first(TransInfo *t)
{
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
- sort_trans_data_container(tc);
+ sort_trans_data_selected_first_container(tc);
}
}
@@ -1201,6 +1204,74 @@ static short pose_grab_with_ik(Main *bmain, Object *ob)
return (tot_ik) ? 1 : 0;
}
+static void pose_mirror_info_init(PoseInitData_Mirror *pid,
+ bPoseChannel *pchan,
+ bPoseChannel *pchan_orig,
+ bool is_mirror_relative)
+{
+ pid->pchan = pchan;
+ copy_v3_v3(pid->orig.loc, pchan->loc);
+ copy_v3_v3(pid->orig.size, pchan->size);
+ pid->orig.curve_in_x = pchan->curve_in_x;
+ pid->orig.curve_out_x = pchan->curve_out_x;
+ pid->orig.roll1 = pchan->roll1;
+ pid->orig.roll2 = pchan->roll2;
+
+ if (pchan->rotmode > 0) {
+ copy_v3_v3(pid->orig.eul, pchan->eul);
+ }
+ else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
+ copy_v3_v3(pid->orig.axis_angle, pchan->rotAxis);
+ pid->orig.axis_angle[3] = pchan->rotAngle;
+ }
+ else {
+ copy_qt_qt(pid->orig.quat, pchan->quat);
+ }
+
+ if (is_mirror_relative) {
+ float pchan_mtx[4][4];
+ float pchan_mtx_mirror[4][4];
+
+ float flip_mtx[4][4];
+ unit_m4(flip_mtx);
+ flip_mtx[0][0] = -1;
+
+ BKE_pchan_to_mat4(pchan_orig, pchan_mtx_mirror);
+ BKE_pchan_to_mat4(pchan, pchan_mtx);
+
+ mul_m4_m4m4(pchan_mtx_mirror, pchan_mtx_mirror, flip_mtx);
+ mul_m4_m4m4(pchan_mtx_mirror, flip_mtx, pchan_mtx_mirror);
+
+ invert_m4(pchan_mtx_mirror);
+ mul_m4_m4m4(pid->offset_mtx, pchan_mtx, pchan_mtx_mirror);
+ }
+ else {
+ unit_m4(pid->offset_mtx);
+ }
+}
+
+static void pose_mirror_info_restore(const PoseInitData_Mirror *pid)
+{
+ bPoseChannel *pchan = pid->pchan;
+ copy_v3_v3(pchan->loc, pid->orig.loc);
+ copy_v3_v3(pchan->size, pid->orig.size);
+ pchan->curve_in_x = pid->orig.curve_in_x;
+ pchan->curve_out_x = pid->orig.curve_out_x;
+ pchan->roll1 = pid->orig.roll1;
+ pchan->roll2 = pid->orig.roll2;
+
+ if (pchan->rotmode > 0) {
+ copy_v3_v3(pchan->eul, pid->orig.eul);
+ }
+ else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
+ copy_v3_v3(pchan->rotAxis, pid->orig.axis_angle);
+ pchan->rotAngle = pid->orig.axis_angle[3];
+ }
+ else {
+ copy_qt_qt(pchan->quat, pid->orig.quat);
+ }
+}
+
/**
* When objects array is NULL, use 't->data_container' as is.
*/
@@ -1215,16 +1286,19 @@ static void createTransPose(TransInfo *t)
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
Object *ob = tc->poseobj;
+ bPose *pose = ob->pose;
bArmature *arm;
short ik_on = 0;
/* check validity of state */
arm = BKE_armature_from_object(tc->poseobj);
- if ((arm == NULL) || (ob->pose == NULL)) {
+ if ((arm == NULL) || (pose == NULL)) {
continue;
}
+ const bool mirror = ((pose->flag & POSE_MIRROR_EDIT) != 0);
+
/* set flags and count total */
tc->data_len = count_set_pose_transflags(ob, t->mode, t->around, has_translate_rotate);
if (tc->data_len == 0) {
@@ -1240,13 +1314,32 @@ static void createTransPose(TransInfo *t)
}
/* do we need to add temporal IK chains? */
- if ((arm->flag & ARM_AUTO_IK) && t->mode == TFM_TRANSLATION) {
+ if ((pose->flag & POSE_AUTO_IK) && t->mode == TFM_TRANSLATION) {
ik_on = pose_grab_with_ik(bmain, ob);
if (ik_on) {
t->flag |= T_AUTOIK;
has_translate_rotate[0] = true;
}
}
+
+ if (mirror) {
+ int total_mirrored = 0;
+ for (bPoseChannel *pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
+ if ((pchan->bone->flag & BONE_TRANSFORM) &&
+ BKE_pose_channel_get_mirrored(ob->pose, pchan->name)) {
+ total_mirrored++;
+ }
+ }
+
+ PoseInitData_Mirror *pid = MEM_mallocN((total_mirrored + 1) * sizeof(PoseInitData_Mirror),
+ "PoseInitData_Mirror");
+
+ /* Trick to terminate iteration. */
+ pid[total_mirrored].pchan = NULL;
+
+ tc->custom.type.data = pid;
+ tc->custom.type.use_free = true;
+ }
}
/* if there are no translatable bones, do rotation */
@@ -1269,6 +1362,17 @@ static void createTransPose(TransInfo *t)
short ik_on = 0;
int i;
+ PoseInitData_Mirror *pid = tc->custom.type.data;
+ int pid_index = 0;
+ bPose *pose = ob->pose;
+
+ if (pose == NULL) {
+ continue;
+ }
+
+ const bool mirror = ((pose->flag & POSE_MIRROR_EDIT) != 0);
+ const bool is_mirror_relative = ((pose->flag & POSE_MIRROR_RELATIVE) != 0);
+
tc->poseobj = ob; /* we also allow non-active objects to be transformed, in weightpaint */
/* init trans data */
@@ -1285,6 +1389,15 @@ static void createTransPose(TransInfo *t)
for (bPoseChannel *pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
if (pchan->bone->flag & BONE_TRANSFORM) {
add_pose_transdata(t, pchan, ob, tc, td);
+
+ if (mirror) {
+ bPoseChannel *pchan_mirror = BKE_pose_channel_get_mirrored(ob->pose, pchan->name);
+ if (pchan_mirror) {
+ pose_mirror_info_init(&pid[pid_index], pchan_mirror, pchan, is_mirror_relative);
+ pid_index++;
+ }
+ }
+
td++;
}
}
@@ -1304,6 +1417,19 @@ static void createTransPose(TransInfo *t)
t->flag &= ~T_PROP_EDIT_ALL;
}
+void restoreMirrorPoseBones(TransDataContainer *tc)
+{
+ bPose *pose = tc->poseobj->pose;
+
+ if (!(pose->flag & POSE_MIRROR_EDIT)) {
+ return;
+ }
+
+ for (PoseInitData_Mirror *pid = tc->custom.type.data; pid->pchan; pid++) {
+ pose_mirror_info_restore(pid);
+ }
+}
+
void restoreBones(TransDataContainer *tc)
{
bArmature *arm;
@@ -9253,7 +9379,7 @@ void createTransData(bContext *C, TransInfo *t)
countAndCleanTransDataContainer(t);
if (t->data_len_all && t->flag & T_PROP_EDIT) {
- sort_trans_data(t); // makes selected become first in array
+ sort_trans_data_selected_first(t);
set_prop_dist(t, 1);
sort_trans_data_dist(t);
}
@@ -9267,7 +9393,7 @@ void createTransData(bContext *C, TransInfo *t)
countAndCleanTransDataContainer(t);
if (t->data_len_all && (t->flag & T_PROP_EDIT)) {
- sort_trans_data(t); // makes selected become first in array
+ sort_trans_data_selected_first(t);
set_prop_dist(t, 1);
sort_trans_data_dist(t);
}
@@ -9281,7 +9407,7 @@ void createTransData(bContext *C, TransInfo *t)
countAndCleanTransDataContainer(t);
if (t->data_len_all && (t->flag & T_PROP_EDIT)) {
- sort_trans_data(t); // makes selected become first in array
+ sort_trans_data_selected_first(t);
set_prop_dist(t, true);
sort_trans_data_dist(t);
}
@@ -9304,7 +9430,7 @@ void createTransData(bContext *C, TransInfo *t)
t->flag |= T_EDIT;
if (t->data_len_all && (t->flag & T_PROP_EDIT)) {
- sort_trans_data(t); // makes selected become first in array
+ sort_trans_data_selected_first(t);
set_prop_dist(t, 1);
sort_trans_data_dist(t);
}
@@ -9321,7 +9447,7 @@ void createTransData(bContext *C, TransInfo *t)
countAndCleanTransDataContainer(t);
if (t->data_len_all && (t->flag & T_PROP_EDIT)) {
- sort_trans_data(t); // makes selected become first in array
+ sort_trans_data_selected_first(t);
/* don't do that, distance has been set in createTransActionData already */
// set_prop_dist(t, false);
sort_trans_data_dist(t);
@@ -9351,7 +9477,7 @@ void createTransData(bContext *C, TransInfo *t)
if (t->data_len_all && (t->flag & T_PROP_EDIT)) {
/* makes selected become first in array */
- sort_trans_data(t);
+ sort_trans_data_selected_first(t);
/* don't do that, distance has been set in createTransGraphEditData already */
set_prop_dist(t, false);
@@ -9367,7 +9493,7 @@ void createTransData(bContext *C, TransInfo *t)
countAndCleanTransDataContainer(t);
if (t->data_len_all && (t->flag & T_PROP_EDIT)) {
- sort_trans_data(t); // makes selected become first in array
+ sort_trans_data_selected_first(t);
set_prop_dist(t, 1);
sort_trans_data_dist(t);
}
@@ -9386,7 +9512,7 @@ void createTransData(bContext *C, TransInfo *t)
countAndCleanTransDataContainer(t);
if (t->data_len_all && (t->flag & T_PROP_EDIT)) {
- sort_trans_data(t); // makes selected become first in array
+ sort_trans_data_selected_first(t);
set_prop_dist(t, true);
sort_trans_data_dist(t);
}
@@ -9426,21 +9552,30 @@ void createTransData(bContext *C, TransInfo *t)
t->flag |= T_EDIT | T_POINTS;
- if (t->data_len_all && t->flag & T_PROP_EDIT) {
- if (ELEM(t->obedit_type, OB_CURVE, OB_MESH)) {
- sort_trans_data(t); // makes selected become first in array
- if ((t->obedit_type == OB_MESH) && (t->flag & T_PROP_CONNECTED)) {
- /* already calculated by editmesh_set_connectivity_distance */
+ if (t->data_len_all) {
+ if (t->flag & T_PROP_EDIT) {
+ if (ELEM(t->obedit_type, OB_CURVE, OB_MESH)) {
+ sort_trans_data_selected_first(t);
+ if ((t->obedit_type == OB_MESH) && (t->flag & T_PROP_CONNECTED)) {
+ /* already calculated by editmesh_set_connectivity_distance */
+ }
+ else {
+ set_prop_dist(t, 0);
+ }
+ sort_trans_data_dist(t);
}
else {
- set_prop_dist(t, 0);
+ sort_trans_data_selected_first(t);
+ set_prop_dist(t, 1);
+ sort_trans_data_dist(t);
}
- sort_trans_data_dist(t);
}
else {
- sort_trans_data(t); // makes selected become first in array
- set_prop_dist(t, 1);
- sort_trans_data_dist(t);
+ if (ELEM(t->obedit_type, OB_CURVE)) {
+ /* Needed because bezier handles can be partially selected
+ * and are still added into transform data. */
+ sort_trans_data_selected_first(t);
+ }
}
}
@@ -9494,7 +9629,7 @@ void createTransData(bContext *C, TransInfo *t)
t->flag |= T_POINTS;
if (t->data_len_all && t->flag & T_PROP_EDIT) {
- sort_trans_data(t); // makes selected become first in array
+ sort_trans_data_selected_first(t);
set_prop_dist(t, 1);
sort_trans_data_dist(t);
}
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index a840c04ab5a..758551be0b5 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -781,6 +781,49 @@ static void recalcData_spaceclip(TransInfo *t)
}
}
+/**
+ * if pose bone (partial) selected, copy data.
+ * context; posemode armature, with mirror editing enabled.
+ *
+ * \param pid: Optional, apply relative transform when set.
+ */
+static void pose_transform_mirror_update(Object *ob, PoseInitData_Mirror *pid)
+{
+ float flip_mtx[4][4];
+ unit_m4(flip_mtx);
+ flip_mtx[0][0] = -1;
+
+ for (bPoseChannel *pchan_orig = ob->pose->chanbase.first; pchan_orig;
+ pchan_orig = pchan_orig->next) {
+ /* no layer check, correct mirror is more important */
+ if (pchan_orig->bone->flag & BONE_TRANSFORM) {
+ bPoseChannel *pchan = BKE_pose_channel_get_mirrored(ob->pose, pchan_orig->name);
+
+ if (pchan) {
+ /* also do bbone scaling */
+ pchan->bone->xwidth = pchan_orig->bone->xwidth;
+ pchan->bone->zwidth = pchan_orig->bone->zwidth;
+
+ /* we assume X-axis flipping for now */
+ pchan->curve_in_x = pchan_orig->curve_in_x * -1;
+ pchan->curve_out_x = pchan_orig->curve_out_x * -1;
+ pchan->roll1 = pchan_orig->roll1 * -1; // XXX?
+ pchan->roll2 = pchan_orig->roll2 * -1; // XXX?
+
+ float pchan_mtx_final[4][4];
+ BKE_pchan_to_mat4(pchan_orig, pchan_mtx_final);
+ mul_m4_m4m4(pchan_mtx_final, pchan_mtx_final, flip_mtx);
+ mul_m4_m4m4(pchan_mtx_final, flip_mtx, pchan_mtx_final);
+ if (pid) {
+ mul_m4_m4m4(pchan_mtx_final, pid->offset_mtx, pchan_mtx_final);
+ pid++;
+ }
+ BKE_pchan_apply_mat4(pchan, pchan_mtx_final, false);
+ }
+ }
+ }
+}
+
/* helper for recalcData() - for object transforms, typically in the 3D view */
static void recalcData_objects(TransInfo *t)
{
@@ -975,12 +1018,22 @@ static void recalcData_objects(TransInfo *t)
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
Object *ob = tc->poseobj;
bArmature *arm = ob->data;
- if (arm->flag & ARM_MIRROR_EDIT) {
- if (t->state != TRANS_CANCEL) {
- ED_armature_edit_transform_mirror_update(ob);
+ if (ob->mode == OB_MODE_EDIT) {
+ if (arm->flag & ARM_MIRROR_EDIT) {
+ if (t->state != TRANS_CANCEL) {
+ ED_armature_edit_transform_mirror_update(ob);
+ }
+ else {
+ restoreBones(tc);
+ }
}
- else {
- restoreBones(tc);
+ }
+ else if (ob->mode == OB_MODE_POSE) {
+ /* actually support TFM_BONESIZE in posemode as well */
+ DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
+ bPose *pose = ob->pose;
+ if (arm->flag & ARM_MIRROR_EDIT || pose->flag & POSE_MIRROR_EDIT) {
+ pose_transform_mirror_update(ob, NULL);
}
}
}
@@ -991,6 +1044,20 @@ static void recalcData_objects(TransInfo *t)
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
Object *ob = tc->poseobj;
bArmature *arm = ob->data;
+ bPose *pose = ob->pose;
+
+ if (pose->flag & POSE_MIRROR_EDIT) {
+ if (t->state != TRANS_CANCEL) {
+ PoseInitData_Mirror *pid = NULL;
+ if (pose->flag & POSE_MIRROR_RELATIVE) {
+ pid = tc->custom.type.data;
+ }
+ pose_transform_mirror_update(ob, pid);
+ }
+ else {
+ restoreMirrorPoseBones(tc);
+ }
+ }
/* if animtimer is running, and the object already has animation data,
* check if the auto-record feature means that we should record 'samples'
@@ -1121,8 +1188,6 @@ static void recalcData_sequencer(TransInfo *t)
seq_prev = seq;
}
- DEG_id_tag_update(&t->scene->id, ID_RECALC_SEQUENCER);
-
flushTransSeq(t);
}
@@ -1311,7 +1376,9 @@ void initTransDataContainers_FromObjectData(TransInfo *t,
BLI_assert((t->flag & T_2D_EDIT) == 0);
copy_m4_m4(tc->mat, objects[i]->obmat);
copy_m3_m4(tc->mat3, tc->mat);
- invert_m4_m4(tc->imat, tc->mat);
+ /* for non-invertible scale matrices, invert_m4_m4_fallback()
+ * can still provide a valid pivot */
+ invert_m4_m4_fallback(tc->imat, tc->mat);
invert_m3_m3(tc->imat3, tc->mat3);
normalize_m3_m3(tc->mat3_unit, tc->mat3);
}
diff --git a/source/blender/editors/transform/transform_gizmo_3d.c b/source/blender/editors/transform/transform_gizmo_3d.c
index 50610f1b3da..35fda39e8dc 100644
--- a/source/blender/editors/transform/transform_gizmo_3d.c
+++ b/source/blender/editors/transform/transform_gizmo_3d.c
@@ -1762,6 +1762,15 @@ static void WIDGETGROUP_gizmo_refresh(const bContext *C, wmGizmoGroup *gzgroup)
}
}
MAN_ITER_AXES_END;
+
+ /* Ensure rotate disks don't overlap scale arrows, especially in ortho view. */
+ float rotate_select_bias = 0.0f;
+ if ((ggd->twtype & V3D_GIZMO_SHOW_OBJECT_SCALE) && ggd->twtype & V3D_GIZMO_SHOW_OBJECT_ROTATE) {
+ rotate_select_bias = -2.0f;
+ }
+ for (int i = MAN_AXIS_RANGE_ROT_START; i < MAN_AXIS_RANGE_ROT_END; i++) {
+ ggd->gizmos[i]->select_bias = rotate_select_bias;
+ }
}
static void WIDGETGROUP_gizmo_message_subscribe(const bContext *C,
diff --git a/source/blender/editors/util/CMakeLists.txt b/source/blender/editors/util/CMakeLists.txt
index 3b49784d5eb..0564cb07897 100644
--- a/source/blender/editors/util/CMakeLists.txt
+++ b/source/blender/editors/util/CMakeLists.txt
@@ -84,6 +84,7 @@ set(SRC
../include/ED_sound.h
../include/ED_space_api.h
../include/ED_text.h
+ ../include/ED_time_scrub_ui.h
../include/ED_transform.h
../include/ED_transform_snap_object_context.h
../include/ED_transverts.h
diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c
index 804b9c22104..3a5aead3d44 100644
--- a/source/blender/editors/uvedit/uvedit_draw.c
+++ b/source/blender/editors/uvedit/uvedit_draw.c
@@ -170,6 +170,7 @@ static void uvedit_get_batches(Object *ob,
const bool draw_stretch = (sima->flag & SI_DRAW_STRETCH) != 0;
const bool draw_faces = (sima->flag & SI_NO_DRAWFACES) == 0;
+ DRW_mesh_batch_cache_validate(ob->data);
*edges = DRW_mesh_batch_cache_get_edituv_edges(ob->data);
*verts = DRW_mesh_batch_cache_get_edituv_verts(ob->data);
@@ -206,6 +207,7 @@ static void draw_uvs_shadow(SpaceImage *UNUSED(sima),
float col[4];
UI_GetThemeColor4fv(TH_UV_SHADOW, col);
+ DRW_mesh_batch_cache_validate(me);
GPUBatch *edges = DRW_mesh_batch_cache_get_uv_edges(me);
DRW_mesh_batch_cache_create_requested(eval_ob, me, scene->toolsettings, false, false);
@@ -228,6 +230,7 @@ static void draw_uvs_texpaint(Scene *scene, Object *ob, Depsgraph *depsgraph)
return;
}
+ DRW_mesh_batch_cache_validate(me);
GPUBatch *geom = DRW_mesh_batch_cache_get_uv_edges(me);
DRW_mesh_batch_cache_create_requested(eval_ob, me, scene->toolsettings, false, false);
diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
index 85393925802..717bc347cf7 100644
--- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c
+++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
@@ -386,6 +386,10 @@ static ParamHandle *construct_param_handle_multi(Scene *scene,
const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ if (cd_loop_uv_offset == -1) {
+ continue;
+ }
+
BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) {
if ((BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) ||
diff --git a/source/blender/freestyle/intern/geometry/Noise.cpp b/source/blender/freestyle/intern/geometry/Noise.cpp
index 09c29025d15..8b81660fd58 100644
--- a/source/blender/freestyle/intern/geometry/Noise.cpp
+++ b/source/blender/freestyle/intern/geometry/Noise.cpp
@@ -24,6 +24,9 @@
#include <stdlib.h>
#include <time.h>
+#include "BLI_compiler_attrs.h"
+#include "BLI_rand.h"
+
#include "Noise.h"
namespace Freestyle {
@@ -40,9 +43,7 @@ namespace Freestyle {
((s) * (RTable[m] * 0.5 + RTable[m + 1] * (x) + RTable[m + 2] * (y) + RTable[m + 3] * (z)))
# define MAXSIZE 500
-# define NRAND() ((float)rand() / (float)RAND_MAX)
#endif
-#define SEEDNRAND(x) (srand(x * RAND_MAX))
#define BM 0xff
#define N 0x1000
@@ -236,25 +237,26 @@ float Noise::smoothNoise3(Vec3f &vec)
Noise::Noise(long seed)
{
+ /* Use Blender RNG for repeatable results across platforms. */
+ RNG *rng = BLI_rng_new(seed);
int i, j, k;
- SEEDNRAND((seed < 0) ? time(NULL) : seed);
for (i = 0; i < _NOISE_B; i++) {
p[i] = i;
- g1[i] = (float)((rand() % (_NOISE_B + _NOISE_B)) - _NOISE_B) / _NOISE_B;
+ g1[i] = (float)((BLI_rng_get_int(rng) % (_NOISE_B + _NOISE_B)) - _NOISE_B) / _NOISE_B;
for (j = 0; j < 2; j++)
- g2[i][j] = (float)((rand() % (_NOISE_B + _NOISE_B)) - _NOISE_B) / _NOISE_B;
+ g2[i][j] = (float)((BLI_rng_get_int(rng) % (_NOISE_B + _NOISE_B)) - _NOISE_B) / _NOISE_B;
normalize2(g2[i]);
for (j = 0; j < 3; j++)
- g3[i][j] = (float)((rand() % (_NOISE_B + _NOISE_B)) - _NOISE_B) / _NOISE_B;
+ g3[i][j] = (float)((BLI_rng_get_int(rng) % (_NOISE_B + _NOISE_B)) - _NOISE_B) / _NOISE_B;
normalize3(g3[i]);
}
while (--i) {
k = p[i];
- p[i] = p[j = rand() % _NOISE_B];
+ p[i] = p[j = BLI_rng_get_int(rng) % _NOISE_B];
p[j] = k;
}
@@ -268,6 +270,8 @@ Noise::Noise(long seed)
for (j = 0; j < 3; j++)
g3[_NOISE_B + i][j] = g3[i][j];
}
+
+ BLI_rng_free(rng);
}
} /* namespace Freestyle */
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 5a42c4d3d1b..f30eff1484b 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -178,7 +178,6 @@ data_to_c_simple(shaders/gpu_shader_3D_image_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_normal_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_flat_color_vert.glsl SRC)
-data_to_c_simple(shaders/gpu_shader_3D_line_dashed_uniform_color_legacy_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_line_dashed_uniform_color_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_smooth_color_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_normal_smooth_color_vert.glsl SRC)
@@ -225,14 +224,6 @@ data_to_c_simple(shaders/gpu_shader_2D_edituvs_stretch_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_selection_id_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_selection_id_frag.glsl SRC)
-data_to_c_simple(shaders/gpu_shader_edges_front_back_persp_vert.glsl SRC)
-data_to_c_simple(shaders/gpu_shader_edges_front_back_persp_geom.glsl SRC)
-data_to_c_simple(shaders/gpu_shader_edges_front_back_persp_legacy_vert.glsl SRC)
-data_to_c_simple(shaders/gpu_shader_edges_front_back_ortho_vert.glsl SRC)
-data_to_c_simple(shaders/gpu_shader_edges_overlay_vert.glsl SRC)
-data_to_c_simple(shaders/gpu_shader_edges_overlay_geom.glsl SRC)
-data_to_c_simple(shaders/gpu_shader_edges_overlay_simple_geom.glsl SRC)
-data_to_c_simple(shaders/gpu_shader_edges_overlay_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_text_simple_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_text_simple_geom.glsl SRC)
data_to_c_simple(shaders/gpu_shader_text_vert.glsl SRC)
diff --git a/source/blender/gpu/GPU_batch.h b/source/blender/gpu/GPU_batch.h
index 856148563f2..783bfb0b1f0 100644
--- a/source/blender/gpu/GPU_batch.h
+++ b/source/blender/gpu/GPU_batch.h
@@ -33,6 +33,7 @@
#include "GPU_shader.h"
typedef enum {
+ GPU_BATCH_UNUSED,
GPU_BATCH_READY_TO_FORMAT,
GPU_BATCH_READY_TO_BUILD,
GPU_BATCH_BUILDING,
diff --git a/source/blender/gpu/GPU_buffers.h b/source/blender/gpu/GPU_buffers.h
index 718553e2b1c..9009c134837 100644
--- a/source/blender/gpu/GPU_buffers.h
+++ b/source/blender/gpu/GPU_buffers.h
@@ -32,10 +32,10 @@ struct CCGKey;
struct DMFlagMat;
struct GSet;
struct MLoop;
+struct MLoopCol;
struct MLoopTri;
struct MPoly;
struct MVert;
-struct MLoopCol;
struct PBVH;
/* Buffers for drawing from PBVH grids. */
diff --git a/source/blender/gpu/GPU_draw.h b/source/blender/gpu/GPU_draw.h
index 300fc7c65a2..eb54ff127d8 100644
--- a/source/blender/gpu/GPU_draw.h
+++ b/source/blender/gpu/GPU_draw.h
@@ -84,7 +84,7 @@ void GPU_create_gl_tex(unsigned int *bind,
int recth,
int textarget,
bool mipmap,
- bool use_hight_bit_depth,
+ bool use_srgb,
struct Image *ima);
void GPU_create_gl_tex_compressed(unsigned int *bind,
unsigned int *pix,
diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h
index da61dc76422..dd5292d9c58 100644
--- a/source/blender/gpu/GPU_material.h
+++ b/source/blender/gpu/GPU_material.h
@@ -107,7 +107,7 @@ typedef enum eGPUBuiltin {
GPU_VOLUME_TEMPERATURE = (1 << 18),
GPU_BARYCENTRIC_TEXCO = (1 << 19),
GPU_BARYCENTRIC_DIST = (1 << 20),
- GPU_INVERSE_NORMAL_MATRIX = (1 << 21),
+ GPU_WORLD_NORMAL = (1 << 21),
} eGPUBuiltin;
typedef enum eGPUMatFlag {
@@ -145,7 +145,7 @@ typedef enum eGPUMaterialStatus {
GPUNodeLink *GPU_attribute(CustomDataType type, const char *name);
GPUNodeLink *GPU_constant(float *num);
GPUNodeLink *GPU_uniform(float *num);
-GPUNodeLink *GPU_image(struct Image *ima, struct ImageUser *iuser, bool is_data);
+GPUNodeLink *GPU_image(struct Image *ima, struct ImageUser *iuser);
GPUNodeLink *GPU_color_band(GPUMaterial *mat, int size, float *pixels, float *layer);
GPUNodeLink *GPU_builtin(eGPUBuiltin builtin);
@@ -177,6 +177,7 @@ GPUMaterial *GPU_material_from_nodetree_find(struct ListBase *gpumaterials,
const void *engine_type,
int options);
GPUMaterial *GPU_material_from_nodetree(struct Scene *scene,
+ struct Material *ma,
struct bNodeTree *ntree,
struct ListBase *gpumaterials,
const void *engine_type,
@@ -194,6 +195,7 @@ void GPU_materials_free(struct Main *bmain);
struct Scene *GPU_material_scene(GPUMaterial *material);
struct GPUPass *GPU_material_get_pass(GPUMaterial *material);
struct ListBase *GPU_material_get_inputs(GPUMaterial *material);
+struct Material *GPU_material_get_material(GPUMaterial *material);
eGPUMaterialStatus GPU_material_status(GPUMaterial *mat);
struct GPUUniformBuffer *GPU_material_uniform_buffer_get(GPUMaterial *material);
@@ -202,7 +204,6 @@ struct GPUUniformBuffer *GPU_material_create_sss_profile_ubo(void);
void GPU_material_vertex_attrs(GPUMaterial *material, struct GPUVertAttrLayers *attrs);
-bool GPU_material_do_color_management(GPUMaterial *mat);
bool GPU_material_use_domain_surface(GPUMaterial *mat);
bool GPU_material_use_domain_volume(GPUMaterial *mat);
diff --git a/source/blender/gpu/GPU_matrix.h b/source/blender/gpu/GPU_matrix.h
index 67fb2bb2bd4..6f7d25dafa7 100644
--- a/source/blender/gpu/GPU_matrix.h
+++ b/source/blender/gpu/GPU_matrix.h
@@ -106,6 +106,11 @@ bool GPU_matrix_unproject(const float win[3],
const float proj[4][4],
const int view[4],
float world[3]);
+void GPU_matrix_unproject_model_inverted(const float win[3],
+ const float model_inverted[4][4],
+ const float proj[4][4],
+ const int view[4],
+ float world[3]);
/* 2D Projection Matrix */
diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h
index d174aafacce..00570bd7ebc 100644
--- a/source/blender/gpu/GPU_shader.h
+++ b/source/blender/gpu/GPU_shader.h
@@ -100,10 +100,6 @@ typedef enum eGPUBuiltinShader {
/* specialized drawing */
GPU_SHADER_TEXT,
GPU_SHADER_TEXT_SIMPLE,
- GPU_SHADER_EDGES_FRONT_BACK_PERSP,
- GPU_SHADER_EDGES_FRONT_BACK_ORTHO,
- GPU_SHADER_EDGES_OVERLAY_SIMPLE,
- GPU_SHADER_EDGES_OVERLAY,
GPU_SHADER_KEYFRAME_DIAMOND,
GPU_SHADER_SIMPLE_LIGHTING,
GPU_SHADER_SIMPLE_LIGHTING_FLAT_COLOR,
@@ -402,10 +398,7 @@ void GPU_shader_free_builtin_shaders(void);
typedef struct GPUVertAttrLayers {
struct {
- int type;
- int glindex;
- int glinfoindoex;
- int gltexco;
+ int type; /* CustomDataType */
int attr_id;
char name[64]; /* MAX_CUSTOMDATA_LAYER_NAME */
} layer[GPU_MAX_ATTR];
diff --git a/source/blender/gpu/GPU_shader_interface.h b/source/blender/gpu/GPU_shader_interface.h
index ace8832303b..fc7d9e22ea3 100644
--- a/source/blender/gpu/GPU_shader_interface.h
+++ b/source/blender/gpu/GPU_shader_interface.h
@@ -45,13 +45,10 @@ typedef enum {
GPU_UNIFORM_VIEWPROJECTION_INV, /* mat4 ViewProjectionMatrixInverse */
GPU_UNIFORM_NORMAL, /* mat3 NormalMatrix */
- GPU_UNIFORM_NORMAL_INV, /* mat3 NormalMatrixInverse */
- GPU_UNIFORM_WORLDNORMAL, /* mat3 WorldNormalMatrix */
GPU_UNIFORM_CAMERATEXCO, /* vec4 CameraTexCoFactors */
GPU_UNIFORM_ORCO, /* vec3 OrcoTexCoFactors[] */
GPU_UNIFORM_COLOR, /* vec4 color */
- GPU_UNIFORM_EYE, /* vec3 eye */
GPU_UNIFORM_CALLID, /* int callId */
GPU_UNIFORM_OBJECT_INFO, /* vec3 objectInfo */
diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h
index 3527398a396..3fb7dfc6331 100644
--- a/source/blender/gpu/GPU_texture.h
+++ b/source/blender/gpu/GPU_texture.h
@@ -186,10 +186,7 @@ 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,
- int textarget,
- bool is_data);
+GPUTexture *GPU_texture_from_blender(struct Image *ima, struct ImageUser *iuser, int textarget);
GPUTexture *GPU_texture_from_preview(struct PreviewImage *prv, int mipmap);
void GPU_texture_add_mipmap(GPUTexture *tex,
diff --git a/source/blender/gpu/GPU_vertex_buffer.h b/source/blender/gpu/GPU_vertex_buffer.h
index 6d88460964d..3e178e193dc 100644
--- a/source/blender/gpu/GPU_vertex_buffer.h
+++ b/source/blender/gpu/GPU_vertex_buffer.h
@@ -48,12 +48,17 @@ typedef enum {
typedef struct GPUVertBuf {
GPUVertFormat format;
- uint vertex_len; /* number of verts we want to draw */
- uint vertex_alloc; /* number of verts data */
- bool dirty;
+ /** Number of verts we want to draw. */
+ uint vertex_len;
+ /** Number of verts data. */
+ uint vertex_alloc;
+ /** 0 indicates not yet allocated. */
+ uint32_t vbo_id;
+ /** Usage hint for GL optimisation. */
+ uint usage : 2;
+ /** Data has been touched and need to be reuploaded to GPU. */
+ uint dirty : 1;
unsigned char *data; /* NULL indicates data in VRAM (unmapped) */
- uint32_t vbo_id; /* 0 indicates not yet allocated */
- GPUUsageType usage; /* usage hint for GL optimisation */
} GPUVertBuf;
GPUVertBuf *GPU_vertbuf_create(GPUUsageType);
@@ -62,6 +67,7 @@ GPUVertBuf *GPU_vertbuf_create_with_format_ex(const GPUVertFormat *, GPUUsageTyp
#define GPU_vertbuf_create_with_format(format) \
GPU_vertbuf_create_with_format_ex(format, GPU_USAGE_STATIC)
+void GPU_vertbuf_clear(GPUVertBuf *verts);
void GPU_vertbuf_discard(GPUVertBuf *);
void GPU_vertbuf_init(GPUVertBuf *, GPUUsageType);
diff --git a/source/blender/gpu/GPU_vertex_format.h b/source/blender/gpu/GPU_vertex_format.h
index 7f1934431cf..43eec55bca2 100644
--- a/source/blender/gpu/GPU_vertex_format.h
+++ b/source/blender/gpu/GPU_vertex_format.h
@@ -27,6 +27,8 @@
#define __GPU_VERTEX_FORMAT_H__
#include "GPU_common.h"
+#include "BLI_compiler_compat.h"
+#include "BLI_assert.h"
#define GPU_VERT_ATTR_MAX_LEN 16
#define GPU_VERT_ATTR_MAX_NAMES 4
@@ -54,28 +56,41 @@ typedef enum {
} GPUVertFetchMode;
typedef struct GPUVertAttr {
- GPUVertFetchMode fetch_mode;
- GPUVertCompType comp_type;
+ uint fetch_mode : 2;
+ uint comp_type : 3;
+ /* 1 to 4 or 8 or 12 or 16 */
+ uint comp_len : 5;
+ /* size in bytes, 1 to 64 */
+ uint sz : 7;
+ /* from beginning of vertex, in bytes */
+ uint offset : 11;
+ /* up to GPU_VERT_ATTR_MAX_NAMES */
+ uint name_len : 3;
uint gl_comp_type;
- uint comp_len; /* 1 to 4 or 8 or 12 or 16 */
- uint sz; /* size in bytes, 1 to 64 */
- uint offset; /* from beginning of vertex, in bytes */
- uint name_len; /* up to GPU_VERT_ATTR_MAX_NAMES */
- const char *name[GPU_VERT_ATTR_MAX_NAMES];
+ /* -- 8 Bytes -- */
+ uchar names[GPU_VERT_ATTR_MAX_NAMES];
} GPUVertAttr;
+BLI_STATIC_ASSERT(GPU_VERT_ATTR_NAMES_BUF_LEN <= 256,
+ "We use uchar as index inside the name buffer "
+ "so GPU_VERT_ATTR_NAMES_BUF_LEN needs to be be "
+ "smaller than GPUVertFormat->name_offset and "
+ "GPUVertAttr->names maximum value");
+
typedef struct GPUVertFormat {
/** 0 to 16 (GPU_VERT_ATTR_MAX_LEN). */
- uint attr_len;
+ uint attr_len : 5;
/** Total count of active vertex attribute. */
- uint name_len;
- /** Stride in bytes, 1 to 256. */
- uint stride;
- uint name_offset;
- bool packed;
- char names[GPU_VERT_ATTR_NAMES_BUF_LEN];
- /** TODO: variable-size array */
+ uint name_len : 5;
+ /** Stride in bytes, 1 to 1024. */
+ uint stride : 11;
+ /** Has the format been packed. */
+ uint packed : 1;
+ /** Current offset in names[]. */
+ uint name_offset : 8;
+
GPUVertAttr attrs[GPU_VERT_ATTR_MAX_LEN];
+ char names[GPU_VERT_ATTR_NAMES_BUF_LEN];
} GPUVertFormat;
struct GPUShaderInterface;
@@ -88,18 +103,15 @@ void GPU_vertformat_from_interface(GPUVertFormat *format,
uint GPU_vertformat_attr_add(
GPUVertFormat *, const char *name, GPUVertCompType, uint comp_len, GPUVertFetchMode);
void GPU_vertformat_alias_add(GPUVertFormat *, const char *alias);
+
int GPU_vertformat_attr_id_get(const GPUVertFormat *, const char *name);
-/**
- * This makes the "virtual" attributes with suffixes "0", "1", "2"
- * to access triangle data in the vertex shader.
- *
- * IMPORTANT:
- * - Call this before creating the vertex buffer and after creating all attributes
- * - Only first vertex out of 3 has the correct information.
- * Use flat output with #GL_FIRST_VERTEX_CONVENTION.
- */
-void GPU_vertformat_triple_load(GPUVertFormat *format);
+BLI_INLINE const char *GPU_vertformat_attr_name_get(const GPUVertFormat *format,
+ const GPUVertAttr *attr,
+ uint n_idx)
+{
+ return format->names + attr->names[n_idx];
+}
/* format conversion */
diff --git a/source/blender/gpu/GPU_viewport.h b/source/blender/gpu/GPU_viewport.h
index 198a9ec98e2..e61cfe363df 100644
--- a/source/blender/gpu/GPU_viewport.h
+++ b/source/blender/gpu/GPU_viewport.h
@@ -37,12 +37,12 @@ typedef struct GPUViewport GPUViewport;
/* Contains memory pools information */
typedef struct ViewportMemoryPool {
- struct BLI_mempool *calls;
- struct BLI_mempool *states;
- struct BLI_mempool *shgroups;
- struct BLI_mempool *uniforms;
- struct BLI_mempool *passes;
- struct BLI_mempool *images;
+ struct BLI_memblock *calls;
+ struct BLI_memblock *states;
+ struct BLI_memblock *shgroups;
+ struct BLI_memblock *uniforms;
+ struct BLI_memblock *passes;
+ struct BLI_memblock *images;
} ViewportMemoryPool;
/* All FramebufferLists are just the same pointers with different names */
@@ -118,7 +118,7 @@ GPUTexture *GPU_viewport_color_texture(GPUViewport *viewport);
GPUTexture *GPU_viewport_texture_pool_query(
GPUViewport *viewport, void *engine, int width, int height, int format);
-bool GPU_viewport_engines_data_validate(GPUViewport *viewport, unsigned int hash);
+bool GPU_viewport_engines_data_validate(GPUViewport *viewport, void **engine_handle_array);
void GPU_viewport_cache_release(GPUViewport *viewport);
#endif // __GPU_VIEWPORT_H__
diff --git a/source/blender/gpu/intern/gpu_attr_binding.c b/source/blender/gpu/intern/gpu_attr_binding.c
index e280b77f661..802b15a0c4e 100644
--- a/source/blender/gpu/intern/gpu_attr_binding.c
+++ b/source/blender/gpu/intern/gpu_attr_binding.c
@@ -70,7 +70,8 @@ void get_attr_locations(const GPUVertFormat *format,
for (uint a_idx = 0; a_idx < format->attr_len; ++a_idx) {
const GPUVertAttr *a = &format->attrs[a_idx];
for (uint n_idx = 0; n_idx < a->name_len; ++n_idx) {
- const GPUShaderInput *input = GPU_shaderinterface_attr(shaderface, a->name[n_idx]);
+ const char *name = GPU_vertformat_attr_name_get(format, a, n_idx);
+ const GPUShaderInput *input = GPU_shaderinterface_attr(shaderface, name);
#if TRUST_NO_ONE
assert(input != NULL);
/* TODO: make this a recoverable runtime error?
diff --git a/source/blender/gpu/intern/gpu_batch.c b/source/blender/gpu/intern/gpu_batch.c
index f179f9ef22c..45697befe50 100644
--- a/source/blender/gpu/intern/gpu_batch.c
+++ b/source/blender/gpu/intern/gpu_batch.c
@@ -139,6 +139,7 @@ void GPU_batch_clear(GPUBatch *batch)
}
}
GPU_batch_vao_cache_clear(batch);
+ batch->phase = GPU_BATCH_UNUSED;
}
void GPU_batch_discard(GPUBatch *batch)
@@ -369,7 +370,8 @@ static void create_bindings(GPUVertBuf *verts,
const GLvoid *pointer = (const GLubyte *)0 + a->offset + v_first * stride;
for (uint n_idx = 0; n_idx < a->name_len; ++n_idx) {
- const GPUShaderInput *input = GPU_shaderinterface_attr(interface, a->name[n_idx]);
+ const char *name = GPU_vertformat_attr_name_get(format, a, n_idx);
+ const GPUShaderInput *input = GPU_shaderinterface_attr(interface, name);
if (input == NULL) {
continue;
diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c
index a77bba5ab86..8dda98ab990 100644
--- a/source/blender/gpu/intern/gpu_codegen.c
+++ b/source/blender/gpu/intern/gpu_codegen.c
@@ -520,9 +520,6 @@ const char *GPU_builtin_name(eGPUBuiltin builtin)
else if (builtin == GPU_INVERSE_OBJECT_MATRIX) {
return "unfinvobmat";
}
- else if (builtin == GPU_INVERSE_NORMAL_MATRIX) {
- return "unfinvnormat";
- }
else if (builtin == GPU_LOC_TO_VIEW_MATRIX) {
return "unflocaltoviewmat";
}
@@ -532,6 +529,9 @@ const char *GPU_builtin_name(eGPUBuiltin builtin)
else if (builtin == GPU_VIEW_POSITION) {
return "varposition";
}
+ else if (builtin == GPU_WORLD_NORMAL) {
+ return "varwnormal";
+ }
else if (builtin == GPU_VIEW_NORMAL) {
return "varnormal";
}
@@ -786,15 +786,15 @@ static void codegen_call_functions(DynStr *ds, ListBase *nodes, GPUOutput *final
else if (input->builtin == GPU_INVERSE_OBJECT_MATRIX) {
BLI_dynstr_append(ds, "objinv");
}
- else if (input->builtin == GPU_INVERSE_NORMAL_MATRIX) {
- BLI_dynstr_append(ds, "norinv");
- }
else if (input->builtin == GPU_VIEW_POSITION) {
BLI_dynstr_append(ds, "viewposition");
}
else if (input->builtin == GPU_VIEW_NORMAL) {
BLI_dynstr_append(ds, "facingnormal");
}
+ else if (input->builtin == GPU_WORLD_NORMAL) {
+ BLI_dynstr_append(ds, "facingwnormal");
+ }
else {
BLI_dynstr_append(ds, GPU_builtin_name(input->builtin));
}
@@ -879,17 +879,15 @@ static char *code_generate_fragment(GPUMaterial *material,
if (builtins & GPU_INVERSE_OBJECT_MATRIX) {
BLI_dynstr_append(ds, "\t#define objinv ModelMatrixInverse\n");
}
- if (builtins & GPU_INVERSE_NORMAL_MATRIX) {
- BLI_dynstr_append(ds, "\t#define norinv NormalMatrixInverse\n");
- }
if (builtins & GPU_INVERSE_VIEW_MATRIX) {
BLI_dynstr_append(ds, "\t#define viewinv ViewMatrixInverse\n");
}
if (builtins & GPU_LOC_TO_VIEW_MATRIX) {
- BLI_dynstr_append(ds, "\t#define localtoviewmat ModelViewMatrix\n");
+ BLI_dynstr_append(ds, "\t#define localtoviewmat (ViewMatrix * ModelMatrix)\n");
}
if (builtins & GPU_INVERSE_LOC_TO_VIEW_MATRIX) {
- BLI_dynstr_append(ds, "\t#define invlocaltoviewmat ModelViewMatrixInverse\n");
+ BLI_dynstr_append(ds,
+ "\t#define invlocaltoviewmat (ModelMatrixInverse * ViewMatrixInverse)\n");
}
if (builtins & GPU_VIEW_NORMAL) {
BLI_dynstr_append(ds, "#ifdef HAIR_SHADER\n");
@@ -897,9 +895,22 @@ static char *code_generate_fragment(GPUMaterial *material,
BLI_dynstr_append(ds, "\tworld_normals_get(n);\n");
BLI_dynstr_append(ds, "\tvec3 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, "\tvec3 facingnormal = gl_FrontFacing ? viewNormal: -viewNormal;\n");
BLI_dynstr_append(ds, "#endif\n");
}
+ if (builtins & GPU_WORLD_NORMAL) {
+ BLI_dynstr_append(ds, "\tvec3 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, "#else\n");
+ BLI_dynstr_append(ds, "\tworld_normals_get(facingwnormal);\n");
+ BLI_dynstr_append(ds, "#endif\n");
+ }
+ else {
+ BLI_dynstr_append(ds, "\tworld_normals_get(facingwnormal);\n");
+ }
+ }
if (builtins & GPU_VIEW_POSITION) {
BLI_dynstr_append(ds, "\t#define viewposition viewPosition\n");
}
@@ -1024,13 +1035,39 @@ static char *code_generate_vertex(ListBase *nodes, const char *vert_code, bool u
BLI_dynstr_append(ds, "out vec3 barycentricPosg;\n");
}
+ BLI_dynstr_append(ds, "\n#define USE_ATTR\n");
+
+ /* Prototype, defined later (this is because of matrices definition). */
+ BLI_dynstr_append(ds, "void pass_attr(in vec3 position);\n");
+
+ BLI_dynstr_append(ds, "\n");
+
+ if (use_geom) {
+ /* XXX HACK: Eevee specific. */
+ char *vert_new, *vert_new2;
+ vert_new = BLI_str_replaceN(vert_code, "worldPosition", "worldPositiong");
+ vert_new2 = vert_new;
+ vert_new = BLI_str_replaceN(vert_new2, "viewPosition", "viewPositiong");
+ MEM_freeN(vert_new2);
+ vert_new2 = vert_new;
+ vert_new = BLI_str_replaceN(vert_new2, "worldNormal", "worldNormalg");
+ MEM_freeN(vert_new2);
+ vert_new2 = vert_new;
+ vert_new = BLI_str_replaceN(vert_new2, "viewNormal", "viewNormalg");
+ MEM_freeN(vert_new2);
+
+ BLI_dynstr_append(ds, vert_new);
+
+ MEM_freeN(vert_new);
+ }
+ else {
+ BLI_dynstr_append(ds, vert_code);
+ }
+
BLI_dynstr_append(ds, "\n");
BLI_dynstr_append(ds,
"#define USE_ATTR\n"
- "uniform mat3 NormalMatrix;\n"
- "uniform mat4 ModelMatrixInverse;\n"
- "uniform mat4 ModelMatrix;\n"
"vec3 srgb_to_linear_attr(vec3 c) {\n"
"\tc = max(c, vec3(0.0));\n"
"\tvec3 c1 = c * (1.0 / 12.92);\n"
@@ -1108,7 +1145,7 @@ static char *code_generate_vertex(ListBase *nodes, const char *vert_code, bool u
if (input->source == GPU_SOURCE_ATTR && input->attr_first) {
if (input->attr_type == CD_TANGENT) { /* silly exception */
BLI_dynstr_appendf(ds,
- "\tvar%d%s.xyz = NormalMatrix * att%d.xyz;\n",
+ "\tvar%d%s.xyz = transpose(mat3(ModelMatrixInverse)) * att%d.xyz;\n",
input->attr_id,
use_geom ? "g" : "",
input->attr_id);
@@ -1167,28 +1204,6 @@ static char *code_generate_vertex(ListBase *nodes, const char *vert_code, bool u
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);
- }
-
code = BLI_dynstr_get_cstring(ds);
BLI_dynstr_free(ds);
@@ -1494,7 +1509,6 @@ static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, const eGPUType
input->source = GPU_SOURCE_TEX;
input->ima = link->ima;
input->iuser = link->iuser;
- input->image_isdata = link->image_isdata;
break;
case GPU_NODE_LINK_ATTR:
input->source = GPU_SOURCE_ATTR;
@@ -1739,13 +1753,12 @@ GPUNodeLink *GPU_uniform(float *num)
return link;
}
-GPUNodeLink *GPU_image(Image *ima, ImageUser *iuser, bool is_data)
+GPUNodeLink *GPU_image(Image *ima, ImageUser *iuser)
{
GPUNodeLink *link = GPU_node_link_create();
link->link_type = GPU_NODE_LINK_IMAGE_BLENDER;
link->ima = ima;
link->iuser = iuser;
- link->image_isdata = is_data;
return link;
}
diff --git a/source/blender/gpu/intern/gpu_codegen.h b/source/blender/gpu/intern/gpu_codegen.h
index 73155c3aafa..d1bb3f26920 100644
--- a/source/blender/gpu/intern/gpu_codegen.h
+++ b/source/blender/gpu/intern/gpu_codegen.h
@@ -99,7 +99,6 @@ struct GPUNodeLink {
struct {
struct Image *ima;
struct ImageUser *iuser;
- bool image_isdata;
};
};
};
@@ -137,7 +136,6 @@ typedef struct GPUInput {
struct GPUTexture **coba; /* input texture, only set at runtime */
struct Image *ima; /* image */
struct ImageUser *iuser; /* image user */
- bool image_isdata; /* image does not contain color data */
bool bindtex; /* input is responsible for binding the texture? */
int texid; /* number for multitexture, starting from zero */
eGPUType textype; /* texture type (2D, 1D Array ...) */
diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c
index edc2f2171a5..f1c82dc53a7 100644
--- a/source/blender/gpu/intern/gpu_draw.c
+++ b/source/blender/gpu/intern/gpu_draw.c
@@ -50,6 +50,7 @@
#include "MEM_guardedalloc.h"
+#include "IMB_colormanagement.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
@@ -207,53 +208,232 @@ static GPUTexture **gpu_get_image_gputexture(Image *ima, GLenum textarget)
return NULL;
}
-typedef struct VerifyThreadData {
- ImBuf *ibuf;
- float *srgb_frect;
-} VerifyThreadData;
+static uint gpu_texture_create_from_ibuf(Image *ima, ImBuf *ibuf, int textarget)
+{
+ uint bindcode = 0;
+ const bool mipmap = GPU_get_mipmap();
+
+#ifdef WITH_DDS
+ if (ibuf->ftype == IMB_FTYPE_DDS) {
+ /* DDS is loaded directly in compressed form. */
+ GPU_create_gl_tex_compressed(
+ &bindcode, ibuf->rect, ibuf->x, ibuf->y, textarget, mipmap, 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;
+ }
+
+ IMB_colormanagement_imbuf_to_srgb_texture(
+ rect, 0, 0, ibuf->x, ibuf->y, ibuf, compress_as_srgb);
+ }
+ }
+ else if (ibuf->channels != 4) {
+ /* 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. */
+ rect_float = MEM_mallocN(sizeof(float) * 4 * ibuf->x * ibuf->y, __func__);
+ if (rect_float == NULL) {
+ return bindcode;
+ }
-static void gpu_verify_high_bit_srgb_buffer_slice(float *srgb_frect,
- ImBuf *ibuf,
- const int start_line,
- const int height)
+ IMB_buffer_float_from_float(rect_float,
+ ibuf->rect_float,
+ ibuf->channels,
+ IB_PROFILE_LINEAR_RGB,
+ IB_PROFILE_LINEAR_RGB,
+ false,
+ ibuf->x,
+ ibuf->y,
+ ibuf->x,
+ ibuf->x);
+ }
+
+ /* Create OpenGL texture. */
+ GPU_create_gl_tex(&bindcode,
+ (uint *)rect,
+ rect_float,
+ ibuf->x,
+ ibuf->y,
+ textarget,
+ mipmap,
+ 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 void gpu_texture_update_scaled(
+ uchar *rect, float *rect_float, int full_w, int full_h, int x, int y, int w, int h)
{
- size_t offset = ibuf->channels * start_line * ibuf->x;
- float *current_srgb_frect = srgb_frect + offset;
- float *current_rect_float = ibuf->rect_float + offset;
- IMB_buffer_float_from_float(current_srgb_frect,
- current_rect_float,
- ibuf->channels,
- IB_PROFILE_SRGB,
- IB_PROFILE_LINEAR_RGB,
- true,
- ibuf->x,
- height,
- ibuf->x,
- ibuf->x);
- IMB_buffer_float_unpremultiply(current_srgb_frect, ibuf->x, height);
+ /* Partial update with scaling. */
+ int limit_w = smaller_power_of_2_limit(full_w);
+ int limit_h = smaller_power_of_2_limit(full_h);
+ float xratio = limit_w / (float)full_w;
+ float yratio = limit_h / (float)full_h;
+
+ /* Find sub coordinates in scaled image. Take ceiling because we will be
+ * losing 1 pixel due to rounding errors in x,y. */
+ int sub_x = x * xratio;
+ int sub_y = y * yratio;
+ int sub_w = (int)ceil(xratio * w);
+ int sub_h = (int)ceil(yratio * h);
+
+ /* ...but take back if we are over the limit! */
+ if (sub_w + sub_x > limit_w) {
+ sub_w--;
+ }
+ if (sub_h + sub_y > limit_h) {
+ sub_h--;
+ }
+
+ /* Scale pixels. */
+ ImBuf *ibuf = IMB_allocFromBuffer((uint *)rect, rect_float, w, h);
+ IMB_scaleImBuf(ibuf, sub_w, sub_h);
+
+ if (ibuf->rect_float) {
+ glTexSubImage2D(
+ GL_TEXTURE_2D, 0, sub_x, sub_y, sub_w, sub_h, GL_RGBA, GL_FLOAT, ibuf->rect_float);
+ }
+ else {
+ glTexSubImage2D(
+ GL_TEXTURE_2D, 0, sub_x, sub_y, sub_w, sub_h, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
+ }
+
+ IMB_freeImBuf(ibuf);
}
-static void verify_thread_do(void *data_v, int start_scanline, int num_scanlines)
+static void gpu_texture_update_unscaled(
+ uchar *rect, float *rect_float, int x, int y, int w, int h, GLint tex_stride, GLint tex_offset)
{
- VerifyThreadData *data = (VerifyThreadData *)data_v;
- gpu_verify_high_bit_srgb_buffer_slice(
- data->srgb_frect, data->ibuf, start_scanline, num_scanlines);
+ /* Partial update without scaling. Stride and offset are used to copy only a
+ * subset of a possible larger buffer than what we are updating. */
+ GLint row_length;
+ glGetIntegerv(GL_UNPACK_ROW_LENGTH, &row_length);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, tex_stride);
+
+ if (rect_float == NULL) {
+ glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, rect + tex_offset);
+ }
+ else {
+ glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA, GL_FLOAT, rect_float + tex_offset);
+ }
+
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length);
}
-static void gpu_verify_high_bit_srgb_buffer(float *srgb_frect, ImBuf *ibuf)
+static void gpu_texture_update_from_ibuf(ImBuf *ibuf, int x, int y, int w, int h)
{
- if (ibuf->y < 64) {
- gpu_verify_high_bit_srgb_buffer_slice(srgb_frect, ibuf, 0, ibuf->y);
+ /* Partial update of texture for texture painting. This is often much
+ * quicker than fully updating the texture for high resolution images.
+ * Assumes the OpenGL texture is bound to 0. */
+ const bool 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. */
+ IMB_colormanagement_imbuf_to_srgb_texture(rect, x, y, w, h, ibuf, compress_as_srgb);
+ }
+ }
+ else if (ibuf->channels != 4 || scaled) {
+ /* Float pixels. */
+ rect_float = MEM_mallocN(sizeof(float) * 4 * x * y, __func__);
+ if (rect_float == NULL) {
+ return;
+ }
+
+ tex_stride = w;
+ tex_offset = 0;
+
+ size_t ibuf_offset = (y * ibuf->x + x) * ibuf->channels;
+ IMB_buffer_float_from_float(rect_float,
+ ibuf->rect_float + ibuf_offset,
+ ibuf->channels,
+ IB_PROFILE_LINEAR_RGB,
+ IB_PROFILE_LINEAR_RGB,
+ false,
+ w,
+ h,
+ x,
+ ibuf->x);
+ }
+
+ if (scaled) {
+ /* Slower update where we first have to scale the input pixels. */
+ gpu_texture_update_scaled(rect, rect_float, ibuf->x, ibuf->y, x, y, w, h);
}
else {
- VerifyThreadData data;
- data.ibuf = ibuf;
- data.srgb_frect = srgb_frect;
- IMB_processor_apply_threaded_scanlines(ibuf->y, verify_thread_do, &data);
+ /* Fast update at same resolution. */
+ gpu_texture_update_unscaled(rect, rect_float, x, y, 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);
}
}
-GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, int textarget, bool is_data)
+GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, int textarget)
{
if (ima == NULL) {
return NULL;
@@ -286,62 +466,7 @@ GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, int textarget
return *tex;
}
- /* flag to determine whether deep format is used */
- bool use_high_bit_depth = false, do_color_management = false;
-
- if (ibuf->rect_float) {
- use_high_bit_depth = true;
-
- /* TODO unneeded when float images are correctly treated as linear always */
- if (!is_data) {
- do_color_management = true;
- }
- }
-
- const int rectw = ibuf->x;
- const int recth = ibuf->y;
- uint *rect = ibuf->rect;
- float *frect = NULL;
- float *srgb_frect = NULL;
-
- if (use_high_bit_depth) {
- if (do_color_management) {
- frect = srgb_frect = MEM_mallocN(ibuf->x * ibuf->y * sizeof(*srgb_frect) * 4,
- "floar_buf_col_cor");
- gpu_verify_high_bit_srgb_buffer(srgb_frect, ibuf);
- }
- else {
- frect = ibuf->rect_float;
- }
- }
-
- const bool mipmap = GPU_get_mipmap();
-
-#ifdef WITH_DDS
- if (ibuf->ftype == IMB_FTYPE_DDS) {
- GPU_create_gl_tex_compressed(&bindcode, rect, rectw, recth, textarget, mipmap, ima, ibuf);
- }
- else
-#endif
- {
- GPU_create_gl_tex(
- &bindcode, rect, frect, rectw, recth, textarget, mipmap, use_high_bit_depth, ima);
- }
-
- /* mark as non-color data texture */
- if (bindcode) {
- if (is_data) {
- ima->gpuflag |= IMA_GPU_IS_DATA;
- }
- else {
- ima->gpuflag &= ~IMA_GPU_IS_DATA;
- }
- }
-
- /* clean up */
- if (srgb_frect) {
- MEM_freeN(srgb_frect);
- }
+ bindcode = gpu_texture_create_from_ibuf(ima, ibuf, textarget);
BKE_image_release_ibuf(ima, ibuf, NULL);
@@ -349,15 +474,14 @@ GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, int textarget
return *tex;
}
-static void **gpu_gen_cube_map(
- uint *rect, float *frect, int rectw, int recth, bool use_high_bit_depth)
+static void **gpu_gen_cube_map(uint *rect, float *frect, int rectw, int recth)
{
- size_t block_size = use_high_bit_depth ? sizeof(float[4]) : sizeof(uchar[4]);
+ size_t block_size = frect ? sizeof(float[4]) : sizeof(uchar[4]);
void **sides = NULL;
int h = recth / 2;
int w = rectw / 3;
- if ((use_high_bit_depth && frect == NULL) || (!use_high_bit_depth && rect == NULL) || w != h) {
+ if (w != h) {
return sides;
}
@@ -376,7 +500,7 @@ static void **gpu_gen_cube_map(
* | NegZ | PosZ | PosY |
* |______|______|______|
*/
- if (use_high_bit_depth) {
+ if (frect) {
float(*frectb)[4] = (float(*)[4])frect;
float(**fsides)[4] = (float(**)[4])sides;
@@ -430,7 +554,7 @@ void GPU_create_gl_tex(uint *bind,
int recth,
int textarget,
bool mipmap,
- bool use_high_bit_depth,
+ bool use_srgb,
Image *ima)
{
ImBuf *ibuf = NULL;
@@ -441,7 +565,7 @@ void GPU_create_gl_tex(uint *bind,
rectw = smaller_power_of_2_limit(rectw);
recth = smaller_power_of_2_limit(recth);
- if (use_high_bit_depth) {
+ if (frect) {
ibuf = IMB_allocFromBuffer(NULL, frect, tpx, tpy);
IMB_scaleImBuf(ibuf, rectw, recth);
@@ -459,12 +583,15 @@ void GPU_create_gl_tex(uint *bind,
glGenTextures(1, (GLuint *)bind);
glBindTexture(textarget, *bind);
+ GLenum internal_format = (frect) ? GL_RGBA16F : (use_srgb) ? GL_SRGB8_ALPHA8 : GL_RGBA8;
+
if (textarget == GL_TEXTURE_2D) {
- if (use_high_bit_depth) {
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, rectw, recth, 0, GL_RGBA, GL_FLOAT, frect);
+ if (frect) {
+ glTexImage2D(GL_TEXTURE_2D, 0, internal_format, rectw, recth, 0, GL_RGBA, GL_FLOAT, frect);
}
else {
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, rectw, recth, 0, GL_RGBA, GL_UNSIGNED_BYTE, rect);
+ glTexImage2D(
+ GL_TEXTURE_2D, 0, internal_format, rectw, recth, 0, GL_RGBA, GL_UNSIGNED_BYTE, rect);
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
@@ -484,15 +611,14 @@ void GPU_create_gl_tex(uint *bind,
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, use_high_bit_depth);
- GLenum informat = use_high_bit_depth ? GL_RGBA16F : GL_RGBA8;
- GLenum type = use_high_bit_depth ? GL_FLOAT : GL_UNSIGNED_BYTE;
+ 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,
- informat,
+ internal_format,
w,
h,
0,
@@ -617,14 +743,14 @@ void GPU_create_gl_tex_compressed(
#ifndef WITH_DDS
(void)ibuf;
/* Fall back to uncompressed if DDS isn't enabled */
- GPU_create_gl_tex(bind, pix, NULL, x, y, textarget, mipmap, 0, ima);
+ GPU_create_gl_tex(bind, pix, NULL, x, y, textarget, mipmap, true, ima);
#else
glGenTextures(1, (GLuint *)bind);
glBindTexture(textarget, *bind);
if (textarget == GL_TEXTURE_2D && GPU_upload_dxt_texture(ibuf) == 0) {
glDeleteTextures(1, (GLuint *)bind);
- GPU_create_gl_tex(bind, pix, NULL, x, y, textarget, mipmap, 0, ima);
+ GPU_create_gl_tex(bind, pix, NULL, x, y, textarget, mipmap, true, ima);
}
glBindTexture(textarget, 0);
@@ -680,146 +806,20 @@ void GPU_paint_set_mipmap(Main *bmain, bool mipmap)
}
}
-/* check if image has been downscaled and do scaled partial update */
-static bool gpu_check_scaled_image(
- ImBuf *ibuf, Image *ima, float *frect, int x, int y, int w, int h)
-{
- if (is_over_resolution_limit(GL_TEXTURE_2D, ibuf->x, ibuf->y)) {
- int x_limit = smaller_power_of_2_limit(ibuf->x);
- int y_limit = smaller_power_of_2_limit(ibuf->y);
-
- float xratio = x_limit / (float)ibuf->x;
- float yratio = y_limit / (float)ibuf->y;
-
- /* find new width, height and x,y gpu texture coordinates */
-
- /* take ceiling because we will be losing 1 pixel due to rounding errors in x,y... */
- int rectw = (int)ceil(xratio * w);
- int recth = (int)ceil(yratio * h);
-
- x *= xratio;
- y *= yratio;
-
- /* ...but take back if we are over the limit! */
- if (rectw + x > x_limit) {
- rectw--;
- }
- if (recth + y > y_limit) {
- recth--;
- }
-
- GPU_texture_bind(ima->gputexture[TEXTARGET_TEXTURE_2D], 0);
-
- /* float rectangles are already continuous in memory so we can use IMB_scaleImBuf */
- if (frect) {
- ImBuf *ibuf_scale = IMB_allocFromBuffer(NULL, frect, w, h);
- IMB_scaleImBuf(ibuf_scale, rectw, recth);
-
- glTexSubImage2D(
- GL_TEXTURE_2D, 0, x, y, rectw, recth, GL_RGBA, GL_FLOAT, ibuf_scale->rect_float);
-
- IMB_freeImBuf(ibuf_scale);
- }
- /* byte images are not continuous in memory so do manual interpolation */
- else {
- uchar *scalerect = MEM_mallocN(rectw * recth * sizeof(*scalerect) * 4, "scalerect");
- uint *p = (uint *)scalerect;
- int i, j;
- float inv_xratio = 1.0f / xratio;
- float inv_yratio = 1.0f / yratio;
- for (i = 0; i < rectw; i++) {
- float u = (x + i) * inv_xratio;
- for (j = 0; j < recth; j++) {
- float v = (y + j) * inv_yratio;
- bilinear_interpolation_color_wrap(ibuf, (uchar *)(p + i + j * (rectw)), NULL, u, v);
- }
- }
-
- glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, rectw, recth, GL_RGBA, GL_UNSIGNED_BYTE, scalerect);
-
- MEM_freeN(scalerect);
- }
-
- if (GPU_get_mipmap()) {
- glGenerateMipmap(GL_TEXTURE_2D);
- }
- else {
- ima->gpuflag &= ~IMA_GPU_MIPMAP_COMPLETE;
- }
-
- GPU_texture_unbind(ima->gputexture[TEXTARGET_TEXTURE_2D]);
-
- return true;
- }
-
- return false;
-}
-
void GPU_paint_update_image(Image *ima, ImageUser *iuser, int x, int y, int w, int h)
{
ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL);
if ((ima->gputexture[TEXTARGET_TEXTURE_2D] == NULL) || (ibuf == NULL) || (w == 0) || (h == 0)) {
- /* these cases require full reload still */
+ /* Full reload of texture. */
GPU_free_image(ima);
}
else {
- /* for the special case, we can do a partial update
- * which is much quicker for painting */
- GLint row_length, skip_pixels, skip_rows;
-
- /* if color correction is needed, we must update the part that needs updating. */
- if (ibuf->rect_float) {
- float *buffer = MEM_mallocN(w * h * sizeof(float) * 4, "temp_texpaint_float_buf");
- bool is_data = (ima->gpuflag & IMA_GPU_IS_DATA) != 0;
- IMB_partial_rect_from_float(ibuf, buffer, x, y, w, h, is_data);
-
- if (gpu_check_scaled_image(ibuf, ima, buffer, x, y, w, h)) {
- MEM_freeN(buffer);
- BKE_image_release_ibuf(ima, ibuf, NULL);
- return;
- }
-
- GPU_texture_bind(ima->gputexture[TEXTARGET_TEXTURE_2D], 0);
- glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA, GL_FLOAT, buffer);
-
- MEM_freeN(buffer);
-
- if (GPU_get_mipmap()) {
- glGenerateMipmap(GL_TEXTURE_2D);
- }
- else {
- ima->gpuflag &= ~IMA_GPU_MIPMAP_COMPLETE;
- }
-
- GPU_texture_unbind(ima->gputexture[TEXTARGET_TEXTURE_2D]);
-
- BKE_image_release_ibuf(ima, ibuf, NULL);
- return;
- }
-
- if (gpu_check_scaled_image(ibuf, ima, NULL, x, y, w, h)) {
- BKE_image_release_ibuf(ima, ibuf, NULL);
- return;
- }
-
+ /* Partial update of texture. */
GPU_texture_bind(ima->gputexture[TEXTARGET_TEXTURE_2D], 0);
- glGetIntegerv(GL_UNPACK_ROW_LENGTH, &row_length);
- glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &skip_pixels);
- glGetIntegerv(GL_UNPACK_SKIP_ROWS, &skip_rows);
-
- glPixelStorei(GL_UNPACK_ROW_LENGTH, ibuf->x);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, x);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, y);
-
- glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
-
- glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, skip_pixels);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, skip_rows);
+ gpu_texture_update_from_ibuf(ibuf, x, y, w, h);
- /* see comment above as to why we are using gpu mipmap generation here */
if (GPU_get_mipmap()) {
glGenerateMipmap(GL_TEXTURE_2D);
}
@@ -1242,7 +1242,7 @@ static void gpu_free_image_immediate(Image *ima)
}
}
- ima->gpuflag &= ~(IMA_GPU_MIPMAP_COMPLETE | IMA_GPU_IS_DATA);
+ ima->gpuflag &= ~(IMA_GPU_MIPMAP_COMPLETE);
}
void GPU_free_image(Image *ima)
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index 1a668a48eed..de9ed56abf5 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -231,6 +231,12 @@ ListBase *GPU_material_get_inputs(GPUMaterial *material)
return &material->inputs;
}
+/* Return can be NULL if it's a world material. */
+Material *GPU_material_get_material(GPUMaterial *material)
+{
+ return material->ma;
+}
+
GPUUniformBuffer *GPU_material_uniform_buffer_get(GPUMaterial *material)
{
return material->ubo;
@@ -597,15 +603,6 @@ eGPUMaterialStatus GPU_material_status(GPUMaterial *mat)
/* Code generation */
-bool GPU_material_do_color_management(GPUMaterial *mat)
-{
- if (!BKE_scene_check_color_management_enabled(mat->scene)) {
- return false;
- }
-
- return true;
-}
-
bool GPU_material_use_domain_surface(GPUMaterial *mat)
{
return (mat->domain & GPU_DOMAIN_SURFACE);
@@ -646,6 +643,7 @@ GPUMaterial *GPU_material_from_nodetree_find(ListBase *gpumaterials,
* so only do this when they are needed.
*/
GPUMaterial *GPU_material_from_nodetree(Scene *scene,
+ struct Material *ma,
struct bNodeTree *ntree,
ListBase *gpumaterials,
const void *engine_type,
@@ -664,6 +662,7 @@ GPUMaterial *GPU_material_from_nodetree(Scene *scene,
/* allocate material */
GPUMaterial *mat = MEM_callocN(sizeof(GPUMaterial), "GPUMaterial");
+ mat->ma = ma;
mat->scene = scene;
mat->engine_type = engine_type;
mat->options = options;
diff --git a/source/blender/gpu/intern/gpu_matrix.c b/source/blender/gpu/intern/gpu_matrix.c
index 5d65861c1e2..cc89da19705 100644
--- a/source/blender/gpu/intern/gpu_matrix.c
+++ b/source/blender/gpu/intern/gpu_matrix.c
@@ -502,19 +502,13 @@ static void gpu_mul_invert_projmat_m4_unmapped_v3(const float projmat[4][4], flo
co[2] *= -1;
}
-bool GPU_matrix_unproject(const float win[3],
- const float model[4][4],
- const float proj[4][4],
- const int view[4],
- float world[3])
+void GPU_matrix_unproject_model_inverted(const float win[3],
+ const float model_inverted[4][4],
+ const float proj[4][4],
+ const int view[4],
+ float world[3])
{
float in[3];
- float viewinv[4][4];
-
- if (!invert_m4_m4(viewinv, model)) {
- zero_v3(world);
- return false;
- }
copy_v3_v3(in, win);
@@ -523,8 +517,22 @@ bool GPU_matrix_unproject(const float win[3],
in[1] = (in[1] - view[1]) / view[3];
gpu_mul_invert_projmat_m4_unmapped_v3(proj, in);
- mul_v3_m4v3(world, viewinv, in);
+ mul_v3_m4v3(world, model_inverted, in);
+}
+bool GPU_matrix_unproject(const float win[3],
+ const float model[4][4],
+ const float proj[4][4],
+ const int view[4],
+ float world[3])
+{
+ float model_inverted[4][4];
+
+ if (!invert_m4_m4(model_inverted, model)) {
+ zero_v3(world);
+ return false;
+ }
+ GPU_matrix_unproject_model_inverted(win, model_inverted, proj, view, world);
return true;
}
diff --git a/source/blender/gpu/intern/gpu_select_sample_query.c b/source/blender/gpu/intern/gpu_select_sample_query.c
index 3fbc24d6089..56f9ef69221 100644
--- a/source/blender/gpu/intern/gpu_select_sample_query.c
+++ b/source/blender/gpu/intern/gpu_select_sample_query.c
@@ -104,8 +104,11 @@ void gpu_select_query_begin(
/* occlusion queries operates on fragments that pass tests and since we are interested on all
* objects in the view frustum independently of their order, we need to disable the depth test */
if (mode == GPU_SELECT_ALL) {
- glDisable(GL_DEPTH_TEST);
- glDepthMask(GL_FALSE);
+ /* glQueries on Windows+Intel drivers only works with depth testing turned on.
+ * See T62947 for details */
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_ALWAYS);
+ glDepthMask(GL_TRUE);
}
else if (mode == GPU_SELECT_NEAREST_FIRST_PASS) {
glClear(GL_DEPTH_BUFFER_BIT);
diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c
index 3d5b0dda5e4..7201025ad8a 100644
--- a/source/blender/gpu/intern/gpu_shader.c
+++ b/source/blender/gpu/intern/gpu_shader.c
@@ -145,17 +145,8 @@ extern char datatoc_gpu_shader_selection_id_frag_glsl[];
extern char datatoc_gpu_shader_2D_line_dashed_uniform_color_vert_glsl[];
extern char datatoc_gpu_shader_2D_line_dashed_frag_glsl[];
extern char datatoc_gpu_shader_2D_line_dashed_geom_glsl[];
-extern char datatoc_gpu_shader_3D_line_dashed_uniform_color_legacy_vert_glsl[];
extern char datatoc_gpu_shader_3D_line_dashed_uniform_color_vert_glsl[];
-extern char datatoc_gpu_shader_edges_front_back_persp_vert_glsl[];
-extern char datatoc_gpu_shader_edges_front_back_persp_geom_glsl[];
-extern char datatoc_gpu_shader_edges_front_back_persp_legacy_vert_glsl[];
-extern char datatoc_gpu_shader_edges_front_back_ortho_vert_glsl[];
-extern char datatoc_gpu_shader_edges_overlay_vert_glsl[];
-extern char datatoc_gpu_shader_edges_overlay_geom_glsl[];
-extern char datatoc_gpu_shader_edges_overlay_simple_geom_glsl[];
-extern char datatoc_gpu_shader_edges_overlay_frag_glsl[];
extern char datatoc_gpu_shader_text_vert_glsl[];
extern char datatoc_gpu_shader_text_geom_glsl[];
extern char datatoc_gpu_shader_text_frag_glsl[];
@@ -729,23 +720,28 @@ void GPU_shader_uniform_vector(
return;
}
- if (length == 1) {
- glUniform1fv(location, arraysize, value);
- }
- else if (length == 2) {
- glUniform2fv(location, arraysize, value);
- }
- else if (length == 3) {
- glUniform3fv(location, arraysize, value);
- }
- else if (length == 4) {
- glUniform4fv(location, arraysize, value);
- }
- else if (length == 9) {
- glUniformMatrix3fv(location, arraysize, 0, value);
- }
- else if (length == 16) {
- glUniformMatrix4fv(location, arraysize, 0, value);
+ 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;
}
}
@@ -756,17 +752,22 @@ void GPU_shader_uniform_vector_int(
return;
}
- if (length == 1) {
- glUniform1iv(location, arraysize, value);
- }
- else if (length == 2) {
- glUniform2iv(location, arraysize, value);
- }
- else if (length == 3) {
- glUniform3iv(location, arraysize, value);
- }
- else if (length == 4) {
- glUniform4iv(location, arraysize, value);
+ 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;
}
}
@@ -832,30 +833,6 @@ static const GPUShaderStages builtin_shader_stages[GPU_SHADER_BUILTIN_LEN] = {
.vert = datatoc_gpu_shader_keyframe_diamond_vert_glsl,
.frag = datatoc_gpu_shader_keyframe_diamond_frag_glsl,
},
- /* This version is magical but slow! */
- [GPU_SHADER_EDGES_FRONT_BACK_PERSP] =
- {
- .vert = datatoc_gpu_shader_edges_front_back_persp_vert_glsl,
- .geom = datatoc_gpu_shader_edges_front_back_persp_geom_glsl,
- .frag = datatoc_gpu_shader_flat_color_frag_glsl,
- },
- [GPU_SHADER_EDGES_FRONT_BACK_ORTHO] =
- {
- .vert = datatoc_gpu_shader_edges_front_back_ortho_vert_glsl,
- .frag = datatoc_gpu_shader_flat_color_frag_glsl,
- },
- [GPU_SHADER_EDGES_OVERLAY_SIMPLE] =
- {
- .vert = datatoc_gpu_shader_3D_vert_glsl,
- .geom = datatoc_gpu_shader_edges_overlay_simple_geom_glsl,
- .frag = datatoc_gpu_shader_edges_overlay_frag_glsl,
- },
- [GPU_SHADER_EDGES_OVERLAY] =
- {
- .vert = datatoc_gpu_shader_edges_overlay_vert_glsl,
- .geom = datatoc_gpu_shader_edges_overlay_geom_glsl,
- .frag = datatoc_gpu_shader_edges_overlay_frag_glsl,
- },
[GPU_SHADER_SIMPLE_LIGHTING] =
{
.vert = datatoc_gpu_shader_3D_normal_vert_glsl,
@@ -1322,28 +1299,8 @@ GPUShader *GPU_shader_get_builtin_shader_with_config(eGPUBuiltinShader shader,
GPUShader **sh_p = &builtin_shaders[sh_cfg][shader];
if (*sh_p == NULL) {
- GPUShaderStages stages_legacy = {NULL};
const GPUShaderStages *stages = &builtin_shader_stages[shader];
- if (shader == GPU_SHADER_EDGES_FRONT_BACK_PERSP) {
- /* TODO: remove after switch to core profile (maybe) */
- if (!GLEW_VERSION_3_2) {
- stages_legacy.vert = datatoc_gpu_shader_edges_front_back_persp_legacy_vert_glsl;
- stages_legacy.frag = datatoc_gpu_shader_flat_color_alpha_test_0_frag_glsl;
- stages = &stages_legacy;
- }
- }
- else if (shader == GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR) {
- /* Dashed need geometry shader, which are not supported by legacy OpenGL,
- * fallback to solid lines. */
- /* TODO: remove after switch to core profile (maybe) */
- if (!GLEW_VERSION_3_2) {
- stages_legacy.vert = datatoc_gpu_shader_3D_line_dashed_uniform_color_legacy_vert_glsl;
- stages_legacy.frag = datatoc_gpu_shader_2D_line_dashed_frag_glsl;
- stages = &stages_legacy;
- }
- }
-
/* common case */
if (sh_cfg == GPU_SHADER_CFG_DEFAULT) {
*sh_p = GPU_shader_create(
diff --git a/source/blender/gpu/intern/gpu_shader_interface.c b/source/blender/gpu/intern/gpu_shader_interface.c
index 698499af1ab..97dbb80d736 100644
--- a/source/blender/gpu/intern/gpu_shader_interface.c
+++ b/source/blender/gpu/intern/gpu_shader_interface.c
@@ -61,13 +61,10 @@ static const char *BuiltinUniform_name(GPUUniformBuiltin u)
[GPU_UNIFORM_VIEWPROJECTION_INV] = "ViewProjectionMatrixInverse",
[GPU_UNIFORM_NORMAL] = "NormalMatrix",
- [GPU_UNIFORM_NORMAL_INV] = "NormalMatrixInverse",
- [GPU_UNIFORM_WORLDNORMAL] = "WorldNormalMatrix",
[GPU_UNIFORM_CAMERATEXCO] = "CameraTexCoFactors",
[GPU_UNIFORM_ORCO] = "OrcoTexCoFactors",
[GPU_UNIFORM_COLOR] = "color",
- [GPU_UNIFORM_EYE] = "eye",
[GPU_UNIFORM_CALLID] = "callId",
[GPU_UNIFORM_OBJECT_INFO] = "unfobjectinfo",
diff --git a/source/blender/gpu/intern/gpu_texture.c b/source/blender/gpu/intern/gpu_texture.c
index ad4831ed903..58d0dd5576f 100644
--- a/source/blender/gpu/intern/gpu_texture.c
+++ b/source/blender/gpu/intern/gpu_texture.c
@@ -1081,7 +1081,7 @@ GPUTexture *GPU_texture_from_preview(PreviewImage *prv, int mipmap)
/* this binds a texture, so that's why we restore it to 0 */
if (bindcode == 0) {
GPU_create_gl_tex(
- &bindcode, prv->rect[0], NULL, prv->w[0], prv->h[0], GL_TEXTURE_2D, mipmap, 0, NULL);
+ &bindcode, prv->rect[0], NULL, prv->w[0], prv->h[0], GL_TEXTURE_2D, mipmap, false, NULL);
}
if (tex) {
tex->bindcode = bindcode;
diff --git a/source/blender/gpu/intern/gpu_vertex_buffer.c b/source/blender/gpu/intern/gpu_vertex_buffer.c
index f9823c18723..2f854fe03ea 100644
--- a/source/blender/gpu/intern/gpu_vertex_buffer.c
+++ b/source/blender/gpu/intern/gpu_vertex_buffer.c
@@ -85,17 +85,24 @@ void GPU_vertbuf_init_with_format_ex(GPUVertBuf *verts,
}
}
-void GPU_vertbuf_discard(GPUVertBuf *verts)
+/** Same as discard but does not free. */
+void GPU_vertbuf_clear(GPUVertBuf *verts)
{
if (verts->vbo_id) {
GPU_buf_free(verts->vbo_id);
+ verts->vbo_id = 0;
#if VRAM_USAGE
vbo_memory_usage -= GPU_vertbuf_size_get(verts);
#endif
}
if (verts->data) {
- MEM_freeN(verts->data);
+ MEM_SAFE_FREE(verts->data);
}
+}
+
+void GPU_vertbuf_discard(GPUVertBuf *verts)
+{
+ GPU_vertbuf_clear(verts);
MEM_freeN(verts);
}
diff --git a/source/blender/gpu/intern/gpu_vertex_format.c b/source/blender/gpu/intern/gpu_vertex_format.c
index 388773afbbc..37e1f9cf9da 100644
--- a/source/blender/gpu/intern/gpu_vertex_format.c
+++ b/source/blender/gpu/intern/gpu_vertex_format.c
@@ -58,12 +58,6 @@ void GPU_vertformat_copy(GPUVertFormat *dest, const GPUVertFormat *src)
{
/* copy regular struct fields */
memcpy(dest, src, sizeof(GPUVertFormat));
-
- for (uint i = 0; i < dest->attr_len; i++) {
- for (uint j = 0; j < dest->attrs[i].name_len; j++) {
- dest->attrs[i].name[j] = (char *)dest + (src->attrs[i].name[j] - ((char *)src));
- }
- }
}
static GLenum convert_comp_type_to_gl(GPUVertCompType type)
@@ -122,32 +116,20 @@ uint vertex_buffer_size(const GPUVertFormat *format, uint vertex_len)
return format->stride * vertex_len;
}
-static const char *copy_attr_name(GPUVertFormat *format, const char *name, const char *suffix)
+static uchar copy_attr_name(GPUVertFormat *format, const char *name)
{
/* strncpy does 110% of what we need; let's do exactly 100% */
- char *name_copy = format->names + format->name_offset;
- uint available = GPU_VERT_ATTR_NAMES_BUF_LEN - format->name_offset;
+ uchar name_offset = format->name_offset;
+ char *name_copy = format->names + name_offset;
+ uint available = GPU_VERT_ATTR_NAMES_BUF_LEN - name_offset;
bool terminated = false;
for (uint i = 0; i < available; ++i) {
const char c = name[i];
name_copy[i] = c;
if (c == '\0') {
- if (suffix) {
- for (uint j = 0; j < available; ++j) {
- const char s = suffix[j];
- name_copy[i + j] = s;
- if (s == '\0') {
- terminated = true;
- format->name_offset += (i + j + 1);
- break;
- }
- }
- }
- else {
- terminated = true;
- format->name_offset += (i + 1);
- }
+ terminated = true;
+ format->name_offset += (i + 1);
break;
}
}
@@ -157,7 +139,7 @@ static const char *copy_attr_name(GPUVertFormat *format, const char *name, const
#else
(void)terminated;
#endif
- return name_copy;
+ return name_offset;
}
uint GPU_vertformat_attr_add(GPUVertFormat *format,
@@ -196,7 +178,7 @@ uint GPU_vertformat_attr_add(GPUVertFormat *format,
const uint attr_id = format->attr_len++;
GPUVertAttr *attr = &format->attrs[attr_id];
- attr->name[attr->name_len++] = copy_attr_name(format, name, NULL);
+ 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) ?
@@ -217,7 +199,7 @@ void GPU_vertformat_alias_add(GPUVertFormat *format, const char *alias)
assert(attr->name_len < GPU_VERT_ATTR_MAX_NAMES);
#endif
format->name_len++; /* multiname support */
- attr->name[attr->name_len++] = copy_attr_name(format, alias, NULL);
+ attr->names[attr->name_len++] = copy_attr_name(format, alias);
}
int GPU_vertformat_attr_id_get(const GPUVertFormat *format, const char *name)
@@ -225,7 +207,8 @@ int GPU_vertformat_attr_id_get(const GPUVertFormat *format, const char *name)
for (int i = 0; i < format->attr_len; i++) {
const GPUVertAttr *attr = &format->attrs[i];
for (int j = 0; j < attr->name_len; j++) {
- if (STREQ(name, attr->name[j])) {
+ const char *attr_name = GPU_vertformat_attr_name_get(format, attr, j);
+ if (STREQ(name, attr_name)) {
return i;
}
}
@@ -233,41 +216,6 @@ int GPU_vertformat_attr_id_get(const GPUVertFormat *format, const char *name)
return -1;
}
-void GPU_vertformat_triple_load(GPUVertFormat *format)
-{
-#if TRUST_NO_ONE
- assert(!format->packed);
- assert(format->attr_len * 3 < GPU_VERT_ATTR_MAX_LEN);
- assert(format->name_len + format->attr_len * 3 < GPU_VERT_ATTR_MAX_LEN);
-#endif
-
- VertexFormat_pack(format);
-
- uint old_attr_len = format->attr_len;
- for (uint a_idx = 0; a_idx < old_attr_len; ++a_idx) {
- GPUVertAttr *attr = &format->attrs[a_idx];
- /* Duplicate attr twice */
- for (int i = 1; i < 3; ++i) {
- GPUVertAttr *dst_attr = &format->attrs[format->attr_len];
- memcpy(dst_attr, attr, sizeof(GPUVertAttr));
- /* Increase offset to the next vertex. */
- dst_attr->offset += format->stride * i;
- /* Only copy first name for now. */
- dst_attr->name_len = 0;
- dst_attr->name[dst_attr->name_len++] = copy_attr_name(
- format, attr->name[0], (i == 1) ? "1" : "2");
- format->attr_len++;
- }
-
-#if TRUST_NO_ONE
- assert(attr->name_len < GPU_VERT_ATTR_MAX_NAMES);
-#endif
- /* Add alias to first attr. */
- format->name_len++;
- attr->name[attr->name_len++] = copy_attr_name(format, attr->name[0], "0");
- }
-}
-
uint padding(uint offset, uint alignment)
{
const uint mod = offset % alignment;
@@ -364,7 +312,6 @@ static uint calc_input_component_size(const GPUShaderInput *input)
static void get_fetch_mode_and_comp_type(int gl_type,
GPUVertCompType *r_comp_type,
- uint *r_gl_comp_type,
GPUVertFetchMode *r_fetch_mode)
{
switch (gl_type) {
@@ -382,7 +329,6 @@ static void get_fetch_mode_and_comp_type(int gl_type,
case GL_FLOAT_MAT4x2:
case GL_FLOAT_MAT4x3:
*r_comp_type = GPU_COMP_F32;
- *r_gl_comp_type = GL_FLOAT;
*r_fetch_mode = GPU_FETCH_FLOAT;
break;
case GL_INT:
@@ -390,7 +336,6 @@ static void get_fetch_mode_and_comp_type(int gl_type,
case GL_INT_VEC3:
case GL_INT_VEC4:
*r_comp_type = GPU_COMP_I32;
- *r_gl_comp_type = GL_INT;
*r_fetch_mode = GPU_FETCH_INT;
break;
case GL_UNSIGNED_INT:
@@ -398,7 +343,6 @@ static void get_fetch_mode_and_comp_type(int gl_type,
case GL_UNSIGNED_INT_VEC3:
case GL_UNSIGNED_INT_VEC4:
*r_comp_type = GPU_COMP_U32;
- *r_gl_comp_type = GL_UNSIGNED_INT;
*r_fetch_mode = GPU_FETCH_INT;
break;
default:
@@ -424,15 +368,19 @@ void GPU_vertformat_from_interface(GPUVertFormat *format, const GPUShaderInterfa
format->name_len++; /* multiname support */
format->attr_len++;
+ GPUVertCompType comp_type;
+ GPUVertFetchMode fetch_mode;
+ get_fetch_mode_and_comp_type(input->gl_type, &comp_type, &fetch_mode);
+
GPUVertAttr *attr = &format->attrs[input->location];
- attr->name[attr->name_len++] = copy_attr_name(
- format, name_buffer + input->name_offset, NULL);
+ attr->names[attr->name_len++] = copy_attr_name(format, name_buffer + input->name_offset);
attr->offset = 0; /* offsets & stride are calculated later (during pack) */
attr->comp_len = calc_input_component_size(input);
attr->sz = attr->comp_len * 4;
- get_fetch_mode_and_comp_type(
- input->gl_type, &attr->comp_type, &attr->gl_comp_type, &attr->fetch_mode);
+ attr->fetch_mode = fetch_mode;
+ attr->comp_type = comp_type;
+ attr->gl_comp_type = convert_comp_type_to_gl(comp_type);
}
}
}
diff --git a/source/blender/gpu/intern/gpu_viewport.c b/source/blender/gpu/intern/gpu_viewport.c
index 558b3f025a8..b825819ceb4 100644
--- a/source/blender/gpu/intern/gpu_viewport.c
+++ b/source/blender/gpu/intern/gpu_viewport.c
@@ -27,7 +27,7 @@
#include "BLI_listbase.h"
#include "BLI_rect.h"
-#include "BLI_mempool.h"
+#include "BLI_memblock.h"
#include "BIF_gl.h"
@@ -48,6 +48,8 @@
static const int default_fbl_len = (sizeof(DefaultFramebufferList)) / sizeof(void *);
static const int default_txl_len = (sizeof(DefaultTextureList)) / sizeof(void *);
+#define MAX_ENABLE_ENGINE 8
+
/* Maximum number of simultaneous engine enabled at the same time.
* Setting it lower than the real number will do lead to
* higher VRAM usage due to sub-efficient buffer reuse. */
@@ -64,8 +66,11 @@ struct GPUViewport {
int samples;
int flag;
- ListBase data; /* ViewportEngineData wrapped in LinkData */
- uint data_hash; /* If hash mismatch we free all ViewportEngineData in this viewport */
+ /* If engine_handles mismatch we free all ViewportEngineData in this viewport */
+ struct {
+ void *handle;
+ ViewportEngineData *data;
+ } engine_data[MAX_ENABLE_ENGINE];
DefaultFramebufferList *fbl;
DefaultTextureList *txl;
@@ -172,7 +177,6 @@ void GPU_viewport_clear_from_offscreen(GPUViewport *viewport)
void *GPU_viewport_engine_data_create(GPUViewport *viewport, void *engine_type)
{
- LinkData *ld = MEM_callocN(sizeof(LinkData), "LinkData");
ViewportEngineData *data = MEM_callocN(sizeof(ViewportEngineData), "ViewportEngineData");
int fbl_len, txl_len, psl_len, stl_len;
@@ -185,20 +189,25 @@ void *GPU_viewport_engine_data_create(GPUViewport *viewport, void *engine_type)
data->psl = MEM_callocN((sizeof(void *) * psl_len) + sizeof(PassList), "PassList");
data->stl = MEM_callocN((sizeof(void *) * stl_len) + sizeof(StorageList), "StorageList");
- ld->data = data;
- BLI_addtail(&viewport->data, ld);
+ for (int i = 0; i < MAX_ENABLE_ENGINE; i++) {
+ if (viewport->engine_data[i].handle == NULL) {
+ viewport->engine_data[i].handle = engine_type;
+ viewport->engine_data[i].data = data;
+ return data;
+ }
+ }
- return data;
+ BLI_assert(!"Too many draw engines enabled at the same time");
+ return NULL;
}
static void gpu_viewport_engines_data_free(GPUViewport *viewport)
{
int fbl_len, txl_len, psl_len, stl_len;
- LinkData *next;
- for (LinkData *link = viewport->data.first; link; link = next) {
- next = link->next;
- ViewportEngineData *data = link->data;
+ for (int i = 0; i < MAX_ENABLE_ENGINE && viewport->engine_data[i].handle; i++) {
+ ViewportEngineData *data = viewport->engine_data[i].data;
+
DRW_engine_viewport_data_size_get(data->engine_type, &fbl_len, &txl_len, &psl_len, &stl_len);
gpu_viewport_buffers_free(data->fbl, fbl_len, data->txl, txl_len);
@@ -219,19 +228,20 @@ static void gpu_viewport_engines_data_free(GPUViewport *viewport)
MEM_freeN(data);
- BLI_remlink(&viewport->data, link);
- MEM_freeN(link);
+ /* Mark as unused*/
+ viewport->engine_data[i].handle = NULL;
}
gpu_viewport_texture_pool_free(viewport);
}
-void *GPU_viewport_engine_data_get(GPUViewport *viewport, void *engine_type)
+void *GPU_viewport_engine_data_get(GPUViewport *viewport, void *engine_handle)
{
- for (LinkData *link = viewport->data.first; link; link = link->next) {
- ViewportEngineData *vdata = link->data;
- if (vdata->engine_type == engine_type) {
- return vdata;
+ BLI_assert(engine_handle != NULL);
+
+ for (int i = 0; i < MAX_ENABLE_ENGINE; i++) {
+ if (viewport->engine_data[i].handle == engine_handle) {
+ return viewport->engine_data[i].data;
}
}
return NULL;
@@ -352,24 +362,22 @@ static void gpu_viewport_texture_pool_free(GPUViewport *viewport)
BLI_freelistN(&viewport->tex_pool);
}
-bool GPU_viewport_engines_data_validate(GPUViewport *viewport, uint hash)
+/* Takes an NULL terminated array of engine_handle. Returns true is data is still valid. */
+bool GPU_viewport_engines_data_validate(GPUViewport *viewport, void **engine_handle_array)
{
- bool dirty = false;
-
- if (viewport->data_hash != hash) {
- gpu_viewport_engines_data_free(viewport);
- dirty = true;
+ for (int i = 0; i < MAX_ENABLE_ENGINE && engine_handle_array[i]; i++) {
+ if (viewport->engine_data[i].handle != engine_handle_array[i]) {
+ gpu_viewport_engines_data_free(viewport);
+ return false;
+ }
}
-
- viewport->data_hash = hash;
-
- return dirty;
+ return true;
}
void GPU_viewport_cache_release(GPUViewport *viewport)
{
- for (LinkData *link = viewport->data.first; link; link = link->next) {
- ViewportEngineData *data = link->data;
+ for (int i = 0; i < MAX_ENABLE_ENGINE && viewport->engine_data[i].handle; i++) {
+ ViewportEngineData *data = viewport->engine_data[i].data;
int psl_len;
DRW_engine_viewport_data_size_get(data->engine_type, NULL, NULL, &psl_len, NULL);
gpu_viewport_passes_free(data->psl, psl_len);
@@ -468,8 +476,8 @@ void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect)
(TextureList *)viewport->txl,
default_txl_len);
- for (LinkData *link = viewport->data.first; link; link = link->next) {
- ViewportEngineData *data = link->data;
+ for (int i = 0; i < MAX_ENABLE_ENGINE && viewport->engine_data[i].handle; i++) {
+ ViewportEngineData *data = viewport->engine_data[i].data;
DRW_engine_viewport_data_size_get(data->engine_type, &fbl_len, &txl_len, NULL, NULL);
gpu_viewport_buffers_free(data->fbl, fbl_len, data->txl, txl_len);
}
@@ -593,13 +601,7 @@ static void gpu_viewport_storage_free(StorageList *stl, int stl_len)
static void gpu_viewport_passes_free(PassList *psl, int psl_len)
{
- for (int i = 0; i < psl_len; i++) {
- struct DRWPass *pass = psl->passes[i];
- if (pass) {
- DRW_pass_free(pass);
- psl->passes[i] = NULL;
- }
- }
+ memset(psl, 0, sizeof(struct DRWPass *) * psl_len);
}
/* Must be executed inside Drawmanager Opengl Context. */
@@ -618,28 +620,28 @@ void GPU_viewport_free(GPUViewport *viewport)
MEM_freeN(viewport->txl);
if (viewport->vmempool.calls != NULL) {
- BLI_mempool_destroy(viewport->vmempool.calls);
+ BLI_memblock_destroy(viewport->vmempool.calls, NULL);
}
if (viewport->vmempool.states != NULL) {
- BLI_mempool_destroy(viewport->vmempool.states);
+ BLI_memblock_destroy(viewport->vmempool.states, NULL);
}
if (viewport->vmempool.shgroups != NULL) {
- BLI_mempool_destroy(viewport->vmempool.shgroups);
+ BLI_memblock_destroy(viewport->vmempool.shgroups, NULL);
}
if (viewport->vmempool.uniforms != NULL) {
- BLI_mempool_destroy(viewport->vmempool.uniforms);
+ BLI_memblock_destroy(viewport->vmempool.uniforms, NULL);
}
if (viewport->vmempool.passes != NULL) {
- BLI_mempool_destroy(viewport->vmempool.passes);
+ BLI_memblock_destroy(viewport->vmempool.passes, NULL);
}
if (viewport->vmempool.images != NULL) {
- BLI_mempool_iter iter;
+ BLI_memblock_iter iter;
GPUTexture **tex;
- BLI_mempool_iternew(viewport->vmempool.images, &iter);
- while ((tex = BLI_mempool_iterstep(&iter))) {
+ BLI_memblock_iternew(viewport->vmempool.images, &iter);
+ while ((tex = BLI_memblock_iterstep(&iter))) {
GPU_texture_free(*tex);
}
- BLI_mempool_destroy(viewport->vmempool.images);
+ BLI_memblock_destroy(viewport->vmempool.images, NULL);
}
DRW_instance_data_list_free(viewport->idatalist);
diff --git a/source/blender/gpu/shaders/gpu_shader_edges_front_back_ortho_vert.glsl b/source/blender/gpu/shaders/gpu_shader_edges_front_back_ortho_vert.glsl
deleted file mode 100644
index a71dfba575b..00000000000
--- a/source/blender/gpu/shaders/gpu_shader_edges_front_back_ortho_vert.glsl
+++ /dev/null
@@ -1,54 +0,0 @@
-
-// Draw "fancy" wireframe, displaying front-facing, back-facing and
-// silhouette lines differently.
-// Mike Erwin, April 2015
-
-uniform bool drawFront = true;
-uniform bool drawBack = true;
-uniform bool drawSilhouette = true;
-
-uniform vec4 frontColor;
-uniform vec4 backColor;
-uniform vec4 silhouetteColor;
-
-uniform vec3 eye; // direction we are looking
-
-uniform mat4 ModelViewProjectionMatrix;
-
-in vec3 pos;
-
-// normals of faces this edge joins (object coords)
-in vec3 N1;
-in vec3 N2;
-
-flat out vec4 finalColor;
-
-// TODO: in float angle; // [-pi .. +pi], + peak, 0 flat, - valley
-
-// to discard an entire line, set both endpoints to nowhere
-// and it won't produce any fragments
-const vec4 nowhere = vec4(vec3(0.0), 1.0);
-
-void main()
-{
- bool face_1_front = dot(N1, eye) > 0.0;
- bool face_2_front = dot(N2, eye) > 0.0;
-
- vec4 position = ModelViewProjectionMatrix * vec4(pos, 1.0);
-
- if (face_1_front && face_2_front) {
- // front-facing edge
- gl_Position = drawFront ? position : nowhere;
- finalColor = frontColor;
- }
- else if (face_1_front || face_2_front) {
- // exactly one face is front-facing, silhouette edge
- gl_Position = drawSilhouette ? position : nowhere;
- finalColor = silhouetteColor;
- }
- else {
- // back-facing edge
- gl_Position = drawBack ? position : nowhere;
- finalColor = backColor;
- }
-}
diff --git a/source/blender/gpu/shaders/gpu_shader_edges_front_back_persp_geom.glsl b/source/blender/gpu/shaders/gpu_shader_edges_front_back_persp_geom.glsl
deleted file mode 100644
index 3de14704781..00000000000
--- a/source/blender/gpu/shaders/gpu_shader_edges_front_back_persp_geom.glsl
+++ /dev/null
@@ -1,60 +0,0 @@
-
-// Draw "fancy" wireframe, displaying front-facing, back-facing and
-// silhouette lines differently.
-// Mike Erwin, April 2015
-
-// After working with this shader a while, convinced we should make
-// separate shaders for perpective & ortho. (Oct 2016)
-
-// Due to perspective, the line segment's endpoints might disagree on
-// whether the adjacent faces are front facing. This geometry shader
-// decides which edge type to use if endpoints disagree.
-
-uniform mat4 ProjectionMatrix;
-
-uniform bool drawFront = true;
-uniform bool drawBack = true;
-uniform bool drawSilhouette = true;
-
-uniform vec4 frontColor;
-uniform vec4 backColor;
-uniform vec4 silhouetteColor;
-
-layout(lines) in;
-layout(line_strip, max_vertices = 2) out;
-
-in vec4 MV_pos[];
-in float edgeClass[];
-
-flat out vec4 finalColor;
-
-void emitLine(vec4 color)
-{
- gl_Position = ProjectionMatrix * MV_pos[0];
- EmitVertex();
- gl_Position = ProjectionMatrix * MV_pos[1];
- finalColor = color;
- EmitVertex();
- EndPrimitive();
-}
-
-void main()
-{
- float finalEdgeClass = max(edgeClass[0], edgeClass[1]);
-
- if (finalEdgeClass > 0.0f) {
- // front-facing edge
- if (drawFront)
- emitLine(frontColor);
- }
- else if (finalEdgeClass < 0.0f) {
- // back-facing edge
- if (drawBack)
- emitLine(backColor);
- }
- else {
- // exactly one face is front-facing, silhouette edge
- if (drawSilhouette)
- emitLine(silhouetteColor);
- }
-}
diff --git a/source/blender/gpu/shaders/gpu_shader_edges_front_back_persp_legacy_vert.glsl b/source/blender/gpu/shaders/gpu_shader_edges_front_back_persp_legacy_vert.glsl
deleted file mode 100644
index ffd52a0a225..00000000000
--- a/source/blender/gpu/shaders/gpu_shader_edges_front_back_persp_legacy_vert.glsl
+++ /dev/null
@@ -1,68 +0,0 @@
-
-// Draw "fancy" wireframe, displaying front-facing, back-facing and
-// silhouette lines differently.
-// Mike Erwin, April 2015
-
-// After working with this shader a while, convinced we should make
-// separate shaders for perpective & ortho. (Oct 2016)
-
-// This shader is an imperfect stepping stone until all platforms are
-// ready for geometry shaders.
-
-// Due to perspective, the line segment's endpoints might disagree on
-// whether the adjacent faces are front facing. Need to use a geometry
-// shader or pass in an extra position attribute (the other endpoint)
-// to do this properly.
-
-uniform bool drawFront = true;
-uniform bool drawBack = true;
-uniform bool drawSilhouette = true;
-
-uniform vec4 frontColor;
-uniform vec4 backColor;
-uniform vec4 silhouetteColor;
-
-uniform mat4 ModelViewMatrix;
-uniform mat4 ModelViewProjectionMatrix;
-uniform mat3 NormalMatrix;
-
-in vec3 pos;
-
-// normals of faces this edge joins (object coords)
-in vec3 N1;
-in vec3 N2;
-
-flat out vec4 finalColor;
-
-// TODO: in float angle; // [-pi .. +pi], + peak, 0 flat, - valley
-
-// to discard an entire line, set its color to invisible
-// (must have GL_BLEND enabled, or discard in fragment shader)
-const vec4 invisible = vec4(0.0);
-
-bool front(vec3 N)
-{
- vec4 xformed = ModelViewMatrix * vec4(pos, 1.0);
- return dot(NormalMatrix * N, normalize(-xformed.xyz)) > 0.0;
-}
-
-void main()
-{
- bool face_1_front = front(N1);
- bool face_2_front = front(N2);
-
- gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
-
- if (face_1_front && face_2_front) {
- // front-facing edge
- finalColor = drawFront ? frontColor : invisible;
- }
- else if (face_1_front || face_2_front) {
- // exactly one face is front-facing, silhouette edge
- finalColor = drawSilhouette ? silhouetteColor : invisible;
- }
- else {
- // back-facing edge
- finalColor = drawBack ? backColor : invisible;
- }
-}
diff --git a/source/blender/gpu/shaders/gpu_shader_edges_front_back_persp_vert.glsl b/source/blender/gpu/shaders/gpu_shader_edges_front_back_persp_vert.glsl
deleted file mode 100644
index c8b722e1d7e..00000000000
--- a/source/blender/gpu/shaders/gpu_shader_edges_front_back_persp_vert.glsl
+++ /dev/null
@@ -1,44 +0,0 @@
-
-// Draw "fancy" wireframe, displaying front-facing, back-facing and
-// silhouette lines differently.
-// Mike Erwin, April 2015
-
-// After working with this shader a while, convinced we should make
-// separate shaders for perpective & ortho. (Oct 2016)
-
-// Due to perspective, the line segment's endpoints might disagree on
-// whether the adjacent faces are front facing. We use a geometry
-// shader to resolve this properly.
-
-uniform mat4 ModelViewMatrix;
-uniform mat3 NormalMatrix;
-
-in vec3 pos;
-in vec3 N1, N2; // normals of faces this edge joins (object coords)
-
-out vec4 MV_pos;
-out float edgeClass;
-
-// TODO: in float angle; // [-pi .. +pi], + peak, 0 flat, - valley
-
-bool front(vec3 N, vec3 eye)
-{
- return dot(NormalMatrix * N, eye) > 0.0;
-}
-
-void main()
-{
- MV_pos = ModelViewMatrix * vec4(pos, 1.0);
-
- vec3 eye = normalize(-MV_pos.xyz);
-
- bool face_1_front = front(N1, eye);
- bool face_2_front = front(N2, eye);
-
- if (face_1_front && face_2_front)
- edgeClass = 1.0; // front-facing edge
- else if (face_1_front || face_2_front)
- edgeClass = 0.0; // exactly one face is front-facing, silhouette edge
- else
- edgeClass = -1.0; // back-facing edge
-}
diff --git a/source/blender/gpu/shaders/gpu_shader_edges_overlay_frag.glsl b/source/blender/gpu/shaders/gpu_shader_edges_overlay_frag.glsl
deleted file mode 100644
index 7b35f67dd54..00000000000
--- a/source/blender/gpu/shaders/gpu_shader_edges_overlay_frag.glsl
+++ /dev/null
@@ -1,21 +0,0 @@
-
-#define SMOOTH 1
-
-const float transitionWidth = 1.0;
-
-uniform vec4 fillColor = vec4(0);
-uniform vec4 outlineColor = vec4(0, 0, 0, 1);
-
-noperspective in vec3 distanceToOutline;
-
-out vec4 FragColor;
-
-void main()
-{
- float edgeness = min(min(distanceToOutline.x, distanceToOutline.y), distanceToOutline.z);
-#if SMOOTH
- FragColor = mix(outlineColor, fillColor, smoothstep(0, transitionWidth, edgeness));
-#else
- FragColor = (edgeness <= 0) ? outlineColor : fillColor;
-#endif
-}
diff --git a/source/blender/gpu/shaders/gpu_shader_edges_overlay_geom.glsl b/source/blender/gpu/shaders/gpu_shader_edges_overlay_geom.glsl
deleted file mode 100644
index 48fff1629fd..00000000000
--- a/source/blender/gpu/shaders/gpu_shader_edges_overlay_geom.glsl
+++ /dev/null
@@ -1,72 +0,0 @@
-layout(triangles) in;
-layout(triangle_strip, max_vertices = 3) out;
-
-uniform float outlineWidth = 1.0;
-uniform vec2 viewportSize;
-
-in vec4 pos_xformed[];
-in float widthModulator[];
-
-noperspective out vec3 distanceToOutline;
-
-// project to screen space
-vec2 proj(int axis)
-{
- vec4 pos = pos_xformed[axis];
- return (0.5 * (pos.xy / pos.w) + 0.5) * viewportSize;
-}
-
-float dist(vec2 pos[3], int v)
-{
- // current vertex position
- vec2 vpos = pos[v];
- // endpoints of opposite edge
- vec2 e1 = pos[(v + 1) % 3];
- vec2 e2 = pos[(v + 2) % 3];
-
- float abs_det = length(cross(vec3(vpos - e1, 0), vec3(vpos - e2, 0))); // could simplify
- return abs_det / distance(e2, e1);
-}
-
-vec3 distance[3];
-
-void clearEdge(int v)
-{
- float distant = 10 * outlineWidth;
- for (int i = 0; i < 3; ++i)
- distance[i][v] += distant;
-}
-
-void modulateEdge(int v)
-{
- float offset = min(widthModulator[v], 1) * outlineWidth;
- for (int i = 0; i < 3; ++i)
- distance[i][v] -= offset;
-}
-
-void main()
-{
- vec2 pos[3] = vec2[3](proj(0), proj(1), proj(2));
-
- for (int v = 0; v < 3; ++v)
- distance[v] = vec3(0);
-
- for (int v = 0; v < 3; ++v) {
- if (widthModulator[v] > 0) {
- distance[v][v] = dist(pos, v);
- modulateEdge(v);
- }
- }
-
- for (int v = 0; v < 3; ++v)
- if (widthModulator[v] <= 0)
- clearEdge(v);
-
- for (int v = 0; v < 3; ++v) {
- gl_Position = pos_xformed[v];
- distanceToOutline = distance[v];
- EmitVertex();
- }
-
- EndPrimitive();
-}
diff --git a/source/blender/gpu/shaders/gpu_shader_edges_overlay_simple_geom.glsl b/source/blender/gpu/shaders/gpu_shader_edges_overlay_simple_geom.glsl
deleted file mode 100644
index 12f5a2c7811..00000000000
--- a/source/blender/gpu/shaders/gpu_shader_edges_overlay_simple_geom.glsl
+++ /dev/null
@@ -1,56 +0,0 @@
-layout(triangles) in;
-layout(triangle_strip, max_vertices = 3) out;
-
-uniform float outlineWidth = 1.0;
-uniform vec2 viewportSize;
-
-noperspective out vec3 distanceToOutline;
-
-// project to screen space
-vec2 proj(int axis)
-{
- vec4 pos = gl_in[axis].gl_Position;
- return (0.5 * (pos.xy / pos.w) + 0.5) * viewportSize;
-}
-
-float dist(vec2 pos[3], int v)
-{
- // current vertex position
- vec2 vpos = pos[v];
- // endpoints of opposite edge
- vec2 e1 = pos[(v + 1) % 3];
- vec2 e2 = pos[(v + 2) % 3];
-
- float abs_det = length(cross(vec3(vpos - e1, 0), vec3(vpos - e2, 0))); // could simplify
- return abs_det / distance(e2, e1);
-}
-
-vec3 distance[3];
-
-void modulateEdge(int v)
-{
- float offset = 0.5 * outlineWidth;
- for (int i = 0; i < 3; ++i)
- distance[i][v] -= offset;
-}
-
-void main()
-{
- vec2 pos[3] = vec2[3](proj(0), proj(1), proj(2));
-
- for (int v = 0; v < 3; ++v)
- distance[v] = vec3(0);
-
- for (int v = 0; v < 3; ++v) {
- distance[v][v] = dist(pos, v);
- modulateEdge(v);
- }
-
- for (int v = 0; v < 3; ++v) {
- gl_Position = gl_in[v].gl_Position;
- distanceToOutline = distance[v];
- EmitVertex();
- }
-
- EndPrimitive();
-}
diff --git a/source/blender/gpu/shaders/gpu_shader_edges_overlay_vert.glsl b/source/blender/gpu/shaders/gpu_shader_edges_overlay_vert.glsl
deleted file mode 100644
index 33615ac36e5..00000000000
--- a/source/blender/gpu/shaders/gpu_shader_edges_overlay_vert.glsl
+++ /dev/null
@@ -1,14 +0,0 @@
-
-uniform mat4 ModelViewProjectionMatrix;
-
-in vec3 pos;
-in float edgeWidthModulator;
-
-out vec4 pos_xformed;
-out float widthModulator;
-
-void main()
-{
- pos_xformed = ModelViewProjectionMatrix * vec4(pos, 1.0);
- widthModulator = edgeWidthModulator;
-}
diff --git a/source/blender/gpu/shaders/gpu_shader_instance_edges_variying_color_vert.glsl b/source/blender/gpu/shaders/gpu_shader_instance_edges_variying_color_vert.glsl
index d9e73f81c45..62a526cae49 100644
--- a/source/blender/gpu/shaders/gpu_shader_instance_edges_variying_color_vert.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_instance_edges_variying_color_vert.glsl
@@ -26,21 +26,21 @@ out vec3 fCol;
// TODO: in float angle; // [-pi .. +pi], + peak, 0 flat, - valley
-bool front(mat3 NormalMatrix, vec3 N, vec3 eye)
+bool front(mat3 normal_matrix, vec3 N, vec3 eye)
{
- return dot(NormalMatrix * N, eye) > 0.0;
+ return dot(normal_matrix * N, eye) > 0.0;
}
void main()
{
vec3 eye;
- mat4 ModelViewMatrix = ViewMatrix * InstanceModelMatrix;
+ mat4 model_view_matrix = ViewMatrix * InstanceModelMatrix;
vec4 pos_4d = vec4(pos, 1.0);
- MV_pos = ModelViewMatrix * pos_4d;
+ MV_pos = model_view_matrix * pos_4d;
- mat3 NormalMatrix = transpose(inverse(mat3(ModelViewMatrix)));
+ mat3 normal_matrix = transpose(inverse(mat3(model_view_matrix)));
/* if persp */
if (ProjectionMatrix[3][3] == 0.0) {
@@ -50,8 +50,8 @@ void main()
eye = vec3(0.0, 0.0, 1.0);
}
- bool face_1_front = front(NormalMatrix, N1, eye);
- bool face_2_front = front(NormalMatrix, N2, eye);
+ bool face_1_front = front(normal_matrix, N1, eye);
+ bool face_2_front = front(normal_matrix, N2, eye);
if (face_1_front && face_2_front)
edgeClass = 1.0; // front-facing edge
diff --git a/source/blender/gpu/shaders/gpu_shader_instance_objectspace_variying_color_vert.glsl b/source/blender/gpu/shaders/gpu_shader_instance_objectspace_variying_color_vert.glsl
index 9b1a08d8d86..5b3922d7a72 100644
--- a/source/blender/gpu/shaders/gpu_shader_instance_objectspace_variying_color_vert.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_instance_objectspace_variying_color_vert.glsl
@@ -1,5 +1,5 @@
-uniform mat4 ViewMatrix;
+uniform mat4 ViewMatrixInverse;
uniform mat4 ViewProjectionMatrix;
/* ---- Instantiated Attrs ---- */
@@ -15,13 +15,12 @@ flat out vec4 finalColor;
void main()
{
- mat4 ModelViewProjectionMatrix = ViewProjectionMatrix * InstanceModelMatrix;
- /* This is slow and run per vertex, but it's still faster than
- * doing it per instance on CPU and sending it on via instance attr. */
- mat3 NormalMatrix = transpose(inverse(mat3(ViewMatrix * InstanceModelMatrix)));
+ gl_Position = ViewProjectionMatrix * (InstanceModelMatrix * vec4(pos, 1.0));
- gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
- normal = NormalMatrix * nor;
+ /* This is slow and run per vertex, but it's still faster than
+ * doing it per instance on CPU and sending it on via instance attribute. */
+ mat3 normal_mat = transpose(inverse(mat3(InstanceModelMatrix)));
+ normal = normalize((transpose(mat3(ViewMatrixInverse)) * (normal_mat * nor)));
finalColor = color;
}
diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl
index 1cbf58f9d16..94770aa2ebf 100644
--- a/source/blender/gpu/shaders/gpu_shader_material.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material.glsl
@@ -1,14 +1,4 @@
-uniform mat4 ModelViewMatrix;
-uniform mat4 ModelViewMatrixInverse;
-uniform mat3 NormalMatrix;
-uniform mat3 NormalMatrixInverse;
-
-#ifndef USE_ATTR
-uniform mat4 ModelMatrix;
-uniform mat4 ModelMatrixInverse;
-#endif
-
/* Converters */
float convert_rgba_to_float(vec4 color)
@@ -119,38 +109,6 @@ void hsv_to_rgb(vec4 hsv, out vec4 outcol)
outcol = vec4(rgb, hsv.w);
}
-float srgb_to_linearrgb(float c)
-{
- if (c < 0.04045)
- return (c < 0.0) ? 0.0 : c * (1.0 / 12.92);
- else
- return pow((c + 0.055) * (1.0 / 1.055), 2.4);
-}
-
-float linearrgb_to_srgb(float c)
-{
- if (c < 0.0031308)
- return (c < 0.0) ? 0.0 : c * 12.92;
- else
- return 1.055 * pow(c, 1.0 / 2.4) - 0.055;
-}
-
-void srgb_to_linearrgb(vec4 col_from, out vec4 col_to)
-{
- col_to.r = srgb_to_linearrgb(col_from.r);
- col_to.g = srgb_to_linearrgb(col_from.g);
- col_to.b = srgb_to_linearrgb(col_from.b);
- col_to.a = col_from.a;
-}
-
-void linearrgb_to_srgb(vec4 col_from, out vec4 col_to)
-{
- col_to.r = linearrgb_to_srgb(col_from.r);
- col_to.g = linearrgb_to_srgb(col_from.g);
- col_to.b = linearrgb_to_srgb(col_from.b);
- col_to.a = col_from.a;
-}
-
void color_to_normal_new_shading(vec3 color, out vec3 normal)
{
normal = vec3(2.0) * color - vec3(1.0);
@@ -204,9 +162,9 @@ void direction_transform_m4v3(vec3 vin, mat4 mat, out vec3 vout)
vout = (mat * vec4(vin, 0.0)).xyz;
}
-void mat3_mul(vec3 vin, mat3 mat, out vec3 vout)
+void normal_transform_transposed_m4v3(vec3 vin, mat4 mat, out vec3 vout)
{
- vout = mat * vin;
+ vout = transpose(mat3(mat)) * vin;
}
void point_transform_m4v3(vec3 vin, mat4 mat, out vec3 vout)
@@ -1276,6 +1234,8 @@ void node_bsdf_principled(vec4 base_color,
float ior,
float transmission,
float transmission_roughness,
+ vec4 emission,
+ float alpha,
vec3 N,
vec3 CN,
vec3 T,
@@ -1355,6 +1315,8 @@ void node_bsdf_principled(vec4 base_color,
# endif
result.sss_data.rgb *= (1.0 - transmission);
# endif
+ result.radiance += emission.rgb;
+ result.opacity = alpha;
}
void node_bsdf_principled_dielectric(vec4 base_color,
@@ -1374,6 +1336,8 @@ void node_bsdf_principled_dielectric(vec4 base_color,
float ior,
float transmission,
float transmission_roughness,
+ vec4 emission,
+ float alpha,
vec3 N,
vec3 CN,
vec3 T,
@@ -1403,6 +1367,8 @@ void node_bsdf_principled_dielectric(vec4 base_color,
result.ssr_data = vec4(ssr_spec, roughness);
result.ssr_normal = normal_encode(vN, viewCameraVec);
result.ssr_id = int(ssr_id);
+ result.radiance += emission.rgb;
+ result.opacity = alpha;
}
void node_bsdf_principled_metallic(vec4 base_color,
@@ -1422,6 +1388,8 @@ void node_bsdf_principled_metallic(vec4 base_color,
float ior,
float transmission,
float transmission_roughness,
+ vec4 emission,
+ float alpha,
vec3 N,
vec3 CN,
vec3 T,
@@ -1442,6 +1410,8 @@ void node_bsdf_principled_metallic(vec4 base_color,
result.ssr_data = vec4(ssr_spec, roughness);
result.ssr_normal = normal_encode(vN, viewCameraVec);
result.ssr_id = int(ssr_id);
+ result.radiance += emission.rgb;
+ result.opacity = alpha;
}
void node_bsdf_principled_clearcoat(vec4 base_color,
@@ -1461,6 +1431,8 @@ void node_bsdf_principled_clearcoat(vec4 base_color,
float ior,
float transmission,
float transmission_roughness,
+ vec4 emission,
+ float alpha,
vec3 N,
vec3 CN,
vec3 T,
@@ -1490,6 +1462,8 @@ void node_bsdf_principled_clearcoat(vec4 base_color,
result.ssr_data = vec4(ssr_spec, roughness);
result.ssr_normal = normal_encode(vN, viewCameraVec);
result.ssr_id = int(ssr_id);
+ result.radiance += emission.rgb;
+ result.opacity = alpha;
}
void node_bsdf_principled_subsurface(vec4 base_color,
@@ -1509,6 +1483,8 @@ void node_bsdf_principled_subsurface(vec4 base_color,
float ior,
float transmission,
float transmission_roughness,
+ vec4 emission,
+ float alpha,
vec3 N,
vec3 CN,
vec3 T,
@@ -1563,6 +1539,8 @@ void node_bsdf_principled_subsurface(vec4 base_color,
result.radiance += (out_diff + out_trans) * mixed_ss_base_color;
# endif
result.radiance += out_diff * out_sheen;
+ result.radiance += emission.rgb;
+ result.opacity = alpha;
}
void node_bsdf_principled_glass(vec4 base_color,
@@ -1582,6 +1560,8 @@ void node_bsdf_principled_glass(vec4 base_color,
float ior,
float transmission,
float transmission_roughness,
+ vec4 emission,
+ float alpha,
vec3 N,
vec3 CN,
vec3 T,
@@ -1616,6 +1596,8 @@ void node_bsdf_principled_glass(vec4 base_color,
result.ssr_data = vec4(ssr_spec, roughness);
result.ssr_normal = normal_encode(vN, viewCameraVec);
result.ssr_id = int(ssr_id);
+ result.radiance += emission.rgb;
+ result.opacity = alpha;
}
void node_bsdf_translucent(vec4 color, vec3 N, out Closure result)
@@ -1744,11 +1726,11 @@ void node_tex_environment_texco(vec3 viewvec, out vec3 worldvec)
vec4 v = (ProjectionMatrix[3][3] == 0.0) ? vec4(viewvec, 1.0) : vec4(0.0, 0.0, 1.0, 1.0);
vec4 co_homogenous = (ProjectionMatrixInverse * v);
- vec4 co = vec4(co_homogenous.xyz / co_homogenous.w, 0.0);
+ vec3 co = co_homogenous.xyz / co_homogenous.w;
# if defined(WORLD_BACKGROUND) || defined(PROBE_CAPTURE)
- worldvec = (ViewMatrixInverse * co).xyz;
+ worldvec = mat3(ViewMatrixInverse) * co;
# else
- worldvec = (ModelViewMatrixInverse * co).xyz;
+ worldvec = mat3(ModelMatrixInverse) * (mat3(ViewMatrixInverse) * co);
# endif
#endif
}
@@ -2015,18 +1997,13 @@ void tangent_orco_z(vec3 orco_in, out vec3 orco_out)
orco_out = orco_in.yxz * vec3(-0.5, 0.5, 0.0) + vec3(0.25, -0.25, 0.0);
}
-void node_tangentmap(vec4 attr_tangent, mat4 toworld, out vec3 tangent)
+void node_tangentmap(vec4 attr_tangent, out vec3 tangent)
{
- tangent = normalize((toworld * vec4(attr_tangent.xyz, 0.0)).xyz);
+ tangent = normalize(attr_tangent.xyz);
}
-void node_tangent(vec3 N, vec3 orco, mat4 objmat, mat4 toworld, out vec3 T)
+void node_tangent(vec3 N, vec3 orco, mat4 objmat, out vec3 T)
{
-#ifndef VOLUMETRICS
- N = normalize(gl_FrontFacing ? worldNormal : -worldNormal);
-#else
- N = (toworld * vec4(N, 0.0)).xyz;
-#endif
T = (objmat * vec4(orco, 0.0)).xyz;
T = cross(N, normalize(cross(T, N)));
}
@@ -2070,7 +2047,7 @@ void node_geometry(vec3 I,
true_normal = normal;
# endif
tangent_orco_z(orco, orco);
- node_tangent(N, orco, objmat, toworld, tangent);
+ node_tangent(N, orco, objmat, tangent);
parametric = vec3(barycentric, 0.0);
backfacing = (gl_FrontFacing) ? 0.0 : 1.0;
@@ -2092,9 +2069,8 @@ void generated_texco(vec3 I, vec3 attr_orco, out vec3 generated)
}
void node_tex_coord(vec3 I,
- vec3 N,
- mat4 viewinvmat,
- mat4 obinvmat,
+ vec3 wN,
+ mat4 obmatinv,
vec4 camerafac,
vec3 attr_orco,
vec3 attr_uv,
@@ -2107,22 +2083,18 @@ void node_tex_coord(vec3 I,
out vec3 reflection)
{
generated = attr_orco;
- normal = normalize(NormalMatrixInverse * N);
+ normal = normalize(normal_world_to_object(wN));
uv = attr_uv;
- object = (obinvmat * (viewinvmat * vec4(I, 1.0))).xyz;
+ object = (obmatinv * (ViewMatrixInverse * vec4(I, 1.0))).xyz;
camera = vec3(I.xy, -I.z);
vec4 projvec = ProjectionMatrix * vec4(I, 1.0);
window = vec3(mtex_2d_mapping(projvec.xyz / projvec.w).xy * camerafac.xy + camerafac.zw, 0.0);
-
- vec3 shade_I = (ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0);
- vec3 view_reflection = reflect(shade_I, normalize(N));
- reflection = (viewinvmat * vec4(view_reflection, 0.0)).xyz;
+ reflection = reflect(cameraVec, normalize(wN));
}
void node_tex_coord_background(vec3 I,
vec3 N,
- mat4 viewinvmat,
- mat4 obinvmat,
+ mat4 obmatinv,
vec4 camerafac,
vec3 attr_orco,
vec3 attr_uv,
@@ -2141,11 +2113,7 @@ void node_tex_coord_background(vec3 I,
co = normalize(co);
-#if defined(WORLD_BACKGROUND) || defined(PROBE_CAPTURE)
vec3 coords = (ViewMatrixInverse * co).xyz;
-#else
- vec3 coords = (ModelViewMatrixInverse * co).xyz;
-#endif
generated = coords;
normal = -coords;
@@ -2346,6 +2314,21 @@ void node_tex_environment_empty(vec3 co, out vec4 color)
/* 16bits floats limits. Higher/Lower values produce +/-inf. */
#define safe_color(a) (clamp(a, -65520.0, 65520.0))
+void tex_color_alpha_clear(vec4 color, out vec4 result)
+{
+ result = vec4(color.rgb, 1.0);
+}
+
+void tex_color_alpha_unpremultiply(vec4 color, out vec4 result)
+{
+ if (color.a == 0.0 || color.a == 1.0) {
+ result = vec4(color.rgb, 1.0);
+ }
+ else {
+ result = vec4(color.rgb / color.a, 1.0);
+ }
+}
+
void node_tex_image_linear(vec3 co, sampler2D ima, out vec4 color, out float alpha)
{
color = safe_color(texture(ima, co.xy));
@@ -3246,6 +3229,7 @@ void node_light_falloff(
void node_object_info(mat4 obmat,
vec4 info,
+ float mat_index,
out vec3 location,
out float object_index,
out float material_index,
@@ -3253,7 +3237,7 @@ void node_object_info(mat4 obmat,
{
location = obmat[3].xyz;
object_index = info.x;
- material_index = info.y;
+ material_index = mat_index;
random = info.z;
}
@@ -3347,6 +3331,7 @@ void node_vector_displacement_tangent(vec4 vector,
mat4 viewmat,
out vec3 result)
{
+ /* TODO(fclem) this is broken. revisit latter. */
vec3 N_object = normalize(((vec4(normal, 0.0) * viewmat) * obmat).xyz);
vec3 T_object = normalize(((vec4(tangent.xyz, 0.0) * viewmat) * obmat).xyz);
vec3 B_object = tangent.w * normalize(cross(N_object, T_object));
@@ -3391,11 +3376,11 @@ void node_output_world(Closure surface, Closure volume, out Closure result)
#endif /* VOLUMETRICS */
}
-#ifndef VOLUMETRICS
/* TODO : clean this ifdef mess */
/* EEVEE output */
void world_normals_get(out vec3 N)
{
+#ifndef VOLUMETRICS
# ifdef HAIR_SHADER
vec3 B = normalize(cross(worldNormal, hairTangent));
float cos_theta;
@@ -3413,8 +3398,12 @@ void world_normals_get(out vec3 N)
# else
N = gl_FrontFacing ? worldNormal : -worldNormal;
# endif
+#else
+ generated_from_orco(vec3(0.0), N);
+#endif
}
+#ifndef VOLUMETRICS
void node_eevee_specular(vec4 diffuse,
vec4 specular,
float roughness,
diff --git a/source/blender/imbuf/IMB_colormanagement.h b/source/blender/imbuf/IMB_colormanagement.h
index 620f8984d9f..e683d38a0aa 100644
--- a/source/blender/imbuf/IMB_colormanagement.h
+++ b/source/blender/imbuf/IMB_colormanagement.h
@@ -58,6 +58,10 @@ void IMB_colormanagement_assign_rect_colorspace(struct ImBuf *ibuf, const char *
const char *IMB_colormanagement_get_float_colorspace(struct ImBuf *ibuf);
const char *IMB_colormanagement_get_rect_colorspace(struct ImBuf *ibuf);
+bool IMB_colormanagement_space_is_data(struct ColorSpace *colorspace);
+bool IMB_colormanagement_space_is_scene_linear(struct ColorSpace *colorspace);
+bool IMB_colormanagement_space_is_srgb(struct ColorSpace *colorspace);
+
BLI_INLINE float IMB_colormanagement_get_luminance(const float rgb[3]);
BLI_INLINE unsigned char IMB_colormanagement_get_luminance_byte(const unsigned char[3]);
BLI_INLINE void IMB_colormangement_xyz_to_rgb(float rgb[3], const float xyz[3]);
@@ -124,6 +128,14 @@ void IMB_colormanagement_colorspace_to_scene_linear(float *buffer,
struct ColorSpace *colorspace,
bool predivide);
+void IMB_colormanagement_imbuf_to_srgb_texture(unsigned char *rect,
+ const int x,
+ const int y,
+ const int width,
+ const int height,
+ const struct ImBuf *ibuf,
+ const bool compress_as_srgb);
+
void IMB_colormanagement_scene_linear_to_color_picking_v3(float pixel[3]);
void IMB_colormanagement_color_picking_to_scene_linear_v3(float pixel[3]);
@@ -340,6 +352,7 @@ enum {
COLOR_ROLE_DEFAULT_SEQUENCER,
COLOR_ROLE_DEFAULT_BYTE,
COLOR_ROLE_DEFAULT_FLOAT,
+ COLOR_ROLE_DATA,
};
#include "intern/colormanagement_inline.c"
diff --git a/source/blender/imbuf/intern/IMB_colormanagement_intern.h b/source/blender/imbuf/intern/IMB_colormanagement_intern.h
index 2566016ffdd..a83f2d60b8c 100644
--- a/source/blender/imbuf/intern/IMB_colormanagement_intern.h
+++ b/source/blender/imbuf/intern/IMB_colormanagement_intern.h
@@ -48,6 +48,13 @@ typedef struct ColorSpace {
bool is_invertible;
bool is_data;
+
+ /* Additional info computed only when needed since it's not cheap. */
+ struct {
+ bool cached;
+ bool is_srgb;
+ bool is_scene_linear;
+ } info;
} ColorSpace;
typedef struct ColorManagedDisplay {
diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c
index f31d4ede693..b460d268d38 100644
--- a/source/blender/imbuf/intern/colormanagement.c
+++ b/source/blender/imbuf/intern/colormanagement.c
@@ -65,6 +65,7 @@
#define DISPLAY_BUFFER_CHANNELS 4
/* ** list of all supported color spaces, displays and views */
+static char global_role_data[MAX_COLORSPACE_NAME];
static char global_role_scene_linear[MAX_COLORSPACE_NAME];
static char global_role_color_picking[MAX_COLORSPACE_NAME];
static char global_role_texture_painting[MAX_COLORSPACE_NAME];
@@ -488,6 +489,7 @@ static void colormanage_load_config(OCIO_ConstConfigRcPtr *config)
const char *name;
/* get roles */
+ colormanage_role_color_space_name_get(config, global_role_data, OCIO_ROLE_DATA, NULL);
colormanage_role_color_space_name_get(
config, global_role_scene_linear, OCIO_ROLE_SCENE_LINEAR, NULL);
colormanage_role_color_space_name_get(
@@ -1260,6 +1262,8 @@ void IMB_colormanagement_validate_settings(const ColorManagedDisplaySettings *di
const char *IMB_colormanagement_role_colorspace_name_get(int role)
{
switch (role) {
+ case COLOR_ROLE_DATA:
+ return global_role_data;
case COLOR_ROLE_SCENE_LINEAR:
return global_role_scene_linear;
case COLOR_ROLE_COLOR_PICKING:
@@ -1341,6 +1345,42 @@ const char *IMB_colormanagement_get_rect_colorspace(ImBuf *ibuf)
}
}
+bool IMB_colormanagement_space_is_data(ColorSpace *colorspace)
+{
+ return (colorspace && colorspace->is_data);
+}
+
+static void colormanage_ensure_srgb_scene_linear_info(ColorSpace *colorspace)
+{
+ if (!colorspace->info.cached) {
+ OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig();
+ OCIO_ConstColorSpaceRcPtr *ocio_colorspace = OCIO_configGetColorSpace(config,
+ colorspace->name);
+
+ bool is_scene_linear, is_srgb;
+ OCIO_colorSpaceIsBuiltin(config, ocio_colorspace, &is_scene_linear, &is_srgb);
+
+ OCIO_colorSpaceRelease(ocio_colorspace);
+ OCIO_configRelease(config);
+
+ colorspace->info.is_scene_linear = is_scene_linear;
+ colorspace->info.is_srgb = is_srgb;
+ colorspace->info.cached = true;
+ }
+}
+
+bool IMB_colormanagement_space_is_scene_linear(ColorSpace *colorspace)
+{
+ colormanage_ensure_srgb_scene_linear_info(colorspace);
+ return (colorspace && colorspace->info.is_scene_linear);
+}
+
+bool IMB_colormanagement_space_is_srgb(ColorSpace *colorspace)
+{
+ colormanage_ensure_srgb_scene_linear_info(colorspace);
+ return (colorspace && colorspace->info.is_srgb);
+}
+
/*********************** Threaded display buffer transform routines *************************/
typedef struct DisplayBufferThread {
@@ -2111,6 +2151,57 @@ void IMB_colormanagement_colorspace_to_scene_linear(float *buffer,
}
}
+void IMB_colormanagement_imbuf_to_srgb_texture(unsigned char *out_buffer,
+ const int offset_x,
+ const int offset_y,
+ const int width,
+ const int height,
+ const struct ImBuf *ibuf,
+ const bool compress_as_srgb)
+{
+ /* Convert byte buffer for texture storage on the GPU. These have builtin
+ * support for converting sRGB to linear, which allows us to store textures
+ * without precision or performance loss at minimal memory usage. */
+ BLI_assert(ibuf->rect && ibuf->rect_float == NULL);
+
+ OCIO_ConstProcessorRcPtr *processor = NULL;
+ if (compress_as_srgb && ibuf->rect_colorspace &&
+ !IMB_colormanagement_space_is_srgb(ibuf->rect_colorspace)) {
+ processor = colorspace_to_scene_linear_processor(ibuf->rect_colorspace);
+ }
+
+ /* TODO(brecht): make this multithreaded, or at least process in batches. */
+ const unsigned char *in_buffer = (unsigned char *)ibuf->rect;
+
+ for (int y = 0; y < height; y++) {
+ const size_t in_offset = (offset_y + y) * ibuf->x + offset_x;
+ const size_t out_offset = y * width;
+ const unsigned char *in = in_buffer + in_offset * 4;
+ unsigned char *out = out_buffer + out_offset * 4;
+
+ if (processor) {
+ /* Convert to scene linear, to sRGB and premultiply. */
+ for (int x = 0; x < width; x++, in += 4, out += 4) {
+ float pixel[4];
+ rgba_uchar_to_float(pixel, in);
+ OCIO_processorApplyRGB(processor, pixel);
+ linearrgb_to_srgb_v3_v3(pixel, pixel);
+ mul_v3_fl(pixel, pixel[3]);
+ rgba_float_to_uchar(out, pixel);
+ }
+ }
+ else {
+ /* Premultiply only. */
+ for (int x = 0; x < width; x++, in += 4, out += 4) {
+ out[0] = (in[0] * in[3]) >> 8;
+ out[1] = (in[1] * in[3]) >> 8;
+ out[2] = (in[2] * in[3]) >> 8;
+ out[3] = in[3];
+ }
+ }
+ }
+}
+
/* Conversion between color picking role. Typically we would expect such a
* requirements:
* - It is approximately perceptually linear, so that the HSV numbers and
diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h
index 14b3d97cef4..5a666653043 100644
--- a/source/blender/makesdna/DNA_ID.h
+++ b/source/blender/makesdna/DNA_ID.h
@@ -448,7 +448,9 @@ typedef enum ID_Type {
/* No copy-on-write for these types.
* Keep in sync with check_datablocks_copy_on_writable and deg_copy_on_write_is_needed */
-#define ID_TYPE_IS_COW(_id_type) (!ELEM(_id_type, ID_BR, ID_LS, ID_PAL, ID_IM))
+/* TODO(sergey): Make Sound copyable. It is here only because the code for dependency graph is
+ * being work in progress. */
+#define ID_TYPE_IS_COW(_id_type) (!ELEM(_id_type, ID_BR, ID_LS, ID_PAL, ID_IM, ID_SO))
#ifdef GS
# undef GS
@@ -602,10 +604,6 @@ typedef enum IDRecalcFlag {
*/
ID_RECALC_COPY_ON_WRITE = (1 << 13),
- /* Sequences in the sequencer did change.
- * Use this tag with a scene ID which owns the sequences. */
- ID_RECALC_SEQUENCER = (1 << 14),
-
/***************************************************************************
* Pseudonyms, to have more semantic meaning in the actual code without
* using too much low-level and implementation specific tags. */
diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h
index c524f50ff52..c8a76791cef 100644
--- a/source/blender/makesdna/DNA_action_types.h
+++ b/source/blender/makesdna/DNA_action_types.h
@@ -512,6 +512,12 @@ typedef enum ePose_Flags {
POSE_FLAG_DEPRECATED = (1 << 6), /* deprecated. */
/* pose constraint flags needs to be updated */
POSE_CONSTRAINTS_NEED_UPDATE_FLAGS = (1 << 7),
+ /* Use auto IK in pose mode */
+ POSE_AUTO_IK = (1 << 8),
+ /* Use x-axis mirror in pose mode */
+ POSE_MIRROR_EDIT = (1 << 9),
+ /* Use relative mirroring in mirror mode */
+ POSE_MIRROR_RELATIVE = (1 << 10),
} ePose_Flags;
/* IK Solvers ------------------------------------ */
diff --git a/source/blender/makesdna/DNA_anim_types.h b/source/blender/makesdna/DNA_anim_types.h
index c76d4895b25..ecf587301c7 100644
--- a/source/blender/makesdna/DNA_anim_types.h
+++ b/source/blender/makesdna/DNA_anim_types.h
@@ -357,6 +357,7 @@ typedef enum eDriverTarget_TransformChannels {
DTAR_TRANSCHAN_SCALEX,
DTAR_TRANSCHAN_SCALEY,
DTAR_TRANSCHAN_SCALEZ,
+ DTAR_TRANSCHAN_SCALE_AVG,
MAX_DTAR_TRANSCHAN_TYPES,
} eDriverTarget_TransformChannels;
@@ -969,6 +970,8 @@ typedef enum eInsertKeyFlags {
INSERTKEY_DRIVER = (1 << 8),
/** for cyclic FCurves, adjust key timing to preserve the cycle period and flow */
INSERTKEY_CYCLE_AWARE = (1 << 9),
+ /** don't create new F-Curves (implied by INSERTKEY_REPLACE) */
+ INSERTKEY_AVAILABLE = (1 << 10),
} eInsertKeyFlags;
/* ************************************************ */
diff --git a/source/blender/makesdna/DNA_armature_types.h b/source/blender/makesdna/DNA_armature_types.h
index 483ff3483d3..b18ab503e94 100644
--- a/source/blender/makesdna/DNA_armature_types.h
+++ b/source/blender/makesdna/DNA_armature_types.h
@@ -104,7 +104,11 @@ typedef struct bArmature {
struct AnimData *adt;
ListBase bonebase;
- ListBase chainbase;
+
+ /** Ghash for quicker lookups of bones by name. */
+ struct GHash *bonehash;
+ void *_pad1;
+
/** Editbone listbase, we use pointer so we can check state. */
ListBase *edbo;
@@ -144,9 +148,9 @@ typedef enum eArmature_Flag {
ARM_POSEMODE = (1 << 4),
ARM_FLAG_UNUSED_5 = (1 << 5), /* cleared */
ARM_DELAYDEFORM = (1 << 6),
- ARM_FLAG_UNUSED_7 = (1 << 7), /* cleared */
+ ARM_FLAG_UNUSED_7 = (1 << 7),
ARM_MIRROR_EDIT = (1 << 8),
- ARM_AUTO_IK = (1 << 9),
+ ARM_FLAG_UNUSED_9 = (1 << 9),
/** made option negative, for backwards compat */
ARM_NO_CUSTOM = (1 << 10),
/** draw custom colors */
diff --git a/source/blender/makesdna/DNA_collection_types.h b/source/blender/makesdna/DNA_collection_types.h
index b935acd5a24..c7f3ef4156d 100644
--- a/source/blender/makesdna/DNA_collection_types.h
+++ b/source/blender/makesdna/DNA_collection_types.h
@@ -76,10 +76,10 @@ typedef struct Collection {
/* Collection->flag */
enum {
- COLLECTION_RESTRICT_VIEW = (1 << 0), /* Hidden in viewport. */
+ COLLECTION_RESTRICT_VIEWPORT = (1 << 0), /* Disable in viewports. */
COLLECTION_RESTRICT_SELECT = (1 << 1), /* Not selectable in viewport. */
COLLECTION_DISABLED_DEPRECATED = (1 << 2), /* Not used anymore */
- COLLECTION_RESTRICT_RENDER = (1 << 3), /* Hidden in renders. */
+ COLLECTION_RESTRICT_RENDER = (1 << 3), /* Disable in renders. */
COLLECTION_HAS_OBJECT_CACHE = (1 << 4), /* Runtime: object_cache is populated. */
COLLECTION_IS_MASTER = (1 << 5), /* Is master collection embedded in the scene. */
};
diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h
index f839f22ec9f..c09ea400f4c 100644
--- a/source/blender/makesdna/DNA_constraint_types.h
+++ b/source/blender/makesdna/DNA_constraint_types.h
@@ -289,14 +289,16 @@ typedef struct bLocateLikeConstraint {
typedef struct bSizeLikeConstraint {
struct Object *tar;
int flag;
- int reserved1;
+ float power;
/** MAX_ID_NAME-2. */
char subtarget[64];
} bSizeLikeConstraint;
/* Maintain Volume Constraint */
typedef struct bSameVolumeConstraint {
- int flag;
+ char free_axis;
+ char mode;
+ char _pad[2];
float volume;
} bSameVolumeConstraint;
@@ -758,12 +760,22 @@ typedef enum eTransform_ToFrom {
TRANS_SCALE = 2,
} eTransform_ToFrom;
-/* bSameVolumeConstraint.flag */
-typedef enum eSameVolume_Modes {
+/* bSameVolumeConstraint.free_axis */
+typedef enum eSameVolume_Axis {
SAMEVOL_X = 0,
SAMEVOL_Y = 1,
SAMEVOL_Z = 2,
-} eSameVolume_Modes;
+} eSameVolume_Axis;
+
+/* bSameVolumeConstraint.mode */
+typedef enum eSameVolume_Mode {
+ /* Strictly maintain the volume, overriding non-free axis scale. */
+ SAMEVOL_STRICT = 0,
+ /* Maintain the volume when scale is uniform, pass non-uniform other axis scale through. */
+ SAMEVOL_UNIFORM = 1,
+ /* Maintain the volume when scaled only on the free axis, pass other axis scale through. */
+ SAMEVOL_SINGLE_AXIS = 2,
+} eSameVolume_Mode;
/* bActionConstraint.flag */
typedef enum eActionConstraint_Flags {
@@ -894,6 +906,9 @@ typedef enum eSplineIK_Flags {
/* for "volumetric" xz scale mode, limit the minimum or maximum scale values */
CONSTRAINT_SPLINEIK_USE_BULGE_MIN = (1 << 5),
CONSTRAINT_SPLINEIK_USE_BULGE_MAX = (1 << 6),
+
+ /* apply volume preservation over original scaling of the bone */
+ CONSTRAINT_SPLINEIK_USE_ORIGINAL_SCALE = (1 << 7),
} eSplineIK_Flags;
/* bSplineIKConstraint->xzScaleMode */
diff --git a/source/blender/makesdna/DNA_image_types.h b/source/blender/makesdna/DNA_image_types.h
index fec5f96b4f3..0aceeda20d5 100644
--- a/source/blender/makesdna/DNA_image_types.h
+++ b/source/blender/makesdna/DNA_image_types.h
@@ -191,8 +191,6 @@ enum {
IMA_GPU_REFRESH = (1 << 0),
/** All mipmap levels in OpenGL texture set? */
IMA_GPU_MIPMAP_COMPLETE = (1 << 1),
- /** OpenGL image texture bound as non-color data. */
- IMA_GPU_IS_DATA = (1 << 2),
};
/* ima->type and ima->source moved to BKE_image.h, for API */
diff --git a/source/blender/makesdna/DNA_layer_types.h b/source/blender/makesdna/DNA_layer_types.h
index dd8adeaf153..5f64e3220b7 100644
--- a/source/blender/makesdna/DNA_layer_types.h
+++ b/source/blender/makesdna/DNA_layer_types.h
@@ -133,7 +133,7 @@ enum {
LAYER_COLLECTION_EXCLUDE = (1 << 4),
LAYER_COLLECTION_HOLDOUT = (1 << 5),
LAYER_COLLECTION_INDIRECT_ONLY = (1 << 6),
- LAYER_COLLECTION_RESTRICT_VIEW = (1 << 7),
+ LAYER_COLLECTION_HIDE = (1 << 7),
};
/* Layer Collection->runtime_flag */
diff --git a/source/blender/makesdna/DNA_light_types.h b/source/blender/makesdna/DNA_light_types.h
index 6bd118b7be9..5e881053910 100644
--- a/source/blender/makesdna/DNA_light_types.h
+++ b/source/blender/makesdna/DNA_light_types.h
@@ -66,6 +66,9 @@ typedef struct Light {
short area_shape;
float area_size, area_sizey, area_sizez;
+ float sun_angle;
+ char _pad3[4];
+
/* texact is for buttons */
short texact, shadhalostep;
diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h
index 02f8245413d..d65a4896758 100644
--- a/source/blender/makesdna/DNA_material_types.h
+++ b/source/blender/makesdna/DNA_material_types.h
@@ -99,6 +99,9 @@ typedef struct MaterialGPencilStyle {
/** Factor used to mix texture and stroke color. */
float mix_stroke_factor;
+ /** Mode used to align Dots and Boxes with stroke drawing path and object rotation */
+ int alignment_mode;
+ char _pad[4];
} MaterialGPencilStyle;
/* MaterialGPencilStyle->flag */
@@ -123,8 +126,6 @@ typedef enum eMaterialGPencilStyle_Flag {
GP_STYLE_STROKE_SHOW = (1 << 8),
/* Fill show main switch */
GP_STYLE_FILL_SHOW = (1 << 9),
- /* Don't rotate dots/boxes */
- GP_STYLE_COLOR_LOCK_DOTS = (1 << 10),
/* mix stroke texture */
GP_STYLE_STROKE_TEX_MIX = (1 << 11),
} eMaterialGPencilStyle_Flag;
@@ -315,7 +316,7 @@ enum {
enum {
MA_BL_HIDE_BACKFACE = (1 << 0),
MA_BL_SS_REFRACTION = (1 << 1),
- MA_BL_FLAG_UNUSED_2 = (1 << 2), /* cleared */
+ MA_BL_CULL_BACKFACE = (1 << 2),
MA_BL_TRANSLUCENCY = (1 << 3),
};
@@ -347,4 +348,10 @@ enum {
GP_STYLE_GRADIENT_RADIAL,
};
+/* Grease Pencil Follow Drawing Modes */
+enum {
+ GP_STYLE_FOLLOW_PATH = 0,
+ GP_STYLE_FOLLOW_OBJ,
+ GP_STYLE_FOLLOW_FIXED,
+};
#endif
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 226e1d2f841..3890fc63f3f 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -832,7 +832,7 @@ typedef struct NodeTexSky {
typedef struct NodeTexImage {
NodeTexBase base;
ImageUser iuser;
- int color_space;
+ int color_space DNA_DEPRECATED;
int projection;
float projection_blend;
int interpolation;
@@ -853,7 +853,7 @@ typedef struct NodeTexBrick {
typedef struct NodeTexEnvironment {
NodeTexBase base;
ImageUser iuser;
- int color_space;
+ int color_space DNA_DEPRECATED;
int projection;
int interpolation;
char _pad[4];
@@ -1121,10 +1121,6 @@ typedef struct NodeCryptomatte {
#define SHD_SKY_OLD 0
#define SHD_SKY_NEW 1
-/* image/environment texture */
-#define SHD_COLORSPACE_NONE 0
-#define SHD_COLORSPACE_COLOR 1
-
/* environment texture */
#define SHD_PROJ_EQUIRECTANGULAR 0
#define SHD_PROJ_MIRROR_BALL 1
diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h
index 1aeb4a2f4d2..a73c762e3bf 100644
--- a/source/blender/makesdna/DNA_object_types.h
+++ b/source/blender/makesdna/DNA_object_types.h
@@ -136,6 +136,10 @@ typedef struct Object_Runtime {
/** Only used for drawing the parent/child help-line. */
float parent_display_origin[3];
+ /** Selection id of this object; only available in the original object */
+ int select_id;
+ char _pad1[4];
+
/** Axis aligned boundbox (in localspace). */
struct BoundBox *bb;
@@ -365,9 +369,7 @@ typedef struct Object {
char empty_image_visibility_flag;
char empty_image_depth;
char empty_image_flag;
- char _pad8[1];
-
- int select_id;
+ char _pad8[5];
/** Contains data for levels of detail. */
ListBase lodlevels;
@@ -600,7 +602,7 @@ enum {
/* ob->restrictflag */
enum {
- OB_RESTRICT_VIEW = 1 << 0,
+ OB_RESTRICT_VIEWPORT = 1 << 0,
OB_RESTRICT_SELECT = 1 << 1,
OB_RESTRICT_RENDER = 1 << 2,
};
diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h
index e014de183e3..f5c2a518ef6 100644
--- a/source/blender/makesdna/DNA_screen_types.h
+++ b/source/blender/makesdna/DNA_screen_types.h
@@ -139,7 +139,7 @@ typedef struct Panel {
struct uiLayout *layout;
/** Defined as UI_MAX_NAME_STR. */
- char panelname[64], tabname[64];
+ char panelname[64];
/** Panel name is identifier for restoring location. */
char drawname[64];
/** Offset within the region. */
@@ -155,8 +155,6 @@ typedef struct Panel {
short snap;
/** Panels are aligned according to increasing sort-order. */
int sortorder;
- /** This panel is tabbed in *paneltab. */
- struct Panel *paneltab;
/** Runtime for panel manipulation. */
void *activedata;
/** Sub panels. */
diff --git a/source/blender/makesdna/DNA_sequence_types.h b/source/blender/makesdna/DNA_sequence_types.h
index 5240de4aff9..c21fa2ba64e 100644
--- a/source/blender/makesdna/DNA_sequence_types.h
+++ b/source/blender/makesdna/DNA_sequence_types.h
@@ -232,9 +232,6 @@ typedef struct Sequence {
int cache_flag;
int _pad2[3];
-
- struct Sequence *orig_sequence;
- void *_pad3;
} Sequence;
typedef struct MetaStack {
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index 9e8ece0c6e8..20d4f7d96e4 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -247,7 +247,7 @@ typedef struct SpaceOutliner {
short flag, outlinevis, storeflag, search_flags;
int filter;
char filter_state;
- char _pad;
+ char show_restrict_flags;
short filter_id_type;
/**
@@ -260,7 +260,7 @@ typedef struct SpaceOutliner {
typedef enum eSpaceOutliner_Flag {
SO_TESTBLOCKS = (1 << 0),
SO_NEWSELECTED = (1 << 1),
- SO_HIDE_RESTRICTCOLS = (1 << 2),
+ SO_FLAG_UNUSED_1 = (1 << 2), /* cleared */
SO_HIDE_KEYINGSETINFO = (1 << 3),
SO_SKIP_SORT_ALPHA = (1 << 4),
} eSpaceOutliner_Flag;
@@ -309,6 +309,17 @@ typedef enum eSpaceOutliner_StateFilter {
SO_FILTER_OB_ACTIVE = 3,
} eSpaceOutliner_StateFilter;
+/* SpaceOutliner.show_restrict_flags */
+typedef enum eSpaceOutliner_ShowRestrictFlag {
+ SO_RESTRICT_ENABLE = (1 << 0),
+ SO_RESTRICT_SELECT = (1 << 1),
+ SO_RESTRICT_HIDE = (1 << 2),
+ SO_RESTRICT_VIEWPORT = (1 << 3),
+ SO_RESTRICT_RENDER = (1 << 4),
+ SO_RESTRICT_HOLDOUT = (1 << 5),
+ SO_RESTRICT_INDIRECT_ONLY = (1 << 6),
+} eSpaceOutliner_Restrict;
+
/* SpaceOutliner.outlinevis */
typedef enum eSpaceOutliner_Mode {
SO_SCENES = 0,
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index e3773e8b670..2247ec2e6ee 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -38,11 +38,6 @@ struct ColorBand;
#define MAX_STYLE_NAME 64
-#define GPU_VIEWPORT_QUALITY_FXAA 0.10f
-#define GPU_VIEWPORT_QUALITY_TAA8 0.25f
-#define GPU_VIEWPORT_QUALITY_TAA16 0.6f
-#define GPU_VIEWPORT_QUALITY_TAA32 0.8f
-
/** default offered by Blender.
* #uiFont.uifont_id */
typedef enum eUIFont_ID {
@@ -189,6 +184,8 @@ typedef struct ThemeUI {
char gizmo_b[4];
/* Icon Colors. */
+ /** Scene items. */
+ char icon_scene[4];
/** Collection items. */
char icon_collection[4];
/** Object items. */
@@ -199,6 +196,9 @@ typedef struct ThemeUI {
char icon_modifier[4];
/** Shading related items. */
char icon_shading[4];
+ /** Intensity of the border icons. >0 will render an border around themed
+ * icons. */
+ float icon_border_intensity;
} ThemeUI;
/* try to put them all in one, if needed a special struct can be created as well
@@ -283,6 +283,8 @@ typedef struct ThemeSpace {
char cframe[4];
char time_keyframe[4], time_gp_keyframe[4];
char freestyle_edge_mark[4], freestyle_face_mark[4];
+ char scrubbing_background[4];
+ char _pad5[4];
char nurb_uline[4], nurb_vline[4];
char act_spline[4], nurb_sel_uline[4], nurb_sel_vline[4], lastsel_point[4];
@@ -535,6 +537,11 @@ typedef struct WalkNavigation {
char _pad0[6];
} WalkNavigation;
+typedef struct UserDef_Runtime {
+ char is_dirty;
+ char _pad0[7];
+} UserDef_Runtime;
+
typedef struct UserDef {
/* UserDef has separate do-version handling, and can be read from other files */
int versionfile, subversionfile;
@@ -542,8 +549,12 @@ typedef struct UserDef {
/** #eUserPref_Flag. */
int flag;
/** #eDupli_ID_Flags. */
- int dupflag;
- int savetime;
+ short dupflag;
+ /**
+ * #eUserPref_PrefFlag preferences for the preferences. */
+ char pref_flag;
+ char savetime;
+ char _pad4[4];
/** FILE_MAXDIR length. */
char tempdir[768];
char fontdir[768];
@@ -600,6 +611,7 @@ typedef struct UserDef {
int dpi;
/** Runtime, multiplier to scale UI elements based on DPI. */
float dpi_fac;
+ float inv_dpi_fac;
/** Runtime, line width and point size based on DPI. */
float pixelsize;
/** Deprecated, for forward compatibility. */
@@ -609,7 +621,7 @@ typedef struct UserDef {
int scrollback;
/** Node insert offset (aka auto-offset) margin, but might be useful for later stuff as well. */
char node_margin;
- char _pad2[5];
+ char _pad2[1];
/** #eUserpref_Translation_Flags. */
short transopts;
short menuthreshold1, menuthreshold2;
@@ -633,7 +645,7 @@ typedef struct UserDef {
short undosteps;
char _pad1[2];
int undomemory;
- float gpu_viewport_quality;
+ float gpu_viewport_quality DNA_DEPRECATED;
short gp_manhattendist, gp_euclideandist, gp_eraser;
/** #eGP_UserdefSettings. */
short gp_settings;
@@ -643,7 +655,7 @@ typedef struct UserDef {
char _pad3[4];
short gizmo_flag, gizmo_size;
short edit_studio_light;
- short lookdev_ball_size;
+ short lookdev_sphere_size;
short vbotimeout, vbocollectrate;
short textimeout, texcollectrate;
int memcachelimit;
@@ -761,7 +773,12 @@ typedef struct UserDef {
char factor_display_type;
- char _pad5[3];
+ char viewport_aa;
+
+ char _pad5[2];
+
+ /** Runtime data (keep last). */
+ UserDef_Runtime runtime;
} UserDef;
/* from blenkernel blender.c */
@@ -816,7 +833,7 @@ typedef enum eUserPref_Flag {
USER_TOOLTIPS = (1 << 11),
USER_TWOBUTTONMOUSE = (1 << 12),
USER_NONUMPAD = (1 << 13),
- USER_FLAG_UNUSED_14 = (1 << 14), /* cleared */
+ USER_ADD_CURSORALIGNED = (1 << 14),
USER_FILECOMPRESS = (1 << 15),
USER_SAVE_PREVIEWS = (1 << 16),
USER_CUSTOM_RANGE = (1 << 17),
@@ -831,6 +848,10 @@ typedef enum eUserPref_Flag {
USER_TOOLTIPS_PYTHON = (1 << 26),
} eUserPref_Flag;
+typedef enum eUserPref_PrefFlag {
+ USER_PREF_FLAG_SAVE = (1 << 0),
+} eUserPref_PrefFlag;
+
/** #bPathCompare.flag */
typedef enum ePathCompare_Flag {
USER_PATHCMP_GLOB = (1 << 0),
diff --git a/source/blender/makesdna/DNA_view2d_types.h b/source/blender/makesdna/DNA_view2d_types.h
index 0f25b47cb0b..8734a73c07a 100644
--- a/source/blender/makesdna/DNA_view2d_types.h
+++ b/source/blender/makesdna/DNA_view2d_types.h
@@ -151,10 +151,10 @@ enum {
V2D_SCROLL_BOTTOM = (1 << 3),
/* UNUSED = (1 << 4), */
V2D_SCROLL_HORIZONTAL = (V2D_SCROLL_TOP | V2D_SCROLL_BOTTOM),
- /* scale markings - vertical */
- V2D_SCROLL_SCALE_VERTICAL = (1 << 5),
- /* scale markings - horizontal */
- V2D_SCROLL_SCALE_HORIZONTAL = (1 << 6),
+ /* display vertical scale handles */
+ V2D_SCROLL_VERTICAL_HANDLES = (1 << 5),
+ /* display horizontal scale handles */
+ V2D_SCROLL_HORIZONTAL_HANDLES = (1 << 6),
/* induce hiding of scrollbars - set by region drawing in response to size of region */
V2D_SCROLL_VERTICAL_HIDE = (1 << 7),
V2D_SCROLL_HORIZONTAL_HIDE = (1 << 8),
diff --git a/source/blender/makesdna/intern/dna_rename_defs.h b/source/blender/makesdna/intern/dna_rename_defs.h
index b9e0853b1ab..3aa0ff4b28a 100644
--- a/source/blender/makesdna/intern/dna_rename_defs.h
+++ b/source/blender/makesdna/intern/dna_rename_defs.h
@@ -58,12 +58,12 @@ DNA_STRUCT_RENAME(SpaceIpo, SpaceGraph)
DNA_STRUCT_RENAME(SpaceOops, SpaceOutliner)
DNA_STRUCT_RENAME_ELEM(BPoint, alfa, tilt)
DNA_STRUCT_RENAME_ELEM(BezTriple, alfa, tilt)
-DNA_STRUCT_RENAME_ELEM(Bone, scaleIn, scale_in_x)
-DNA_STRUCT_RENAME_ELEM(Bone, scaleOut, scale_out_x)
DNA_STRUCT_RENAME_ELEM(Bone, curveInX, curve_in_x)
DNA_STRUCT_RENAME_ELEM(Bone, curveInY, curve_in_y)
DNA_STRUCT_RENAME_ELEM(Bone, curveOutX, curve_out_x)
DNA_STRUCT_RENAME_ELEM(Bone, curveOutY, curve_out_y)
+DNA_STRUCT_RENAME_ELEM(Bone, scaleIn, scale_in_x)
+DNA_STRUCT_RENAME_ELEM(Bone, scaleOut, scale_out_x)
DNA_STRUCT_RENAME_ELEM(Camera, YF_dofdist, dof_distance)
DNA_STRUCT_RENAME_ELEM(Camera, clipend, clip_end)
DNA_STRUCT_RENAME_ELEM(Camera, clipsta, clip_start)
@@ -77,12 +77,13 @@ DNA_STRUCT_RENAME_ELEM(ParticleSettings, dup_ob, instance_object)
DNA_STRUCT_RENAME_ELEM(ParticleSettings, dupliweights, instance_weights)
DNA_STRUCT_RENAME_ELEM(View3D, far, clip_end)
DNA_STRUCT_RENAME_ELEM(View3D, near, clip_start)
-DNA_STRUCT_RENAME_ELEM(bPoseChannel, scaleIn, scale_in_x)
-DNA_STRUCT_RENAME_ELEM(bPoseChannel, scaleOut, scale_out_x)
DNA_STRUCT_RENAME_ELEM(bPoseChannel, curveInX, curve_in_x)
DNA_STRUCT_RENAME_ELEM(bPoseChannel, curveInY, curve_in_y)
DNA_STRUCT_RENAME_ELEM(bPoseChannel, curveOutX, curve_out_x)
DNA_STRUCT_RENAME_ELEM(bPoseChannel, curveOutY, curve_out_y)
+DNA_STRUCT_RENAME_ELEM(bPoseChannel, scaleIn, scale_in_x)
+DNA_STRUCT_RENAME_ELEM(bPoseChannel, scaleOut, scale_out_x)
+DNA_STRUCT_RENAME_ELEM(bSameVolumeConstraint, flag, free_axis)
DNA_STRUCT_RENAME_ELEM(bTheme, tact, space_action)
DNA_STRUCT_RENAME_ELEM(bTheme, tbuts, space_properties)
DNA_STRUCT_RENAME_ELEM(bTheme, tclip, space_clip)
diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h
index 119186ff748..02aaef44a1f 100644
--- a/source/blender/makesrna/RNA_enum_types.h
+++ b/source/blender/makesrna/RNA_enum_types.h
@@ -96,6 +96,7 @@ extern const EnumPropertyItem rna_enum_keyblock_type_items[];
extern const EnumPropertyItem rna_enum_keyingset_path_grouping_items[];
extern const EnumPropertyItem rna_enum_keying_flag_items[];
+extern const EnumPropertyItem rna_enum_keying_flag_items_api[];
extern const EnumPropertyItem rna_enum_keyframe_paste_offset_items[];
extern const EnumPropertyItem rna_enum_keyframe_paste_merge_items[];
diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c
index 0122587920c..2f063e4219a 100644
--- a/source/blender/makesrna/intern/makesrna.c
+++ b/source/blender/makesrna/intern/makesrna.c
@@ -2024,7 +2024,7 @@ static void rna_def_function_funcs_header(FILE *f, StructRNA *srna, FunctionDefR
char funcname[2048];
rna_construct_wrapper_function_name(
- funcname, sizeof(funcname), srna->identifier, func->identifier, NULL);
+ funcname, sizeof(funcname), srna->identifier, func->identifier, "func");
rna_generate_static_parameter_prototypes(f, srna, dfunc, funcname, 1);
}
@@ -2452,7 +2452,7 @@ static void rna_def_struct_function_call_impl_cpp(FILE *f, StructRNA *srna, Func
int first = 1;
rna_construct_wrapper_function_name(
- funcname, sizeof(funcname), srna->identifier, func->identifier, NULL);
+ funcname, sizeof(funcname), srna->identifier, func->identifier, "func");
fprintf(f, "%s(", funcname);
@@ -2615,7 +2615,7 @@ static void rna_def_function_wrapper_funcs(FILE *f, StructDefRNA *dsrna, Functio
}
rna_construct_wrapper_function_name(
- funcname, sizeof(funcname), srna->identifier, func->identifier, NULL);
+ funcname, sizeof(funcname), srna->identifier, func->identifier, "func");
rna_generate_static_parameter_prototypes(f, srna, dfunc, funcname, 0);
diff --git a/source/blender/makesrna/intern/rna_animation.c b/source/blender/makesrna/intern/rna_animation.c
index 15429ec6b5e..6a5bae28cc1 100644
--- a/source/blender/makesrna/intern/rna_animation.c
+++ b/source/blender/makesrna/intern/rna_animation.c
@@ -72,6 +72,43 @@ const EnumPropertyItem rna_enum_keying_flag_items[] = {
{0, NULL, 0, NULL, NULL},
};
+/* Contains additional flags suitable for use in Python API functions. */
+const EnumPropertyItem rna_enum_keying_flag_items_api[] = {
+ {INSERTKEY_NEEDED,
+ "INSERTKEY_NEEDED",
+ 0,
+ "Only Needed",
+ "Only insert keyframes where they're needed in the relevant F-Curves"},
+ {INSERTKEY_MATRIX,
+ "INSERTKEY_VISUAL",
+ 0,
+ "Visual Keying",
+ "Insert keyframes based on 'visual transforms'"},
+ {INSERTKEY_XYZ2RGB,
+ "INSERTKEY_XYZ_TO_RGB",
+ 0,
+ "XYZ=RGB Colors",
+ "Color for newly added transformation F-Curves (Location, Rotation, Scale) "
+ "and also Color is based on the transform axis"},
+ {INSERTKEY_REPLACE,
+ "INSERTKEY_REPLACE",
+ 0,
+ "Replace Existing",
+ "Only replace existing keyframes"},
+ {INSERTKEY_AVAILABLE,
+ "INSERTKEY_AVAILABLE",
+ 0,
+ "Only Available",
+ "Don't create F-Curves when they don't already exist"},
+ {INSERTKEY_CYCLE_AWARE,
+ "INSERTKEY_CYCLE_AWARE",
+ 0,
+ "Cycle Aware Keying",
+ "When inserting into a curve with cyclic extrapolation, remap the keyframe inside "
+ "the cycle time range, and if changing an end key, also update the other one"},
+ {0, NULL, 0, NULL, NULL},
+};
+
#ifdef RNA_RUNTIME
# include "BLI_math_base.h"
@@ -1266,6 +1303,9 @@ static void rna_def_animdata(BlenderRNA *brna)
RNA_def_property_ui_text(
prop, "Use NLA Tweak Mode", "Whether to enable or disable tweak mode in NLA");
RNA_def_property_update(prop, NC_ANIMATION | ND_NLA, "rna_AnimData_update");
+
+ /* Animation Data API */
+ RNA_api_animdata(srna);
}
/* --- */
diff --git a/source/blender/makesrna/intern/rna_animation_api.c b/source/blender/makesrna/intern/rna_animation_api.c
index f201b8e6e99..e063e5de22c 100644
--- a/source/blender/makesrna/intern/rna_animation_api.c
+++ b/source/blender/makesrna/intern/rna_animation_api.c
@@ -37,6 +37,7 @@
# include "BKE_context.h"
# include "BKE_report.h"
+# include "BKE_nla.h"
# include "ED_keyframing.h"
@@ -59,6 +60,11 @@ static void rna_KeyingSet_context_refresh(KeyingSet *ks, bContext *C, ReportList
}
}
+static float rna_AnimData_nla_tweak_strip_time_to_scene(AnimData *adt, float frame, bool invert)
+{
+ return BKE_nla_tweakedit_remap(adt, frame, invert ? NLATIME_CONVERT_UNMAP : NLATIME_CONVERT_MAP);
+}
+
#else
void RNA_api_keyingset(StructRNA *srna)
@@ -75,4 +81,25 @@ void RNA_api_keyingset(StructRNA *srna)
RNA_def_function_flag(func, FUNC_USE_CONTEXT | FUNC_USE_REPORTS);
}
+void RNA_api_animdata(StructRNA *srna)
+{
+ FunctionRNA *func;
+ PropertyRNA *parm;
+
+ /* Convert between action time and scene time when tweaking a NLA strip. */
+ func = RNA_def_function(
+ srna, "nla_tweak_strip_time_to_scene", "rna_AnimData_nla_tweak_strip_time_to_scene");
+ RNA_def_function_ui_description(func,
+ "Convert a time value from the local time of the tweaked strip "
+ "to scene time, exactly as done by built-in key editing tools. "
+ "Returns the input time unchanged if not tweaking.");
+ parm = RNA_def_float(
+ func, "frame", 0.0, MINAFRAME, MAXFRAME, "", "Input time", MINAFRAME, MAXFRAME);
+ RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+ RNA_def_boolean(func, "invert", false, "Invert", "Convert scene time to action time");
+ parm = RNA_def_float(
+ func, "result", 0.0, MINAFRAME, MAXFRAME, "", "Converted time", MINAFRAME, MAXFRAME);
+ RNA_def_function_return(func, parm);
+}
+
#endif
diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c
index 5461aaa0f1a..0eec5973ab0 100644
--- a/source/blender/makesrna/intern/rna_armature.c
+++ b/source/blender/makesrna/intern/rna_armature.c
@@ -575,6 +575,20 @@ static void rna_Armature_bones_next(CollectionPropertyIterator *iter)
iter->valid = (internal->link != NULL);
}
+/* not essential, but much faster then the default lookup function */
+static int rna_Armature_bones_lookup_string(PointerRNA *ptr, const char *key, PointerRNA *r_ptr)
+{
+ bArmature *arm = (bArmature *)ptr->data;
+ Bone *bone = BKE_armature_find_bone_name(arm, key);
+ if (bone) {
+ RNA_pointer_create(ptr->id.data, &RNA_Bone, bone, r_ptr);
+ return true;
+ }
+ else {
+ return false;
+ }
+}
+
static bool rna_Armature_is_editmode_get(PointerRNA *ptr)
{
bArmature *arm = (bArmature *)ptr->id.data;
@@ -621,9 +635,10 @@ void rna_def_bone_curved_common(StructRNA *srna, bool is_posebone)
if (is_posebone == false) {
prop = RNA_def_property(srna, "use_endroll_as_inroll", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_ui_text(
- prop, "Inherit End Roll", "Use Roll Out of parent bone as Roll In of its children");
+ prop, "Inherit End Roll", "Add Roll Out of the Start Handle bone to the Roll In value");
RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_ADD_PARENT_END_ROLL);
- RNA_def_property_update(prop, 0, "rna_Armature_update_data");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_update(prop, 0, "rna_Armature_dependency_update");
}
/* Curve X/Y Offsets */
@@ -1285,8 +1300,15 @@ static void rna_def_armature(BlenderRNA *brna)
/* Collections */
prop = RNA_def_property(srna, "bones", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "bonebase", NULL);
- RNA_def_property_collection_funcs(
- prop, NULL, "rna_Armature_bones_next", NULL, NULL, NULL, NULL, NULL, NULL);
+ RNA_def_property_collection_funcs(prop,
+ NULL,
+ "rna_Armature_bones_next",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "rna_Armature_bones_lookup_string",
+ NULL);
RNA_def_property_struct_type(prop, "Bone");
RNA_def_property_ui_text(prop, "Bones", "");
rna_def_armature_bones(brna, prop);
@@ -1359,13 +1381,6 @@ static void rna_def_armature(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
- prop = RNA_def_property(srna, "use_auto_ik", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", ARM_AUTO_IK);
- RNA_def_property_ui_text(
- prop, "Auto IK", "Add temporary IK constraints while grabbing bones in Pose Mode");
- RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
- RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
-
prop = RNA_def_property(srna, "show_bone_custom_shapes", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", ARM_NO_CUSTOM);
RNA_def_property_ui_text(
diff --git a/source/blender/makesrna/intern/rna_collection.c b/source/blender/makesrna/intern/rna_collection.c
index 501895eefc8..ae944f59a35 100644
--- a/source/blender/makesrna/intern/rna_collection.c
+++ b/source/blender/makesrna/intern/rna_collection.c
@@ -405,15 +405,15 @@ void RNA_def_collections(BlenderRNA *brna)
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_icon(prop, ICON_RESTRICT_SELECT_OFF, -1);
- RNA_def_property_ui_text(prop, "Disable Select", "Disable collection for viewport selection");
+ RNA_def_property_ui_text(prop, "Disable Selection", "Disable selection in viewport");
RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_Collection_flag_update");
prop = RNA_def_property(srna, "hide_viewport", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", COLLECTION_RESTRICT_VIEW);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", COLLECTION_RESTRICT_VIEWPORT);
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_icon(prop, ICON_RESTRICT_VIEW_OFF, -1);
- RNA_def_property_ui_text(prop, "Disable Viewport", "Disable collection in viewport");
+ RNA_def_property_ui_text(prop, "Disable in Viewports", "Globally disable in viewports");
RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_Collection_flag_update");
prop = RNA_def_property(srna, "hide_render", PROP_BOOLEAN, PROP_NONE);
@@ -421,7 +421,7 @@ void RNA_def_collections(BlenderRNA *brna)
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_icon(prop, ICON_RESTRICT_RENDER_OFF, -1);
- RNA_def_property_ui_text(prop, "Disable Render", "Disable collection in renders");
+ RNA_def_property_ui_text(prop, "Disable in Renders", "Globally disable in renders");
RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_Collection_flag_update");
}
diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c
index 40ee069657c..8ba1f5440be 100644
--- a/source/blender/makesrna/intern/rna_color.c
+++ b/source/blender/makesrna/intern/rna_color.c
@@ -525,6 +525,22 @@ static char *rna_ColorManagedViewSettings_path(PointerRNA *UNUSED(ptr))
return BLI_strdup("view_settings");
}
+static bool rna_ColorManagedColorspaceSettings_is_data_get(struct PointerRNA *ptr)
+{
+ ColorManagedColorspaceSettings *colorspace = (ColorManagedColorspaceSettings *)ptr->data;
+ const char *data_name = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_DATA);
+ return STREQ(colorspace->name, data_name);
+}
+
+static void rna_ColorManagedColorspaceSettings_is_data_set(struct PointerRNA *ptr, bool value)
+{
+ ColorManagedColorspaceSettings *colorspace = (ColorManagedColorspaceSettings *)ptr->data;
+ if (value) {
+ const char *data_name = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_DATA);
+ STRNCPY(colorspace->name, data_name);
+ }
+}
+
static int rna_ColorManagedColorspaceSettings_colorspace_get(struct PointerRNA *ptr)
{
ColorManagedColorspaceSettings *colorspace = (ColorManagedColorspaceSettings *)ptr->data;
@@ -1227,6 +1243,7 @@ static void rna_def_colormanage(BlenderRNA *brna)
prop = RNA_def_property(srna, "name", PROP_ENUM, PROP_NONE);
RNA_def_property_flag(prop, PROP_ENUM_NO_CONTEXT);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_enum_items(prop, color_space_items);
RNA_def_property_enum_funcs(prop,
"rna_ColorManagedColorspaceSettings_colorspace_get",
@@ -1235,6 +1252,17 @@ static void rna_def_colormanage(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Input Color Space", "Color space of the image or movie on disk");
RNA_def_property_update(prop, NC_WINDOW, "rna_ColorManagedColorspaceSettings_reload_update");
+ prop = RNA_def_property(srna, "is_data", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_boolean_funcs(prop,
+ "rna_ColorManagedColorspaceSettings_is_data_get",
+ "rna_ColorManagedColorspaceSettings_is_data_set");
+ RNA_def_property_ui_text(
+ prop,
+ "Is Data",
+ "Treat image as non-color data without color management, like normal or displacement maps");
+ RNA_def_property_update(prop, NC_WINDOW, "rna_ColorManagement_update");
+
//
srna = RNA_def_struct(brna, "ColorManagedSequencerColorspaceSettings", NULL);
RNA_def_struct_path_func(srna, "rna_ColorManagedSequencerColorspaceSettings_path");
diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c
index c1c235d497b..41ad94f6119 100644
--- a/source/blender/makesrna/intern/rna_constraint.c
+++ b/source/blender/makesrna/intern/rna_constraint.c
@@ -1327,6 +1327,13 @@ static void rna_def_constraint_size_like(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Copy Z", "Copy the target's Z scale");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+ prop = RNA_def_property(srna, "power", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "power");
+ RNA_def_property_float_default(prop, 1.0f);
+ RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, 3);
+ RNA_def_property_ui_text(prop, "Power", "Raise the target's scale to the specified power");
+ RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+
prop = RNA_def_property(srna, "use_offset", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SIZELIKE_OFFSET);
RNA_def_property_ui_text(prop, "Offset", "Combine original scale with copied scale");
@@ -1346,13 +1353,34 @@ static void rna_def_constraint_same_volume(BlenderRNA *brna)
StructRNA *srna;
PropertyRNA *prop;
- static const EnumPropertyItem volume_items[] = {
+ static const EnumPropertyItem axis_items[] = {
{SAMEVOL_X, "SAMEVOL_X", 0, "X", ""},
{SAMEVOL_Y, "SAMEVOL_Y", 0, "Y", ""},
{SAMEVOL_Z, "SAMEVOL_Z", 0, "Z", ""},
{0, NULL, 0, NULL, NULL},
};
+ static const EnumPropertyItem mode_items[] = {
+ {SAMEVOL_STRICT,
+ "STRICT",
+ 0,
+ "Strict",
+ "Volume is strictly preserved, overriding the scaling of non-free axes"},
+ {SAMEVOL_UNIFORM,
+ "UNIFORM",
+ 0,
+ "Uniform",
+ "Volume is preserved when the object is scaled uniformly. "
+ "Deviations from uniform scale on non-free axes are passed through"},
+ {SAMEVOL_SINGLE_AXIS,
+ "SINGLE_AXIS",
+ 0,
+ "Single Axis",
+ "Volume is preserved when the object is scaled only on the free axis. "
+ "Non-free axis scaling is passed through"},
+ {0, NULL, 0, NULL, NULL},
+ };
+
srna = RNA_def_struct(brna, "MaintainVolumeConstraint", "Constraint");
RNA_def_struct_ui_text(srna,
"Maintain Volume Constraint",
@@ -1360,11 +1388,18 @@ static void rna_def_constraint_same_volume(BlenderRNA *brna)
RNA_def_struct_sdna_from(srna, "bSameVolumeConstraint", "data");
prop = RNA_def_property(srna, "free_axis", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_sdna(prop, NULL, "flag");
- RNA_def_property_enum_items(prop, volume_items);
+ RNA_def_property_enum_sdna(prop, NULL, "free_axis");
+ RNA_def_property_enum_items(prop, axis_items);
RNA_def_property_ui_text(prop, "Free Axis", "The free scaling axis of the object");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+ prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "mode");
+ RNA_def_property_enum_items(prop, mode_items);
+ RNA_def_property_ui_text(
+ prop, "Mode", "The way the constraint treats original non-free axis scaling");
+ RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+
prop = RNA_def_property(srna, "volume", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_range(prop, 0.001f, 100.0f);
RNA_def_property_ui_text(prop, "Volume", "Volume of the bone at rest");
@@ -2576,6 +2611,13 @@ static void rna_def_constraint_spline_ik(BlenderRNA *brna)
"on top of the shape and scaling of the curve itself");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+ /* take original scaling of the bone into account in volume preservation */
+ prop = RNA_def_property(srna, "use_original_scale", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", CONSTRAINT_SPLINEIK_USE_ORIGINAL_SCALE);
+ RNA_def_property_ui_text(
+ prop, "Use Original Scale", "Apply volume preservation over the original scaling");
+ RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+
/* volume presevation for "volumetric" scale mode */
prop = RNA_def_property(srna, "bulge", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 0.0, 100.f);
diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c
index 20fbbed572c..8e24e9a8364 100644
--- a/source/blender/makesrna/intern/rna_define.c
+++ b/source/blender/makesrna/intern/rna_define.c
@@ -890,9 +890,9 @@ StructRNA *RNA_def_struct_ptr(BlenderRNA *brna, const char *identifier, StructRN
srna->description = "";
/* may be overwritten later RNA_def_struct_translation_context */
srna->translation_context = BLT_I18NCONTEXT_DEFAULT_BPYRNA;
- srna->flag |= STRUCT_UNDO;
if (!srnafrom) {
srna->icon = ICON_DOT;
+ srna->flag |= STRUCT_UNDO;
}
if (DefRNA.preprocess) {
diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c
index c8df01a7dc7..63feceb4a8a 100644
--- a/source/blender/makesrna/intern/rna_fcurve.c
+++ b/source/blender/makesrna/intern/rna_fcurve.c
@@ -1534,6 +1534,7 @@ static void rna_def_fmodifier(BlenderRNA *brna)
prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_enum_items(prop, rna_enum_fmodifier_type_items);
+ RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_ACTION);
RNA_def_property_ui_text(prop, "Type", "F-Curve Modifier Type");
/* settings */
@@ -1645,6 +1646,7 @@ static void rna_def_drivertarget(BlenderRNA *brna)
{DTAR_TRANSCHAN_SCALEX, "SCALE_X", 0, "X Scale", ""},
{DTAR_TRANSCHAN_SCALEY, "SCALE_Y", 0, "Y Scale", ""},
{DTAR_TRANSCHAN_SCALEZ, "SCALE_Z", 0, "Z Scale", ""},
+ {DTAR_TRANSCHAN_SCALE_AVG, "SCALE_AVG", 0, "Average Scale", ""},
{0, NULL, 0, NULL, NULL},
};
diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c
index 34373e469c1..83ec33286f4 100644
--- a/source/blender/makesrna/intern/rna_image.c
+++ b/source/blender/makesrna/intern/rna_image.c
@@ -406,7 +406,8 @@ static void rna_Image_pixels_set(PointerRNA *ptr, const float *values)
((unsigned char *)ibuf->rect)[i] = unit_float_to_uchar_clamp(values[i]);
}
- ibuf->userflags |= IB_BITMAPDIRTY | IB_DISPLAY_BUFFER_INVALID | IB_MIPMAP_INVALID;
+ ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID | IB_MIPMAP_INVALID;
+ BKE_image_mark_dirty(ima, ibuf);
if (!G.background) {
GPU_free_image(ima);
}
diff --git a/source/blender/makesrna/intern/rna_image_api.c b/source/blender/makesrna/intern/rna_image_api.c
index ca75f862b11..553dbeeb97b 100644
--- a/source/blender/makesrna/intern/rna_image_api.c
+++ b/source/blender/makesrna/intern/rna_image_api.c
@@ -211,69 +211,30 @@ static void rna_Image_scale(Image *image, ReportList *reports, int width, int he
}
}
-static int rna_Image_gl_load(Image *image, ReportList *reports, int frame, int filter, int mag)
+static int rna_Image_gl_load(Image *image, ReportList *reports, int frame)
{
- GPUTexture *tex = image->gputexture[TEXTARGET_TEXTURE_2D];
- int error = GL_NO_ERROR;
-
- if (tex)
- return error;
-
ImageUser iuser = {NULL};
iuser.framenr = frame;
iuser.ok = true;
- void *lock;
- ImBuf *ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock);
-
- /* clean glError buffer */
- while (glGetError() != GL_NO_ERROR) {
- }
+ GPUTexture *tex = GPU_texture_from_blender(image, &iuser, GL_TEXTURE_2D);
- if (ibuf == NULL || ibuf->rect == NULL) {
- BKE_reportf(reports, RPT_ERROR, "Image '%s' does not have any image data", image->id.name + 2);
- BKE_image_release_ibuf(image, ibuf, lock);
+ if (tex == NULL) {
+ BKE_reportf(reports, RPT_ERROR, "Failed to load image texture '%s'", image->id.name + 2);
return (int)GL_INVALID_OPERATION;
}
- unsigned int bindcode = 0;
- GPU_create_gl_tex(&bindcode,
- ibuf->rect,
- ibuf->rect_float,
- ibuf->x,
- ibuf->y,
- GL_TEXTURE_2D,
- (filter != GL_NEAREST && filter != GL_LINEAR),
- false,
- image);
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLint)filter);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLint)mag);
-
- /* TODO(merwin): validate input (dimensions, filter, mag) before calling OpenGL
- * instead of trusting input & testing for error after */
- error = glGetError();
-
- if (error) {
- glDeleteTextures(1, (GLuint *)&bindcode);
- }
- else {
- image->gputexture[TEXTARGET_TEXTURE_2D] = GPU_texture_from_bindcode(GL_TEXTURE_2D, bindcode);
- }
-
- BKE_image_release_ibuf(image, ibuf, lock);
-
- return error;
+ return GL_NO_ERROR;
}
-static int rna_Image_gl_touch(Image *image, ReportList *reports, int frame, int filter, int mag)
+static int rna_Image_gl_touch(Image *image, ReportList *reports, int frame)
{
int error = GL_NO_ERROR;
BKE_image_tag_time(image);
if (image->gputexture[TEXTARGET_TEXTURE_2D] == NULL)
- error = rna_Image_gl_load(image, reports, frame, filter, mag);
+ error = rna_Image_gl_load(image, reports, frame);
return error;
}
@@ -367,52 +328,20 @@ void RNA_api_image(StructRNA *srna)
RNA_def_function_flag(func, FUNC_USE_REPORTS);
RNA_def_int(
func, "frame", 0, 0, INT_MAX, "Frame", "Frame of image sequence or movie", 0, INT_MAX);
- RNA_def_int(func,
- "filter",
- GL_LINEAR_MIPMAP_NEAREST,
- -INT_MAX,
- INT_MAX,
- "Filter",
- "The texture minifying function to use if the image wasn't loaded",
- -INT_MAX,
- INT_MAX);
- RNA_def_int(func,
- "mag",
- GL_LINEAR,
- -INT_MAX,
- INT_MAX,
- "Magnification",
- "The texture magnification function to use if the image wasn't loaded",
- -INT_MAX,
- INT_MAX);
/* return value */
parm = RNA_def_int(
func, "error", 0, -INT_MAX, INT_MAX, "Error", "OpenGL error value", -INT_MAX, INT_MAX);
RNA_def_function_return(func, parm);
func = RNA_def_function(srna, "gl_load", "rna_Image_gl_load");
- RNA_def_function_ui_description(func, "Load the image into OpenGL graphics memory");
+ RNA_def_function_ui_description(
+ func,
+ "Load the image into an OpenGL texture. On success, image.bindcode will contain the "
+ "OpenGL texture bindcode. Colors read from the texture will be in scene linear color space "
+ "and have premultiplied alpha.");
RNA_def_function_flag(func, FUNC_USE_REPORTS);
RNA_def_int(
func, "frame", 0, 0, INT_MAX, "Frame", "Frame of image sequence or movie", 0, INT_MAX);
- RNA_def_int(func,
- "filter",
- GL_LINEAR_MIPMAP_NEAREST,
- -INT_MAX,
- INT_MAX,
- "Filter",
- "The texture minifying function",
- -INT_MAX,
- INT_MAX);
- RNA_def_int(func,
- "mag",
- GL_LINEAR,
- -INT_MAX,
- INT_MAX,
- "Magnification",
- "The texture magnification function",
- -INT_MAX,
- INT_MAX);
/* return value */
parm = RNA_def_int(
func, "error", 0, -INT_MAX, INT_MAX, "Error", "OpenGL error value", -INT_MAX, INT_MAX);
diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h
index 75c6011bbe8..e4311f238af 100644
--- a/source/blender/makesrna/intern/rna_internal.h
+++ b/source/blender/makesrna/intern/rna_internal.h
@@ -343,6 +343,7 @@ char *rna_Node_ImageUser_path(struct PointerRNA *ptr);
/* API functions */
void RNA_api_action(StructRNA *srna);
+void RNA_api_animdata(struct StructRNA *srna);
void RNA_api_armature_edit_bone(StructRNA *srna);
void RNA_api_bone(StructRNA *srna);
void RNA_api_camera(StructRNA *srna);
diff --git a/source/blender/makesrna/intern/rna_layer.c b/source/blender/makesrna/intern/rna_layer.c
index a71adec4e5c..c8af49c47ff 100644
--- a/source/blender/makesrna/intern/rna_layer.c
+++ b/source/blender/makesrna/intern/rna_layer.c
@@ -187,6 +187,15 @@ static void rna_ObjectBase_select_update(Main *UNUSED(bmain),
ED_object_base_select(base, mode);
}
+static void rna_ObjectBase_hide_viewport_update(bContext *C, PointerRNA *UNUSED(ptr))
+{
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_layer_collection_sync(scene, view_layer);
+ DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS);
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+}
+
static void rna_LayerCollection_name_get(struct PointerRNA *ptr, char *value)
{
ID *id = (ID *)((LayerCollection *)ptr->data)->collection;
@@ -199,12 +208,29 @@ int rna_LayerCollection_name_length(PointerRNA *ptr)
return strlen(id->name + 2);
}
+static void rna_LayerCollection_exclude_update_recursive(ListBase *lb, const bool exclude)
+{
+ for (LayerCollection *lc = lb->first; lc; lc = lc->next) {
+ if (exclude) {
+ lc->flag |= LAYER_COLLECTION_EXCLUDE;
+ }
+ else {
+ lc->flag &= ~LAYER_COLLECTION_EXCLUDE;
+ }
+ rna_LayerCollection_exclude_update_recursive(&lc->layer_collections, exclude);
+ }
+}
+
static void rna_LayerCollection_exclude_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
{
Scene *scene = (Scene *)ptr->id.data;
LayerCollection *lc = (LayerCollection *)ptr->data;
ViewLayer *view_layer = BKE_view_layer_find_from_collection(scene, lc);
+ /* Set/Unset it recursively to match the behaviour of excluding via the menu or shortcuts. */
+ rna_LayerCollection_exclude_update_recursive(&lc->layer_collections,
+ (lc->flag & LAYER_COLLECTION_EXCLUDE) != 0);
+
BKE_layer_collection_sync(scene, view_layer);
DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS);
@@ -266,21 +292,26 @@ static void rna_def_layer_collection(BlenderRNA *brna)
RNA_def_property_struct_type(prop, "LayerCollection");
RNA_def_property_ui_text(prop, "Children", "Child layer collections");
+ /* Restriction flags. */
prop = RNA_def_property(srna, "exclude", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", LAYER_COLLECTION_EXCLUDE);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_ui_text(prop, "Exclude", "Exclude collection from view layer");
+ RNA_def_property_ui_text(prop, "Exclude from View Layer", "Exclude from view layer");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_ui_icon(prop, ICON_CHECKBOX_HLT, -1);
RNA_def_property_update(prop, NC_SCENE | ND_LAYER, "rna_LayerCollection_exclude_update");
prop = RNA_def_property(srna, "holdout", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", LAYER_COLLECTION_HOLDOUT);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_ui_icon(prop, ICON_CLIPUV_HLT, -1);
RNA_def_property_ui_text(prop, "Holdout", "Mask out objects in collection from view layer");
RNA_def_property_update(prop, NC_SCENE | ND_LAYER, "rna_LayerCollection_update");
prop = RNA_def_property(srna, "indirect_only", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", LAYER_COLLECTION_INDIRECT_ONLY);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_ui_icon(prop, ICON_MOD_PHYSICS, 0);
RNA_def_property_ui_text(
prop,
"Indirect Only",
@@ -289,14 +320,13 @@ static void rna_def_layer_collection(BlenderRNA *brna)
RNA_def_property_update(prop, NC_SCENE | ND_LAYER, "rna_LayerCollection_update");
prop = RNA_def_property(srna, "hide_viewport", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", LAYER_COLLECTION_RESTRICT_VIEW);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", LAYER_COLLECTION_HIDE);
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
- RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_icon(prop, ICON_HIDE_OFF, -1);
- RNA_def_property_ui_text(
- prop, "Disable Viewport", "Disable collection in viewport for this view layer");
+ RNA_def_property_ui_text(prop, "Hide in Viewport", "Temporarily hide in viewport");
RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_LayerCollection_update");
+ /* Run-time flags. */
prop = RNA_def_property(srna, "is_visible", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "runtime_flag", LAYER_COLLECTION_VISIBLE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
@@ -374,6 +404,14 @@ static void rna_def_object_base(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", BASE_SELECTED);
RNA_def_property_ui_text(prop, "Select", "Object base selection state");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_ObjectBase_select_update");
+
+ prop = RNA_def_property(srna, "hide_viewport", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", BASE_HIDDEN);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
+ RNA_def_property_ui_icon(prop, ICON_HIDE_OFF, -1);
+ RNA_def_property_ui_text(prop, "Hide in Viewport", "Temporarily hide in viewport");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_ObjectBase_hide_viewport_update");
}
void RNA_def_view_layer(BlenderRNA *brna)
@@ -428,7 +466,7 @@ void RNA_def_view_layer(BlenderRNA *brna)
/* layer options */
prop = RNA_def_property(srna, "use", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", VIEW_LAYER_RENDER);
- RNA_def_property_ui_text(prop, "Enabled", "Disable or enable the render layer");
+ RNA_def_property_ui_text(prop, "Enabled", "Enable or disable rendering of this View Layer");
RNA_def_property_update(prop, NC_SCENE | ND_LAYER, NULL);
prop = RNA_def_property(srna, "use_freestyle", PROP_BOOLEAN, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_light.c b/source/blender/makesrna/intern/rna_light.c
index da2b5752a0f..54c8049d4d2 100644
--- a/source/blender/makesrna/intern/rna_light.c
+++ b/source/blender/makesrna/intern/rna_light.c
@@ -545,12 +545,20 @@ static void rna_def_spot_light(BlenderRNA *brna)
static void rna_def_sun_light(BlenderRNA *brna)
{
StructRNA *srna;
+ PropertyRNA *prop;
srna = RNA_def_struct(brna, "SunLight", "Light");
RNA_def_struct_sdna(srna, "Light");
RNA_def_struct_ui_text(srna, "Sun Light", "Constant direction parallel ray Light");
RNA_def_struct_ui_icon(srna, ICON_LIGHT_SUN);
+ prop = RNA_def_property(srna, "angle", PROP_FLOAT, PROP_ANGLE);
+ RNA_def_property_float_sdna(prop, NULL, "sun_angle");
+ RNA_def_property_float_default(prop, DEG2RADF(0.526f));
+ RNA_def_property_range(prop, DEG2RADF(0.0f), DEG2RADF(180.0f));
+ RNA_def_property_ui_text(prop, "Angle", "Angular diameter of the Sun as seen from the Earth");
+ RNA_def_property_update(prop, 0, "rna_Light_update");
+
rna_def_light_energy(srna, true);
rna_def_light_shadow(srna, true);
}
diff --git a/source/blender/makesrna/intern/rna_lightprobe.c b/source/blender/makesrna/intern/rna_lightprobe.c
index 125d2ade567..8b6b248eac2 100644
--- a/source/blender/makesrna/intern/rna_lightprobe.c
+++ b/source/blender/makesrna/intern/rna_lightprobe.c
@@ -77,7 +77,7 @@ static void rna_def_lightprobe(BlenderRNA *brna)
srna = RNA_def_struct(brna, "LightProbe", "ID");
RNA_def_struct_ui_text(
srna, "LightProbe", "Light Probe data-block for lighting capture objects");
- RNA_def_struct_ui_icon(srna, ICON_OUTLINER_OB_LIGHTPROBE);
+ RNA_def_struct_ui_icon(srna, ICON_OUTLINER_DATA_LIGHTPROBE);
prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, lightprobe_type_items);
diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c
index d66b4e5be44..edfdbe293a3 100644
--- a/source/blender/makesrna/intern/rna_material.c
+++ b/source/blender/makesrna/intern/rna_material.c
@@ -440,6 +440,17 @@ static void rna_def_material_greasepencil(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL},
};
+ static EnumPropertyItem alignment_draw_items[] = {
+ {GP_STYLE_FOLLOW_PATH, "PATH", 0, "Path", "Follow stroke drawing path and object rotation"},
+ {GP_STYLE_FOLLOW_OBJ, "OBJECT", 0, "Object", "Follow object rotation only"},
+ {GP_STYLE_FOLLOW_FIXED,
+ "FIXED",
+ 0,
+ "Fixed",
+ "Do not follow drawing path or object rotation and keeps aligned with viewport"},
+ {0, NULL, 0, NULL, NULL},
+ };
+
srna = RNA_def_struct(brna, "MaterialGPencilStyle", NULL);
RNA_def_struct_sdna(srna, "MaterialGPencilStyle");
RNA_def_struct_ui_text(srna, "Grease Pencil Color", "");
@@ -611,10 +622,12 @@ static void rna_def_material_greasepencil(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Show Fill", "Show stroke fills of this material");
RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialGpencil_update");
- /* keep Dots and Boxes aligned to screen and not to drawing path */
- prop = RNA_def_property(srna, "use_follow_path", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", GP_STYLE_COLOR_LOCK_DOTS);
- RNA_def_property_ui_text(prop, "Follow Path", "Keep Dots and Boxes aligned to drawing path");
+ /* Mode to align Dots and Boxes to drawing path and object rotation */
+ prop = RNA_def_property(srna, "alignment_mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_bitflag_sdna(prop, NULL, "alignment_mode");
+ RNA_def_property_enum_items(prop, alignment_draw_items);
+ RNA_def_property_ui_text(
+ prop, "Alignment", "Defines how align Dots and Boxes with drawing path and object rotation");
RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialGpencil_nopreview_update");
/* pass index for future compositing and editing tools */
@@ -778,6 +791,12 @@ void RNA_def_material(BlenderRNA *brna)
"(avoids transparency sorting problems)");
RNA_def_property_update(prop, 0, "rna_Material_draw_update");
+ prop = RNA_def_property(srna, "use_backface_culling", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "blend_flag", MA_BL_CULL_BACKFACE);
+ RNA_def_property_ui_text(
+ prop, "Backface Culling", "Use back face culling to hide the back side of faces");
+ RNA_def_property_update(prop, 0, "rna_Material_draw_update");
+
prop = RNA_def_property(srna, "use_screen_refraction", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "blend_flag", MA_BL_SS_REFRACTION);
RNA_def_property_ui_text(
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index 6ab83bc063c..ede1bf89e06 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -445,6 +445,8 @@ const EnumPropertyItem rna_enum_axis_flag_xyz_items[] = {
# include "BKE_object.h"
# include "BKE_particle.h"
+# include "BLI_sort_utils.h"
+
# include "DEG_depsgraph.h"
# include "DEG_depsgraph_build.h"
# include "DEG_depsgraph_query.h"
@@ -743,12 +745,79 @@ RNA_MOD_OBJECT_SET(SurfaceDeform, target, OB_MESH);
static void rna_HookModifier_object_set(PointerRNA *ptr, PointerRNA value)
{
+ Object *owner = (Object *)ptr->id.data;
HookModifierData *hmd = ptr->data;
Object *ob = (Object *)value.data;
hmd->object = ob;
id_lib_extern((ID *)ob);
- BKE_object_modifier_hook_reset(ob, hmd);
+ BKE_object_modifier_hook_reset(owner, hmd);
+}
+
+static void rna_HookModifier_subtarget_set(PointerRNA *ptr, const char *value)
+{
+ Object *owner = (Object *)ptr->id.data;
+ HookModifierData *hmd = ptr->data;
+
+ BLI_strncpy(hmd->subtarget, value, sizeof(hmd->subtarget));
+ BKE_object_modifier_hook_reset(owner, hmd);
+}
+
+static int rna_HookModifier_vertex_indices_get_length(PointerRNA *ptr,
+ int length[RNA_MAX_ARRAY_DIMENSION])
+{
+ HookModifierData *hmd = ptr->data;
+ int totindex = hmd->indexar ? hmd->totindex : 0;
+ return (length[0] = totindex);
+}
+
+static void rna_HookModifier_vertex_indices_get(PointerRNA *ptr, int *values)
+{
+ HookModifierData *hmd = ptr->data;
+ if (hmd->indexar != NULL) {
+ memcpy(values, hmd->indexar, sizeof(int) * hmd->totindex);
+ }
+}
+
+static void rna_HookModifier_vertex_indices_set(HookModifierData *hmd,
+ ReportList *reports,
+ int indices_len,
+ int *indices)
+{
+ if (indices_len == 0) {
+ MEM_SAFE_FREE(hmd->indexar);
+ hmd->totindex = 0;
+ }
+ else {
+ /* Reject negative indices. */
+ for (int i = 0; i < indices_len; i++) {
+ if (indices[i] < 0) {
+ BKE_reportf(reports, RPT_ERROR, "Negative vertex index in vertex_indices_set");
+ return;
+ }
+ }
+
+ /* Copy and sort the index array. */
+ size_t size = sizeof(int) * indices_len;
+ int *buffer = MEM_mallocN(size, "hook indexar");
+ memcpy(buffer, indices, size);
+
+ qsort(buffer, indices_len, sizeof(int), BLI_sortutil_cmp_int);
+
+ /* Reject duplicate indices. */
+ for (int i = 1; i < indices_len; i++) {
+ if (buffer[i] == buffer[i - 1]) {
+ BKE_reportf(reports, RPT_ERROR, "Duplicate index %d in vertex_indices_set", buffer[i]);
+ MEM_freeN(buffer);
+ return;
+ }
+ }
+
+ /* Success - save the new array. */
+ MEM_SAFE_FREE(hmd->indexar);
+ hmd->indexar = buffer;
+ hmd->totindex = indices_len;
+ }
}
static PointerRNA rna_UVProjector_object_get(PointerRNA *ptr)
@@ -2151,6 +2220,8 @@ static void rna_def_modifier_hook(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
+ FunctionRNA *func;
+ PropertyRNA *parm;
srna = RNA_def_struct(brna, "HookModifier", "Modifier");
RNA_def_struct_ui_text(
@@ -2183,9 +2254,10 @@ static void rna_def_modifier_hook(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Falloff Curve", "Custom falloff curve");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
- prop = RNA_def_property(srna, "center", PROP_FLOAT, PROP_NONE);
+ prop = RNA_def_property(srna, "center", PROP_FLOAT, PROP_TRANSLATION);
RNA_def_property_float_sdna(prop, NULL, "cent");
- RNA_def_property_ui_text(prop, "Hook Center", "");
+ RNA_def_property_ui_text(
+ prop, "Hook Center", "Center of the hook, used for falloff and display");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "matrix_inverse", PROP_FLOAT, PROP_MATRIX);
@@ -2208,6 +2280,7 @@ static void rna_def_modifier_hook(BlenderRNA *brna)
prop,
"Sub-Target",
"Name of Parent Bone for hook (if applicable), also recalculates and clears offset");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_HookModifier_subtarget_set");
RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
prop = RNA_def_property(srna, "use_falloff_uniform", PROP_BOOLEAN, PROP_NONE);
@@ -2223,6 +2296,26 @@ static void rna_def_modifier_hook(BlenderRNA *brna)
"Name of Vertex Group which determines influence of modifier per point");
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_HookModifier_name_set");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_property(srna, "vertex_indices", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_array(prop, RNA_MAX_ARRAY_LENGTH);
+ RNA_def_property_flag(prop, PROP_DYNAMIC);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_dynamic_array_funcs(prop, "rna_HookModifier_vertex_indices_get_length");
+ RNA_def_property_int_funcs(prop, "rna_HookModifier_vertex_indices_get", NULL, NULL);
+ RNA_def_property_ui_text(prop,
+ "Vertex Indices",
+ "Indices of vertices bound to the modifier. For bezier curves, "
+ "handles count as additional vertices");
+
+ func = RNA_def_function(srna, "vertex_indices_set", "rna_HookModifier_vertex_indices_set");
+ RNA_def_function_ui_description(
+ func, "Validates and assigns the array of vertex indices bound to the modifier");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
+ parm = RNA_def_int_array(
+ func, "indices", 1, NULL, INT_MIN, INT_MAX, "", "Vertex Indices", 0, INT_MAX);
+ RNA_def_property_array(parm, RNA_MAX_ARRAY_LENGTH);
+ RNA_def_parameter_flags(parm, PROP_DYNAMIC, PARM_REQUIRED);
}
static void rna_def_modifier_softbody(BlenderRNA *brna)
@@ -3102,6 +3195,7 @@ static void rna_def_modifier_particleinstance(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_children", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", eParticleInstanceFlag_Children);
RNA_def_property_ui_text(prop, "Children", "Create instances from child particles");
+ RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_PARTICLESETTINGS);
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "use_path", PROP_BOOLEAN, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index e4270f3854e..4906f8ac28e 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -3987,21 +3987,6 @@ static void def_sh_tex_sky(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
-static const EnumPropertyItem sh_tex_prop_color_space_items[] = {
- {SHD_COLORSPACE_COLOR,
- "COLOR",
- 0,
- "Color",
- "Image contains color data, and will be converted to linear color for rendering"},
- {SHD_COLORSPACE_NONE,
- "NONE",
- 0,
- "Non-Color Data",
- "Image contains non-color data, for example a displacement or normal map, "
- "and will not be converted"},
- {0, NULL, 0, NULL, NULL},
-};
-
static const EnumPropertyItem sh_tex_prop_interpolation_items[] = {
{SHD_INTERP_LINEAR, "Linear", 0, "Linear", "Linear interpolation"},
{SHD_INTERP_CLOSEST, "Closest", 0, "Closest", "No interpolation (sample closest texel)"},
@@ -4038,12 +4023,6 @@ static void def_sh_tex_environment(StructRNA *srna)
RNA_def_struct_sdna_from(srna, "NodeTexEnvironment", "storage");
def_sh_tex(srna);
- prop = RNA_def_property(srna, "color_space", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, sh_tex_prop_color_space_items);
- RNA_def_property_enum_default(prop, SHD_COLORSPACE_COLOR);
- RNA_def_property_ui_text(prop, "Color Space", "Image file color space");
- RNA_def_property_update(prop, 0, "rna_Node_update");
-
prop = RNA_def_property(srna, "projection", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, prop_projection_items);
RNA_def_property_ui_text(prop, "Projection", "Projection of the input image");
@@ -4122,12 +4101,6 @@ static void def_sh_tex_image(StructRNA *srna)
RNA_def_struct_sdna_from(srna, "NodeTexImage", "storage");
def_sh_tex(srna);
- prop = RNA_def_property(srna, "color_space", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, sh_tex_prop_color_space_items);
- RNA_def_property_enum_default(prop, SHD_COLORSPACE_COLOR);
- RNA_def_property_ui_text(prop, "Color Space", "Image file color space");
- RNA_def_property_update(prop, 0, "rna_Node_update");
-
prop = RNA_def_property(srna, "projection", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, prop_projection_items);
RNA_def_property_ui_text(
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index 219445f629f..b2cbfbbf6f0 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -2801,9 +2801,9 @@ static void rna_def_object(BlenderRNA *brna)
/* restrict */
prop = RNA_def_property(srna, "hide_viewport", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "restrictflag", OB_RESTRICT_VIEW);
+ RNA_def_property_boolean_sdna(prop, NULL, "restrictflag", OB_RESTRICT_VIEWPORT);
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
- RNA_def_property_ui_text(prop, "Disable View", "Disable object in the viewport");
+ RNA_def_property_ui_text(prop, "Disable in Viewports", "Globally disable in viewports");
RNA_def_property_ui_icon(prop, ICON_RESTRICT_VIEW_OFF, -1);
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Object_hide_update");
@@ -2811,14 +2811,14 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "restrictflag", OB_RESTRICT_SELECT);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
- RNA_def_property_ui_text(prop, "Disable Select", "Disable object selection in the viewport");
+ RNA_def_property_ui_text(prop, "Disable Selection", "Disable selection in viewport");
RNA_def_property_ui_icon(prop, ICON_RESTRICT_SELECT_OFF, -1);
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Object_hide_update");
prop = RNA_def_property(srna, "hide_render", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "restrictflag", OB_RESTRICT_RENDER);
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
- RNA_def_property_ui_text(prop, "Disable Render", "Disable object in renders");
+ RNA_def_property_ui_text(prop, "Disable in Renders", "Globally disable in renders");
RNA_def_property_ui_icon(prop, ICON_RESTRICT_RENDER_OFF, -1);
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Object_hide_update");
diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c
index 5f41bf68572..c997a82f02d 100644
--- a/source/blender/makesrna/intern/rna_object_api.c
+++ b/source/blender/makesrna/intern/rna_object_api.c
@@ -398,7 +398,7 @@ static PointerRNA rna_Object_shape_key_add(
if ((kb = BKE_object_shapekey_insert(bmain, ob, name, from_mix))) {
PointerRNA keyptr;
- RNA_pointer_create((ID *)ob->data, &RNA_ShapeKey, kb, &keyptr);
+ RNA_pointer_create((ID *)BKE_key_from_object(ob), &RNA_ShapeKey, kb, &keyptr);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
return keyptr;
diff --git a/source/blender/makesrna/intern/rna_object_force.c b/source/blender/makesrna/intern/rna_object_force.c
index c4f0eb35627..2abb1f3227a 100644
--- a/source/blender/makesrna/intern/rna_object_force.c
+++ b/source/blender/makesrna/intern/rna_object_force.c
@@ -754,7 +754,7 @@ static void rna_def_pointcache_common(StructRNA *srna)
static const EnumPropertyItem point_cache_compress_items[] = {
{PTCACHE_COMPRESS_NO, "NO", 0, "None", "No compression"},
- {PTCACHE_COMPRESS_LZO, "LIGHT", 0, "Light", "Fast but not so effective compression"},
+ {PTCACHE_COMPRESS_LZO, "LIGHT", 0, "Lite", "Fast but not so effective compression"},
{PTCACHE_COMPRESS_LZMA, "HEAVY", 0, "Heavy", "Effective but slow compression"},
{0, NULL, 0, NULL, NULL},
};
diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c
index 1b4a7efbdd8..2f7f8c70760 100644
--- a/source/blender/makesrna/intern/rna_pose.c
+++ b/source/blender/makesrna/intern/rna_pose.c
@@ -122,6 +122,11 @@ static void rna_Pose_IK_update(Main *UNUSED(bmain), Scene *UNUSED(scene), Pointe
BIK_clear_data(ob->pose);
}
+static char *rna_Pose_path(PointerRNA *UNUSED(ptr))
+{
+ return BLI_strdup("pose");
+}
+
static char *rna_PoseBone_path(PointerRNA *ptr)
{
bPoseChannel *pchan = ptr->data;
@@ -284,6 +289,18 @@ static void rna_PoseChannel_name_set(PointerRNA *ptr, const char *value)
ED_armature_bone_rename(G_MAIN, ob->data, oldname, newname);
}
+static PointerRNA rna_PoseChannel_bone_get(PointerRNA *ptr)
+{
+ Object *ob = (Object *)ptr->id.data;
+ bPoseChannel *pchan = (bPoseChannel *)ptr->data;
+ PointerRNA tmp_ptr = *ptr;
+
+ /* Replace the id_data pointer with the Armature ID. */
+ tmp_ptr.id.data = ob->data;
+
+ return rna_pointer_inherit_refine(&tmp_ptr, &RNA_Bone, pchan->bone);
+}
+
static bool rna_PoseChannel_has_ik_get(PointerRNA *ptr)
{
Object *ob = (Object *)ptr->id.data;
@@ -911,6 +928,7 @@ static void rna_def_pose_channel(BlenderRNA *brna)
prop = RNA_def_property(srna, "bone", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_struct_type(prop, "Bone");
+ RNA_def_property_pointer_funcs(prop, "rna_PoseChannel_bone_get", NULL, NULL, NULL);
RNA_def_property_flag(prop, PROP_PTR_NO_OWNERSHIP);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Bone", "Bone associated with this PoseBone");
@@ -1551,6 +1569,31 @@ static void rna_def_pose(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "IK Param", "Parameters for IK solver");
+ /* pose edit options */
+ prop = RNA_def_property(srna, "use_mirror_x", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", POSE_MIRROR_EDIT);
+ RNA_def_property_ui_text(
+ prop, "X-Axis Mirror", "Apply changes to matching bone on opposite side of X-Axis");
+ RNA_def_struct_path_func(srna, "rna_Pose_path");
+ RNA_def_property_update(prop, 0, "rna_Pose_update");
+ RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
+
+ prop = RNA_def_property(srna, "use_mirror_relative", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", POSE_MIRROR_RELATIVE);
+ RNA_def_property_ui_text(
+ prop, "Relative Mirror", "Apply relative transformations in X-mirror mode");
+ RNA_def_struct_path_func(srna, "rna_Pose_path");
+ RNA_def_property_update(prop, 0, "rna_Pose_update");
+ RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
+
+ prop = RNA_def_property(srna, "use_auto_ik", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", POSE_AUTO_IK);
+ RNA_def_property_ui_text(
+ prop, "Auto IK", "Add temporary IK constraints while grabbing bones in Pose Mode");
+ RNA_def_struct_path_func(srna, "rna_Pose_path");
+ RNA_def_property_update(prop, 0, "rna_Pose_update");
+ RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
+
/* animviz */
rna_def_animviz_common(srna);
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 5f9e72f74b4..83d7fae14c0 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -2856,7 +2856,7 @@ static void rna_def_tool_settings(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "proportional_objects", 0);
RNA_def_property_ui_text(
prop, "Proportional Editing Objects", "Proportional editing object mode");
- RNA_def_property_ui_icon(prop, ICON_PROP_ON, 0);
+ RNA_def_property_ui_icon(prop, ICON_PROP_OFF, 1);
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* header redraw */
prop = RNA_def_property(srna, "use_proportional_projected", PROP_BOOLEAN, PROP_NONE);
@@ -2900,6 +2900,8 @@ static void rna_def_tool_settings(BlenderRNA *brna)
RNA_def_property_enum_items(prop, rna_enum_proportional_falloff_items);
RNA_def_property_ui_text(
prop, "Proportional Editing Falloff", "Falloff type for proportional editing mode");
+ /* Abusing id_curve :/ */
+ RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_CURVE);
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* header redraw */
prop = RNA_def_property(srna, "proportional_size", PROP_FLOAT, PROP_DISTANCE);
@@ -3619,7 +3621,8 @@ static void rna_def_unit_settings(BlenderRNA *brna)
/* Units */
prop = RNA_def_property(srna, "system", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, unit_systems);
- RNA_def_property_ui_text(prop, "Unit System", "The unit system to use for user interface controls");
+ RNA_def_property_ui_text(
+ prop, "Unit System", "The unit system to use for user interface controls");
RNA_def_property_update(prop, NC_WINDOW, "rna_UnitSettings_system_update");
prop = RNA_def_property(srna, "system_rotation", PROP_ENUM, PROP_NONE);
@@ -6642,13 +6645,14 @@ static void rna_def_scene_display(BlenderRNA *brna)
prop = RNA_def_property(srna, "render_aa", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, rna_enum_scene_display_aa_methods);
- RNA_def_property_ui_text(prop, "Render Anti-Aliasing", "Method of anti-aliasing when rendering");
+ RNA_def_property_ui_text(
+ prop, "Render Anti-Aliasing", "Method of anti-aliasing when rendering final image");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
prop = RNA_def_property(srna, "viewport_aa", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, rna_enum_scene_display_aa_methods);
RNA_def_property_ui_text(
- prop, "Viewport Anti-Aliasing", "Method of anti-aliasing in 3d viewport");
+ prop, "Viewport Anti-Aliasing", "Method of anti-aliasing when rendering 3d viewport");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
/* OpenGL render engine settings. */
diff --git a/source/blender/makesrna/intern/rna_smoke.c b/source/blender/makesrna/intern/rna_smoke.c
index b6486d7a3f4..f4fba02efe5 100644
--- a/source/blender/makesrna/intern/rna_smoke.c
+++ b/source/blender/makesrna/intern/rna_smoke.c
@@ -463,7 +463,7 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL}};
static const EnumPropertyItem smoke_cache_comp_items[] = {
- {SM_CACHE_LIGHT, "CACHELIGHT", 0, "Light", "Fast but not so effective compression"},
+ {SM_CACHE_LIGHT, "CACHELIGHT", 0, "Lite", "Fast but not so effective compression"},
{SM_CACHE_HEAVY, "CACHEHEAVY", 0, "Heavy", "Effective but slow compression"},
{0, NULL, 0, NULL, NULL},
};
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index 1e14fd06b4f..f6515648164 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -644,6 +644,20 @@ static void rna_Space_show_region_header_update(bContext *C, PointerRNA *ptr)
rna_Space_bool_from_region_flag_update_by_type(C, ptr, RGN_TYPE_HEADER, RGN_FLAG_HIDDEN);
}
+/* Footer Region. */
+static bool rna_Space_show_region_footer_get(PointerRNA *ptr)
+{
+ return !rna_Space_bool_from_region_flag_get_by_type(ptr, RGN_TYPE_FOOTER, RGN_FLAG_HIDDEN);
+}
+static void rna_Space_show_region_footer_set(PointerRNA *ptr, bool value)
+{
+ rna_Space_bool_from_region_flag_set_by_type(ptr, RGN_TYPE_FOOTER, RGN_FLAG_HIDDEN, !value);
+}
+static void rna_Space_show_region_footer_update(bContext *C, PointerRNA *ptr)
+{
+ rna_Space_bool_from_region_flag_update_by_type(C, ptr, RGN_TYPE_FOOTER, RGN_FLAG_HIDDEN);
+}
+
/* Tool Header Region.
*
* This depends on the 'RGN_TYPE_TOOL_HEADER'
@@ -2460,6 +2474,10 @@ static void rna_def_space_generic_show_region_toggles(StructRNA *srna, int regio
region_type_mask &= ~(1 << RGN_TYPE_HEADER);
DEF_SHOW_REGION_PROPERTY(show_region_header, "Header", "");
}
+ if (region_type_mask & (1 << RGN_TYPE_FOOTER)) {
+ region_type_mask &= ~(1 << RGN_TYPE_FOOTER);
+ DEF_SHOW_REGION_PROPERTY(show_region_footer, "Footer", "");
+ }
if (region_type_mask & (1 << RGN_TYPE_TOOLS)) {
region_type_mask &= ~(1 << RGN_TYPE_TOOLS);
DEF_SHOW_REGION_PROPERTY(show_region_toolbar, "Toolbar", "");
@@ -2750,25 +2768,60 @@ static void rna_def_space_outliner(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "search_flags", SO_FIND_CASE_SENSITIVE);
RNA_def_property_ui_text(
prop, "Case Sensitive Matches Only", "Only use case sensitive matches of search string");
- RNA_def_property_ui_icon(prop, ICON_SYNTAX_OFF, 0);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_OUTLINER, NULL);
prop = RNA_def_property(srna, "use_filter_complete", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "search_flags", SO_FIND_COMPLETE);
RNA_def_property_ui_text(
prop, "Complete Matches Only", "Only use complete matches of search string");
- RNA_def_property_ui_icon(prop, ICON_OUTLINER_DATA_FONT, 0);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_OUTLINER, NULL);
prop = RNA_def_property(srna, "use_sort_alpha", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SO_SKIP_SORT_ALPHA);
RNA_def_property_ui_text(prop, "Sort Alphabetically", "");
- RNA_def_property_ui_icon(prop, ICON_SORTALPHA, 0);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_OUTLINER, NULL);
- prop = RNA_def_property(srna, "show_restrict_columns", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SO_HIDE_RESTRICTCOLS);
- RNA_def_property_ui_text(prop, "Show Restriction Columns", "Show column");
+ /* Granular restriction column option. */
+ prop = RNA_def_property(srna, "show_restrict_column_enable", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "show_restrict_flags", SO_RESTRICT_ENABLE);
+ RNA_def_property_ui_text(prop, "Exclude from View Layer", "Exclude from view layer");
+ RNA_def_property_ui_icon(prop, ICON_CHECKBOX_HLT, 0);
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_OUTLINER, NULL);
+
+ prop = RNA_def_property(srna, "show_restrict_column_select", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "show_restrict_flags", SO_RESTRICT_SELECT);
+ RNA_def_property_ui_text(prop, "Selectable", "Selectable");
+ RNA_def_property_ui_icon(prop, ICON_RESTRICT_SELECT_OFF, 0);
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_OUTLINER, NULL);
+
+ prop = RNA_def_property(srna, "show_restrict_column_hide", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "show_restrict_flags", SO_RESTRICT_HIDE);
+ RNA_def_property_ui_text(prop, "Hide in Viewport", "Temporarily hide in viewport");
+ RNA_def_property_ui_icon(prop, ICON_HIDE_OFF, 0);
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_OUTLINER, NULL);
+
+ prop = RNA_def_property(srna, "show_restrict_column_viewport", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "show_restrict_flags", SO_RESTRICT_VIEWPORT);
+ RNA_def_property_ui_text(prop, "Disable in Viewports", "Globally disable in viewports");
+ RNA_def_property_ui_icon(prop, ICON_RESTRICT_VIEW_OFF, 0);
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_OUTLINER, NULL);
+
+ prop = RNA_def_property(srna, "show_restrict_column_render", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "show_restrict_flags", SO_RESTRICT_RENDER);
+ RNA_def_property_ui_text(prop, "Disable in Renders", "Globally disable in renders");
+ RNA_def_property_ui_icon(prop, ICON_RESTRICT_RENDER_OFF, 0);
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_OUTLINER, NULL);
+
+ prop = RNA_def_property(srna, "show_restrict_column_holdout", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "show_restrict_flags", SO_RESTRICT_HOLDOUT);
+ RNA_def_property_ui_text(prop, "Holdout", "Holdout");
+ RNA_def_property_ui_icon(prop, ICON_CLIPUV_DEHLT, 0);
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_OUTLINER, NULL);
+
+ prop = RNA_def_property(srna, "show_restrict_column_indirect_only", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "show_restrict_flags", SO_RESTRICT_INDIRECT_ONLY);
+ RNA_def_property_ui_text(prop, "Indirect Only", "Indirect only");
+ RNA_def_property_ui_icon(prop, ICON_MOD_PHYSICS, 0);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_OUTLINER, NULL);
/* Filters. */
@@ -3275,7 +3328,7 @@ static void rna_def_space_view3d_overlay(BlenderRNA *brna)
prop = RNA_def_property(srna, "show_look_dev", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "overlay.flag", V3D_OVERLAY_LOOK_DEV);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_ui_text(prop, "Look Dev Preview", "Show look development balls and palette");
+ RNA_def_property_ui_text(prop, "Look Dev Preview", "Show look development spheres and palette");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
prop = RNA_def_property(srna, "show_wireframes", PROP_BOOLEAN, PROP_NONE);
@@ -4473,7 +4526,7 @@ static void rna_def_space_text(BlenderRNA *brna)
RNA_def_struct_sdna(srna, "SpaceText");
RNA_def_struct_ui_text(srna, "Space Text Editor", "Text editor space data");
- rna_def_space_generic_show_region_toggles(srna, (1 << RGN_TYPE_UI));
+ rna_def_space_generic_show_region_toggles(srna, (1 << RGN_TYPE_UI) | (1 << RGN_TYPE_FOOTER));
/* text */
prop = RNA_def_property(srna, "text", PROP_POINTER, PROP_NONE);
@@ -5146,7 +5199,7 @@ static void rna_def_fileselect_params(BlenderRNA *brna)
"Show/hide Paint Curve data-blocks"},
{FILTER_ID_LP,
"LIGHT_PROBE",
- ICON_LIGHTPROBE_CUBEMAP,
+ ICON_OUTLINER_DATA_LIGHTPROBE,
"Light Probes",
"Show/hide Light Probe data-blocks"},
{FILTER_ID_SCE, "SCENE", ICON_SCENE_DATA, "Scenes", "Show/hide Scene data-blocks"},
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index a9bec8262dd..38877ba6fdd 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -42,6 +42,8 @@
#include "RNA_define.h"
#include "RNA_enum_types.h"
+#include "UI_interface_icons.h"
+
#include "rna_internal.h"
#include "WM_api.h"
@@ -99,6 +101,45 @@ static const EnumPropertyItem rna_enum_studio_light_type_items[] = {
{0, NULL, 0, NULL, NULL},
};
+static const EnumPropertyItem rna_enum_userdef_viewport_aa_items[] = {
+ {SCE_DISPLAY_AA_OFF,
+ "OFF",
+ 0,
+ "No Anti-Aliasing",
+ "Scene will be rendering without any anti-aliasing"},
+ {SCE_DISPLAY_AA_FXAA,
+ "FXAA",
+ 0,
+ "Single Pass Anti-Aliasing",
+ "Scene will be rendered using a single pass anti-aliasing method (FXAA)"},
+ {SCE_DISPLAY_AA_SAMPLES_5,
+ "5",
+ 0,
+ "5 Samples",
+ "Scene will be rendered using 5 anti-aliasing samples"},
+ {SCE_DISPLAY_AA_SAMPLES_8,
+ "8",
+ 0,
+ "8 Samples",
+ "Scene will be rendered using 8 anti-aliasing samples"},
+ {SCE_DISPLAY_AA_SAMPLES_11,
+ "11",
+ 0,
+ "11 Samples",
+ "Scene will be rendered using 11 anti-aliasing samples"},
+ {SCE_DISPLAY_AA_SAMPLES_16,
+ "16",
+ 0,
+ "16 Samples",
+ "Scene will be rendered using 16 anti-aliasing samples"},
+ {SCE_DISPLAY_AA_SAMPLES_32,
+ "32",
+ 0,
+ "32 Samples",
+ "Scene will be rendered using 32 anti-aliasing samples"},
+ {0, NULL, 0, NULL, NULL},
+};
+
#ifdef RNA_RUNTIME
# include "BLI_math_vector.h"
@@ -143,8 +184,19 @@ static void rna_userdef_version_get(PointerRNA *ptr, int *value)
value[2] = userdef->subversionfile;
}
+static void rna_userdef_ui_update(Main *UNUSED(bmain),
+ Scene *UNUSED(scene),
+ PointerRNA *UNUSED(ptr))
+{
+ WM_main_add_notifier(NC_WINDOW, NULL);
+}
+
static void rna_userdef_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *UNUSED(ptr))
{
+ /* We can't use 'ptr->data' because this update function
+ * is used for themes and other nested data. */
+ U.runtime.is_dirty = true;
+
WM_main_add_notifier(NC_WINDOW, NULL);
}
@@ -156,6 +208,12 @@ static void rna_userdef_theme_update(Main *bmain, Scene *scene, PointerRNA *ptr)
rna_userdef_update(bmain, scene, ptr);
}
+static void rna_userdef_theme_update_icons(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+ UI_icons_reload_internal_textures();
+ rna_userdef_theme_update(bmain, scene, ptr);
+}
+
/* also used by buffer swap switching */
static void rna_userdef_dpi_update(Main *UNUSED(bmain),
Scene *UNUSED(scene),
@@ -401,6 +459,7 @@ static bAddon *rna_userdef_addon_new(void)
ListBase *addons_list = &U.addons;
bAddon *addon = BKE_addon_new();
BLI_addtail(addons_list, addon);
+ U.runtime.is_dirty = true;
return addon;
}
@@ -415,12 +474,14 @@ static void rna_userdef_addon_remove(ReportList *reports, PointerRNA *addon_ptr)
BLI_remlink(addons_list, addon);
BKE_addon_free(addon);
RNA_POINTER_INVALIDATE(addon_ptr);
+ U.runtime.is_dirty = true;
}
static bPathCompare *rna_userdef_pathcompare_new(void)
{
bPathCompare *path_cmp = MEM_callocN(sizeof(bPathCompare), "bPathCompare");
BLI_addtail(&U.autoexec_paths, path_cmp);
+ U.runtime.is_dirty = true;
return path_cmp;
}
@@ -434,6 +495,7 @@ static void rna_userdef_pathcompare_remove(ReportList *reports, PointerRNA *path
BLI_freelinkN(&U.autoexec_paths, path_cmp);
RNA_POINTER_INVALIDATE(path_cmp_ptr);
+ U.runtime.is_dirty = true;
}
static void rna_userdef_temp_update(Main *UNUSED(bmain),
@@ -1338,6 +1400,12 @@ static void rna_def_userdef_theme_ui(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
/* Icon colors. */
+ prop = RNA_def_property(srna, "icon_scene", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_float_sdna(prop, NULL, "icon_scene");
+ RNA_def_property_array(prop, 4);
+ RNA_def_property_ui_text(prop, "Scene", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
+
prop = RNA_def_property(srna, "icon_collection", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "icon_collection");
RNA_def_property_array(prop, 4);
@@ -1367,6 +1435,13 @@ static void rna_def_userdef_theme_ui(BlenderRNA *brna)
RNA_def_property_array(prop, 4);
RNA_def_property_ui_text(prop, "Shading", "");
RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
+
+ prop = RNA_def_property(srna, "icon_border_intensity", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "icon_border_intensity");
+ RNA_def_property_ui_text(
+ prop, "Icon Border", "Control the intensity of the border around themes icons");
+ RNA_def_property_ui_range(prop, 0.0, 1.0, 0.1, 2);
+ RNA_def_property_update(prop, 0, "rna_userdef_theme_update_icons");
}
static void rna_def_userdef_theme_space_common(StructRNA *srna)
@@ -2065,6 +2140,11 @@ static void rna_def_userdef_theme_space_graph(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Current Frame", "");
RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
+ prop = RNA_def_property(srna, "scrubbing_background", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 4);
+ RNA_def_property_ui_text(prop, "Scrubbing/Markers Region", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
+
prop = RNA_def_property(srna, "window_sliders", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "shade1");
RNA_def_property_array(prop, 3);
@@ -2759,6 +2839,11 @@ static void rna_def_userdef_theme_space_seq(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Current Frame", "");
RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
+ prop = RNA_def_property(srna, "scrubbing_background", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 4);
+ RNA_def_property_ui_text(prop, "Scrubbing/Markers Region", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
+
prop = RNA_def_property(srna, "keyframe", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "vertex_select");
RNA_def_property_array(prop, 3);
@@ -2816,6 +2901,11 @@ static void rna_def_userdef_theme_space_action(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Current Frame", "");
RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
+ prop = RNA_def_property(srna, "scrubbing_background", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 4);
+ RNA_def_property_ui_text(prop, "Scrubbing/Markers Region", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
+
prop = RNA_def_property(srna, "value_sliders", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "face");
RNA_def_property_array(prop, 3);
@@ -3108,6 +3198,11 @@ static void rna_def_userdef_theme_space_nla(BlenderRNA *brna)
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Current Frame", "");
RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
+
+ prop = RNA_def_property(srna, "scrubbing_background", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 4);
+ RNA_def_property_ui_text(prop, "Scrubbing/Markers Region", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
}
static void rna_def_userdef_theme_colorset(BlenderRNA *brna)
@@ -3215,6 +3310,11 @@ static void rna_def_userdef_theme_space_clip(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Current Frame", "");
RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
+ prop = RNA_def_property(srna, "scrubbing_background", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 4);
+ RNA_def_property_ui_text(prop, "Scrubbing/Markers Region", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
+
prop = RNA_def_property(srna, "strips", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "strip");
RNA_def_property_array(prop, 3);
@@ -4109,12 +4209,12 @@ static void rna_def_userdef_view(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_userdef_update");
/* Lookdev */
- prop = RNA_def_property(srna, "lookdev_ball_size", PROP_INT, PROP_PIXEL);
- RNA_def_property_int_sdna(prop, NULL, "lookdev_ball_size");
+ prop = RNA_def_property(srna, "lookdev_sphere_size", PROP_INT, PROP_PIXEL);
+ RNA_def_property_int_sdna(prop, NULL, "lookdev_sphere_size");
RNA_def_property_range(prop, 50, 400);
RNA_def_property_int_default(prop, 150);
RNA_def_property_ui_text(
- prop, "LookDev Balls Size", "Maximum diameter of the LookDev balls size");
+ prop, "Look Dev Spheres Size", "Maximum diameter of the look development sphere size");
RNA_def_property_update(prop, 0, "rna_userdef_update");
/* View2D Grid Displays */
@@ -4247,7 +4347,12 @@ static void rna_def_userdef_edit(BlenderRNA *brna)
"VIEW",
0,
"View",
- "Align newly added objects facing the active 3D View direction"},
+ "Align newly added objects to the active 3D View direction"},
+ {USER_ADD_CURSORALIGNED,
+ "CURSOR",
+ 0,
+ "3D Cursor",
+ "Align newly added objects to the 3D Cursor's rotation"},
{0, NULL, 0, NULL, NULL},
};
@@ -4706,12 +4811,11 @@ static void rna_def_userdef_system(BlenderRNA *brna)
prop, "Region Overlap", "Draw tool/property regions over the main region");
RNA_def_property_update(prop, 0, "rna_userdef_dpi_update");
- prop = RNA_def_property(srna, "gpu_viewport_quality", PROP_FLOAT, PROP_FACTOR);
- RNA_def_property_float_sdna(prop, NULL, "gpu_viewport_quality");
- RNA_def_property_float_default(prop, 0.6f);
- RNA_def_property_range(prop, 0.0f, 1.0f);
+ prop = RNA_def_property(srna, "viewport_aa", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, rna_enum_userdef_viewport_aa_items);
RNA_def_property_ui_text(
- prop, "Viewport Quality", "Quality setting for Solid mode rendering in the 3d viewport");
+ prop, "Viewport Anti-Aliasing", "Method of anti-aliasing in 3d viewport");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, 0, "rna_userdef_update");
prop = RNA_def_property(srna, "solid_lights", PROP_COLLECTION, PROP_NONE);
@@ -5499,7 +5603,7 @@ void RNA_def_userdef(BlenderRNA *brna)
RNA_def_property_enum_items(prop, preference_section_items);
RNA_def_property_ui_text(
prop, "Active Section", "Active section of the preferences shown in the user interface");
- RNA_def_property_update(prop, 0, "rna_userdef_update");
+ RNA_def_property_update(prop, 0, "rna_userdef_ui_update");
/* don't expose this directly via the UI, modify via an operator */
prop = RNA_def_property(srna, "app_template", PROP_STRING, PROP_NONE);
@@ -5595,6 +5699,16 @@ void RNA_def_userdef(BlenderRNA *brna)
NULL);
RNA_def_property_ui_text(prop, "Studio Lights", "");
+ /* Preferences Flags */
+ prop = RNA_def_property(srna, "use_preferences_save", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "pref_flag", USER_PREF_FLAG_SAVE);
+ RNA_def_property_ui_text(prop, "Save on Exit", "Save modified preferences on exit");
+
+ prop = RNA_def_property(srna, "is_dirty", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "runtime.is_dirty", 0);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Dirty", "Preferences have changed");
+
rna_def_userdef_view(brna);
rna_def_userdef_edit(brna);
rna_def_userdef_input(brna);
diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c
index 3f904df6e00..e4af1b549d6 100644
--- a/source/blender/makesrna/intern/rna_wm.c
+++ b/source/blender/makesrna/intern/rna_wm.c
@@ -1868,6 +1868,7 @@ static void rna_def_operator(BlenderRNA *brna)
RNA_def_struct_idprops_func(srna, "rna_OperatorProperties_idprops");
RNA_def_struct_property_tags(srna, rna_enum_operator_property_tags);
RNA_def_struct_flag(srna, STRUCT_NO_DATABLOCK_IDPROPERTIES);
+ RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
}
static void rna_def_macro_operator(BlenderRNA *brna)
@@ -2105,6 +2106,7 @@ static void rna_def_event(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "shift", 1);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Shift", "True when the Shift key is held");
+ RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_WINDOWMANAGER);
prop = RNA_def_property(srna, "ctrl", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "ctrl", 1);
@@ -2601,6 +2603,7 @@ static void rna_def_keyconfig(BlenderRNA *brna)
/* RNA_def_property_enum_sdna(prop, NULL, "shift"); */
/* RNA_def_property_enum_items(prop, keymap_modifiers_items); */
RNA_def_property_ui_text(prop, "Shift", "Shift key pressed");
+ RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_WINDOWMANAGER);
RNA_def_property_update(prop, 0, "rna_KeyMapItem_update");
prop = RNA_def_property(srna, "ctrl", PROP_BOOLEAN, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_wm_gizmo.c b/source/blender/makesrna/intern/rna_wm_gizmo.c
index a473f97d554..22162aa017b 100644
--- a/source/blender/makesrna/intern/rna_wm_gizmo.c
+++ b/source/blender/makesrna/intern/rna_wm_gizmo.c
@@ -384,6 +384,7 @@ static void rna_Gizmo_matrix_world_get(PointerRNA *ptr, float value[16])
RNA_GIZMO_GENERIC_FLOAT_RW_DEF(scale_basis, scale_basis);
RNA_GIZMO_GENERIC_FLOAT_RW_DEF(line_width, line_width);
+RNA_GIZMO_GENERIC_FLOAT_RW_DEF(select_bias, select_bias);
RNA_GIZMO_GENERIC_FLAG_RW_DEF(flag_use_draw_hover, flag, WM_GIZMO_DRAW_HOVER);
RNA_GIZMO_GENERIC_FLAG_RW_DEF(flag_use_draw_modal, flag, WM_GIZMO_DRAW_MODAL);
@@ -1159,6 +1160,12 @@ static void rna_def_gizmo(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_property_range(prop, 0.0f, FLT_MAX);
RNA_def_property_update(prop, NC_SCREEN | NA_EDITED, NULL);
+ prop = RNA_def_property(srna, "select_bias", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Select Bias", "Depth bias used for selection");
+ RNA_def_property_float_funcs(
+ prop, "rna_Gizmo_select_bias_get", "rna_Gizmo_select_bias_set", NULL);
+ RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);
+
/* wmGizmo.flag */
/* WM_GIZMO_HIDDEN */
prop = RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE);
diff --git a/source/blender/modifiers/intern/MOD_multires.c b/source/blender/modifiers/intern/MOD_multires.c
index 6e5426bbf40..c61ebe0448c 100644
--- a/source/blender/modifiers/intern/MOD_multires.c
+++ b/source/blender/modifiers/intern/MOD_multires.c
@@ -195,7 +195,14 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes
* Annoying and not so much black-boxed as far as sculpting goes, and
* surely there is a better way of solving this. */
if (ctx->object->sculpt != NULL) {
- ctx->object->sculpt->subdiv_ccg = result->runtime.subdiv_ccg;
+ SculptSession *sculpt_session = ctx->object->sculpt;
+ sculpt_session->subdiv_ccg = result->runtime.subdiv_ccg;
+ sculpt_session->multires = mmd;
+ sculpt_session->totvert = mesh->totvert;
+ sculpt_session->totpoly = mesh->totpoly;
+ sculpt_session->mvert = NULL;
+ sculpt_session->mpoly = NULL;
+ sculpt_session->mloop = NULL;
}
/* NOTE: CCG becomes an owner of Subdiv descriptor, so can not share
* this pointer. Not sure if it's needed, but might have a second look
diff --git a/source/blender/nodes/shader/node_shader_util.h b/source/blender/nodes/shader/node_shader_util.h
index 916cb81953e..165ada05a56 100644
--- a/source/blender/nodes/shader/node_shader_util.h
+++ b/source/blender/nodes/shader/node_shader_util.h
@@ -67,6 +67,7 @@
#include "RE_shader_ext.h"
#include "GPU_material.h"
+#include "GPU_texture.h"
#include "GPU_uniformbuffer.h"
bool sh_node_poll_default(struct bNodeType *ntype, struct bNodeTree *ntree);
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c
index 37c35c0adc8..6c3e082f36a 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c
@@ -39,6 +39,8 @@ static bNodeSocketTemplate sh_node_bsdf_principled_in[] = {
{SOCK_FLOAT, 1, N_("IOR"), 1.45f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f},
{SOCK_FLOAT, 1, N_("Transmission"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
{SOCK_FLOAT, 1, N_("Transmission Roughness"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ {SOCK_RGBA, 1, N_("Emission"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
+ {SOCK_FLOAT, 1, N_("Alpha"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
{SOCK_VECTOR,
1,
N_("Normal"),
@@ -99,26 +101,25 @@ static int node_shader_gpu_bsdf_principled(GPUMaterial *mat,
GPUNodeLink *sss_scale;
/* Normals */
- if (!in[17].link) {
- GPU_link(mat, "world_normals_get", &in[17].link);
+ if (!in[19].link) {
+ GPU_link(mat, "world_normals_get", &in[19].link);
}
/* Clearcoat Normals */
- if (!in[18].link) {
- GPU_link(mat, "world_normals_get", &in[18].link);
+ if (!in[20].link) {
+ GPU_link(mat, "world_normals_get", &in[20].link);
}
/* Tangents */
- if (!in[19].link) {
+ if (!in[21].link) {
GPUNodeLink *orco = GPU_attribute(CD_ORCO, "");
- GPU_link(mat, "tangent_orco_z", orco, &in[19].link);
+ GPU_link(mat, "tangent_orco_z", orco, &in[21].link);
GPU_link(mat,
"node_tangent",
- GPU_builtin(GPU_VIEW_NORMAL),
- in[19].link,
+ GPU_builtin(GPU_WORLD_NORMAL),
+ in[21].link,
GPU_builtin(GPU_OBJECT_MATRIX),
- GPU_builtin(GPU_INVERSE_VIEW_MATRIX),
- &in[19].link);
+ &in[21].link);
}
/* SSS Profile */
diff --git a/source/blender/nodes/shader/nodes/node_shader_normal_map.c b/source/blender/nodes/shader/nodes/node_shader_normal_map.c
index d769a219fa0..4976d038065 100644
--- a/source/blender/nodes/shader/nodes/node_shader_normal_map.c
+++ b/source/blender/nodes/shader/nodes/node_shader_normal_map.c
@@ -84,52 +84,33 @@ static int gpu_shader_normal_map(GPUMaterial *mat,
realnorm = GPU_constant(in[1].vec);
}
- negnorm = GPU_builtin(GPU_VIEW_NORMAL);
+ negnorm = GPU_builtin(GPU_WORLD_NORMAL);
GPU_link(mat, "math_max", strength, GPU_constant(d), &strength);
const char *color_to_normal_fnc_name = "color_to_normal_new_shading";
if (nm->space == SHD_SPACE_BLENDER_OBJECT || nm->space == SHD_SPACE_BLENDER_WORLD) {
color_to_normal_fnc_name = "color_to_blender_normal_new_shading";
}
+
+ GPU_link(mat, color_to_normal_fnc_name, realnorm, &realnorm);
switch (nm->space) {
case SHD_SPACE_TANGENT:
- GPU_link(mat, "color_to_normal_new_shading", realnorm, &realnorm);
GPU_link(mat,
"node_normal_map",
GPU_builtin(GPU_OBJECT_INFO),
GPU_attribute(CD_TANGENT, nm->uv_map),
- negnorm,
+ GPU_builtin(GPU_WORLD_NORMAL),
realnorm,
&realnorm);
- GPU_link(
- mat, "vec_math_mix", strength, realnorm, GPU_builtin(GPU_VIEW_NORMAL), &out[0].link);
- /* for uniform scale this is sufficient to match Cycles */
- GPU_link(mat,
- "direction_transform_m4v3",
- out[0].link,
- GPU_builtin(GPU_INVERSE_VIEW_MATRIX),
- &out[0].link);
- GPU_link(mat, "vect_normalize", out[0].link, &out[0].link);
- return true;
+ break;
case SHD_SPACE_OBJECT:
case SHD_SPACE_BLENDER_OBJECT:
- GPU_link(mat,
- "direction_transform_m4v3",
- negnorm,
- GPU_builtin(GPU_INVERSE_VIEW_MATRIX),
- &negnorm);
- GPU_link(mat, color_to_normal_fnc_name, realnorm, &realnorm);
GPU_link(
mat, "direction_transform_m4v3", realnorm, GPU_builtin(GPU_OBJECT_MATRIX), &realnorm);
break;
case SHD_SPACE_WORLD:
case SHD_SPACE_BLENDER_WORLD:
- GPU_link(mat,
- "direction_transform_m4v3",
- negnorm,
- GPU_builtin(GPU_INVERSE_VIEW_MATRIX),
- &negnorm);
- GPU_link(mat, color_to_normal_fnc_name, realnorm, &realnorm);
+ /* Nothing to do. */
break;
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_object_info.c b/source/blender/nodes/shader/nodes/node_shader_object_info.c
index 5520f6f325f..118b8136693 100644
--- a/source/blender/nodes/shader/nodes/node_shader_object_info.c
+++ b/source/blender/nodes/shader/nodes/node_shader_object_info.c
@@ -35,13 +35,17 @@ static int node_shader_gpu_object_info(GPUMaterial *mat,
GPUNodeStack *in,
GPUNodeStack *out)
{
+ Material *ma = GPU_material_get_material(mat);
+ /* Convert to float. */
+ float index = ma ? ma->index : 0;
return GPU_stack_link(mat,
node,
"node_object_info",
in,
out,
GPU_builtin(GPU_OBJECT_MATRIX),
- GPU_builtin(GPU_OBJECT_INFO));
+ GPU_builtin(GPU_OBJECT_INFO),
+ GPU_constant(&index));
}
static void node_shader_exec_object_info(void *UNUSED(data),
diff --git a/source/blender/nodes/shader/nodes/node_shader_tangent.c b/source/blender/nodes/shader/nodes/node_shader_tangent.c
index 5512754d9a2..6795f48edb3 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tangent.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tangent.c
@@ -42,13 +42,7 @@ static int node_shader_gpu_tangent(GPUMaterial *mat,
NodeShaderTangent *attr = node->storage;
if (attr->direction_type == SHD_TANGENT_UVMAP) {
- return GPU_stack_link(mat,
- node,
- "node_tangentmap",
- in,
- out,
- GPU_attribute(CD_TANGENT, ""),
- GPU_builtin(GPU_INVERSE_VIEW_MATRIX));
+ return GPU_stack_link(mat, node, "node_tangentmap", in, out, GPU_attribute(CD_TANGENT, ""));
}
else {
GPUNodeLink *orco = GPU_attribute(CD_ORCO, "");
@@ -68,10 +62,9 @@ static int node_shader_gpu_tangent(GPUMaterial *mat,
"node_tangent",
in,
out,
- GPU_builtin(GPU_VIEW_NORMAL),
+ GPU_builtin(GPU_WORLD_NORMAL),
orco,
- GPU_builtin(GPU_OBJECT_MATRIX),
- GPU_builtin(GPU_INVERSE_VIEW_MATRIX));
+ GPU_builtin(GPU_OBJECT_MATRIX));
}
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_coord.c b/source/blender/nodes/shader/nodes/node_shader_tex_coord.c
index fd62e8ce960..0e34f2ca9b1 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_coord.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_coord.c
@@ -42,10 +42,6 @@ static int node_shader_gpu_tex_coord(GPUMaterial *mat,
{
Object *ob = (Object *)node->id;
- if (ob != NULL) {
- invert_m4_m4(ob->imat, ob->obmat);
- }
-
GPUNodeLink *inv_obmat = (ob != NULL) ? GPU_uniform(&ob->imat[0][0]) :
GPU_builtin(GPU_INVERSE_OBJECT_MATRIX);
@@ -60,8 +56,7 @@ static int node_shader_gpu_tex_coord(GPUMaterial *mat,
in,
out,
GPU_builtin(GPU_VIEW_POSITION),
- GPU_builtin(GPU_VIEW_NORMAL),
- GPU_builtin(GPU_INVERSE_VIEW_MATRIX),
+ GPU_builtin(GPU_WORLD_NORMAL),
inv_obmat,
GPU_builtin(GPU_CAMERA_TEXCO_FACTORS),
orco,
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 c3b8bc8bfd0..615f55e4350 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
@@ -46,7 +46,6 @@ static void node_shader_init_tex_environment(bNodeTree *UNUSED(ntree), bNode *no
NodeTexEnvironment *tex = MEM_callocN(sizeof(NodeTexEnvironment), "NodeTexEnvironment");
BKE_texture_mapping_default(&tex->base.tex_mapping, TEXMAP_TYPE_POINT);
BKE_texture_colormapping_default(&tex->base.color_mapping);
- tex->color_space = SHD_COLORSPACE_COLOR;
tex->projection = SHD_PROJ_EQUIRECTANGULAR;
BKE_imageuser_default(&tex->iuser);
@@ -68,7 +67,6 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat,
NodeTexImage *tex_original = node_original->storage;
ImageUser *iuser = &tex_original->iuser;
- int isdata = tex->color_space == SHD_COLORSPACE_NONE;
GPUNodeLink *outalpha;
if (!ima) {
@@ -89,7 +87,7 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat,
"node_tex_environment_equirectangular",
in[0].link,
GPU_constant(&clamp_size),
- GPU_image(ima, iuser, isdata),
+ GPU_image(ima, iuser),
&in[0].link);
}
else {
@@ -104,7 +102,7 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat,
GPU_link(mat,
"node_tex_image_linear_no_mip",
in[0].link,
- GPU_image(ima, iuser, isdata),
+ GPU_image(ima, iuser),
&out[0].link,
&outalpha);
break;
@@ -112,26 +110,19 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat,
GPU_link(mat,
"node_tex_image_nearest",
in[0].link,
- GPU_image(ima, iuser, isdata),
+ GPU_image(ima, iuser),
&out[0].link,
&outalpha);
break;
default:
- GPU_link(mat,
- "node_tex_image_cubic",
- in[0].link,
- GPU_image(ima, iuser, isdata),
- &out[0].link,
- &outalpha);
+ GPU_link(
+ mat, "node_tex_image_cubic", in[0].link, GPU_image(ima, iuser), &out[0].link, &outalpha);
break;
}
- ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL);
- if (ibuf && (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA) == 0 &&
- GPU_material_do_color_management(mat)) {
- GPU_link(mat, "srgb_to_linearrgb", out[0].link, &out[0].link);
+ if (out[0].hasoutput) {
+ GPU_link(mat, "tex_color_alpha_clear", out[0].link, &out[0].link);
}
- BKE_image_release_ibuf(ima, ibuf, NULL);
return true;
}
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 91d58bc41d0..924714e561a 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_image.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_image.c
@@ -57,7 +57,6 @@ static void node_shader_init_tex_image(bNodeTree *UNUSED(ntree), bNode *node)
NodeTexImage *tex = MEM_callocN(sizeof(NodeTexImage), "NodeTexImage");
BKE_texture_mapping_default(&tex->base.tex_mapping, TEXMAP_TYPE_POINT);
BKE_texture_colormapping_default(&tex->base.color_mapping);
- tex->color_space = SHD_COLORSPACE_COLOR;
BKE_imageuser_default(&tex->iuser);
node->storage = tex;
@@ -99,7 +98,6 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat,
const char *gpu_node_name = (tex->projection == SHD_PROJ_BOX) ? names_box[tex->interpolation] :
names[tex->interpolation];
- bool do_color_correction = false;
bool do_texco_extend = (tex->extension != SHD_IMAGE_EXTENSION_REPEAT);
const bool do_texco_clip = (tex->extension == SHD_IMAGE_EXTENSION_CLIP);
@@ -111,23 +109,13 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat,
}
GPUNodeLink *norm, *col1, *col2, *col3, *input_coords, *gpu_image;
- GPUNodeLink *vnor, *nor_mat_inv, *blend;
+ GPUNodeLink *vnor, *ob_mat, *blend;
GPUNodeLink **texco = &in[0].link;
- int isdata = tex->color_space == SHD_COLORSPACE_NONE;
-
if (!ima) {
return GPU_stack_link(mat, node, "node_tex_image_empty", in, out);
}
- ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL);
- if ((tex->color_space == SHD_COLORSPACE_COLOR) && ibuf &&
- (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA) == 0 &&
- GPU_material_do_color_management(mat)) {
- do_color_correction = true;
- }
- BKE_image_release_ibuf(ima, ibuf, NULL);
-
if (!*texco) {
*texco = GPU_attribute(CD_MTFACE, "");
}
@@ -140,25 +128,20 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat,
GPU_link(mat, "set_rgb", *texco, &input_coords);
}
if (do_texco_extend) {
- GPU_link(mat, "point_texco_clamp", *texco, GPU_image(ima, iuser, isdata), texco);
+ GPU_link(mat, "point_texco_clamp", *texco, GPU_image(ima, iuser), texco);
}
- GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(ima, iuser, isdata));
+ GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(ima, iuser));
break;
case SHD_PROJ_BOX:
- vnor = GPU_builtin(GPU_VIEW_NORMAL);
- nor_mat_inv = GPU_builtin(GPU_INVERSE_NORMAL_MATRIX);
+ vnor = GPU_builtin(GPU_WORLD_NORMAL);
+ ob_mat = GPU_builtin(GPU_OBJECT_MATRIX);
blend = GPU_uniform(&tex->projection_blend);
- gpu_image = GPU_image(ima, iuser, isdata);
-
- GPU_link(mat, "mat3_mul", vnor, nor_mat_inv, &norm);
- GPU_link(
- mat, gpu_node_name, *texco, norm, GPU_image(ima, iuser, isdata), &col1, &col2, &col3);
- if (do_color_correction) {
- GPU_link(mat, "srgb_to_linearrgb", col1, &col1);
- GPU_link(mat, "srgb_to_linearrgb", col2, &col2);
- GPU_link(mat, "srgb_to_linearrgb", col3, &col3);
- }
+ gpu_image = GPU_image(ima, iuser);
+
+ /* equivalent to normal_world_to_object */
+ GPU_link(mat, "normal_transform_transposed_m4v3", vnor, ob_mat, &norm);
+ GPU_link(mat, gpu_node_name, *texco, norm, GPU_image(ima, iuser), &col1, &col2, &col3);
GPU_stack_link(
mat, node, "node_tex_image_box", in, out, norm, col1, col2, col3, gpu_image, blend);
break;
@@ -170,9 +153,9 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat,
GPU_link(mat, "set_rgb", *texco, &input_coords);
}
if (do_texco_extend) {
- GPU_link(mat, "point_texco_clamp", *texco, GPU_image(ima, iuser, isdata), texco);
+ GPU_link(mat, "point_texco_clamp", *texco, GPU_image(ima, iuser), texco);
}
- GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(ima, iuser, isdata));
+ GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(ima, iuser));
break;
case SHD_PROJ_TUBE:
@@ -182,20 +165,26 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat,
GPU_link(mat, "set_rgb", *texco, &input_coords);
}
if (do_texco_extend) {
- GPU_link(mat, "point_texco_clamp", *texco, GPU_image(ima, iuser, isdata), texco);
+ GPU_link(mat, "point_texco_clamp", *texco, GPU_image(ima, iuser), texco);
}
- GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(ima, iuser, isdata));
+ GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(ima, iuser));
break;
}
if (tex->projection != SHD_PROJ_BOX) {
if (do_texco_clip) {
gpu_node_name = names_clip[tex->interpolation];
- GPU_stack_link(
- mat, node, gpu_node_name, in, out, GPU_image(ima, iuser, isdata), out[0].link);
+ in[0].link = input_coords;
+ GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(ima, iuser), out[0].link);
+ }
+ }
+
+ if (out[0].hasoutput) {
+ if (out[1].hasoutput) {
+ GPU_link(mat, "tex_color_alpha_unpremultiply", out[0].link, &out[0].link);
}
- if (do_color_correction) {
- GPU_link(mat, "srgb_to_linearrgb", out[0].link, &out[0].link);
+ else {
+ GPU_link(mat, "tex_color_alpha_clear", out[0].link, &out[0].link);
}
}
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 cbc012040b0..ac8b49c4572 100644
--- a/source/blender/nodes/shader/nodes/node_shader_vector_displacement.c
+++ b/source/blender/nodes/shader/nodes/node_shader_vector_displacement.c
@@ -61,7 +61,7 @@ static int gpu_shader_vector_displacement(GPUMaterial *mat,
in,
out,
GPU_attribute(CD_TANGENT, ""),
- GPU_builtin(GPU_VIEW_NORMAL),
+ GPU_builtin(GPU_WORLD_NORMAL),
GPU_builtin(GPU_OBJECT_MATRIX),
GPU_builtin(GPU_VIEW_MATRIX));
}
diff --git a/source/blender/python/intern/bpy_rna_anim.c b/source/blender/python/intern/bpy_rna_anim.c
index 79c31c8caad..710ae0433e0 100644
--- a/source/blender/python/intern/bpy_rna_anim.c
+++ b/source/blender/python/intern/bpy_rna_anim.c
@@ -263,8 +263,9 @@ static int pyrna_struct_keyframe_parse(PointerRNA *ptr,
/* flag may be null (no option currently for remove keyframes e.g.). */
if (r_options) {
- if (pyoptions && (pyrna_set_to_enum_bitfield(
- rna_enum_keying_flag_items, pyoptions, r_options, error_prefix) == -1)) {
+ if (pyoptions &&
+ (pyrna_set_to_enum_bitfield(
+ rna_enum_keying_flag_items_api, pyoptions, r_options, error_prefix) == -1)) {
return -1;
}
@@ -299,8 +300,11 @@ char pyrna_struct_keyframe_insert_doc[] =
"F-Curves.\n"
" - ``INSERTKEY_VISUAL`` Insert keyframes based on 'visual transforms'.\n"
" - ``INSERTKEY_XYZ_TO_RGB`` Color for newly added transformation F-Curves (Location, "
- "Rotation, Scale)\n"
- " and also Color is based on the transform axis.\n"
+ "Rotation, Scale) is based on the transform axis.\n"
+ " - ``INSERTKEY_REPLACE`` Only replace already exising keyframes.\n"
+ " - ``INSERTKEY_AVAILABLE`` Only insert into already existing F-Curves.\n"
+ " - ``INSERTKEY_CYCLE_AWARE`` Take cyclic extrapolation into account "
+ "(Cycle-Aware Keying option).\n"
" :type flag: set\n"
" :return: Success of keyframe insertion.\n"
" :rtype: boolean\n";
diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h
index 46d2df0acb5..db051d58d6c 100644
--- a/source/blender/render/extern/include/RE_pipeline.h
+++ b/source/blender/render/extern/include/RE_pipeline.h
@@ -284,21 +284,21 @@ bool RE_WriteRenderViewsMovie(struct ReportList *reports,
bool preview);
/* only RE_NewRender() needed, main Blender render calls */
-void RE_BlenderFrame(struct Render *re,
- struct Main *bmain,
- struct Scene *scene,
- struct ViewLayer *single_layer,
- struct Object *camera_override,
- int frame,
- const bool write_still);
-void RE_BlenderAnim(struct Render *re,
+void RE_RenderFrame(struct Render *re,
struct Main *bmain,
struct Scene *scene,
struct ViewLayer *single_layer,
struct Object *camera_override,
- int sfra,
- int efra,
- int tfra);
+ int frame,
+ const bool write_still);
+void RE_RenderAnim(struct Render *re,
+ struct Main *bmain,
+ struct Scene *scene,
+ struct ViewLayer *single_layer,
+ struct Object *camera_override,
+ int sfra,
+ int efra,
+ int tfra);
#ifdef WITH_FREESTYLE
void RE_RenderFreestyleStrokes(struct Render *re,
struct Main *bmain,
@@ -307,6 +307,9 @@ void RE_RenderFreestyleStrokes(struct Render *re,
void RE_RenderFreestyleExternal(struct Render *re);
#endif
+/* Free memory and clear runtime data which is only needed during rendering. */
+void RE_CleanAfterRender(struct Render *re);
+
void RE_SetActiveRenderView(struct Render *re, const char *viewname);
const char *RE_GetActiveRenderView(struct Render *re);
diff --git a/source/blender/render/intern/source/multires_bake.c b/source/blender/render/intern/source/multires_bake.c
index 237debceb83..878a774ab37 100644
--- a/source/blender/render/intern/source/multires_bake.c
+++ b/source/blender/render/intern/source/multires_bake.c
@@ -1458,7 +1458,8 @@ static void finish_images(MultiresBakeRender *bkr, MultiresBakeResult *result)
bake_ibuf_filter(ibuf, userdata->mask_buffer, bkr->bake_filter);
- ibuf->userflags |= IB_BITMAPDIRTY | IB_DISPLAY_BUFFER_INVALID;
+ ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
+ BKE_image_mark_dirty(ima, ibuf);
if (ibuf->rect_float) {
ibuf->userflags |= IB_RECT_INVALID;
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index 7d3002ea71d..9c1c713ab94 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -1988,7 +1988,7 @@ const char *RE_GetActiveRenderView(Render *re)
/* evaluating scene options for general Blender render */
static int render_initialize_from_main(Render *re,
- RenderData *rd,
+ const RenderData *rd,
Main *bmain,
Scene *scene,
ViewLayer *single_layer,
@@ -2072,13 +2072,13 @@ void RE_SetReports(Render *re, ReportList *reports)
}
/* general Blender frame render call */
-void RE_BlenderFrame(Render *re,
- Main *bmain,
- Scene *scene,
- ViewLayer *single_layer,
- Object *camera_override,
- int frame,
- const bool write_still)
+void RE_RenderFrame(Render *re,
+ Main *bmain,
+ Scene *scene,
+ ViewLayer *single_layer,
+ Object *camera_override,
+ int frame,
+ const bool write_still)
{
BLI_callback_exec(re->main, (ID *)scene, BLI_CB_EVT_RENDER_INIT);
@@ -2090,6 +2090,7 @@ void RE_BlenderFrame(Render *re,
if (render_initialize_from_main(
re, &scene->r, bmain, scene, single_layer, camera_override, 0, 0)) {
+ const RenderData rd = scene->r;
MEM_reset_peak_memory();
BLI_callback_exec(re->main, (ID *)scene, BLI_CB_EVT_RENDER_PRE);
@@ -2097,18 +2098,18 @@ void RE_BlenderFrame(Render *re,
do_render_all_options(re);
if (write_still && !G.is_break) {
- if (BKE_imtype_is_movie(scene->r.im_format.imtype)) {
+ if (BKE_imtype_is_movie(rd.im_format.imtype)) {
/* operator checks this but in case its called from elsewhere */
printf("Error: cant write single images with a movie format!\n");
}
else {
char name[FILE_MAX];
BKE_image_path_from_imformat(name,
- scene->r.pic,
+ rd.pic,
BKE_main_blendfile_path(bmain),
scene->r.cfra,
- &scene->r.im_format,
- (scene->r.scemode & R_EXTENSION) != 0,
+ &rd.im_format,
+ (rd.scemode & R_EXTENSION) != 0,
false,
NULL);
@@ -2117,7 +2118,8 @@ void RE_BlenderFrame(Render *re,
}
}
- BLI_callback_exec(re->main, (ID *)scene, BLI_CB_EVT_RENDER_POST); /* keep after file save */
+ /* keep after file save */
+ BLI_callback_exec(re->main, (ID *)scene, BLI_CB_EVT_RENDER_POST);
if (write_still) {
BLI_callback_exec(re->main, (ID *)scene, BLI_CB_EVT_RENDER_WRITE);
}
@@ -2126,8 +2128,7 @@ void RE_BlenderFrame(Render *re,
BLI_callback_exec(
re->main, (ID *)scene, G.is_break ? BLI_CB_EVT_RENDER_CANCEL : BLI_CB_EVT_RENDER_COMPLETE);
- /* Destroy the opengl context in the correct thread. */
- RE_gl_context_destroy(re);
+ RE_CleanAfterRender(re);
/* UGLY WARNING */
G.is_rendering = false;
@@ -2427,7 +2428,10 @@ static int do_write_image_or_movie(Render *re,
return ok;
}
-static void get_videos_dimensions(Render *re, RenderData *rd, size_t *r_width, size_t *r_height)
+static void get_videos_dimensions(const Render *re,
+ const RenderData *rd,
+ size_t *r_width,
+ size_t *r_height)
{
size_t width, height;
if (re->r.mode & R_BORDER) {
@@ -2461,23 +2465,23 @@ static void re_movie_free_all(Render *re, bMovieHandle *mh, int totvideos)
}
/* saves images to disk */
-void RE_BlenderAnim(Render *re,
- Main *bmain,
- Scene *scene,
- ViewLayer *single_layer,
- Object *camera_override,
- int sfra,
- int efra,
- int tfra)
-{
- RenderData rd = scene->r;
+void RE_RenderAnim(Render *re,
+ Main *bmain,
+ Scene *scene,
+ ViewLayer *single_layer,
+ Object *camera_override,
+ int sfra,
+ int efra,
+ int tfra)
+{
+ const RenderData rd = scene->r;
bMovieHandle *mh = NULL;
- int cfrao = scene->r.cfra;
+ const int cfrao = rd.cfra;
int nfra, totrendered = 0, totskipped = 0;
const int totvideos = BKE_scene_multiview_num_videos_get(&rd);
- const bool is_movie = BKE_imtype_is_movie(scene->r.im_format.imtype);
- const bool is_multiview_name = ((scene->r.scemode & R_MULTIVIEW) != 0 &&
- (scene->r.im_format.views_format == R_IMF_VIEWS_INDIVIDUAL));
+ const bool is_movie = BKE_imtype_is_movie(rd.im_format.imtype);
+ const bool is_multiview_name = ((rd.scemode & R_MULTIVIEW) != 0 &&
+ (rd.im_format.views_format == R_IMF_VIEWS_INDIVIDUAL));
BLI_callback_exec(re->main, (ID *)scene, BLI_CB_EVT_RENDER_INIT);
@@ -2493,7 +2497,7 @@ void RE_BlenderAnim(Render *re,
get_videos_dimensions(re, &rd, &width, &height);
- mh = BKE_movie_handle_get(scene->r.im_format.imtype);
+ mh = BKE_movie_handle_get(rd.im_format.imtype);
if (mh == NULL) {
BKE_report(re->reports, RPT_ERROR, "Movie format unsupported");
return;
@@ -2530,23 +2534,6 @@ void RE_BlenderAnim(Render *re,
for (nfra = sfra, scene->r.cfra = sfra; scene->r.cfra <= efra; scene->r.cfra++) {
char name[FILE_MAX];
- /* Special case for 'mh->get_next_frame'
- * this overrides regular frame stepping logic */
- if (mh && mh->get_next_frame) {
- while (G.is_break == false) {
- int nfra_test = mh->get_next_frame(re->movie_ctx_arr[0], &re->r, re->reports);
- if (nfra_test >= 0 && nfra_test >= sfra && nfra_test <= efra) {
- nfra = nfra_test;
- break;
- }
- else {
- if (re->test_break(re->tbh)) {
- G.is_break = true;
- }
- }
- }
- }
-
/* Here is a feedback loop exists -- render initialization requires updated
* render layers settings which could be animated, but scene evaluation for
* the frame happens later because it depends on what layers are visible to
@@ -2582,18 +2569,18 @@ void RE_BlenderAnim(Render *re,
/* Touch/NoOverwrite options are only valid for image's */
if (is_movie == false) {
- if (scene->r.mode & (R_NO_OVERWRITE | R_TOUCH)) {
+ if (rd.mode & (R_NO_OVERWRITE | R_TOUCH)) {
BKE_image_path_from_imformat(name,
- scene->r.pic,
+ rd.pic,
BKE_main_blendfile_path(bmain),
scene->r.cfra,
- &scene->r.im_format,
- (scene->r.scemode & R_EXTENSION) != 0,
+ &rd.im_format,
+ (rd.scemode & R_EXTENSION) != 0,
true,
NULL);
}
- if (scene->r.mode & R_NO_OVERWRITE) {
+ if (rd.mode & R_NO_OVERWRITE) {
if (!is_multiview_name) {
if (BLI_exists(name)) {
printf("skipping existing frame \"%s\"\n", name);
@@ -2626,7 +2613,7 @@ void RE_BlenderAnim(Render *re,
}
}
- if (scene->r.mode & R_TOUCH) {
+ if (rd.mode & R_TOUCH) {
if (!is_multiview_name) {
if (!BLI_exists(name)) {
BLI_make_existing_file(name); /* makes the dir if its not there */
@@ -2675,7 +2662,7 @@ void RE_BlenderAnim(Render *re,
if (G.is_break == true) {
/* remove touched file */
if (is_movie == false) {
- if ((scene->r.mode & R_TOUCH)) {
+ if ((rd.mode & R_TOUCH)) {
if (!is_multiview_name) {
if ((BLI_file_size(name) == 0)) {
/* BLI_exists(name) is implicit */
@@ -2706,8 +2693,8 @@ void RE_BlenderAnim(Render *re,
}
if (G.is_break == false) {
- BLI_callback_exec(
- re->main, (ID *)scene, BLI_CB_EVT_RENDER_POST); /* keep after file save */
+ /* keep after file save */
+ BLI_callback_exec(re->main, (ID *)scene, BLI_CB_EVT_RENDER_POST);
BLI_callback_exec(re->main, (ID *)scene, BLI_CB_EVT_RENDER_WRITE);
}
}
@@ -2730,8 +2717,7 @@ void RE_BlenderAnim(Render *re,
re->main, (ID *)scene, G.is_break ? BLI_CB_EVT_RENDER_CANCEL : BLI_CB_EVT_RENDER_COMPLETE);
BKE_sound_reset_scene_specs(scene);
- /* Destroy the opengl context in the correct thread. */
- RE_gl_context_destroy(re);
+ RE_CleanAfterRender(re);
/* UGLY WARNING */
G.is_rendering = false;
@@ -2756,6 +2742,12 @@ void RE_PreviewRender(Render *re, Main *bmain, Scene *sce)
do_render_3d(re);
}
+void RE_CleanAfterRender(Render *re)
+{
+ /* Destroy the opengl context in the correct thread. */
+ RE_gl_context_destroy(re);
+}
+
/* note; repeated win/disprect calc... solve that nicer, also in compo */
/* only the temp file! */
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index f1037dadf85..bd02a1e13c1 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -373,7 +373,8 @@ int WM_operator_confirm_message_ex(struct bContext *C,
struct wmOperator *op,
const char *title,
const int icon,
- const char *message);
+ const char *message,
+ const short opcontext);
int WM_operator_confirm_message(struct bContext *C, struct wmOperator *op, const char *message);
/* operator api */
@@ -660,6 +661,7 @@ enum {
WM_JOB_TYPE_SHADER_COMPILATION,
WM_JOB_TYPE_STUDIOLIGHT,
WM_JOB_TYPE_LIGHT_BAKE,
+ WM_JOB_TYPE_FSMENU_BOOKMARK_VALIDATE,
/* add as needed, screencast, seq proxy build
* if having hard coded values is a problem */
};
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index 154c4837a68..b3c36857dce 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -605,7 +605,7 @@ typedef struct wmOperatorType {
* that the operator might still fail to execute even if this return true */
bool (*poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT;
- /* Use to check of properties should be displayed in auto-generated UI.
+ /* Use to check if properties should be displayed in auto-generated UI.
* Use 'check' callback to enforce refreshing. */
bool (*poll_property)(const struct bContext *C,
struct wmOperator *op,
diff --git a/source/blender/windowmanager/gizmo/WM_gizmo_types.h b/source/blender/windowmanager/gizmo/WM_gizmo_types.h
index 1c298f378a4..7d38194db1b 100644
--- a/source/blender/windowmanager/gizmo/WM_gizmo_types.h
+++ b/source/blender/windowmanager/gizmo/WM_gizmo_types.h
@@ -198,6 +198,10 @@ struct wmGizmo {
/** For single click button gizmos, use a different part as a fallback, -1 when unused. */
int drag_part;
+ /** Distance to bias this gizmo above others when picking
+ * (in worldspace, scaled by the gizmo scale - when used). */
+ float select_bias;
+
/**
* Transformation of the gizmo in 2d or 3d space.
* - Matrix axis are expected to be unit length (scale is applied after).
diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c
index 31c5e1fb94c..9f36af8b616 100644
--- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c
+++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c
@@ -25,8 +25,10 @@
#include "BLI_listbase.h"
#include "BLI_math.h"
+#include "BLI_math_bits.h"
#include "BLI_rect.h"
#include "BLI_ghash.h"
+#include "BLI_array.h"
#include "BKE_context.h"
#include "BKE_global.h"
@@ -470,7 +472,8 @@ void WM_gizmomap_draw(wmGizmoMap *gzmap,
static void gizmo_draw_select_3D_loop(const bContext *C,
ListBase *visible_gizmos,
- const wmGizmo *gz_stop)
+ const wmGizmo *gz_stop,
+ bool *r_use_select_bias)
{
int select_id = 0;
wmGizmo *gz;
@@ -511,6 +514,10 @@ static void gizmo_draw_select_3D_loop(const bContext *C,
is_depth_skip_prev = is_depth_skip;
}
+ if (gz->select_bias != 0.0) {
+ *r_use_select_bias = true;
+ }
+
/* pass the selection id shifted by 8 bits. Last 8 bits are used for selected gizmo part id */
gz->type->draw_select(C, gz, select_id << 8);
@@ -543,24 +550,68 @@ static int gizmo_find_intersected_3d_intern(ListBase *visible_gizmos,
ED_view3d_draw_setup_view(
CTX_wm_window(C), CTX_data_depsgraph(C), CTX_data_scene(C), ar, v3d, NULL, NULL, &rect);
+ bool use_select_bias = false;
+
GPU_select_begin(buffer, ARRAY_SIZE(buffer), &rect, GPU_SELECT_NEAREST_FIRST_PASS, 0);
/* do the drawing */
- gizmo_draw_select_3D_loop(C, visible_gizmos, gz_stop);
+ gizmo_draw_select_3D_loop(C, visible_gizmos, gz_stop, &use_select_bias);
hits = GPU_select_end();
if (hits > 0) {
GPU_select_begin(buffer, ARRAY_SIZE(buffer), &rect, GPU_SELECT_NEAREST_SECOND_PASS, hits);
- gizmo_draw_select_3D_loop(C, visible_gizmos, gz_stop);
+ gizmo_draw_select_3D_loop(C, visible_gizmos, gz_stop, &use_select_bias);
GPU_select_end();
}
ED_view3d_draw_setup_view(
CTX_wm_window(C), CTX_data_depsgraph(C), CTX_data_scene(C), ar, v3d, NULL, NULL, NULL);
- const GLuint *hit_near = GPU_select_buffer_near(buffer, hits);
-
- return hit_near ? hit_near[3] : -1;
+ if (use_select_bias && (hits > 1)) {
+ wmGizmo **gizmo_table = NULL;
+ BLI_array_staticdeclare(gizmo_table, 1024);
+ for (LinkData *link = visible_gizmos->first; link; link = link->next) {
+ BLI_array_append(gizmo_table, link->data);
+ }
+ float co_direction[3];
+ float co_screen[3] = {co[0], co[1], 0.0f};
+ ED_view3d_win_to_vector(ar, (float[2]){UNPACK2(co)}, co_direction);
+
+ RegionView3D *rv3d = ar->regiondata;
+ const int viewport[4] = {0, 0, ar->winx, ar->winy};
+ float co_3d_origin[3];
+
+ GPU_matrix_unproject_model_inverted(
+ co_screen, rv3d->viewinv, rv3d->winmat, viewport, co_3d_origin);
+
+ GLuint *buf_iter = buffer;
+ int hit_found = -1;
+ float dot_best = FLT_MAX;
+
+ for (int i = 0; i < hits; i++, buf_iter += 4) {
+ BLI_assert(buf_iter[3] != -1);
+ wmGizmo *gz = gizmo_table[buf_iter[3] >> 8];
+ float co_3d[3];
+ co_screen[2] = int_as_float(buf_iter[1]);
+ GPU_matrix_unproject_model_inverted(co_screen, rv3d->viewinv, rv3d->winmat, viewport, co_3d);
+ float select_bias = gz->select_bias;
+ if ((gz->flag & WM_GIZMO_DRAW_NO_SCALE) == 0) {
+ select_bias *= gz->scale_final;
+ }
+ sub_v3_v3(co_3d, co_3d_origin);
+ const float dot_test = dot_v3v3(co_3d, co_direction) - select_bias;
+ if (dot_best > dot_test) {
+ dot_best = dot_test;
+ hit_found = buf_iter[3];
+ }
+ }
+ BLI_array_free(gizmo_table);
+ return hit_found;
+ }
+ else {
+ const GLuint *hit_near = GPU_select_buffer_near(buffer, hits);
+ return hit_near ? hit_near[3] : -1;
+ }
}
/**
diff --git a/source/blender/windowmanager/intern/wm_dragdrop.c b/source/blender/windowmanager/intern/wm_dragdrop.c
index 30311d83509..e4ecf7e6e94 100644
--- a/source/blender/windowmanager/intern/wm_dragdrop.c
+++ b/source/blender/windowmanager/intern/wm_dragdrop.c
@@ -442,7 +442,7 @@ void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect)
drag_rect_minmax(rect, x, y, x + iconsize, y + iconsize);
}
else {
- UI_icon_draw_aspect(x, y, drag->icon, 1.0f / UI_DPI_FAC, 0.8, text_col);
+ UI_icon_draw_ex(x, y, drag->icon, U.inv_dpi_fac, 0.8, 0.0f, text_col, false);
}
}
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index a13b28b7853..13b6260e2b9 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -86,7 +86,6 @@
#include "RNA_enum_types.h"
#include "DEG_depsgraph.h"
-#include "DEG_depsgraph_query.h"
/* Motion in pixels allowed before we don't consider single/double click,
* or detect the start of a tweak event. */
@@ -3091,12 +3090,10 @@ void wm_event_do_handlers(bContext *C)
wm_event_free_all(win);
}
else {
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
Scene *scene = WM_window_get_active_scene(win);
- Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
if (scene) {
- const int is_playing_sound = BKE_sound_scene_playing(scene_eval);
+ int is_playing_sound = BKE_sound_scene_playing(scene);
if (is_playing_sound != -1) {
bool is_playing_screen;
@@ -3116,6 +3113,7 @@ void wm_event_do_handlers(bContext *C)
int ncfra = time * (float)FPS + 0.5f;
if (ncfra != scene->r.cfra) {
scene->r.cfra = ncfra;
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
ED_update_for_newframe(CTX_data_main(C), depsgraph);
WM_event_add_notifier(C, NC_WINDOW, NULL);
}
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index 6d90d4745a6..304daa2dd00 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -716,26 +716,6 @@ const char *WM_init_state_app_template_get(void)
return wm_init_state_app_template.override ? wm_init_state_app_template.app_template : NULL;
}
-static bool wm_app_template_has_userpref(const char *app_template)
-{
- /* Test if app template provides a userpref.blend. If not, we will
- * share user preferences with the rest of Blender. */
- if (!app_template && app_template[0]) {
- return false;
- }
-
- char app_template_path[FILE_MAX];
- if (!BKE_appdir_app_template_id_search(
- app_template, app_template_path, sizeof(app_template_path))) {
- return false;
- }
-
- char userpref_path[FILE_MAX];
- BLI_path_join(
- userpref_path, sizeof(userpref_path), app_template_path, BLENDER_USERPREF_FILE, NULL);
- return BLI_exists(userpref_path);
-}
-
/**
* Called on startup, (context entirely filled with NULLs)
* or called for 'New File' both startup.blend and userpref.blend are checked.
@@ -758,6 +738,7 @@ void wm_homefile_read(bContext *C,
ReportList *reports,
bool use_factory_settings,
bool use_empty_data,
+ bool use_data,
bool use_userdef,
const char *filepath_startup_override,
const char *app_template_override,
@@ -788,7 +769,14 @@ void wm_homefile_read(bContext *C,
* And in this case versioning code is to be run.
*/
bool read_userdef_from_memory = false;
- eBLOReadSkip skip_flags = use_userdef ? 0 : BLO_READ_SKIP_USERDEF;
+ eBLOReadSkip skip_flags = 0;
+
+ if (use_data == false) {
+ skip_flags |= BLO_READ_SKIP_DATA;
+ }
+ if (use_userdef == false) {
+ skip_flags |= BLO_READ_SKIP_USERDEF;
+ }
/* True if we load startup.blend from memory
* or use app-template startup.blend which the user hasn't saved. */
@@ -801,14 +789,16 @@ void wm_homefile_read(bContext *C,
SET_FLAG_FROM_TEST(G.f, (U.flag & USER_SCRIPT_AUTOEXEC_DISABLE) == 0, G_FLAG_SCRIPT_AUTOEXEC);
}
- BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_LOAD_PRE);
+ if (use_data) {
+ BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_LOAD_PRE);
- UI_view2d_zoom_cache_reset();
+ G.relbase_valid = 0;
- G.relbase_valid = 0;
+ /* put aside screens to match with persistent windows later */
+ wm_window_match_init(C, &wmbase);
+ }
- /* put aside screens to match with persistent windows later */
- wm_window_match_init(C, &wmbase);
+ UI_view2d_zoom_cache_reset();
filepath_startup[0] = '\0';
filepath_userdef[0] = '\0';
@@ -931,7 +921,9 @@ void wm_homefile_read(bContext *C,
}
if (success) {
if (update_defaults) {
- BLO_update_defaults_startup_blend(CTX_data_main(C), app_template);
+ if (use_data) {
+ BLO_update_defaults_startup_blend(CTX_data_main(C), app_template);
+ }
}
is_factory_startup = filepath_startup_is_factory;
}
@@ -1010,10 +1002,12 @@ void wm_homefile_read(bContext *C,
BLI_strncpy(U.app_template, app_template_override, sizeof(U.app_template));
}
- /* Prevent buggy files that had G_FILE_RELATIVE_REMAP written out by mistake.
- * Screws up autosaves otherwise can remove this eventually,
- * only in a 2.53 and older, now its not written. */
- G.fileflags &= ~G_FILE_RELATIVE_REMAP;
+ if (use_data) {
+ /* Prevent buggy files that had G_FILE_RELATIVE_REMAP written out by mistake.
+ * Screws up autosaves otherwise can remove this eventually,
+ * only in a 2.53 and older, now its not written. */
+ G.fileflags &= ~G_FILE_RELATIVE_REMAP;
+ }
bmain = CTX_data_main(C);
@@ -1023,8 +1017,10 @@ void wm_homefile_read(bContext *C,
reset_app_template = true;
}
- /* match the read WM with current WM */
- wm_window_match_do(C, &wmbase, &bmain->wm, &bmain->wm);
+ if (use_data) {
+ /* match the read WM with current WM */
+ wm_window_match_do(C, &wmbase, &bmain->wm, &bmain->wm);
+ }
if (use_factory_settings) {
/* Clear keymaps because the current default keymap may have been initialized
@@ -1036,14 +1032,16 @@ void wm_homefile_read(bContext *C,
}
}
- WM_check(C); /* opens window(s), checks keymaps */
+ if (use_data) {
+ WM_check(C); /* opens window(s), checks keymaps */
- bmain->name[0] = '\0';
+ bmain->name[0] = '\0';
- /* start with save preference untitled.blend */
- G.save_over = 0;
+ /* start with save preference untitled.blend */
+ G.save_over = 0;
- wm_file_read_post(C, true, is_factory_startup, reset_app_template);
+ wm_file_read_post(C, true, is_factory_startup, reset_app_template);
+ }
if (r_is_factory_startup) {
*r_is_factory_startup = is_factory_startup;
@@ -1694,69 +1692,138 @@ void WM_OT_userpref_autoexec_path_remove(wmOperatorType *ot)
static int wm_userpref_write_exec(bContext *C, wmOperator *op)
{
wmWindowManager *wm = CTX_wm_manager(C);
- char filepath[FILE_MAX];
- const char *cfgdir;
- bool ok = true;
- bool use_template_userpref = wm_app_template_has_userpref(U.app_template);
- /* update keymaps in user preferences */
+ /* Update keymaps in user preferences. */
WM_keyconfig_update(wm);
- if ((cfgdir = BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL))) {
- bool ok_write;
- BLI_path_join(filepath, sizeof(filepath), cfgdir, BLENDER_USERPREF_FILE, NULL);
+ const bool ok = BKE_blendfile_userdef_write_all(op->reports);
- printf("Writing userprefs: '%s' ", filepath);
- if (use_template_userpref) {
- ok_write = BKE_blendfile_userdef_write_app_template(filepath, op->reports);
- }
- else {
- ok_write = BKE_blendfile_userdef_write(filepath, op->reports);
- }
+ return ok ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
+}
- if (ok_write) {
- printf("ok\n");
- }
- else {
- printf("fail\n");
- ok = false;
- }
- }
- else {
- BKE_report(op->reports, RPT_ERROR, "Unable to create userpref path");
- }
+void WM_OT_save_userpref(wmOperatorType *ot)
+{
+ ot->name = "Save Preferences";
+ ot->idname = "WM_OT_save_userpref";
+ ot->description = "Save preferences separately, overrides startup file preferences";
- if (use_template_userpref) {
- if ((cfgdir = BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, U.app_template))) {
- /* Also save app-template prefs */
- BLI_path_join(filepath, sizeof(filepath), cfgdir, BLENDER_USERPREF_FILE, NULL);
+ ot->invoke = WM_operator_confirm;
+ ot->exec = wm_userpref_write_exec;
+}
- printf("Writing userprefs app-template: '%s' ", filepath);
- if (BKE_blendfile_userdef_write(filepath, op->reports) != 0) {
- printf("ok\n");
+static void rna_struct_update_when_changed(bContext *C,
+ Main *bmain,
+ PointerRNA *ptr_a,
+ PointerRNA *ptr_b)
+{
+ CollectionPropertyIterator iter;
+ PropertyRNA *iterprop = RNA_struct_iterator_property(ptr_a->type);
+ BLI_assert(ptr_a->type == ptr_b->type);
+ RNA_property_collection_begin(ptr_a, iterprop, &iter);
+ for (; iter.valid; RNA_property_collection_next(&iter)) {
+ PropertyRNA *prop = iter.ptr.data;
+ if (STREQ(RNA_property_identifier(prop), "rna_type")) {
+ continue;
+ }
+ switch (RNA_property_type(prop)) {
+ case PROP_POINTER: {
+ PointerRNA ptr_sub_a = RNA_property_pointer_get(ptr_a, prop);
+ PointerRNA ptr_sub_b = RNA_property_pointer_get(ptr_b, prop);
+ rna_struct_update_when_changed(C, bmain, &ptr_sub_a, &ptr_sub_b);
+ break;
}
- else {
- printf("fail\n");
- ok = false;
+ case PROP_COLLECTION:
+ /* Don't handle collections. */
+ break;
+ default: {
+ if (!RNA_property_equals(bmain, ptr_a, ptr_b, prop, RNA_EQ_STRICT)) {
+ RNA_property_update(C, ptr_b, prop);
+ }
}
}
- else {
- BKE_report(op->reports, RPT_ERROR, "Unable to create app-template userpref path");
- ok = false;
- }
}
+ RNA_property_collection_end(&iter);
+}
- return ok ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
+static void wm_userpref_update_when_changed(bContext *C,
+ Main *bmain,
+ UserDef *userdef_prev,
+ UserDef *userdef_curr)
+{
+ PointerRNA ptr_a, ptr_b;
+ RNA_pointer_create(NULL, &RNA_Preferences, userdef_prev, &ptr_a);
+ RNA_pointer_create(NULL, &RNA_Preferences, userdef_curr, &ptr_b);
+ const bool is_dirty = userdef_curr->runtime.is_dirty;
+
+ rna_struct_update_when_changed(C, bmain, &ptr_a, &ptr_b);
+
+#ifdef WITH_PYTHON
+ BPY_execute_string(C, (const char *[]){"addon_utils", NULL}, "addon_utils.reset_all()");
+#endif
+
+ WM_keyconfig_reload(C);
+ userdef_curr->runtime.is_dirty = is_dirty;
}
-void WM_OT_save_userpref(wmOperatorType *ot)
+static int wm_userpref_read_exec(bContext *C, wmOperator *op)
{
- ot->name = "Save Preferences";
- ot->idname = "WM_OT_save_userpref";
- ot->description = "Save preferences separately, overrides startup file preferences";
+ const bool use_data = false;
+ const bool use_userdef = true;
+ const bool use_factory_settings = STREQ(op->type->idname, "WM_OT_read_factory_userpref");
+
+ UserDef U_backup = U;
+
+ wm_homefile_read(C,
+ op->reports,
+ use_factory_settings,
+ false,
+ use_data,
+ use_userdef,
+ NULL,
+ WM_init_state_app_template_get(),
+ NULL);
+
+#define USERDEF_RESTORE(member) \
+ { \
+ U.member = U_backup.member; \
+ } \
+ ((void)0)
+
+ USERDEF_RESTORE(userpref);
+
+#undef USERDEF_RESTORE
+
+ Main *bmain = CTX_data_main(C);
+
+ wm_userpref_update_when_changed(C, bmain, &U_backup, &U);
+
+ if (use_factory_settings) {
+ U.runtime.is_dirty = true;
+ }
+
+ WM_event_add_notifier(C, NC_WINDOW, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void WM_OT_read_userpref(wmOperatorType *ot)
+{
+ ot->name = "Load Preferences";
+ ot->idname = "WM_OT_read_userpref";
+ ot->description = "Load last saved preferences";
ot->invoke = WM_operator_confirm;
- ot->exec = wm_userpref_write_exec;
+ ot->exec = wm_userpref_read_exec;
+}
+
+void WM_OT_read_factory_userpref(wmOperatorType *ot)
+{
+ ot->name = "Load Factory Preferences";
+ ot->idname = "WM_OT_read_factory_userpref";
+ ot->description = "Load default preferences";
+
+ ot->invoke = WM_operator_confirm;
+ ot->exec = wm_userpref_read_exec;
}
static int wm_history_file_read_exec(bContext *UNUSED(C), wmOperator *UNUSED(op))
@@ -1816,14 +1883,15 @@ static int wm_homefile_read_exec(bContext *C, wmOperator *op)
PropertyRNA *prop_app_template = RNA_struct_find_property(op->ptr, "app_template");
const bool use_splash = !use_factory_settings && RNA_boolean_get(op->ptr, "use_splash");
const bool use_empty_data = RNA_boolean_get(op->ptr, "use_empty");
+ const bool use_temporary_preferences = RNA_boolean_get(op->ptr, "use_temporary_preferences");
if (prop_app_template && RNA_property_is_set(op->ptr, prop_app_template)) {
RNA_property_string_get(op->ptr, prop_app_template, app_template_buf);
app_template = app_template_buf;
/* Always load preferences when switching templates with own preferences. */
- use_userdef = wm_app_template_has_userpref(app_template) ||
- wm_app_template_has_userpref(U.app_template);
+ use_userdef = BKE_appdir_app_template_has_userpref(app_template) ||
+ BKE_appdir_app_template_has_userpref(U.app_template);
/* Turn override off, since we're explicitly loading a different app-template. */
WM_init_state_app_template_set(NULL);
@@ -1833,10 +1901,12 @@ static int wm_homefile_read_exec(bContext *C, wmOperator *op)
app_template = WM_init_state_app_template_get();
}
+ bool use_data = true;
wm_homefile_read(C,
op->reports,
use_factory_settings,
use_empty_data,
+ use_data,
use_userdef,
filepath,
app_template,
@@ -1844,6 +1914,8 @@ static int wm_homefile_read_exec(bContext *C, wmOperator *op)
if (use_splash) {
WM_init_splash(C);
}
+ SET_FLAG_FROM_TEST(G.f, use_temporary_preferences, G_FLAG_USERPREF_NO_SAVE_ON_EXIT);
+
return OPERATOR_FINISHED;
}
@@ -1858,6 +1930,24 @@ static int wm_homefile_read_invoke(bContext *C, wmOperator *op, const wmEvent *U
}
}
+static void read_homefile_props(wmOperatorType *ot)
+{
+ PropertyRNA *prop;
+
+ prop = RNA_def_string(ot->srna, "app_template", "Template", sizeof(U.app_template), "", "");
+ RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
+
+ prop = RNA_def_boolean(ot->srna, "use_empty", false, "Empty", "");
+ RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
+
+ prop = RNA_def_boolean(ot->srna,
+ "use_temporary_preferences",
+ false,
+ "Temporary Preferences",
+ "Don't save preferences on exit");
+ RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
+}
+
void WM_OT_read_homefile(wmOperatorType *ot)
{
PropertyRNA *prop;
@@ -1877,23 +1967,17 @@ void WM_OT_read_homefile(wmOperatorType *ot)
ot->srna, "load_ui", true, "Load UI", "Load user interface setup from the .blend file");
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
- prop = RNA_def_boolean(ot->srna, "use_empty", false, "Empty", "");
- RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
-
/* So the splash can be kept open after loading a file (for templates). */
prop = RNA_def_boolean(ot->srna, "use_splash", false, "Splash", "");
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
- prop = RNA_def_string(ot->srna, "app_template", "Template", sizeof(U.app_template), "", "");
- RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
+ read_homefile_props(ot);
/* omit poll to run in background mode */
}
void WM_OT_read_factory_settings(wmOperatorType *ot)
{
- PropertyRNA *prop;
-
ot->name = "Load Factory Settings";
ot->idname = "WM_OT_read_factory_settings";
ot->description = "Load default file and preferences";
@@ -1901,12 +1985,7 @@ void WM_OT_read_factory_settings(wmOperatorType *ot)
ot->invoke = WM_operator_confirm;
ot->exec = wm_homefile_read_exec;
- prop = RNA_def_string(ot->srna, "app_template", "Template", sizeof(U.app_template), "", "");
- RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
-
- prop = RNA_def_boolean(ot->srna, "use_empty", false, "Empty", "");
- RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
-
+ read_homefile_props(ot);
/* omit poll to run in background mode */
}
@@ -1939,13 +2018,83 @@ static bool wm_file_read_opwrap(bContext *C,
return success;
}
-/* currently fits in a pointer */
-struct FileRuntime {
- bool is_untrusted;
+/* Generic operator state utilities
+ *********************************************/
+
+static void create_operator_state(wmOperatorType *ot, int first_state)
+{
+ PropertyRNA *prop = RNA_def_int(
+ ot->srna, "state", first_state, INT32_MIN, INT32_MAX, "State", "", INT32_MIN, INT32_MAX);
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ RNA_def_property_flag(prop, PROP_HIDDEN);
+}
+
+static int get_operator_state(wmOperator *op)
+{
+ return RNA_int_get(op->ptr, "state");
+}
+
+static void set_next_operator_state(wmOperator *op, int state)
+{
+ RNA_int_set(op->ptr, "state", state);
+}
+
+typedef struct OperatorDispatchTarget {
+ int state;
+ int (*run)(bContext *C, wmOperator *op);
+} OperatorDispatchTarget;
+
+static int operator_state_dispatch(bContext *C, wmOperator *op, OperatorDispatchTarget *targets)
+{
+ int state = get_operator_state(op);
+ for (int i = 0; targets[i].run; i++) {
+ OperatorDispatchTarget target = targets[i];
+ if (target.state == state) {
+ return target.run(C, op);
+ }
+ }
+ BLI_assert(false);
+ return OPERATOR_CANCELLED;
+}
+
+/* Open Mainfile operator
+ ********************************************/
+
+enum {
+ OPEN_MAINFILE_STATE_DISCARD_CHANGES,
+ OPEN_MAINFILE_STATE_SELECT_FILE_PATH,
+ OPEN_MAINFILE_STATE_OPEN,
};
-static int wm_open_mainfile_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+static int wm_open_mainfile_dispatch(bContext *C, wmOperator *op);
+
+static int wm_open_mainfile__discard_changes(bContext *C, wmOperator *op)
+{
+ if (RNA_boolean_get(op->ptr, "display_file_selector")) {
+ set_next_operator_state(op, OPEN_MAINFILE_STATE_SELECT_FILE_PATH);
+ }
+ else {
+ set_next_operator_state(op, OPEN_MAINFILE_STATE_OPEN);
+ }
+
+ wmWindowManager *wm = CTX_wm_manager(C);
+ if (U.uiflag & USER_SAVE_PROMPT && !wm->file_saved) {
+ return WM_operator_confirm_message_ex(C,
+ op,
+ "Warning",
+ ICON_INFO,
+ "Changes in current file will be lost. Continue?",
+ WM_OP_INVOKE_DEFAULT);
+ }
+ else {
+ return wm_open_mainfile_dispatch(C, op);
+ }
+}
+
+static int wm_open_mainfile__select_file_path(bContext *C, wmOperator *op)
{
+ set_next_operator_state(op, OPEN_MAINFILE_STATE_OPEN);
+
Main *bmain = CTX_data_main(C);
const char *openname = BKE_main_blendfile_path(bmain);
@@ -1973,7 +2122,7 @@ static int wm_open_mainfile_invoke(bContext *C, wmOperator *op, const wmEvent *U
return OPERATOR_RUNNING_MODAL;
}
-static int wm_open_mainfile_exec(bContext *C, wmOperator *op)
+static int wm_open_mainfile__open(bContext *C, wmOperator *op)
{
char filepath[FILE_MAX];
bool success;
@@ -2011,6 +2160,33 @@ static int wm_open_mainfile_exec(bContext *C, wmOperator *op)
}
}
+static OperatorDispatchTarget wm_open_mainfile_dispatch_targets[] = {
+ {OPEN_MAINFILE_STATE_DISCARD_CHANGES, wm_open_mainfile__discard_changes},
+ {OPEN_MAINFILE_STATE_SELECT_FILE_PATH, wm_open_mainfile__select_file_path},
+ {OPEN_MAINFILE_STATE_OPEN, wm_open_mainfile__open},
+ {0, NULL},
+};
+
+static int wm_open_mainfile_dispatch(bContext *C, wmOperator *op)
+{
+ return operator_state_dispatch(C, op, wm_open_mainfile_dispatch_targets);
+}
+
+static int wm_open_mainfile_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ return wm_open_mainfile_dispatch(C, op);
+}
+
+static int wm_open_mainfile_exec(bContext *C, wmOperator *op)
+{
+ return wm_open_mainfile__open(C, op);
+}
+
+/* currently fits in a pointer */
+struct FileRuntime {
+ bool is_untrusted;
+};
+
static bool wm_open_mainfile_check(bContext *UNUSED(C), wmOperator *op)
{
struct FileRuntime *file_info = (struct FileRuntime *)&op->customdata;
@@ -2091,6 +2267,12 @@ void WM_OT_open_mainfile(wmOperatorType *ot)
"Trusted Source",
"Allow .blend file to execute scripts automatically, default available from "
"system preferences");
+
+ PropertyRNA *prop = RNA_def_boolean(
+ ot->srna, "display_file_selector", true, "Display File Selector", "");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+
+ create_operator_state(ot, OPEN_MAINFILE_STATE_DISCARD_CHANGES);
}
/** \} */
@@ -2629,7 +2811,7 @@ void wm_test_autorun_warning(bContext *C)
if (win) {
wmWindow *prevwin = CTX_wm_window(C);
CTX_wm_window_set(C, win);
- UI_popup_block_invoke(C, block_create_autorun_warning, NULL);
+ UI_popup_block_invoke(C, block_create_autorun_warning, NULL, NULL);
CTX_wm_window_set(C, prevwin);
}
}
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index 5529aec1aa5..04a3115992f 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -52,6 +52,7 @@
#include "BLO_writefile.h"
#include "BLO_undofile.h"
+#include "BKE_blendfile.h"
#include "BKE_blender.h"
#include "BKE_blender_undo.h"
#include "BKE_context.h"
@@ -64,8 +65,6 @@
#include "BKE_node.h"
#include "BKE_report.h"
#include "BKE_screen.h"
-#include "BKE_scene.h"
-#include "BKE_sound.h"
#include "BKE_keyconfig.h"
#include "BKE_addon.h"
@@ -124,7 +123,6 @@
#include "COM_compositor.h"
#include "DEG_depsgraph.h"
-#include "DEG_depsgraph_query.h"
#include "DRW_engine.h"
@@ -197,30 +195,6 @@ void WM_init_opengl(Main *bmain)
opengl_is_init = true;
}
-static void sound_jack_sync_callback(Main *bmain, int mode, float time)
-{
- /* Ugly: Blender doesn't like it when the animation is played back during rendering. */
- if (G.is_rendering) {
- return;
- }
-
- wmWindowManager *wm = bmain->wm.first;
-
- for (wmWindow *window = wm->windows.first; window != NULL; window = window->next) {
- Scene *scene = WM_window_get_active_scene(window);
- if ((scene->audio.flag & AUDIO_SYNC) == 0) {
- continue;
- }
- ViewLayer *view_layer = WM_window_get_active_view_layer(window);
- Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene, view_layer, false);
- if (depsgraph == NULL) {
- continue;
- }
- Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
- BKE_sound_jack_scene_update(scene_eval, mode, time);
- }
-}
-
/* only called once, for startup */
void WM_init(bContext *C, int argc, const char **argv)
{
@@ -228,7 +202,6 @@ void WM_init(bContext *C, int argc, const char **argv)
if (!G.background) {
wm_ghost_init(C); /* note: it assigns C to ghost! */
wm_init_cursor_data();
- BKE_sound_jack_sync_callback_set(sound_jack_sync_callback);
}
GHOST_CreateSystemPaths();
@@ -282,11 +255,15 @@ void WM_init(bContext *C, int argc, const char **argv)
/* get the default database, plus a wm */
bool is_factory_startup = true;
+ const bool use_data = true;
+ const bool use_userdef = true;
+
wm_homefile_read(C,
NULL,
G.factory_startup,
false,
- true,
+ use_data,
+ use_userdef,
NULL,
WM_init_state_app_template_get(),
&is_factory_startup);
@@ -497,6 +474,14 @@ void WM_exit_ext(bContext *C, const bool do_python)
WM_event_remove_handlers(C, &win->modalhandlers);
ED_screen_exit(C, win, WM_window_get_active_screen(win));
}
+
+ if (!G.background) {
+ if ((U.pref_flag & USER_PREF_FLAG_SAVE) && ((G.f & G_FLAG_USERPREF_NO_SAVE_ON_EXIT) == 0)) {
+ if (U.runtime.is_dirty) {
+ BKE_blendfile_userdef_write_all(NULL);
+ }
+ }
+ }
}
BLI_timer_free();
diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c
index bae9a5de1e6..4bcbce028b1 100644
--- a/source/blender/windowmanager/intern/wm_keymap.c
+++ b/source/blender/windowmanager/intern/wm_keymap.c
@@ -310,6 +310,7 @@ bool WM_keyconfig_remove(wmWindowManager *wm, wmKeyConfig *keyconf)
if (BLI_findindex(&wm->keyconfigs, keyconf) != -1) {
if (STREQLEN(U.keyconfigstr, keyconf->idname, sizeof(U.keyconfigstr))) {
BLI_strncpy(U.keyconfigstr, wm->defaultconf->idname, sizeof(U.keyconfigstr));
+ U.runtime.is_dirty = true;
WM_keyconfig_update_tag(NULL, NULL);
}
@@ -360,6 +361,9 @@ 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) {
+ U.runtime.is_dirty = true;
+ }
WM_keyconfig_update_tag(NULL, NULL);
WM_keyconfig_update(wm);
@@ -1120,7 +1124,8 @@ const char *WM_key_event_string(const short type, const bool compact)
if (platform == MACOS) {
icon_glyph = "\xe2\x87\xa7";
}
- return key_event_icon_or_text(font_id, IFACE_("Shift"), icon_glyph);
+ return key_event_icon_or_text(
+ font_id, CTX_IFACE_(BLT_I18NCONTEXT_ID_WINDOWMANAGER, "Shift"), icon_glyph);
}
case LEFTCTRLKEY:
case RIGHTCTRLKEY:
diff --git a/source/blender/windowmanager/intern/wm_operator_props.c b/source/blender/windowmanager/intern/wm_operator_props.c
index ece57f5a63b..3ad7247d993 100644
--- a/source/blender/windowmanager/intern/wm_operator_props.c
+++ b/source/blender/windowmanager/intern/wm_operator_props.c
@@ -94,7 +94,9 @@ void WM_operator_properties_filesel(wmOperatorType *ot,
}
if (flag & WM_FILESEL_FILES) {
- RNA_def_collection_runtime(ot->srna, "files", &RNA_OperatorFileListElement, "Files", "");
+ prop = RNA_def_collection_runtime(
+ ot->srna, "files", &RNA_OperatorFileListElement, "Files", "");
+ RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
}
if (action == FILE_SAVE) {
@@ -344,11 +346,11 @@ void WM_operator_properties_gesture_box(wmOperatorType *ot)
void WM_operator_properties_select_operation(wmOperatorType *ot)
{
static const EnumPropertyItem select_mode_items[] = {
- {SEL_OP_SET, "SET", 0, "New", ""},
- {SEL_OP_ADD, "ADD", 0, "Add", ""},
- {SEL_OP_SUB, "SUB", 0, "Subtract", ""},
- {SEL_OP_XOR, "XOR", 0, "Difference", ""},
- {SEL_OP_AND, "AND", 0, "Intersect", ""},
+ {SEL_OP_SET, "SET", ICON_SELECT_SET, "Set", "Set a new selection"},
+ {SEL_OP_ADD, "ADD", ICON_SELECT_EXTEND, "Extend", "Extend existing selection"},
+ {SEL_OP_SUB, "SUB", ICON_SELECT_SUBTRACT, "Subtract", "Subtract existing selection"},
+ {SEL_OP_XOR, "XOR", ICON_SELECT_DIFFERENCE, "Difference", "Inverts existing selection"},
+ {SEL_OP_AND, "AND", ICON_SELECT_INTERSECT, "Intersect", "Intersect existing selection"},
{0, NULL, 0, NULL, NULL},
};
PropertyRNA *prop = RNA_def_enum(ot->srna, "mode", select_mode_items, SEL_OP_SET, "Mode", "");
@@ -359,9 +361,9 @@ void WM_operator_properties_select_operation(wmOperatorType *ot)
void WM_operator_properties_select_operation_simple(wmOperatorType *ot)
{
static const EnumPropertyItem select_mode_items[] = {
- {SEL_OP_SET, "SET", 0, "New", ""},
- {SEL_OP_ADD, "ADD", 0, "Add", ""},
- {SEL_OP_SUB, "SUB", 0, "Subtract", ""},
+ {SEL_OP_SET, "SET", ICON_SELECT_SET, "Set", "Set a new selection"},
+ {SEL_OP_ADD, "ADD", ICON_SELECT_EXTEND, "Extend", "Extend existing selection"},
+ {SEL_OP_SUB, "SUB", ICON_SELECT_SUBTRACT, "Subtract", "Subtract existing selection"},
{0, NULL, 0, NULL, NULL},
};
PropertyRNA *prop = RNA_def_enum(ot->srna, "mode", select_mode_items, SEL_OP_SET, "Mode", "");
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index ec803c9bba7..8445f27ceba 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -870,7 +870,7 @@ int WM_enum_search_invoke_previews(bContext *C, wmOperator *op, short prv_cols,
search_menu.prv_cols = prv_cols;
search_menu.prv_rows = prv_rows;
- UI_popup_block_invoke(C, wm_enum_search_menu, &search_menu);
+ UI_popup_block_invoke(C, wm_enum_search_menu, &search_menu, NULL);
return OPERATOR_INTERFACE;
}
@@ -879,13 +879,17 @@ int WM_enum_search_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(eve
{
static struct EnumSearchMenu search_menu;
search_menu.op = op;
- UI_popup_block_invoke(C, wm_enum_search_menu, &search_menu);
+ UI_popup_block_invoke(C, wm_enum_search_menu, &search_menu, NULL);
return OPERATOR_INTERFACE;
}
/* Can't be used as an invoke directly, needs message arg (can be NULL) */
-int WM_operator_confirm_message_ex(
- bContext *C, wmOperator *op, const char *title, const int icon, const char *message)
+int WM_operator_confirm_message_ex(bContext *C,
+ wmOperator *op,
+ const char *title,
+ const int icon,
+ const char *message,
+ const short opcontext)
{
uiPopupMenu *pup;
uiLayout *layout;
@@ -900,8 +904,7 @@ int WM_operator_confirm_message_ex(
pup = UI_popup_menu_begin(C, title, icon);
layout = UI_popup_menu_layout(pup);
- uiItemFullO_ptr(
- layout, op->type, message, ICON_NONE, properties, WM_OP_EXEC_REGION_WIN, 0, NULL);
+ uiItemFullO_ptr(layout, op->type, message, ICON_NONE, properties, opcontext, 0, NULL);
UI_popup_menu_end(C, pup);
return OPERATOR_INTERFACE;
@@ -909,7 +912,8 @@ int WM_operator_confirm_message_ex(
int WM_operator_confirm_message(bContext *C, wmOperator *op, const char *message)
{
- return WM_operator_confirm_message_ex(C, op, IFACE_("OK?"), ICON_QUESTION, message);
+ return WM_operator_confirm_message_ex(
+ C, op, IFACE_("OK?"), ICON_QUESTION, message, WM_OP_EXEC_REGION_WIN);
}
int WM_operator_confirm(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
@@ -1398,7 +1402,7 @@ int WM_operator_redo_popup(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- UI_popup_block_invoke(C, wm_block_create_redo, op);
+ UI_popup_block_invoke(C, wm_block_create_redo, op, NULL);
return OPERATOR_CANCELLED;
}
@@ -1710,7 +1714,7 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar
static int wm_splash_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
{
- UI_popup_block_invoke(C, wm_block_create_splash, NULL);
+ UI_popup_block_invoke(C, wm_block_create_splash, NULL, NULL);
return OPERATOR_FINISHED;
}
@@ -1816,7 +1820,7 @@ static int wm_search_menu_invoke(bContext *C, wmOperator *UNUSED(op), const wmEv
data.size[0] = UI_searchbox_size_x() * 2;
data.size[1] = UI_searchbox_size_y();
- UI_popup_block_invoke(C, wm_block_search_menu, &data);
+ UI_popup_block_invoke(C, wm_block_search_menu, &data, NULL);
return OPERATOR_INTERFACE;
}
@@ -3504,6 +3508,8 @@ void wm_operatortypes_register(void)
WM_operatortype_append(WM_OT_read_factory_settings);
WM_operatortype_append(WM_OT_save_homefile);
WM_operatortype_append(WM_OT_save_userpref);
+ WM_operatortype_append(WM_OT_read_userpref);
+ WM_operatortype_append(WM_OT_read_factory_userpref);
WM_operatortype_append(WM_OT_userpref_autoexec_path_add);
WM_operatortype_append(WM_OT_userpref_autoexec_path_remove);
WM_operatortype_append(WM_OT_window_fullscreen_toggle);
diff --git a/source/blender/windowmanager/intern/wm_toolsystem.c b/source/blender/windowmanager/intern/wm_toolsystem.c
index f429415bee9..92ef235722b 100644
--- a/source/blender/windowmanager/intern/wm_toolsystem.c
+++ b/source/blender/windowmanager/intern/wm_toolsystem.c
@@ -574,6 +574,20 @@ void WM_toolsystem_refresh_active(bContext *C)
}
}
}
+
+ BKE_workspace_id_tag_all_visible(bmain, LIB_TAG_DOIT);
+
+ LISTBASE_FOREACH (WorkSpace *, workspace, &bmain->workspaces) {
+ if (workspace->id.tag & LIB_TAG_DOIT) {
+ workspace->id.tag &= ~LIB_TAG_DOIT;
+ /* Refresh to ensure data is initialized.
+ * This is needed because undo can load a state which no longer has the underlying DNA data
+ * needed for the tool (un-initialized paint-slots for eg), see: T64339. */
+ for (bToolRef *tref = workspace->tools.first; tref; tref = tref->next) {
+ toolsystem_refresh_ref(C, workspace, tref);
+ }
+ }
+ }
}
void WM_toolsystem_refresh_screen_area(WorkSpace *workspace, ViewLayer *view_layer, ScrArea *sa)
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index e98067d78cc..409befd8c47 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -512,7 +512,7 @@ static void wm_confirm_quit(bContext *C)
if (GHOST_SupportsNativeDialogs() == 0) {
if (!UI_popup_block_name_exists(C, "confirm_quit_popup")) {
- UI_popup_block_invoke(C, block_create_confirm_quit, NULL);
+ UI_popup_block_invoke(C, block_create_confirm_quit, NULL, NULL);
}
}
else if (GHOST_confirmQuit(win->ghostwin)) {
@@ -672,6 +672,7 @@ void WM_window_set_dpi(wmWindow *win)
U.dpi = dpi / pixelsize;
U.virtual_pixel = (pixelsize == 1) ? VIRTUAL_PIXEL_NATIVE : VIRTUAL_PIXEL_DOUBLE;
U.dpi_fac = ((U.pixelsize * (float)U.dpi) / 72.0f);
+ U.inv_dpi_fac = 1.0f / U.dpi_fac;
/* Set user preferences globals for drawing, and for forward compatibility. */
U.widget_unit = (U.pixelsize * U.dpi * 20 + 36) / 72;
diff --git a/source/blender/windowmanager/wm_files.h b/source/blender/windowmanager/wm_files.h
index c60df27e24b..24209504a07 100644
--- a/source/blender/windowmanager/wm_files.h
+++ b/source/blender/windowmanager/wm_files.h
@@ -33,6 +33,7 @@ void wm_homefile_read(struct bContext *C,
struct ReportList *reports,
bool use_factory_settings,
bool use_empty_data,
+ bool use_data,
bool use_userdef,
const char *filepath_startup_override,
const char *app_template_override,
@@ -43,6 +44,8 @@ void WM_OT_save_homefile(struct wmOperatorType *ot);
void WM_OT_userpref_autoexec_path_add(struct wmOperatorType *ot);
void WM_OT_userpref_autoexec_path_remove(struct wmOperatorType *ot);
void WM_OT_save_userpref(struct wmOperatorType *ot);
+void WM_OT_read_userpref(struct wmOperatorType *ot);
+void WM_OT_read_factory_userpref(struct wmOperatorType *ot);
void WM_OT_read_history(struct wmOperatorType *ot);
void WM_OT_read_homefile(struct wmOperatorType *ot);
void WM_OT_read_factory_settings(struct wmOperatorType *ot);