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
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/blender/CMakeLists.txt5
-rw-r--r--source/blender/alembic/intern/abc_mesh.cc2
-rw-r--r--source/blender/blenfont/intern/blf.c2
-rw-r--r--source/blender/blenkernel/BKE_DerivedMesh.h4
-rw-r--r--source/blender/blenkernel/BKE_addon.h13
-rw-r--r--source/blender/blenkernel/BKE_brush.h5
-rw-r--r--source/blender/blenkernel/BKE_cloth.h4
-rw-r--r--source/blender/blenkernel/BKE_collection.h3
-rw-r--r--source/blender/blenkernel/BKE_context.h6
-rw-r--r--source/blender/blenkernel/BKE_layer.h19
-rw-r--r--source/blender/blenkernel/BKE_mball.h6
-rw-r--r--source/blender/blenkernel/BKE_modifier.h3
-rw-r--r--source/blender/blenkernel/BKE_multires.h33
-rw-r--r--source/blender/blenkernel/BKE_node.h1
-rw-r--r--source/blender/blenkernel/BKE_object.h21
-rw-r--r--source/blender/blenkernel/BKE_paint.h21
-rw-r--r--source/blender/blenkernel/BKE_particle.h7
-rw-r--r--source/blender/blenkernel/BKE_pointcache.h4
-rw-r--r--source/blender/blenkernel/BKE_shrinkwrap.h7
-rw-r--r--source/blender/blenkernel/BKE_workspace.h27
-rw-r--r--source/blender/blenkernel/CMakeLists.txt1
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c44
-rw-r--r--source/blender/blenkernel/intern/addon.c47
-rw-r--r--source/blender/blenkernel/intern/armature_update.c26
-rw-r--r--source/blender/blenkernel/intern/blender.c7
-rw-r--r--source/blender/blenkernel/intern/boids.c2
-rw-r--r--source/blender/blenkernel/intern/bpath.c4
-rw-r--r--source/blender/blenkernel/intern/brush.c4
-rw-r--r--source/blender/blenkernel/intern/bullet.c2
-rw-r--r--source/blender/blenkernel/intern/bvhutils.c12
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c9
-rw-r--r--source/blender/blenkernel/intern/cloth.c6
-rw-r--r--source/blender/blenkernel/intern/collection.c69
-rw-r--r--source/blender/blenkernel/intern/collision.c2
-rw-r--r--source/blender/blenkernel/intern/colorband.c2
-rw-r--r--source/blender/blenkernel/intern/context.c25
-rw-r--r--source/blender/blenkernel/intern/curve_decimate.c2
-rw-r--r--source/blender/blenkernel/intern/dynamicpaint.c4
-rw-r--r--source/blender/blenkernel/intern/editderivedmesh.c2
-rw-r--r--source/blender/blenkernel/intern/effect.c5
-rw-r--r--source/blender/blenkernel/intern/fluidsim.c4
-rw-r--r--source/blender/blenkernel/intern/font.c9
-rw-r--r--source/blender/blenkernel/intern/group.c2
-rw-r--r--source/blender/blenkernel/intern/image.c16
-rw-r--r--source/blender/blenkernel/intern/layer.c234
-rw-r--r--source/blender/blenkernel/intern/library.c2
-rw-r--r--source/blender/blenkernel/intern/library_query.c6
-rw-r--r--source/blender/blenkernel/intern/mball.c6
-rw-r--r--source/blender/blenkernel/intern/mesh.c2
-rw-r--r--source/blender/blenkernel/intern/mesh_evaluate.c31
-rw-r--r--source/blender/blenkernel/intern/mesh_remap.c2
-rw-r--r--source/blender/blenkernel/intern/mesh_validate.c2
-rw-r--r--source/blender/blenkernel/intern/modifier.c8
-rw-r--r--source/blender/blenkernel/intern/movieclip.c20
-rw-r--r--source/blender/blenkernel/intern/multires.c132
-rw-r--r--source/blender/blenkernel/intern/node.c4
-rw-r--r--source/blender/blenkernel/intern/object.c60
-rw-r--r--source/blender/blenkernel/intern/object_deform.c6
-rw-r--r--source/blender/blenkernel/intern/object_dupli.c7
-rw-r--r--source/blender/blenkernel/intern/object_update.c4
-rw-r--r--source/blender/blenkernel/intern/ocean.c8
-rw-r--r--source/blender/blenkernel/intern/outliner_treehash.c4
-rw-r--r--source/blender/blenkernel/intern/paint.c151
-rw-r--r--source/blender/blenkernel/intern/particle.c107
-rw-r--r--source/blender/blenkernel/intern/particle_child.c328
-rw-r--r--source/blender/blenkernel/intern/particle_distribute.c2
-rw-r--r--source/blender/blenkernel/intern/particle_system.c23
-rw-r--r--source/blender/blenkernel/intern/pbvh.c6
-rw-r--r--source/blender/blenkernel/intern/pbvh_bmesh.c32
-rw-r--r--source/blender/blenkernel/intern/pointcache.c2
-rw-r--r--source/blender/blenkernel/intern/rigidbody.c2
-rw-r--r--source/blender/blenkernel/intern/scene.c19
-rw-r--r--source/blender/blenkernel/intern/screen.c2
-rw-r--r--source/blender/blenkernel/intern/shrinkwrap.c10
-rw-r--r--source/blender/blenkernel/intern/smoke.c6
-rw-r--r--source/blender/blenkernel/intern/softbody.c12
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c27
-rw-r--r--source/blender/blenkernel/intern/texture.c1
-rw-r--r--source/blender/blenkernel/intern/tracking_util.c4
-rw-r--r--source/blender/blenkernel/intern/workspace.c52
-rw-r--r--source/blender/blenkernel/particle_private.h54
-rw-r--r--source/blender/blenlib/BLI_array.h2
-rw-r--r--source/blender/blenlib/BLI_boxpack_2d.h (renamed from source/blender/blenlib/BLI_boxpack2d.h)10
-rw-r--r--source/blender/blenlib/BLI_buffer.h2
-rw-r--r--source/blender/blenlib/BLI_convexhull_2d.h (renamed from source/blender/blenlib/BLI_convexhull2d.h)8
-rw-r--r--source/blender/blenlib/BLI_dial_2d.h (renamed from source/blender/blenlib/BLI_dial.h)8
-rw-r--r--source/blender/blenlib/BLI_edgehash.h4
-rw-r--r--source/blender/blenlib/BLI_fileops.h1
-rw-r--r--source/blender/blenlib/BLI_ghash.h247
-rw-r--r--source/blender/blenlib/BLI_gsqueue.h4
-rw-r--r--source/blender/blenlib/BLI_hash.h5
-rw-r--r--source/blender/blenlib/BLI_heap.h4
-rw-r--r--source/blender/blenlib/BLI_jitter_2d.h (renamed from source/blender/blenlib/BLI_jitter.h)8
-rw-r--r--source/blender/blenlib/BLI_kdopbvh.h2
-rw-r--r--source/blender/blenlib/BLI_lasso_2d.h (renamed from source/blender/blenlib/BLI_lasso.h)8
-rw-r--r--source/blender/blenlib/BLI_linklist_stack.h2
-rw-r--r--source/blender/blenlib/BLI_listbase.h15
-rw-r--r--source/blender/blenlib/BLI_math_base.h4
-rw-r--r--source/blender/blenlib/BLI_math_geom.h1
-rw-r--r--source/blender/blenlib/BLI_mempool.h2
-rw-r--r--source/blender/blenlib/BLI_polyfill_2d.h (renamed from source/blender/blenlib/BLI_polyfill2d.h)6
-rw-r--r--source/blender/blenlib/BLI_polyfill_2d_beautify.h (renamed from source/blender/blenlib/BLI_polyfill2d_beautify.h)0
-rw-r--r--source/blender/blenlib/BLI_smallhash.h2
-rw-r--r--source/blender/blenlib/BLI_threads.h24
-rw-r--r--source/blender/blenlib/BLI_voronoi_2d.h (renamed from source/blender/blenlib/BLI_voronoi.h)2
-rw-r--r--source/blender/blenlib/CMakeLists.txt33
-rw-r--r--source/blender/blenlib/intern/BLI_dial_2d.c (renamed from source/blender/blenlib/intern/BLI_dial.c)6
-rw-r--r--source/blender/blenlib/intern/BLI_ghash.c267
-rw-r--r--source/blender/blenlib/intern/BLI_ghash_utils.c288
-rw-r--r--source/blender/blenlib/intern/BLI_heap.c6
-rw-r--r--source/blender/blenlib/intern/BLI_kdopbvh.c2
-rw-r--r--source/blender/blenlib/intern/BLI_mempool.c2
-rw-r--r--source/blender/blenlib/intern/array_store.c6
-rw-r--r--source/blender/blenlib/intern/astar.c2
-rw-r--r--source/blender/blenlib/intern/boxpack_2d.c (renamed from source/blender/blenlib/intern/boxpack2d.c)2
-rw-r--r--source/blender/blenlib/intern/convexhull_2d.c (renamed from source/blender/blenlib/intern/convexhull2d.c)4
-rw-r--r--source/blender/blenlib/intern/edgehash.c10
-rw-r--r--source/blender/blenlib/intern/gsqueue.c4
-rw-r--r--source/blender/blenlib/intern/jitter_2d.c (renamed from source/blender/blenlib/intern/jitter.c)2
-rw-r--r--source/blender/blenlib/intern/lasso_2d.c (renamed from source/blender/blenlib/intern/lasso.c)4
-rw-r--r--source/blender/blenlib/intern/math_base_inline.c21
-rw-r--r--source/blender/blenlib/intern/math_geom.c12
-rw-r--r--source/blender/blenlib/intern/math_vector.c2
-rw-r--r--source/blender/blenlib/intern/polyfill_2d.c (renamed from source/blender/blenlib/intern/polyfill2d.c)4
-rw-r--r--source/blender/blenlib/intern/polyfill_2d_beautify.c (renamed from source/blender/blenlib/intern/polyfill2d_beautify.c)4
-rw-r--r--source/blender/blenlib/intern/smallhash.c2
-rw-r--r--source/blender/blenlib/intern/task.c6
-rw-r--r--source/blender/blenlib/intern/threads.c34
-rw-r--r--source/blender/blenlib/intern/voronoi_2d.c (renamed from source/blender/blenlib/intern/voronoi.c)10
-rw-r--r--source/blender/blenloader/intern/readfile.c75
-rw-r--r--source/blender/blenloader/intern/versioning_250.c9
-rw-r--r--source/blender/blenloader/intern/versioning_260.c2
-rw-r--r--source/blender/blenloader/intern/versioning_270.c2
-rw-r--r--source/blender/blenloader/intern/versioning_280.c28
-rw-r--r--source/blender/blenloader/intern/versioning_legacy.c2
-rw-r--r--source/blender/blenloader/intern/writefile.c37
-rw-r--r--source/blender/blentranslation/msgfmt/msgfmt.c2
-rw-r--r--source/blender/bmesh/intern/bmesh_core.c7
-rw-r--r--source/blender/bmesh/intern/bmesh_iterators.c4
-rw-r--r--source/blender/bmesh/intern/bmesh_log.c4
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh.c5
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh_conv.c8
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh_conv.h3
-rw-r--r--source/blender/bmesh/intern/bmesh_opdefines.c1
-rw-r--r--source/blender/bmesh/intern/bmesh_operators.c2
-rw-r--r--source/blender/bmesh/intern/bmesh_polygon.c15
-rw-r--r--source/blender/bmesh/operators/bmo_connect_concave.c4
-rw-r--r--source/blender/bmesh/operators/bmo_connect_pair.c4
-rw-r--r--source/blender/bmesh/operators/bmo_dissolve.c2
-rw-r--r--source/blender/bmesh/operators/bmo_edgenet.c2
-rw-r--r--source/blender/bmesh/operators/bmo_hull.c2
-rw-r--r--source/blender/bmesh/operators/bmo_mesh_conv.c11
-rw-r--r--source/blender/bmesh/operators/bmo_rotate_edges.c2
-rw-r--r--source/blender/bmesh/operators/bmo_subdivide.c10
-rw-r--r--source/blender/bmesh/operators/bmo_subdivide_edgering.c4
-rw-r--r--source/blender/bmesh/operators/bmo_triangulate.c2
-rw-r--r--source/blender/bmesh/tools/bmesh_beautify.c4
-rw-r--r--source/blender/bmesh/tools/bmesh_bevel.c282
-rw-r--r--source/blender/bmesh/tools/bmesh_decimate_collapse.c8
-rw-r--r--source/blender/bmesh/tools/bmesh_edgenet.c4
-rw-r--r--source/blender/bmesh/tools/bmesh_intersect.c6
-rw-r--r--source/blender/bmesh/tools/bmesh_path.c6
-rw-r--r--source/blender/bmesh/tools/bmesh_region_match.c14
-rw-r--r--source/blender/bmesh/tools/bmesh_separate.c2
-rw-r--r--source/blender/bmesh/tools/bmesh_triangulate.c4
-rw-r--r--source/blender/collada/AnimationExporter.cpp7
-rw-r--r--source/blender/collada/AnimationImporter.cpp15
-rw-r--r--source/blender/collada/DocumentExporter.cpp11
-rw-r--r--source/blender/collada/ErrorHandler.cpp15
-rw-r--r--source/blender/collada/SkinInfo.cpp2
-rw-r--r--source/blender/collada/collada_utils.cpp37
-rw-r--r--source/blender/collada/collada_utils.h2
-rw-r--r--source/blender/compositor/intern/COM_WorkScheduler.cpp12
-rw-r--r--source/blender/compositor/operations/COM_CompositorOperation.cpp4
-rw-r--r--source/blender/compositor/operations/COM_KeyingScreenOperation.h2
-rw-r--r--source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cpp2
-rw-r--r--source/blender/compositor/operations/COM_ViewerOperation.cpp6
-rw-r--r--source/blender/depsgraph/DEG_depsgraph.h15
-rw-r--r--source/blender/depsgraph/DEG_depsgraph_query.h1
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.cc46
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes_layer_collection.cc2
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc8
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc8
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.cc197
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.h16
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations_layer_collection.cc2
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc45
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc6
-rw-r--r--source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc6
-rw-r--r--source/blender/depsgraph/intern/depsgraph.cc6
-rw-r--r--source/blender/depsgraph/intern/depsgraph_build.cc8
-rw-r--r--source/blender/depsgraph/intern/depsgraph_eval.cc15
-rw-r--r--source/blender/depsgraph/intern/depsgraph_query_iter.cc19
-rw-r--r--source/blender/depsgraph/intern/depsgraph_tag.cc72
-rw-r--r--source/blender/depsgraph/intern/depsgraph_type_defines.cc2
-rw-r--r--source/blender/depsgraph/intern/depsgraph_types.h3
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval.cc2
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc34
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_flush.cc4
-rw-r--r--source/blender/depsgraph/intern/nodes/deg_node_component.cc6
-rw-r--r--source/blender/draw/CMakeLists.txt2
-rw-r--r--source/blender/draw/DRW_engine.h14
-rw-r--r--source/blender/draw/engines/clay/clay_engine.c49
-rw-r--r--source/blender/draw/engines/clay/shaders/clay_frag.glsl7
-rw-r--r--source/blender/draw/engines/eevee/eevee_bloom.c20
-rw-r--r--source/blender/draw/engines/eevee/eevee_data.c4
-rw-r--r--source/blender/draw/engines/eevee/eevee_depth_of_field.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_effects.c13
-rw-r--r--source/blender/draw/engines/eevee/eevee_engine.c29
-rw-r--r--source/blender/draw/engines/eevee/eevee_lightprobes.c92
-rw-r--r--source/blender/draw/engines/eevee/eevee_lights.c10
-rw-r--r--source/blender/draw/engines/eevee/eevee_materials.c103
-rw-r--r--source/blender/draw/engines/eevee/eevee_mist.c135
-rw-r--r--source/blender/draw/engines/eevee/eevee_motion_blur.c1
-rw-r--r--source/blender/draw/engines/eevee/eevee_occlusion.c62
-rw-r--r--source/blender/draw/engines/eevee/eevee_private.h36
-rw-r--r--source/blender/draw/engines/eevee/eevee_render.c352
-rw-r--r--source/blender/draw/engines/eevee/eevee_subsurface.c122
-rw-r--r--source/blender/draw/engines/eevee/eevee_temporal_sampling.c104
-rw-r--r--source/blender/draw/engines/eevee/eevee_volumes.c26
-rw-r--r--source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl146
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_gtao_frag.glsl3
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_minmaxz_frag.glsl9
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_mist_frag.glsl31
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl16
-rw-r--r--source/blender/draw/intern/DRW_render.h44
-rw-r--r--source/blender/draw/intern/draw_armature.c4
-rw-r--r--source/blender/draw/intern/draw_common.c178
-rw-r--r--source/blender/draw/intern/draw_common.h6
-rw-r--r--source/blender/draw/intern/draw_instance_data.c131
-rw-r--r--source/blender/draw/intern/draw_instance_data.h16
-rw-r--r--source/blender/draw/intern/draw_manager.c617
-rw-r--r--source/blender/draw/intern/draw_view.c12
-rw-r--r--source/blender/draw/modes/edit_curve_mode.c3
-rw-r--r--source/blender/draw/modes/edit_lattice_mode.c4
-rw-r--r--source/blender/draw/modes/edit_mesh_mode.c3
-rw-r--r--source/blender/draw/modes/edit_metaball_mode.c16
-rw-r--r--source/blender/draw/modes/edit_text_mode.c4
-rw-r--r--source/blender/draw/modes/object_mode.c79
-rw-r--r--source/blender/draw/modes/particle_mode.c4
-rw-r--r--source/blender/draw/modes/pose_mode.c8
-rw-r--r--source/blender/editors/animation/anim_channels_defines.c2
-rw-r--r--source/blender/editors/animation/anim_channels_edit.c61
-rw-r--r--source/blender/editors/animation/anim_draw.c2
-rw-r--r--source/blender/editors/animation/anim_markers.c9
-rw-r--r--source/blender/editors/animation/keyframes_edit.c2
-rw-r--r--source/blender/editors/animation/keyframing.c13
-rw-r--r--source/blender/editors/armature/armature_edit.c12
-rw-r--r--source/blender/editors/armature/armature_intern.h2
-rw-r--r--source/blender/editors/armature/armature_relations.c5
-rw-r--r--source/blender/editors/armature/armature_select.c9
-rw-r--r--source/blender/editors/armature/armature_skinning.c41
-rw-r--r--source/blender/editors/armature/editarmature_sketch.c4
-rw-r--r--source/blender/editors/armature/meshlaplacian.c12
-rw-r--r--source/blender/editors/armature/meshlaplacian.h10
-rw-r--r--source/blender/editors/armature/pose_edit.c12
-rw-r--r--source/blender/editors/armature/pose_select.c20
-rw-r--r--source/blender/editors/armature/reeb.c10
-rw-r--r--source/blender/editors/curve/editcurve.c4
-rw-r--r--source/blender/editors/curve/editcurve_paint.c14
-rw-r--r--source/blender/editors/curve/editcurve_select.c2
-rw-r--r--source/blender/editors/gpencil/drawgpencil.c4
-rw-r--r--source/blender/editors/gpencil/gpencil_convert.c4
-rw-r--r--source/blender/editors/gpencil/gpencil_paint.c2
-rw-r--r--source/blender/editors/gpencil/gpencil_select.c2
-rw-r--r--source/blender/editors/include/BIF_glutil.h32
-rw-r--r--source/blender/editors/include/ED_armature.h5
-rw-r--r--source/blender/editors/include/ED_image.h6
-rw-r--r--source/blender/editors/include/ED_info.h5
-rw-r--r--source/blender/editors/include/ED_mesh.h10
-rw-r--r--source/blender/editors/include/ED_object.h61
-rw-r--r--source/blender/editors/include/ED_screen.h7
-rw-r--r--source/blender/editors/include/ED_uvedit.h7
-rw-r--r--source/blender/editors/include/ED_view3d.h2
-rw-r--r--source/blender/editors/interface/CMakeLists.txt6
-rw-r--r--source/blender/editors/interface/interface.c31
-rw-r--r--source/blender/editors/interface/interface_draw.c30
-rw-r--r--source/blender/editors/interface/interface_handlers.c48
-rw-r--r--source/blender/editors/interface/interface_icons.c18
-rw-r--r--source/blender/editors/interface/interface_region_popup.c5
-rw-r--r--source/blender/editors/interface/interface_region_tooltip.c10
-rw-r--r--source/blender/editors/interface/interface_templates.c16
-rw-r--r--source/blender/editors/interface/interface_widgets.c2
-rw-r--r--source/blender/editors/interface/resources.c18
-rw-r--r--source/blender/editors/interface/view2d.c7
-rw-r--r--source/blender/editors/manipulator_library/manipulator_types/cage2d_manipulator.c2
-rw-r--r--source/blender/editors/manipulator_library/manipulator_types/cage3d_manipulator.c2
-rw-r--r--source/blender/editors/mask/mask_draw.c2
-rw-r--r--source/blender/editors/mask/mask_select.c2
-rw-r--r--source/blender/editors/mesh/editface.c13
-rw-r--r--source/blender/editors/mesh/editmesh_intersect.c2
-rw-r--r--source/blender/editors/mesh/editmesh_knife.c8
-rw-r--r--source/blender/editors/mesh/editmesh_path.c35
-rw-r--r--source/blender/editors/mesh/editmesh_select.c4
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c6
-rw-r--r--source/blender/editors/mesh/editmesh_undo.c2
-rw-r--r--source/blender/editors/mesh/editmesh_utils.c7
-rw-r--r--source/blender/editors/mesh/mesh_data.c11
-rw-r--r--source/blender/editors/mesh/mesh_navmesh.c8
-rw-r--r--source/blender/editors/mesh/meshtools.c41
-rw-r--r--source/blender/editors/object/object_add.c26
-rw-r--r--source/blender/editors/object/object_bake.c27
-rw-r--r--source/blender/editors/object/object_bake_api.c5
-rw-r--r--source/blender/editors/object/object_constraint.c61
-rw-r--r--source/blender/editors/object/object_edit.c198
-rw-r--r--source/blender/editors/object/object_facemap_ops.c9
-rw-r--r--source/blender/editors/object/object_modifier.c97
-rw-r--r--source/blender/editors/object/object_ops.c5
-rw-r--r--source/blender/editors/object/object_relations.c24
-rw-r--r--source/blender/editors/object/object_select.c91
-rw-r--r--source/blender/editors/object/object_shapekey.c10
-rw-r--r--source/blender/editors/object/object_transform.c5
-rw-r--r--source/blender/editors/object/object_vgroup.c222
-rw-r--r--source/blender/editors/physics/particle_edit.c39
-rw-r--r--source/blender/editors/physics/particle_object.c8
-rw-r--r--source/blender/editors/physics/physics_fluid.c2
-rw-r--r--source/blender/editors/render/render_internal.c12
-rw-r--r--source/blender/editors/render/render_opengl.c2
-rw-r--r--source/blender/editors/render/render_preview.c23
-rw-r--r--source/blender/editors/render/render_shading.c6
-rw-r--r--source/blender/editors/render/render_update.c22
-rw-r--r--source/blender/editors/scene/scene_edit.c4
-rw-r--r--source/blender/editors/screen/CMakeLists.txt1
-rw-r--r--source/blender/editors/screen/area.c72
-rw-r--r--source/blender/editors/screen/glutil.c136
-rw-r--r--source/blender/editors/screen/screen_context.c16
-rw-r--r--source/blender/editors/screen/screen_draw.c6
-rw-r--r--source/blender/editors/screen/screen_edit.c81
-rw-r--r--source/blender/editors/screen/screen_ops.c67
-rw-r--r--source/blender/editors/screen/workspace_edit.c40
-rw-r--r--source/blender/editors/sculpt_paint/paint_curve.c6
-rw-r--r--source/blender/editors/sculpt_paint/paint_hide.c4
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c52
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_proj.c24
-rw-r--r--source/blender/editors/sculpt_paint/paint_mask.c8
-rw-r--r--source/blender/editors/sculpt_paint/paint_ops.c9
-rw-r--r--source/blender/editors/sculpt_paint/paint_utils.c3
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex.c305
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex_color_ops.c4
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex_proj.c17
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c3
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex_weight_utils.c6
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c251
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_intern.h19
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_undo.c16
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_uv.c6
-rw-r--r--source/blender/editors/space_action/action_select.c2
-rw-r--r--source/blender/editors/space_buttons/CMakeLists.txt1
-rw-r--r--source/blender/editors/space_buttons/buttons_context.c5
-rw-r--r--source/blender/editors/space_buttons/buttons_texture.c2
-rw-r--r--source/blender/editors/space_clip/clip_draw.c6
-rw-r--r--source/blender/editors/space_clip/clip_utils.c2
-rw-r--r--source/blender/editors/space_clip/tracking_select.c2
-rw-r--r--source/blender/editors/space_file/file_draw.c2
-rw-r--r--source/blender/editors/space_file/space_file.c3
-rw-r--r--source/blender/editors/space_graph/graph_draw.c2
-rw-r--r--source/blender/editors/space_graph/graph_select.c2
-rw-r--r--source/blender/editors/space_image/image_draw.c14
-rw-r--r--source/blender/editors/space_image/image_edit.c18
-rw-r--r--source/blender/editors/space_image/image_ops.c9
-rw-r--r--source/blender/editors/space_image/space_image.c11
-rw-r--r--source/blender/editors/space_info/info_report.c3
-rw-r--r--source/blender/editors/space_info/info_stats.c43
-rw-r--r--source/blender/editors/space_info/textview.c2
-rw-r--r--source/blender/editors/space_nla/nla_draw.c6
-rw-r--r--source/blender/editors/space_node/drawnode.c25
-rw-r--r--source/blender/editors/space_node/node_draw.c5
-rw-r--r--source/blender/editors/space_node/node_select.c2
-rw-r--r--source/blender/editors/space_outliner/outliner_collections.c301
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.c61
-rw-r--r--source/blender/editors/space_outliner/outliner_edit.c6
-rw-r--r--source/blender/editors/space_outliner/outliner_intern.h19
-rw-r--r--source/blender/editors/space_outliner/outliner_ops.c4
-rw-r--r--source/blender/editors/space_outliner/outliner_select.c45
-rw-r--r--source/blender/editors/space_outliner/outliner_tools.c74
-rw-r--r--source/blender/editors/space_outliner/outliner_tree.c415
-rw-r--r--source/blender/editors/space_sequencer/sequencer_draw.c14
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c2
-rw-r--r--source/blender/editors/space_text/text_draw.c2
-rw-r--r--source/blender/editors/space_time/space_time.c5
-rw-r--r--source/blender/editors/space_view3d/drawarmature.c44
-rw-r--r--source/blender/editors/space_view3d/drawmesh.c20
-rw-r--r--source/blender/editors/space_view3d/drawobject.c270
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c24
-rw-r--r--source/blender/editors/space_view3d/view3d_buttons.c7
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c79
-rw-r--r--source/blender/editors/space_view3d/view3d_draw_legacy.c77
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c43
-rw-r--r--source/blender/editors/space_view3d/view3d_header.c25
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h31
-rw-r--r--source/blender/editors/space_view3d/view3d_manipulator_forcefield.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_manipulator_navigate_type.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c76
-rw-r--r--source/blender/editors/space_view3d/view3d_snap.c11
-rw-r--r--source/blender/editors/space_view3d/view3d_utils.c4
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c21
-rw-r--r--source/blender/editors/transform/transform.c11
-rw-r--r--source/blender/editors/transform/transform.h8
-rw-r--r--source/blender/editors/transform/transform_conversions.c47
-rw-r--r--source/blender/editors/transform/transform_generics.c14
-rw-r--r--source/blender/editors/transform/transform_manipulator.c30
-rw-r--r--source/blender/editors/transform/transform_manipulator2d.c2
-rw-r--r--source/blender/editors/transform/transform_ops.c3
-rw-r--r--source/blender/editors/transform/transform_orientations.c14
-rw-r--r--source/blender/editors/transform/transform_snap.c4
-rw-r--r--source/blender/editors/transform/transform_snap_object.c15
-rw-r--r--source/blender/editors/util/ed_util.c95
-rw-r--r--source/blender/editors/util/undo.c36
-rw-r--r--source/blender/editors/uvedit/uvedit_buttons.c14
-rw-r--r--source/blender/editors/uvedit/uvedit_draw.c28
-rw-r--r--source/blender/editors/uvedit/uvedit_intern.h10
-rw-r--r--source/blender/editors/uvedit/uvedit_ops.c139
-rw-r--r--source/blender/editors/uvedit/uvedit_parametrizer.c10
-rw-r--r--source/blender/editors/uvedit/uvedit_smart_stitch.c9
-rw-r--r--source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp39
-rw-r--r--source/blender/gpu/CMakeLists.txt4
-rw-r--r--source/blender/gpu/GPU_draw.h10
-rw-r--r--source/blender/gpu/GPU_extensions.h1
-rw-r--r--source/blender/gpu/GPU_framebuffer.h6
-rw-r--r--source/blender/gpu/GPU_material.h3
-rw-r--r--source/blender/gpu/GPU_shader.h5
-rw-r--r--source/blender/gpu/GPU_viewport.h1
-rw-r--r--source/blender/gpu/intern/gpu_batch.c2
-rw-r--r--source/blender/gpu/intern/gpu_buffers.c2
-rw-r--r--source/blender/gpu/intern/gpu_compositing.c6
-rw-r--r--source/blender/gpu/intern/gpu_draw.c36
-rw-r--r--source/blender/gpu/intern/gpu_extensions.c8
-rw-r--r--source/blender/gpu/intern/gpu_framebuffer.c64
-rw-r--r--source/blender/gpu/intern/gpu_material.c10
-rw-r--r--source/blender/gpu/intern/gpu_shader.c12
-rw-r--r--source/blender/gpu/intern/gpu_viewport.c22
-rw-r--r--source/blender/gpu/shaders/gpu_shader_image_frag.glsl (renamed from source/blender/gpu/shaders/gpu_shader_image_rect_modulate_alpha_frag.glsl)4
-rw-r--r--source/blender/gpu/shaders/gpu_shader_image_interlace_frag.glsl4
-rw-r--r--source/blender/gpu/shaders/gpu_shader_instance_mball_handles_vert.glsl (renamed from source/blender/gpu/shaders/gpu_shader_instance_mball_helpers_vert.glsl)0
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material.glsl82
-rw-r--r--source/blender/imbuf/intern/colormanagement.c14
-rw-r--r--source/blender/imbuf/intern/moviecache.c2
-rw-r--r--source/blender/imbuf/intern/thumbs.c16
-rw-r--r--source/blender/makesdna/DNA_brush_types.h2
-rw-r--r--source/blender/makesdna/DNA_meta_types.h2
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h14
-rw-r--r--source/blender/makesdna/DNA_node_types.h13
-rw-r--r--source/blender/makesdna/DNA_object_enums.h49
-rw-r--r--source/blender/makesdna/DNA_object_fluidsim_types.h (renamed from source/blender/makesdna/DNA_object_fluidsim.h)9
-rw-r--r--source/blender/makesdna/DNA_object_force_types.h (renamed from source/blender/makesdna/DNA_object_force.h)8
-rw-r--r--source/blender/makesdna/DNA_object_types.h24
-rw-r--r--source/blender/makesdna/DNA_particle_types.h15
-rw-r--r--source/blender/makesdna/DNA_scene_types.h10
-rw-r--r--source/blender/makesdna/DNA_screen_types.h10
-rw-r--r--source/blender/makesdna/DNA_smoke_types.h2
-rw-r--r--source/blender/makesdna/DNA_texture_types.h2
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h1
-rw-r--r--source/blender/makesdna/DNA_windowmanager_types.h6
-rw-r--r--source/blender/makesdna/DNA_workspace_types.h3
-rw-r--r--source/blender/makesdna/DNA_world_types.h6
-rw-r--r--source/blender/makesdna/intern/CMakeLists.txt1
-rw-r--r--source/blender/makesdna/intern/makesdna.c8
-rw-r--r--source/blender/makesrna/RNA_types.h36
-rw-r--r--source/blender/makesrna/intern/rna_access.c15
-rw-r--r--source/blender/makesrna/intern/rna_brush.c12
-rw-r--r--source/blender/makesrna/intern/rna_dynamicpaint.c2
-rw-r--r--source/blender/makesrna/intern/rna_fluidsim.c2
-rw-r--r--source/blender/makesrna/intern/rna_layer.c85
-rw-r--r--source/blender/makesrna/intern/rna_material.c11
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c13
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c67
-rw-r--r--source/blender/makesrna/intern/rna_object.c28
-rw-r--r--source/blender/makesrna/intern/rna_object_api.c6
-rw-r--r--source/blender/makesrna/intern/rna_object_force.c7
-rw-r--r--source/blender/makesrna/intern/rna_particle.c61
-rw-r--r--source/blender/makesrna/intern/rna_rna.c10
-rw-r--r--source/blender/makesrna/intern/rna_scene.c7
-rw-r--r--source/blender/makesrna/intern/rna_scene_api.c6
-rw-r--r--source/blender/makesrna/intern/rna_screen.c5
-rw-r--r--source/blender/makesrna/intern/rna_sculpt_paint.c6
-rw-r--r--source/blender/makesrna/intern/rna_sequencer.c1
-rw-r--r--source/blender/makesrna/intern/rna_smoke.c2
-rw-r--r--source/blender/makesrna/intern/rna_space.c23
-rw-r--r--source/blender/makesrna/intern/rna_texture.c4
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c30
-rw-r--r--source/blender/makesrna/intern/rna_wm.c36
-rw-r--r--source/blender/makesrna/intern/rna_workspace.c4
-rw-r--r--source/blender/makesrna/intern/rna_world.c6
-rw-r--r--source/blender/modifiers/CMakeLists.txt11
-rw-r--r--source/blender/modifiers/intern/MOD_boolean.c106
-rw-r--r--source/blender/modifiers/intern/MOD_boolean_util.c790
-rw-r--r--source/blender/modifiers/intern/MOD_boolean_util.h46
-rw-r--r--source/blender/modifiers/intern/MOD_build.c14
-rw-r--r--source/blender/modifiers/intern/MOD_dynamicpaint.c2
-rw-r--r--source/blender/modifiers/intern/MOD_fluidsim.c2
-rw-r--r--source/blender/modifiers/intern/MOD_fluidsim_util.c2
-rw-r--r--source/blender/modifiers/intern/MOD_meshdeform.c4
-rw-r--r--source/blender/modifiers/intern/MOD_multires.c6
-rw-r--r--source/blender/modifiers/intern/MOD_shrinkwrap.c8
-rw-r--r--source/blender/modifiers/intern/MOD_skin.c2
-rw-r--r--source/blender/modifiers/intern/MOD_smoke.c2
-rw-r--r--source/blender/modifiers/intern/MOD_softbody.c2
-rw-r--r--source/blender/modifiers/intern/MOD_subsurf.c6
-rw-r--r--source/blender/modifiers/intern/MOD_surfacedeform.c30
-rw-r--r--source/blender/nodes/CMakeLists.txt2
-rw-r--r--source/blender/nodes/NOD_shader.h1
-rw-r--r--source/blender/nodes/NOD_static_types.h3
-rw-r--r--source/blender/nodes/shader/node_shader_tree.c4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c1
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_displacement.c25
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_hair_info.c1
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_normal_map.c32
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_particle_info.c3
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_environment.c1
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_image.c1
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_vector_displacement.c83
-rw-r--r--source/blender/nodes/texture/node_texture_tree.c14
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_image.c4
-rw-r--r--source/blender/physics/intern/BPH_mass_spring.cpp2
-rw-r--r--source/blender/physics/intern/implicit_blender.c2
-rw-r--r--source/blender/physics/intern/implicit_eigen.cpp2
-rw-r--r--source/blender/python/bmesh/bmesh_py_ops_call.c8
-rw-r--r--source/blender/python/bmesh/bmesh_py_types.c6
-rw-r--r--source/blender/python/intern/CMakeLists.txt4
-rw-r--r--source/blender/python/intern/bpy_app_build_options.c7
-rw-r--r--source/blender/python/intern/bpy_operator.c2
-rw-r--r--source/blender/python/intern/bpy_rna.c6
-rw-r--r--source/blender/python/intern/gpu_offscreen.c6
-rw-r--r--source/blender/python/mathutils/mathutils_bvhtree.c2
-rw-r--r--source/blender/python/mathutils/mathutils_geometry.c4
-rw-r--r--source/blender/render/extern/include/RE_shader_ext.h2
-rw-r--r--source/blender/render/intern/source/bake.c16
-rw-r--r--source/blender/render/intern/source/convertblender.c5
-rw-r--r--source/blender/render/intern/source/envmap.c4
-rw-r--r--source/blender/render/intern/source/external_engine.c4
-rw-r--r--source/blender/render/intern/source/imagetexture.c8
-rw-r--r--source/blender/render/intern/source/initrender.c2
-rw-r--r--source/blender/render/intern/source/multires_bake.c6
-rw-r--r--source/blender/render/intern/source/occlusion.c16
-rw-r--r--source/blender/render/intern/source/pipeline.c29
-rw-r--r--source/blender/render/intern/source/render_result.c4
-rw-r--r--source/blender/render/intern/source/render_texture.c4
-rw-r--r--source/blender/render/intern/source/renderdatabase.c3
-rw-r--r--source/blender/render/intern/source/shadbuf.c24
-rw-r--r--source/blender/render/intern/source/sss.c4
-rw-r--r--source/blender/render/intern/source/voxeldata.c2
-rw-r--r--source/blender/render/intern/source/zbuf.c2
-rw-r--r--source/blender/windowmanager/CMakeLists.txt1
-rw-r--r--source/blender/windowmanager/WM_api.h13
-rw-r--r--source/blender/windowmanager/WM_types.h11
-rw-r--r--source/blender/windowmanager/intern/wm_draw.c128
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c18
-rw-r--r--source/blender/windowmanager/intern/wm_files.c8
-rw-r--r--source/blender/windowmanager/intern/wm_files_link.c19
-rw-r--r--source/blender/windowmanager/intern/wm_gesture.c40
-rw-r--r--source/blender/windowmanager/intern/wm_gesture_ops.c52
-rw-r--r--source/blender/windowmanager/intern/wm_init_exit.c2
-rw-r--r--source/blender/windowmanager/intern/wm_jobs.c8
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c4
-rw-r--r--source/blender/windowmanager/intern/wm_playanim.c2
-rw-r--r--source/blender/windowmanager/intern/wm_stereo.c85
-rw-r--r--source/blender/windowmanager/intern/wm_subwindow.c326
-rw-r--r--source/blender/windowmanager/intern/wm_window.c30
-rw-r--r--source/blender/windowmanager/manipulators/intern/wm_manipulator_map.c17
-rw-r--r--source/blender/windowmanager/message_bus/intern/wm_message_bus.c3
-rw-r--r--source/blender/windowmanager/message_bus/intern/wm_message_bus_static.c2
-rw-r--r--source/blender/windowmanager/message_bus/wm_message_bus.h2
-rw-r--r--source/blender/windowmanager/wm_draw.h4
-rw-r--r--source/blender/windowmanager/wm_subwindow.h52
-rw-r--r--source/blenderplayer/CMakeLists.txt4
-rw-r--r--source/blenderplayer/bad_level_call_stubs/stubs.c18
-rw-r--r--source/creator/CMakeLists.txt66
-rw-r--r--source/creator/creator_args.c10
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.cpp10
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp2
-rw-r--r--source/gameengine/VideoTexture/VideoFFmpeg.cpp6
m---------source/tools0
572 files changed, 8834 insertions, 6360 deletions
diff --git a/source/blender/CMakeLists.txt b/source/blender/CMakeLists.txt
index c2fac8fc7d7..316ab531a05 100644
--- a/source/blender/CMakeLists.txt
+++ b/source/blender/CMakeLists.txt
@@ -65,8 +65,9 @@ set(SRC_DNA_INC
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_modifier_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_nla_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_node_types.h
- ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_object_fluidsim.h
- ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_object_force.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_object_fluidsim_types.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_object_force_types.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_object_enums.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_object_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_outliner_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_packedFile_types.h
diff --git a/source/blender/alembic/intern/abc_mesh.cc b/source/blender/alembic/intern/abc_mesh.cc
index fa2bbb8dfc3..c2c99e2b11f 100644
--- a/source/blender/alembic/intern/abc_mesh.cc
+++ b/source/blender/alembic/intern/abc_mesh.cc
@@ -31,7 +31,7 @@ extern "C" {
#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
#include "DNA_modifier_types.h"
-#include "DNA_object_fluidsim.h"
+#include "DNA_object_fluidsim_types.h"
#include "DNA_object_types.h"
#include "BLI_math_geom.h"
diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c
index 24347d57917..0cca1852c91 100644
--- a/source/blender/blenfont/intern/blf.c
+++ b/source/blender/blenfont/intern/blf.c
@@ -551,7 +551,7 @@ static void blf_draw_gl__start(FontBLF *font)
*/
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
gpuPushMatrix();
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index 9bb44a726de..c3cea6c883c 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -100,6 +100,8 @@ struct GPUDrawObject;
struct PBVH;
struct EvaluationContext;
+#include "DNA_object_enums.h"
+
/* number of sub-elements each mesh element has (for interpolation) */
#define SUB_ELEMS_VERT 0
#define SUB_ELEMS_EDGE 2
@@ -381,7 +383,7 @@ struct DerivedMesh {
/** Get the BVH used for paint modes
*/
- struct PBVH *(*getPBVH)(struct Object *ob, DerivedMesh *dm);
+ struct PBVH *(*getPBVH)(struct Object *ob, DerivedMesh *dm, eObjectMode object_mode);
/* Drawing Operations */
diff --git a/source/blender/blenkernel/BKE_addon.h b/source/blender/blenkernel/BKE_addon.h
index 74c1edd1c1b..e631d1d6537 100644
--- a/source/blender/blenkernel/BKE_addon.h
+++ b/source/blender/blenkernel/BKE_addon.h
@@ -26,8 +26,11 @@
* \ingroup bke
*/
-#include "RNA_types.h"
+struct ListBase;
+struct bAddon;
+
+#ifdef __RNA_TYPES_H__
typedef struct bAddonPrefType {
/* type info */
char idname[64]; // best keep the same size as BKE_ST_MAXNAME
@@ -36,6 +39,10 @@ typedef struct bAddonPrefType {
ExtensionRNA ext;
} bAddonPrefType;
+#else
+typedef struct bAddonPrefType bAddonPrefType;
+#endif
+
bAddonPrefType *BKE_addon_pref_type_find(const char *idname, bool quiet);
void BKE_addon_pref_type_add(bAddonPrefType *apt);
void BKE_addon_pref_type_remove(const bAddonPrefType *apt);
@@ -43,4 +50,8 @@ void BKE_addon_pref_type_remove(const bAddonPrefType *apt);
void BKE_addon_pref_type_init(void);
void BKE_addon_pref_type_free(void);
+struct bAddon *BKE_addon_new(void);
+struct bAddon *BKE_addon_ensure(struct ListBase *addons, const char *module);
+void BKE_addon_free(struct bAddon *addon);
+
#endif /* __BKE_ADDON_H__ */
diff --git a/source/blender/blenkernel/BKE_brush.h b/source/blender/blenkernel/BKE_brush.h
index e7af7400850..f2601f2ca32 100644
--- a/source/blender/blenkernel/BKE_brush.h
+++ b/source/blender/blenkernel/BKE_brush.h
@@ -36,6 +36,7 @@ struct Scene;
struct UnifiedPaintSettings;
// enum eCurveMappingPreset;
+#include "DNA_object_enums.h"
/* globals for brush execution */
void BKE_brush_system_init(void);
@@ -43,8 +44,8 @@ void BKE_brush_system_exit(void);
/* datablock functions */
void BKE_brush_init(struct Brush *brush);
-struct Brush *BKE_brush_add(struct Main *bmain, const char *name, short ob_mode);
-struct Brush *BKE_brush_first_search(struct Main *bmain, short ob_mode);
+struct Brush *BKE_brush_add(struct Main *bmain, const char *name, const eObjectMode ob_mode);
+struct Brush *BKE_brush_first_search(struct Main *bmain, const eObjectMode ob_mode);
void BKE_brush_copy_data(struct Main *bmain, struct Brush *brush_dst, const struct Brush *brush_src, const int flag);
struct Brush *BKE_brush_copy(struct Main *bmain, const struct Brush *brush);
void BKE_brush_make_local(struct Main *bmain, struct Brush *brush, const bool lib_local);
diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h
index 7f7cbd678e2..27b928c1671 100644
--- a/source/blender/blenkernel/BKE_cloth.h
+++ b/source/blender/blenkernel/BKE_cloth.h
@@ -236,7 +236,9 @@ void bvhtree_update_from_cloth(struct ClothModifierData *clmd, bool moving);
void bvhselftree_update_from_cloth(struct ClothModifierData *clmd, bool moving);
// needed for button_object.c
-void cloth_clear_cache (struct Object *ob, struct ClothModifierData *clmd, float framenr );
+void cloth_clear_cache(
+ const struct EvaluationContext *eval_ctx,
+ struct Object *ob, struct ClothModifierData *clmd, float framenr );
void cloth_parallel_transport_hair_frame(float mat[3][3], const float dir_old[3], const float dir_new[3]);
diff --git a/source/blender/blenkernel/BKE_collection.h b/source/blender/blenkernel/BKE_collection.h
index 48b4ff881ae..3bf14346ccb 100644
--- a/source/blender/blenkernel/BKE_collection.h
+++ b/source/blender/blenkernel/BKE_collection.h
@@ -49,8 +49,9 @@ struct SceneCollection *BKE_collection_add(
struct ID *owner_id, struct SceneCollection *sc_parent, const int type, const char *name);
bool BKE_collection_remove(struct ID *owner_id, struct SceneCollection *sc);
void BKE_collection_copy_data(struct SceneCollection *sc_dst, struct SceneCollection *sc_src, const int flag);
+struct SceneCollection *BKE_collection_duplicate(struct ID *owner_id, struct SceneCollection *scene_collection);
struct SceneCollection *BKE_collection_master(const struct ID *owner_id);
-void BKE_collection_rename(const struct Scene *scene, struct SceneCollection *sc, const char *name);
+void BKE_collection_rename(const struct ID *owner_id, struct SceneCollection *sc, const char *name);
void BKE_collection_master_free(struct ID *owner_id, const bool do_id_user);
bool BKE_collection_object_add(const struct ID *owner_id, struct SceneCollection *sc, struct Object *object);
void BKE_collection_object_add_from(struct Scene *scene, struct Object *ob_src, struct Object *ob_dst);
diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h
index 3d53f28c185..8aa253bfc3a 100644
--- a/source/blender/blenkernel/BKE_context.h
+++ b/source/blender/blenkernel/BKE_context.h
@@ -77,6 +77,8 @@ struct SpaceClip;
struct ID;
struct EvaluationContext;
+#include "DNA_object_enums.h"
+
/* Structs */
struct bContext;
@@ -261,7 +263,9 @@ struct RenderEngineType *CTX_data_engine_type(const bContext *C);
struct ToolSettings *CTX_data_tool_settings(const bContext *C);
const char *CTX_data_mode_string(const bContext *C);
-int CTX_data_mode_enum_ex(const struct Object *obedit, const struct Object *ob);
+int CTX_data_mode_enum_ex(
+ const struct Object *obedit, const struct Object *ob,
+ const eObjectMode object_mode);
int CTX_data_mode_enum(const bContext *C);
void CTX_data_main_set(bContext *C, struct Main *bmain);
diff --git a/source/blender/blenkernel/BKE_layer.h b/source/blender/blenkernel/BKE_layer.h
index b605b208f66..17b854e5bf7 100644
--- a/source/blender/blenkernel/BKE_layer.h
+++ b/source/blender/blenkernel/BKE_layer.h
@@ -29,6 +29,8 @@
#include "BKE_collection.h"
+#include "DNA_scene_types.h"
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -76,11 +78,18 @@ struct Base *BKE_view_layer_base_find(struct ViewLayer *view_layer, struct Objec
void BKE_view_layer_base_deselect_all(struct ViewLayer *view_layer);
void BKE_view_layer_base_select(struct ViewLayer *view_layer, struct Base *selbase);
+void BKE_layer_collection_sync_flags(
+ struct ID *owner_id,
+ struct SceneCollection *scene_collection_dst,
+ struct SceneCollection *scene_collection_src);
+
void BKE_view_layer_copy_data(
struct ViewLayer *view_layer_dst, struct ViewLayer *view_layer_src,
struct SceneCollection *mc_dst, struct SceneCollection *mc_src,
const int flag);
+struct LayerCollection *BKE_layer_collection_duplicate(struct ID *owner_id, struct LayerCollection *layer_collection);
+
void BKE_layer_collection_free(struct ViewLayer *view_layer, struct LayerCollection *lc);
struct LayerCollection *BKE_layer_collection_get_active(struct ViewLayer *view_layer);
@@ -106,6 +115,8 @@ void BKE_collection_enable(struct ViewLayer *view_layer, struct LayerCollection
bool BKE_view_layer_has_collection(struct ViewLayer *view_layer, const struct SceneCollection *sc);
bool BKE_scene_has_object(struct Scene *scene, struct Object *ob);
+void BKE_layer_collection_objects_select(struct LayerCollection *layer_collection);
+
/* syncing */
void BKE_layer_sync_new_scene_collection(struct ID *owner_id, const struct SceneCollection *sc_parent, struct SceneCollection *sc);
@@ -228,9 +239,9 @@ void BKE_visible_bases_iterator_end(BLI_Iterator *iter);
#define FOREACH_OBJECT(view_layer, _instance) \
{ \
Object *_instance; \
- Base *base; \
- for (base = (view_layer)->object_bases.first; base; base = base->next) { \
- _instance = base->object;
+ Base *_base; \
+ for (_base = (view_layer)->object_bases.first; _base; _base = _base->next) { \
+ _instance = _base->object;
#define FOREACH_OBJECT_END \
} \
@@ -263,6 +274,8 @@ void BKE_visible_bases_iterator_end(BLI_Iterator *iter);
typedef struct ObjectsRenderableIteratorData {
struct Scene *scene;
+ struct Base base_temp;
+ struct Scene scene_temp;
struct {
struct ViewLayer *view_layer;
diff --git a/source/blender/blenkernel/BKE_mball.h b/source/blender/blenkernel/BKE_mball.h
index 9db277f95fb..d4776d890d2 100644
--- a/source/blender/blenkernel/BKE_mball.h
+++ b/source/blender/blenkernel/BKE_mball.h
@@ -77,9 +77,9 @@ void BKE_mball_eval_geometry(const struct EvaluationContext *eval_ctx,
struct MetaBall *mball);
/* Draw Cache */
-void BKE_mball_element_calc_display_m3x4(float r_scale_xform[3][4],
- const float obmat[4][4],
- const float local_pos[3]);
+void BKE_mball_element_calc_scale_xform(float r_scale_xform[3][4],
+ const float obmat[4][4],
+ const float local_pos[3]);
enum {
BKE_MBALL_BATCH_DIRTY_ALL = 0,
diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h
index 451823aedf5..8ee67850e5f 100644
--- a/source/blender/blenkernel/BKE_modifier.h
+++ b/source/blender/blenkernel/BKE_modifier.h
@@ -374,7 +374,8 @@ struct Object *modifiers_isDeformedByArmature(struct Object *ob);
struct Object *modifiers_isDeformedByLattice(struct Object *ob);
struct Object *modifiers_isDeformedByCurve(struct Object *ob);
bool modifiers_usesArmature(struct Object *ob, struct bArmature *arm);
-bool modifiers_isCorrectableDeformed(struct Scene *scene, struct Object *ob);
+bool modifiers_isCorrectableDeformed(
+ const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob);
void modifier_freeTemporaryData(struct ModifierData *md);
bool modifiers_isPreview(struct Object *ob);
diff --git a/source/blender/blenkernel/BKE_multires.h b/source/blender/blenkernel/BKE_multires.h
index 761bb7e8acb..22933a093ed 100644
--- a/source/blender/blenkernel/BKE_multires.h
+++ b/source/blender/blenkernel/BKE_multires.h
@@ -48,20 +48,21 @@ struct MVert;
struct MPoly;
struct MLoopTri;
+#include "DNA_object_enums.h"
+
/* Delete mesh mdisps and grid paint masks */
void multires_customdata_delete(struct Mesh *me);
-void multires_set_tot_level(struct Object *ob,
- struct MultiresModifierData *mmd, int lvl);
+void multires_set_tot_level(struct MultiresModifierData *mmd, int lvl, eObjectMode object_mode);
void multires_mark_as_modified(struct Object *ob, enum MultiresModifiedFlags flags);
void multires_force_update(struct Object *ob);
-void multires_force_render_update(struct Object *ob);
+void multires_force_render_update(struct Object *ob, eObjectMode object_mode);
void multires_force_external_reload(struct Object *ob);
/* internal, only called in subsurf_ccg.c */
-void multires_modifier_update_mdisps(struct DerivedMesh *dm);
+void multires_modifier_update_mdisps(struct DerivedMesh *dm, eObjectMode object_mode);
void multires_modifier_update_hidden(struct DerivedMesh *dm);
void multiresModifier_set_levels_from_disps(struct MultiresModifierData *mmd, struct Object *ob);
@@ -73,21 +74,27 @@ typedef enum {
MULTIRES_IGNORE_SIMPLIFY = 8
} MultiresFlags;
-struct DerivedMesh *multires_make_derived_from_derived(struct DerivedMesh *dm,
- struct MultiresModifierData *mmd,
- struct Object *ob,
- MultiresFlags flags);
+struct DerivedMesh *multires_make_derived_from_derived(
+ struct DerivedMesh *dm,
+ struct MultiresModifierData *mmd,
+ struct Object *ob,
+ MultiresFlags flags,
+ eObjectMode object_mode);
struct MultiresModifierData *find_multires_modifier_before(struct Scene *scene,
struct ModifierData *lastmd);
struct MultiresModifierData *get_multires_modifier(struct Scene *scene, struct Object *ob, bool use_first);
struct DerivedMesh *get_multires_dm(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct MultiresModifierData *mmd,
struct Object *ob);
-void multiresModifier_del_levels(struct MultiresModifierData *, struct Object *, int direction);
-void multiresModifier_base_apply(struct MultiresModifierData *mmd, struct Object *ob);
-void multiresModifier_subdivide(struct MultiresModifierData *mmd, struct Object *ob, int updateblock, int simple);
+void multiresModifier_del_levels(
+ struct MultiresModifierData *, struct Object *, int direction, eObjectMode object_mode);
+void multiresModifier_base_apply(
+ struct MultiresModifierData *mmd, struct Object *ob, eObjectMode object_mode);
+void multiresModifier_subdivide(
+ struct MultiresModifierData *mmd, struct Object *ob, int updateblock, int simple, eObjectMode object_mode);
void multiresModifier_sync_levels_ex(
- struct Object *ob_dst, struct MultiresModifierData *mmd_src, struct MultiresModifierData *mmd_dst);
+ struct Object *ob_dst, struct MultiresModifierData *mmd_src, struct MultiresModifierData *mmd_dst,
+ eObjectMode object_mode);
int multiresModifier_reshape(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct MultiresModifierData *mmd,
struct Object *dst, struct Object *src);
int multiresModifier_reshapeFromDM(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct MultiresModifierData *mmd,
@@ -103,7 +110,7 @@ enum {
MULTIRES_SPACE_OBJECT,
MULTIRES_SPACE_ABSOLUTE
};
-void multires_set_space(struct DerivedMesh *dm, struct Object *ob, int from, int to);
+void multires_set_space(struct DerivedMesh *dm, struct Object *ob, int from, int to, eObjectMode object_mode);
/* Related to the old multires */
void multires_free(struct Multires *mr);
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 4e30cb076d4..770b2b4a185 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -801,6 +801,7 @@ struct ShadeResult;
#define SH_NODE_EEVEE_SPECULAR 195
#define SH_NODE_BEVEL 197
#define SH_NODE_DISPLACEMENT 198
+#define SH_NODE_VECTOR_DISPLACEMENT 199
/* custom defines options for Material node */
#define SH_NODE_MAT_DIFF 1
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index d98c52aa91a..536b21e83ce 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -50,6 +50,8 @@ struct RigidBodyWorld;
struct HookModifierData;
struct ModifierData;
+#include "DNA_object_enums.h"
+
void BKE_object_workob_clear(struct Object *workob);
void BKE_object_workob_calc_parent(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct Object *workob);
@@ -72,16 +74,18 @@ void BKE_object_modifier_hook_reset(struct Object *ob, struct HookModifierData *
bool BKE_object_support_modifier_type_check(struct Object *ob, int modifier_type);
-void BKE_object_link_modifiers(struct Object *ob_dst, const struct Object *ob_src);
+void BKE_object_link_modifiers(
+ struct Object *ob_dst, const struct Object *ob_src,
+ eObjectMode object_mode);
void BKE_object_free_modifiers(struct Object *ob);
void BKE_object_make_proxy(struct Object *ob, struct Object *target, struct Object *gob);
void BKE_object_copy_proxy_drivers(struct Object *ob, struct Object *target);
bool BKE_object_exists_check(struct Object *obtest);
-bool BKE_object_is_in_editmode(struct Object *ob);
+bool BKE_object_is_in_editmode(const struct Object *ob);
bool BKE_object_is_in_editmode_vgroup(struct Object *ob);
-bool BKE_object_is_in_wpaint_select_vert(struct Object *ob);
+bool BKE_object_is_in_wpaint_select_vert(const struct Object *ob, eObjectMode object_mode);
typedef enum eObjectVisibilityCheck {
OB_VISIBILITY_CHECK_FOR_VIEWPORT,
@@ -113,9 +117,12 @@ void BKE_object_lod_add(struct Object *ob);
void BKE_object_lod_sort(struct Object *ob);
bool BKE_object_lod_remove(struct Object *ob, int level);
void BKE_object_lod_update(struct Object *ob, const float camera_position[3]);
-bool BKE_object_lod_is_usable(struct Object *ob, struct ViewLayer *view_layer);
-struct Object *BKE_object_lod_meshob_get(struct Object *ob, struct ViewLayer *view_layer);
-struct Object *BKE_object_lod_matob_get(struct Object *ob, struct ViewLayer *view_layer);
+bool BKE_object_lod_is_usable(
+ struct Object *ob, struct ViewLayer *view_layer, const eObjectMode object_mode);
+struct Object *BKE_object_lod_meshob_get(
+ struct Object *ob, struct ViewLayer *view_layer, const eObjectMode object_mode);
+struct Object *BKE_object_lod_matob_get(
+ struct Object *ob, struct ViewLayer *view_layer, const eObjectMode object_mode);
void BKE_object_copy_data(struct Main *bmain, struct Object *ob_dst, const struct Object *ob_src, const int flag);
struct Object *BKE_object_copy(struct Main *bmain, const struct Object *ob);
@@ -134,8 +141,10 @@ void BKE_object_to_mat4(struct Object *ob, float mat[4][4]);
void BKE_object_apply_mat4(struct Object *ob, float mat[4][4], const bool use_compat, const bool use_parent);
void BKE_object_matrix_local_get(struct Object *ob, float mat[4][4]);
+bool BKE_object_pose_context_check_ex(struct Object *ob, bool selected);
bool BKE_object_pose_context_check(struct Object *ob);
struct Object *BKE_object_pose_armature_get(struct Object *ob);
+struct Object *BKE_object_pose_armature_get_visible(struct Object *ob, struct ViewLayer *view_layer);
void BKE_object_get_parent_matrix(struct Scene *scene, struct Object *ob,
struct Object *par, float parentmat[4][4]);
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index b952859e508..2840971f157 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -62,6 +62,8 @@ struct EvaluationContext;
enum eOverlayFlags;
+#include "DNA_object_enums.h"
+
extern const char PAINT_CURSOR_SCULPT[3];
extern const char PAINT_CURSOR_VERTEX_PAINT[3];
extern const char PAINT_CURSOR_WEIGHT_PAINT[3];
@@ -91,8 +93,10 @@ typedef enum eOverlayControlFlags {
PAINT_OVERLAY_OVERRIDE_PRIMARY | \
PAINT_OVERLAY_OVERRIDE_CURSOR)
-void BKE_paint_invalidate_overlay_tex(struct Scene *scene, struct ViewLayer *view_layer, const struct Tex *tex);
-void BKE_paint_invalidate_cursor_overlay(struct Scene *scene, struct ViewLayer *view_layer, struct CurveMapping *curve);
+void BKE_paint_invalidate_overlay_tex(
+ struct Scene *scene, struct ViewLayer *view_layer, const struct Tex *tex, eObjectMode object_mode);
+void BKE_paint_invalidate_cursor_overlay(
+ struct Scene *scene, struct ViewLayer *view_layer, struct CurveMapping *curve, eObjectMode object_mode);
void BKE_paint_invalidate_overlay_all(void);
eOverlayControlFlags BKE_paint_get_overlay_flags(void);
void BKE_paint_reset_overlay_invalid(eOverlayControlFlags flag);
@@ -124,9 +128,10 @@ void BKE_paint_copy(struct Paint *src, struct Paint *tar, const int flag);
void BKE_paint_cavity_curve_preset(struct Paint *p, int preset);
-short BKE_paint_object_mode_from_paint_mode(ePaintMode mode);
+eObjectMode BKE_paint_object_mode_from_paint_mode(ePaintMode mode);
struct Paint *BKE_paint_get_active_from_paintmode(struct Scene *sce, ePaintMode mode);
-struct Paint *BKE_paint_get_active(struct Scene *sce, struct ViewLayer *view_layer);
+struct Paint *BKE_paint_get_active(
+ struct Scene *sce, struct ViewLayer *view_layer, const eObjectMode object_mode);
struct Paint *BKE_paint_get_active_from_context(const struct bContext *C);
ePaintMode BKE_paintmode_get_active_from_context(const struct bContext *C);
struct Brush *BKE_paint_brush(struct Paint *paint);
@@ -142,9 +147,9 @@ bool BKE_paint_proj_mesh_data_check(struct Scene *scene, struct Object *ob, bool
/* testing face select mode
* Texture paint could be removed since selected faces are not used
* however hiding faces is useful */
-bool BKE_paint_select_face_test(struct Object *ob);
-bool BKE_paint_select_vert_test(struct Object *ob);
-bool BKE_paint_select_elem_test(struct Object *ob);
+bool BKE_paint_select_face_test(struct Object *ob, eObjectMode object_mode);
+bool BKE_paint_select_vert_test(struct Object *ob, eObjectMode object_mode);
+bool BKE_paint_select_elem_test(struct Object *ob, eObjectMode object_mode);
/* partial visibility */
bool paint_is_face_hidden(const struct MLoopTri *lt, const struct MVert *mvert, const struct MLoop *mloop);
@@ -214,7 +219,6 @@ typedef struct SculptSession {
/* Layer brush persistence between strokes */
float (*layer_co)[3]; /* Copy of the mesh vertices' locations */
- struct SculptStroke *stroke;
struct StrokeCache *cache;
union {
@@ -256,6 +260,7 @@ void BKE_sculpt_update_mesh_elements(
struct MultiresModifierData *BKE_sculpt_multires_active(struct Scene *scene, struct Object *ob);
int BKE_sculpt_mask_layers_ensure(struct Object *ob,
struct MultiresModifierData *mmd);
+void BKE_sculpt_toolsettings_data_ensure(struct Scene *scene);
enum {
SCULPT_MASK_LAYER_CALC_VERT = (1 << 0),
diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h
index 8bc521c515f..2db4126057a 100644
--- a/source/blender/blenkernel/BKE_particle.h
+++ b/source/blender/blenkernel/BKE_particle.h
@@ -115,6 +115,7 @@ typedef struct ParticleTexture {
float damp, gravity, field; /* used in physics */
float length, clump, kink_freq, kink_amp, effector; /* used in path caching */
float rough1, rough2, roughe; /* used in path caching */
+ float twist; /* used in path caching */
} ParticleTexture;
typedef struct ParticleSeam {
@@ -162,9 +163,11 @@ typedef struct ParticleThreadContext {
float *vg_length, *vg_clump, *vg_kink;
float *vg_rough1, *vg_rough2, *vg_roughe;
float *vg_effector;
+ float *vg_twist;
struct CurveMapping *clumpcurve;
struct CurveMapping *roughcurve;
+ struct CurveMapping *twistcurve;
} ParticleThreadContext;
typedef struct ParticleTask {
@@ -298,7 +301,8 @@ void psys_set_current_num(Object *ob, int index);
struct LatticeDeformData *psys_create_lattice_deform_data(struct ParticleSimulationData *sim);
-bool psys_in_edit_mode(struct ViewLayer *view_layer, struct ParticleSystem *psys);
+bool psys_in_edit_mode(
+ const struct EvaluationContext *eval_ctx, struct ViewLayer *view_layer, struct ParticleSystem *psys);
bool psys_check_enabled(struct Object *ob, struct ParticleSystem *psys, const bool use_render_params);
bool psys_check_edited(struct ParticleSystem *psys);
@@ -352,6 +356,7 @@ int psys_get_particle_state(struct ParticleSimulationData *sim, int p, struct Pa
/* child paths */
void BKE_particlesettings_clump_curve_init(struct ParticleSettings *part);
void BKE_particlesettings_rough_curve_init(struct ParticleSettings *part);
+void BKE_particlesettings_twist_curve_init(struct ParticleSettings *part);
void psys_apply_child_modifiers(struct ParticleThreadContext *ctx, struct ListBase *modifiers,
struct ChildParticle *cpa, struct ParticleTexture *ptex, const float orco[3], const float ornor[3], float hairmat[4][4],
struct ParticleCacheKey *keys, struct ParticleCacheKey *parent_keys, const float parent_orco[3]);
diff --git a/source/blender/blenkernel/BKE_pointcache.h b/source/blender/blenkernel/BKE_pointcache.h
index 9a5a9e9e56a..e9be6d9f7ca 100644
--- a/source/blender/blenkernel/BKE_pointcache.h
+++ b/source/blender/blenkernel/BKE_pointcache.h
@@ -34,7 +34,7 @@
#include "DNA_ID.h"
#include "DNA_dynamicpaint_types.h"
-#include "DNA_object_force.h"
+#include "DNA_object_force_types.h"
#include "DNA_boid_types.h"
#include <stdio.h> /* for FILE */
@@ -141,7 +141,7 @@ typedef struct PTCacheID {
unsigned int default_step;
unsigned int max_step;
- /* flags defined in DNA_object_force.h */
+ /* flags defined in DNA_object_force_types.h */
unsigned int data_types, info_types;
/* copies point data to cache data */
diff --git a/source/blender/blenkernel/BKE_shrinkwrap.h b/source/blender/blenkernel/BKE_shrinkwrap.h
index d2ab4f3164c..0c4f2bc9c05 100644
--- a/source/blender/blenkernel/BKE_shrinkwrap.h
+++ b/source/blender/blenkernel/BKE_shrinkwrap.h
@@ -54,6 +54,7 @@ struct ShrinkwrapModifierData;
struct MDeformVert;
struct BVHTree;
struct SpaceTransform;
+struct EvaluationContext;
typedef struct ShrinkwrapCalcData {
@@ -76,8 +77,10 @@ typedef struct ShrinkwrapCalcData {
} ShrinkwrapCalcData;
-void shrinkwrapModifier_deform(struct ShrinkwrapModifierData *smd, struct Object *ob, struct DerivedMesh *dm,
- float (*vertexCos)[3], int numVerts, bool for_render);
+void shrinkwrapModifier_deform(
+ const struct EvaluationContext *eval_ctx,
+ struct ShrinkwrapModifierData *smd, struct Object *ob, struct DerivedMesh *dm,
+ float (*vertexCos)[3], int numVerts, bool for_render);
/*
* This function casts a ray in the given BVHTree.. but it takes into consideration the space_transform, that is:
diff --git a/source/blender/blenkernel/BKE_workspace.h b/source/blender/blenkernel/BKE_workspace.h
index 9f989f7ae8f..b309ae838d6 100644
--- a/source/blender/blenkernel/BKE_workspace.h
+++ b/source/blender/blenkernel/BKE_workspace.h
@@ -34,17 +34,6 @@ struct Scene;
struct TransformOrientation;
struct ViewLayer;
-/**
- * Plan is to store the object-mode per workspace, not per object anymore.
- * However, there's quite some work to be done for that, so for now, there is just a basic
- * implementation of an object <-> workspace object-mode syncing for testing, with some known
- * problems. Main problem being that the modes can get out of sync when changing object selection.
- * Would require a pile of temporary changes to always sync modes when changing selection. So just
- * leaving this here for some testing until object-mode is really a workspace level setting.
- */
-#define USE_WORKSPACE_MODE
-
-
/* -------------------------------------------------------------------- */
/* Create, delete, init */
@@ -106,15 +95,6 @@ void BKE_workspace_active_layout_set(struct WorkSpaceInstanceHook *h
struct bScreen *BKE_workspace_active_screen_get(const struct WorkSpaceInstanceHook *hook) GETTER_ATTRS;
void BKE_workspace_active_screen_set(
struct WorkSpaceInstanceHook *hook, struct WorkSpace *workspace, struct bScreen *screen) SETTER_ATTRS;
-#ifdef USE_WORKSPACE_MODE
-enum eObjectMode BKE_workspace_object_mode_get(
- const struct WorkSpace *workspace,
- const struct Scene *scene) GETTER_ATTRS;
-void BKE_workspace_object_mode_set(
- struct WorkSpace *workspace,
- struct Scene *scene,
- const enum eObjectMode mode) SETTER_ATTRS;
-#endif
struct Base *BKE_workspace_active_base_get(const struct WorkSpace *workspace, const struct Scene *scene);
struct ListBase *BKE_workspace_transform_orientations_get(struct WorkSpace *workspace) GETTER_ATTRS;
struct ViewLayer *BKE_workspace_view_layer_get(
@@ -149,6 +129,13 @@ void BKE_workspace_update_tagged(struct EvaluationContext *eval_ctx,
struct WorkSpace *workspace,
struct Scene *scene);
+void BKE_workspace_update_object_mode(
+ struct EvaluationContext *eval_ctx,
+ struct WorkSpace *workspace);
+
+struct Object *BKE_workspace_edit_object(
+ struct WorkSpace *workspace, struct Scene *scene);
+
#undef GETTER_ATTRS
#undef SETTER_ATTRS
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 279068c440e..3f6bb5b9954 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -315,6 +315,7 @@ set(SRC
nla_private.h
tracking_private.h
+ particle_private.h
intern/CCGSubSurf.h
intern/CCGSubSurf_inline.h
intern/CCGSubSurf_intern.h
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index cfeca50a751..67463ffe915 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -51,6 +51,8 @@
#include "BLI_linklist.h"
#include "BLI_task.h"
+#include "DEG_depsgraph.h"
+
#include "BKE_cdderivedmesh.h"
#include "BKE_colorband.h"
#include "BKE_editmesh.h"
@@ -1660,7 +1662,7 @@ static void shapekey_layers_to_keyblocks(DerivedMesh *dm, Mesh *me, int actshape
cos = CustomData_get_layer_n(&dm->vertData, CD_SHAPEKEY, i);
kb->totelem = dm->numVertData;
- kb->data = kbcos = MEM_malloc_arrayN(kb->totelem, sizeof(float), "kbcos DerivedMesh.c");
+ kb->data = kbcos = MEM_malloc_arrayN(kb->totelem, 3 * sizeof(float), "kbcos DerivedMesh.c");
if (kb->uid == actshape_uid) {
MVert *mvert = dm->getVertArray(dm);
@@ -1776,17 +1778,19 @@ static void mesh_calc_modifiers(
MultiresModifierData *mmd = get_multires_modifier(scene, ob, 0);
const bool has_multires = (mmd && mmd->sculptlvl != 0);
bool multires_applied = false;
- const bool sculpt_mode = ob->mode & OB_MODE_SCULPT && ob->sculpt && !useRenderParams;
+ const bool sculpt_mode = eval_ctx->object_mode & OB_MODE_SCULPT && ob->sculpt && !useRenderParams;
const bool sculpt_dyntopo = (sculpt_mode && ob->sculpt->bm) && !useRenderParams;
const int draw_flag = dm_drawflag_calc(scene->toolsettings, me);
/* Generic preview only in object mode! */
- const bool do_mod_mcol = (ob->mode == OB_MODE_OBJECT);
+ const bool do_mod_mcol = (eval_ctx->object_mode == OB_MODE_OBJECT);
#if 0 /* XXX Will re-enable this when we have global mod stack options. */
const bool do_final_wmcol = (scene->toolsettings->weights_preview == WP_WPREVIEW_FINAL) && do_wmcol;
#endif
const bool do_final_wmcol = false;
- const bool do_init_wmcol = ((dataMask & CD_MASK_PREVIEW_MLOOPCOL) && (ob->mode & OB_MODE_WEIGHT_PAINT) && !do_final_wmcol);
+ const bool do_init_wmcol = (
+ (dataMask & CD_MASK_PREVIEW_MLOOPCOL) &&
+ (eval_ctx->object_mode & OB_MODE_WEIGHT_PAINT) && !do_final_wmcol);
/* XXX Same as above... For now, only weights preview in WPaint mode. */
const bool do_mod_wmcol = do_init_wmcol;
@@ -2624,7 +2628,7 @@ static bool calc_modifiers_skip_orco(const EvaluationContext *eval_ctx,
if (U.opensubdiv_compute_type == USER_OPENSUBDIV_COMPUTE_NONE) {
return false;
}
- else if ((ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) != 0) {
+ else if ((eval_ctx->object_mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) != 0) {
return false;
}
else if ((DEG_get_eval_flags_for_id(eval_ctx->depsgraph, &ob->id) & DAG_EVAL_NEED_CPU) != 0) {
@@ -2665,7 +2669,7 @@ static void mesh_build_data(
ob->lastDataMask = dataMask;
ob->lastNeedMapping = need_mapping;
- if ((ob->mode & OB_MODE_ALL_SCULPT) && ob->sculpt) {
+ if ((eval_ctx->object_mode & OB_MODE_ALL_SCULPT) && ob->sculpt) {
/* create PBVH immediately (would be created on the fly too,
* but this avoids waiting on first stroke) */
@@ -2703,7 +2707,9 @@ static void editbmesh_build_data(
BLI_assert(!(em->derivedFinal->dirty & DM_DIRTY_NORMALS));
}
-static CustomDataMask object_get_datamask(const Scene *scene, Object *ob, bool *r_need_mapping)
+static CustomDataMask object_get_datamask(
+ const EvaluationContext *eval_ctx,
+ const Scene *scene, Object *ob, bool *r_need_mapping)
{
/* TODO(sergey): Avoid this linear list lookup. */
ViewLayer *view_layer = BKE_view_layer_context_active_PLACEHOLDER(scene);
@@ -2715,28 +2721,28 @@ static CustomDataMask object_get_datamask(const Scene *scene, Object *ob, bool *
}
if (ob == actob) {
- bool editing = BKE_paint_select_face_test(ob);
+ bool editing = BKE_paint_select_face_test(ob, eval_ctx->object_mode);
/* weight paint and face select need original indices because of selection buffer drawing */
if (r_need_mapping) {
- *r_need_mapping = (editing || (ob->mode & (OB_MODE_WEIGHT_PAINT | OB_MODE_VERTEX_PAINT)));
+ *r_need_mapping = (editing || (eval_ctx->object_mode & (OB_MODE_WEIGHT_PAINT | OB_MODE_VERTEX_PAINT)));
}
/* check if we need tfaces & mcols due to face select or texture paint */
- if ((ob->mode & OB_MODE_TEXTURE_PAINT) || editing) {
+ if ((eval_ctx->object_mode & OB_MODE_TEXTURE_PAINT) || editing) {
mask |= CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL;
}
/* check if we need mcols due to vertex paint or weightpaint */
- if (ob->mode & OB_MODE_VERTEX_PAINT) {
+ if (eval_ctx->object_mode & OB_MODE_VERTEX_PAINT) {
mask |= CD_MASK_MLOOPCOL;
}
- if (ob->mode & OB_MODE_WEIGHT_PAINT) {
+ if (eval_ctx->object_mode & OB_MODE_WEIGHT_PAINT) {
mask |= CD_MASK_PREVIEW_MLOOPCOL;
}
- if (ob->mode & OB_MODE_EDIT)
+ if (eval_ctx->object_mode & OB_MODE_EDIT)
mask |= CD_MASK_MVERT_SKIN;
}
@@ -2748,7 +2754,7 @@ void makeDerivedMesh(
CustomDataMask dataMask, const bool build_shapekey_layers)
{
bool need_mapping;
- dataMask |= object_get_datamask(scene, ob, &need_mapping);
+ dataMask |= object_get_datamask(eval_ctx, scene, ob, &need_mapping);
if (em) {
editbmesh_build_data(eval_ctx, scene, ob, em, dataMask);
@@ -2767,7 +2773,7 @@ DerivedMesh *mesh_get_derived_final(
* the data we need, rebuild the derived mesh
*/
bool need_mapping;
- dataMask |= object_get_datamask(scene, ob, &need_mapping);
+ dataMask |= object_get_datamask(eval_ctx, scene, ob, &need_mapping);
if (!ob->derivedFinal ||
((dataMask & ob->lastDataMask) != dataMask) ||
@@ -2787,7 +2793,7 @@ DerivedMesh *mesh_get_derived_deform(const struct EvaluationContext *eval_ctx, S
*/
bool need_mapping;
- dataMask |= object_get_datamask(scene, ob, &need_mapping);
+ dataMask |= object_get_datamask(eval_ctx, scene, ob, &need_mapping);
if (!ob->derivedDeform ||
((dataMask & ob->lastDataMask) != dataMask) ||
@@ -2906,7 +2912,7 @@ DerivedMesh *editbmesh_get_derived_cage_and_final(
/* if there's no derived mesh or the last data mask used doesn't include
* the data we need, rebuild the derived mesh
*/
- dataMask |= object_get_datamask(scene, obedit, NULL);
+ dataMask |= object_get_datamask(eval_ctx, scene, obedit, NULL);
if (!em->derivedCage ||
(em->lastDataMask & dataMask) != dataMask)
@@ -2926,7 +2932,7 @@ DerivedMesh *editbmesh_get_derived_cage(
/* if there's no derived mesh or the last data mask used doesn't include
* the data we need, rebuild the derived mesh
*/
- dataMask |= object_get_datamask(scene, obedit, NULL);
+ dataMask |= object_get_datamask(eval_ctx, scene, obedit, NULL);
if (!em->derivedCage ||
(em->lastDataMask & dataMask) != dataMask)
@@ -3719,7 +3725,7 @@ void DM_init_origspace(DerivedMesh *dm)
BKE_mesh_calc_poly_normal(mp, l, mv, p_nor);
axis_dominant_v3_to_m3(mat, p_nor);
- BLI_array_empty(vcos_2d);
+ BLI_array_clear(vcos_2d);
BLI_array_reserve(vcos_2d, mp->totloop);
for (j = 0; j < mp->totloop; j++, l++) {
mul_v3_m3v3(co, mat, mv[l->v].co);
diff --git a/source/blender/blenkernel/intern/addon.c b/source/blender/blenkernel/intern/addon.c
index 0ef12397fe7..689e0fb5ee6 100644
--- a/source/blender/blenkernel/intern/addon.c
+++ b/source/blender/blenkernel/intern/addon.c
@@ -27,13 +27,58 @@
#include <stddef.h>
#include <stdlib.h>
+#include "RNA_types.h"
+
#include "BLI_utildefines.h"
#include "BLI_ghash.h"
+#include "BLI_string.h"
+#include "BLI_listbase.h"
#include "BKE_addon.h" /* own include */
+#include "BKE_idprop.h"
+
+#include "DNA_listBase.h"
+#include "DNA_userdef_types.h"
+
#include "MEM_guardedalloc.h"
+/* -------------------------------------------------------------------- */
+/** \name Add-on New/Free
+ * \{ */
+
+bAddon *BKE_addon_new(void)
+{
+ bAddon *addon = MEM_callocN(sizeof(bAddon), "bAddon");
+ return addon;
+}
+
+bAddon *BKE_addon_ensure(ListBase *addon_list, const char *module)
+{
+ bAddon *addon = BLI_findstring(addon_list, module, offsetof(bAddon, module));
+ if (addon == NULL) {
+ addon = BKE_addon_new();
+ BLI_strncpy(addon->module, module, sizeof(addon->module));
+ BLI_addtail(addon_list, addon);
+ }
+ return addon;
+}
+
+void BKE_addon_free(bAddon *addon)
+{
+ if (addon->prop) {
+ IDP_FreeProperty(addon->prop);
+ MEM_freeN(addon->prop);
+ }
+ MEM_freeN(addon);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Add-on Preference API
+ * \{ */
+
static GHash *global_addonpreftype_hash = NULL;
@@ -81,3 +126,5 @@ void BKE_addon_pref_type_free(void)
BLI_ghash_free(global_addonpreftype_hash, NULL, MEM_freeN);
global_addonpreftype_hash = NULL;
}
+
+/** \} */
diff --git a/source/blender/blenkernel/intern/armature_update.c b/source/blender/blenkernel/intern/armature_update.c
index 1b8bf3feb10..de0dfe2530d 100644
--- a/source/blender/blenkernel/intern/armature_update.c
+++ b/source/blender/blenkernel/intern/armature_update.c
@@ -588,13 +588,15 @@ void BKE_pose_eval_init_ik(const struct EvaluationContext *eval_ctx,
Object *ob,
bPose *UNUSED(pose))
{
- float ctime = BKE_scene_frame_get(scene); /* not accurate... */
-
DEBUG_PRINT("%s on %s\n", __func__, ob->id.name);
-
+ BLI_assert(ob->type == OB_ARMATURE);
+ const float ctime = BKE_scene_frame_get(scene); /* not accurate... */
+ bArmature *arm = (bArmature *)ob->data;
+ if (arm->flag & ARM_RESTPOS) {
+ return;
+ }
/* 2a. construct the IK tree (standard IK) */
BIK_initialize_tree(eval_ctx, scene, ob, ctime);
-
/* 2b. construct the Spline IK trees
* - this is not integrated as an IK plugin, since it should be able
* to function in conjunction with standard IK
@@ -607,9 +609,9 @@ void BKE_pose_eval_bone(const struct EvaluationContext *eval_ctx,
Object *ob,
bPoseChannel *pchan)
{
- bArmature *arm = (bArmature *)ob->data;
DEBUG_PRINT("%s on %s pchan %s\n", __func__, ob->id.name, pchan->name);
BLI_assert(ob->type == OB_ARMATURE);
+ bArmature *arm = (bArmature *)ob->data;
if (arm->edbo || (arm->flag & ARM_RESTPOS)) {
Bone *bone = pchan->bone;
if (bone) {
@@ -674,8 +676,13 @@ void BKE_pose_iktree_evaluate(const struct EvaluationContext *eval_ctx,
Object *ob,
bPoseChannel *rootchan)
{
- float ctime = BKE_scene_frame_get(scene); /* not accurate... */
DEBUG_PRINT("%s on %s pchan %s\n", __func__, ob->id.name, rootchan->name);
+ BLI_assert(ob->type == OB_ARMATURE);
+ const float ctime = BKE_scene_frame_get(scene); /* not accurate... */
+ bArmature *arm = (bArmature *)ob->data;
+ if (arm->flag & ARM_RESTPOS) {
+ return;
+ }
BIK_execute_tree(eval_ctx, scene, ob, rootchan, ctime);
}
@@ -684,8 +691,13 @@ void BKE_pose_splineik_evaluate(const struct EvaluationContext *eval_ctx,
Object *ob,
bPoseChannel *rootchan)
{
- float ctime = BKE_scene_frame_get(scene); /* not accurate... */
DEBUG_PRINT("%s on %s pchan %s\n", __func__, ob->id.name, rootchan->name);
+ BLI_assert(ob->type == OB_ARMATURE);
+ const float ctime = BKE_scene_frame_get(scene); /* not accurate... */
+ bArmature *arm = (bArmature *)ob->data;
+ if (arm->flag & ARM_RESTPOS) {
+ return;
+ }
BKE_splineik_execute_tree(eval_ctx, scene, ob, rootchan, ctime);
}
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index 182b88c1c57..e9a6d0fe5a5 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -45,6 +45,7 @@
#include "IMB_imbuf.h"
#include "IMB_moviecache.h"
+#include "BKE_addon.h"
#include "BKE_blender.h" /* own include */
#include "BKE_blender_version.h" /* own include */
#include "BKE_blendfile.h"
@@ -202,11 +203,7 @@ static void userdef_free_addons(UserDef *userdef)
{
for (bAddon *addon = userdef->addons.first, *addon_next; addon; addon = addon_next) {
addon_next = addon->next;
- if (addon->prop) {
- IDP_FreeProperty(addon->prop);
- MEM_freeN(addon->prop);
- }
- MEM_freeN(addon);
+ BKE_addon_free(addon);
}
BLI_listbase_clear(&userdef->addons);
}
diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c
index 8c78787c259..f440ce711ff 100644
--- a/source/blender/blenkernel/intern/boids.c
+++ b/source/blender/blenkernel/intern/boids.c
@@ -35,7 +35,7 @@
#include "MEM_guardedalloc.h"
-#include "DNA_object_force.h"
+#include "DNA_object_force_types.h"
#include "DNA_scene_types.h"
#include "BLI_rand.h"
diff --git a/source/blender/blenkernel/intern/bpath.c b/source/blender/blenkernel/intern/bpath.c
index 158c6c31432..e9a8de4469d 100644
--- a/source/blender/blenkernel/intern/bpath.c
+++ b/source/blender/blenkernel/intern/bpath.c
@@ -53,8 +53,8 @@
#include "DNA_mesh_types.h"
#include "DNA_modifier_types.h"
#include "DNA_movieclip_types.h"
-#include "DNA_object_fluidsim.h"
-#include "DNA_object_force.h"
+#include "DNA_object_fluidsim_types.h"
+#include "DNA_object_force_types.h"
#include "DNA_object_types.h"
#include "DNA_particle_types.h"
#include "DNA_sequence_types.h"
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index 8d63c1cfb44..d82c1ca56fe 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -151,7 +151,7 @@ void BKE_brush_init(Brush *brush)
/**
* \note Resulting brush will have two users: one as a fake user, another is assumed to be used by the caller.
*/
-Brush *BKE_brush_add(Main *bmain, const char *name, short ob_mode)
+Brush *BKE_brush_add(Main *bmain, const char *name, const eObjectMode ob_mode)
{
Brush *brush;
@@ -164,7 +164,7 @@ Brush *BKE_brush_add(Main *bmain, const char *name, short ob_mode)
return brush;
}
-struct Brush *BKE_brush_first_search(struct Main *bmain, short ob_mode)
+struct Brush *BKE_brush_first_search(struct Main *bmain, const eObjectMode ob_mode)
{
Brush *brush;
diff --git a/source/blender/blenkernel/intern/bullet.c b/source/blender/blenkernel/intern/bullet.c
index 088031e16a7..c16c0f7af31 100644
--- a/source/blender/blenkernel/intern/bullet.c
+++ b/source/blender/blenkernel/intern/bullet.c
@@ -33,7 +33,7 @@
#include "MEM_guardedalloc.h"
/* types */
-#include "DNA_object_force.h" /* here is the softbody struct */
+#include "DNA_object_force_types.h" /* here is the softbody struct */
#include "BKE_bullet.h"
diff --git a/source/blender/blenkernel/intern/bvhutils.c b/source/blender/blenkernel/intern/bvhutils.c
index 775499304d4..cd2c7194237 100644
--- a/source/blender/blenkernel/intern/bvhutils.c
+++ b/source/blender/blenkernel/intern/bvhutils.c
@@ -411,7 +411,7 @@ static BVHTree *bvhtree_from_editmesh_verts_create_tree(
BMVert *eve = BM_vert_at_index(em->bm, i);
BLI_bvhtree_insert(tree, i, eve->co, 1);
}
- BLI_assert(BLI_bvhtree_get_size(tree) == verts_num_active);
+ BLI_assert(BLI_bvhtree_get_len(tree) == verts_num_active);
BLI_bvhtree_balance(tree);
}
@@ -440,7 +440,7 @@ static BVHTree *bvhtree_from_mesh_verts_create_tree(
}
BLI_bvhtree_insert(tree, i, vert[i].co, 1);
}
- BLI_assert(BLI_bvhtree_get_size(tree) == verts_num_active);
+ BLI_assert(BLI_bvhtree_get_len(tree) == verts_num_active);
BLI_bvhtree_balance(tree);
}
@@ -612,7 +612,7 @@ static BVHTree *bvhtree_from_editmesh_edges_create_tree(
BLI_bvhtree_insert(tree, i, co[0], 2);
}
- BLI_assert(BLI_bvhtree_get_size(tree) == edges_num_active);
+ BLI_assert(BLI_bvhtree_get_len(tree) == edges_num_active);
BLI_bvhtree_balance(tree);
}
@@ -829,7 +829,7 @@ static BVHTree *bvhtree_from_mesh_faces_create_tree(
BLI_bvhtree_insert(tree, i, co[0], face[i].v4 ? 4 : 3);
}
}
- BLI_assert(BLI_bvhtree_get_size(tree) == faces_num_active);
+ BLI_assert(BLI_bvhtree_get_len(tree) == faces_num_active);
BLI_bvhtree_balance(tree);
}
}
@@ -990,7 +990,7 @@ static BVHTree *bvhtree_from_editmesh_looptri_create_tree(
}
}
}
- BLI_assert(BLI_bvhtree_get_size(tree) == looptri_num_active);
+ BLI_assert(BLI_bvhtree_get_len(tree) == looptri_num_active);
BLI_bvhtree_balance(tree);
}
}
@@ -1032,7 +1032,7 @@ static BVHTree *bvhtree_from_mesh_looptri_create_tree(
BLI_bvhtree_insert(tree, i, co[0], 3);
}
}
- BLI_assert(BLI_bvhtree_get_size(tree) == looptri_num_active);
+ BLI_assert(BLI_bvhtree_get_len(tree) == looptri_num_active);
BLI_bvhtree_balance(tree);
}
}
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index ea54548ab09..fc860817a83 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -64,6 +64,8 @@
#include "GPU_shader.h"
#include "GPU_basic_shader.h"
+#include "DEG_depsgraph.h"
+
#include <string.h>
#include <limits.h>
#include <math.h>
@@ -260,7 +262,8 @@ static bool can_pbvh_draw(Object *ob, DerivedMesh *dm)
return cddm->mvert == me->mvert || ob->sculpt->kb;
}
-static PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm)
+static PBVH *cdDM_getPBVH(
+ Object *ob, DerivedMesh *dm, eObjectMode UNUSED(object_mode))
{
CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
@@ -3307,7 +3310,7 @@ void CDDM_calc_edges_tessface(DerivedMesh *dm)
}
}
- numEdges = BLI_edgeset_size(eh);
+ numEdges = BLI_edgeset_len(eh);
/* write new edges into a temporary CustomData */
CustomData_reset(&edgeData);
@@ -3376,7 +3379,7 @@ void CDDM_calc_edges(DerivedMesh *dm)
}
}
- numEdges = BLI_edgehash_size(eh);
+ numEdges = BLI_edgehash_len(eh);
/* write new edges into a temporary CustomData */
CustomData_reset(&edgeData);
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index 09b793629f7..22fd0bbfa9c 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -40,6 +40,8 @@
#include "BLI_edgehash.h"
#include "BLI_linklist.h"
+#include "DEG_depsgraph.h"
+
#include "BKE_cdderivedmesh.h"
#include "BKE_cloth.h"
#include "BKE_effect.h"
@@ -304,14 +306,14 @@ void bvhselftree_update_from_cloth(ClothModifierData *clmd, bool moving)
}
}
-void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr)
+void cloth_clear_cache(const EvaluationContext *eval_ctx, Object *ob, ClothModifierData *clmd, float framenr)
{
PTCacheID pid;
BKE_ptcache_id_from_cloth(&pid, ob, clmd);
// don't do anything as long as we're in editmode!
- if (pid.cache->edit && ob->mode & OB_MODE_PARTICLE_EDIT)
+ if (pid.cache->edit && eval_ctx->object_mode & OB_MODE_PARTICLE_EDIT)
return;
BKE_ptcache_id_clear(&pid, PTCACHE_CLEAR_AFTER, framenr);
diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c
index ca77969ccaa..c92096efd07 100644
--- a/source/blender/blenkernel/intern/collection.c
+++ b/source/blender/blenkernel/intern/collection.c
@@ -68,10 +68,9 @@ static SceneCollection *collection_master_from_id(const ID *owner_id)
}
/**
- * Add a collection to a collection ListBase and syncronize all render layers
- * The ListBase is NULL when the collection is to be added to the master collection
+ * Add a new collection, but don't handle syncing with layer collections
*/
-SceneCollection *BKE_collection_add(ID *owner_id, SceneCollection *sc_parent, const int type, const char *name_custom)
+static SceneCollection *collection_add(ID *owner_id, SceneCollection *sc_parent, const int type, const char *name_custom)
{
SceneCollection *sc_master = collection_master_from_id(owner_id);
SceneCollection *sc = MEM_callocN(sizeof(SceneCollection), "New Collection");
@@ -89,17 +88,13 @@ SceneCollection *BKE_collection_add(ID *owner_id, SceneCollection *sc_parent, co
else {
const int number = BLI_listbase_count(&sc_parent->scene_collections) + 1;
const int digits = integer_digits_i(number);
- const int max_len = sizeof(sc_parent->name)
- - 1 /* NULL terminator */
- - (1 + digits) /* " %d" */;
+ const int max_len = sizeof(sc_parent->name) - 1 /* NULL terminator */ - (1 + digits) /* " %d" */;
name = BLI_sprintfN("%.*s %d", max_len, sc_parent->name, number);
}
}
BLI_addtail(&sc_parent->scene_collections, sc);
- BKE_collection_rename((Scene *)owner_id, sc, name);
-
- BKE_layer_sync_new_scene_collection(owner_id, sc_parent, sc);
+ BKE_collection_rename(owner_id, sc, name);
if (name != name_custom) {
MEM_freeN((char *)name);
@@ -109,6 +104,21 @@ SceneCollection *BKE_collection_add(ID *owner_id, SceneCollection *sc_parent, co
}
/**
+ * Add a collection to a collection ListBase and syncronize all render layers
+ * The ListBase is NULL when the collection is to be added to the master collection
+ */
+SceneCollection *BKE_collection_add(ID *owner_id, SceneCollection *sc_parent, const int type, const char *name_custom)
+{
+ if (sc_parent == NULL) {
+ sc_parent = BKE_collection_master(owner_id);
+ }
+
+ SceneCollection *scene_collection = collection_add(owner_id, sc_parent, type, name_custom);
+ BKE_layer_sync_new_scene_collection(owner_id, sc_parent, scene_collection);
+ return scene_collection;
+}
+
+/**
* Free the collection items recursively
*/
static void collection_free(SceneCollection *sc, const bool do_id_user)
@@ -270,6 +280,43 @@ void BKE_collection_copy_data(SceneCollection *sc_dst, SceneCollection *sc_src,
}
}
+/**
+ * Makes a shallow copy of a SceneCollection
+ *
+ * Add a new collection in the same level as the old one, copy any nested collections
+ * but link the objects to the new collection (as oppose to copy them).
+ */
+SceneCollection *BKE_collection_duplicate(ID *owner_id, SceneCollection *scene_collection)
+{
+ SceneCollection *scene_collection_master = BKE_collection_master(owner_id);
+ SceneCollection *scene_collection_parent = find_collection_parent(scene_collection, scene_collection_master);
+
+ /* It's not allowed to copy the master collection. */
+ if (scene_collection_master == scene_collection) {
+ return NULL;
+ }
+
+ SceneCollection *scene_collection_new = collection_add(
+ owner_id,
+ scene_collection_parent,
+ scene_collection->type,
+ scene_collection->name);
+
+ if (scene_collection_new != scene_collection->next) {
+ BLI_remlink(&scene_collection_parent->scene_collections, scene_collection_new);
+ BLI_insertlinkafter(&scene_collection_parent->scene_collections, scene_collection, scene_collection_new);
+ }
+
+ BKE_collection_copy_data(scene_collection_new, scene_collection, 0);
+ BKE_layer_sync_new_scene_collection(owner_id, scene_collection_parent, scene_collection_new);
+
+ /* Make sure every linked instance of the new collection has the same values (flags, overrides, ...) as the
+ * corresponding original collection. */
+ BKE_layer_collection_sync_flags(owner_id, scene_collection_new, scene_collection);
+
+ return scene_collection_new;
+}
+
static SceneCollection *master_collection_from_id(const ID *owner_id)
{
switch (GS(owner_id->name)) {
@@ -298,9 +345,9 @@ static void collection_rename(const ID *owner_id, SceneCollection *sc, const cha
BLI_uniquename(&sc_parent->scene_collections, sc, DATA_("Collection"), '.', offsetof(SceneCollection, name), sizeof(sc->name));
}
-void BKE_collection_rename(const Scene *scene, SceneCollection *sc, const char *name)
+void BKE_collection_rename(const ID *owner_id, SceneCollection *sc, const char *name)
{
- collection_rename(&scene->id, sc, name);
+ collection_rename(owner_id, sc, name);
}
/**
diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c
index 2f80fbbec46..21945f07a10 100644
--- a/source/blender/blenkernel/intern/collision.c
+++ b/source/blender/blenkernel/intern/collision.c
@@ -36,7 +36,7 @@
#include "DNA_effect_types.h"
#include "DNA_group_types.h"
#include "DNA_object_types.h"
-#include "DNA_object_force.h"
+#include "DNA_object_force_types.h"
#include "DNA_scene_types.h"
#include "DNA_meshdata_types.h"
diff --git a/source/blender/blenkernel/intern/colorband.c b/source/blender/blenkernel/intern/colorband.c
index d35e797ddac..f72d4df725a 100644
--- a/source/blender/blenkernel/intern/colorband.c
+++ b/source/blender/blenkernel/intern/colorband.c
@@ -210,7 +210,7 @@ static void colorband_init_from_table_rgba_resample(
while ((carr_len > 1 && !BLI_heap_is_empty(heap)) &&
((carr_len >= MAXCOLORBAND) || (BLI_heap_node_value(BLI_heap_top(heap)) <= eps_2x)))
{
- c = BLI_heap_popmin(heap);
+ c = BLI_heap_pop_min(heap);
struct ColorResampleElem *c_next = c->next, *c_prev = c->prev;
c_prev->next = c_next;
c_next->prev = c_prev;
diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c
index a92299810ec..3d6080b8db9 100644
--- a/source/blender/blenkernel/intern/context.c
+++ b/source/blender/blenkernel/intern/context.c
@@ -1005,7 +1005,7 @@ SceneCollection *CTX_data_scene_collection(const bContext *C)
return BKE_collection_master(&scene->id);
}
-int CTX_data_mode_enum_ex(const Object *obedit, const Object *ob)
+int CTX_data_mode_enum_ex(const Object *obedit, const Object *ob, const eObjectMode object_mode)
{
// Object *obedit = CTX_data_edit_object(C);
if (obedit) {
@@ -1029,12 +1029,12 @@ int CTX_data_mode_enum_ex(const Object *obedit, const Object *ob)
else {
// Object *ob = CTX_data_active_object(C);
if (ob) {
- if (ob->mode & OB_MODE_POSE) return CTX_MODE_POSE;
- else if (ob->mode & OB_MODE_SCULPT) return CTX_MODE_SCULPT;
- else if (ob->mode & OB_MODE_WEIGHT_PAINT) return CTX_MODE_PAINT_WEIGHT;
- else if (ob->mode & OB_MODE_VERTEX_PAINT) return CTX_MODE_PAINT_VERTEX;
- else if (ob->mode & OB_MODE_TEXTURE_PAINT) return CTX_MODE_PAINT_TEXTURE;
- else if (ob->mode & OB_MODE_PARTICLE_EDIT) return CTX_MODE_PARTICLE;
+ if (object_mode & OB_MODE_POSE) return CTX_MODE_POSE;
+ else if (object_mode & OB_MODE_SCULPT) return CTX_MODE_SCULPT;
+ else if (object_mode & OB_MODE_WEIGHT_PAINT) return CTX_MODE_PAINT_WEIGHT;
+ else if (object_mode & OB_MODE_VERTEX_PAINT) return CTX_MODE_PAINT_VERTEX;
+ else if (object_mode & OB_MODE_TEXTURE_PAINT) return CTX_MODE_PAINT_TEXTURE;
+ else if (object_mode & OB_MODE_PARTICLE_EDIT) return CTX_MODE_PARTICLE;
}
}
@@ -1043,9 +1043,10 @@ int CTX_data_mode_enum_ex(const Object *obedit, const Object *ob)
int CTX_data_mode_enum(const bContext *C)
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Object *obedit = CTX_data_edit_object(C);
Object *obact = obedit ? NULL : CTX_data_active_object(C);
- return CTX_data_mode_enum_ex(obedit, obact);
+ return CTX_data_mode_enum_ex(obedit, obact, workspace->object_mode);
}
/* would prefer if we can use the enum version below over this one - Campbell */
@@ -1282,7 +1283,9 @@ void CTX_data_eval_ctx(const bContext *C, EvaluationContext *eval_ctx)
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
RenderEngineType *engine_type = CTX_data_engine_type(C);
- DEG_evaluation_context_init_from_scene(eval_ctx,
- scene, view_layer, engine_type,
- DAG_EVAL_VIEWPORT);
+ WorkSpace *workspace = CTX_wm_workspace(C);
+ DEG_evaluation_context_init_from_scene(
+ eval_ctx,
+ scene, view_layer, engine_type,
+ workspace->object_mode, DAG_EVAL_VIEWPORT);
}
diff --git a/source/blender/blenkernel/intern/curve_decimate.c b/source/blender/blenkernel/intern/curve_decimate.c
index 7983c63c99d..1a6c4714afd 100644
--- a/source/blender/blenkernel/intern/curve_decimate.c
+++ b/source/blender/blenkernel/intern/curve_decimate.c
@@ -159,7 +159,7 @@ static void curve_decimate(
struct Knot *k;
{
- struct Removal *r = BLI_heap_popmin(heap);
+ struct Removal *r = BLI_heap_pop_min(heap);
k = &knots[r->knot_index];
k->heap_node = NULL;
k->prev->handles[1] = r->handles[0];
diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c
index 2591c3c3c47..349f995819c 100644
--- a/source/blender/blenkernel/intern/dynamicpaint.c
+++ b/source/blender/blenkernel/intern/dynamicpaint.c
@@ -4555,7 +4555,7 @@ static int dynamicPaint_paintParticles(DynamicPaintSurface *surface,
}
/* begin thread safe malloc */
- BLI_begin_threaded_malloc();
+ BLI_threaded_malloc_begin();
/* only continue if particle bb is close enough to canvas bb */
if (boundsIntersectDist(&grid->grid_bounds, &part_bb, range)) {
@@ -4590,7 +4590,7 @@ static int dynamicPaint_paintParticles(DynamicPaintSurface *surface,
&settings);
}
}
- BLI_end_threaded_malloc();
+ BLI_threaded_malloc_end();
BLI_kdtree_free(tree);
return 1;
diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c
index 0491cbd21f0..2018962eb62 100644
--- a/source/blender/blenkernel/intern/editderivedmesh.c
+++ b/source/blender/blenkernel/intern/editderivedmesh.c
@@ -44,7 +44,7 @@
#include "atomic_ops.h"
#include "BLI_math.h"
-#include "BLI_jitter.h"
+#include "BLI_jitter_2d.h"
#include "BLI_bitmap.h"
#include "BLI_task.h"
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index 16124fb4777..b54093555f5 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -42,7 +42,7 @@
#include "DNA_listBase.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
-#include "DNA_object_force.h"
+#include "DNA_object_force_types.h"
#include "DNA_particle_types.h"
#include "DNA_texture_types.h"
#include "DNA_scene_types.h"
@@ -221,7 +221,8 @@ ListBase *pdInitEffectors(
if (weights->group) {
view_layer = weights->group->view_layer;
}
- else if (eval_ctx) {
+ /* TODO(mai): the check for view_layer shouldnt be needed, remove when render engine api is updated for this */
+ else if (eval_ctx && eval_ctx->view_layer) {
view_layer = eval_ctx->view_layer;
}
else {
diff --git a/source/blender/blenkernel/intern/fluidsim.c b/source/blender/blenkernel/intern/fluidsim.c
index 12b9abc6d03..a4ed7a9d63f 100644
--- a/source/blender/blenkernel/intern/fluidsim.c
+++ b/source/blender/blenkernel/intern/fluidsim.c
@@ -40,8 +40,8 @@
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
-#include "DNA_object_fluidsim.h"
-#include "DNA_object_force.h" // for pointcache
+#include "DNA_object_fluidsim_types.h"
+#include "DNA_object_force_types.h" // for pointcache
#include "DNA_object_types.h"
#include "DNA_particle_types.h"
#include "DNA_scene_types.h"
diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c
index a314cc0a131..5545eba8764 100644
--- a/source/blender/blenkernel/intern/font.c
+++ b/source/blender/blenkernel/intern/font.c
@@ -1080,8 +1080,13 @@ makebreak:
float distfac, imat[4][4], imat3[3][3], cmat[3][3];
float minx, maxx, miny, maxy;
float timeofs, sizefac;
-
- invert_m4_m4(imat, ob->obmat);
+
+ if (ob != NULL) {
+ invert_m4_m4(imat, ob->obmat);
+ }
+ else {
+ unit_m4(imat);
+ }
copy_m3_m4(imat3, imat);
copy_m3_m4(cmat, cu->textoncurve->obmat);
diff --git a/source/blender/blenkernel/intern/group.c b/source/blender/blenkernel/intern/group.c
index ca6d92efa80..c615f67fe42 100644
--- a/source/blender/blenkernel/intern/group.c
+++ b/source/blender/blenkernel/intern/group.c
@@ -387,7 +387,7 @@ static void group_eval_layer_collections(
ListBase *layer_collections,
LayerCollection *parent_layer_collection)
{
- BLI_LISTBASE_FOREACH (LayerCollection *, layer_collection, layer_collections) {
+ LISTBASE_FOREACH (LayerCollection *, layer_collection, layer_collections) {
/* Evaluate layer collection itself. */
BKE_layer_eval_layer_collection(eval_ctx,
layer_collection,
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index d720dc41abf..d38987c942f 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -2548,7 +2548,7 @@ void BKE_image_verify_viewer_views(const RenderData *rd, Image *ima, ImageUser *
bool do_reset;
const bool is_multiview = (rd->scemode & R_MULTIVIEW) != 0;
- BLI_lock_thread(LOCK_DRAW_IMAGE);
+ BLI_thread_lock(LOCK_DRAW_IMAGE);
if (!BKE_scene_multiview_is_stereo3d(rd))
iuser->flag &= ~IMA_SHOW_STEREO;
@@ -2582,7 +2582,7 @@ void BKE_image_verify_viewer_views(const RenderData *rd, Image *ima, ImageUser *
BLI_spin_unlock(&image_spin);
}
- BLI_unlock_thread(LOCK_DRAW_IMAGE);
+ BLI_thread_unlock(LOCK_DRAW_IMAGE);
}
void BKE_image_walk_all_users(const Main *mainp, void *customdata,
@@ -3663,7 +3663,7 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **r_loc
/* release is done in BKE_image_release_ibuf using r_lock */
if (from_render) {
- BLI_lock_thread(LOCK_VIEWER);
+ BLI_thread_lock(LOCK_VIEWER);
*r_lock = re;
rv = NULL;
}
@@ -3756,7 +3756,7 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **r_loc
}
/* invalidate color managed buffers if render result changed */
- BLI_lock_thread(LOCK_COLORMANAGE);
+ BLI_thread_lock(LOCK_COLORMANAGE);
if (ibuf->x != rres.rectx || ibuf->y != rres.recty || ibuf->rect_float != rectf) {
ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
}
@@ -3797,7 +3797,7 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **r_loc
ibuf->flags &= ~IB_zbuffloat;
}
- BLI_unlock_thread(LOCK_COLORMANAGE);
+ BLI_thread_unlock(LOCK_COLORMANAGE);
ibuf->dither = dither;
@@ -3999,7 +3999,7 @@ static ImBuf *image_acquire_ibuf(Image *ima, ImageUser *iuser, void **r_lock)
/* requires lock/unlock, otherwise don't return image */
if (r_lock) {
/* unlock in BKE_image_release_ibuf */
- BLI_lock_thread(LOCK_VIEWER);
+ BLI_thread_lock(LOCK_VIEWER);
*r_lock = ima;
/* XXX anim play for viewer nodes not yet supported */
@@ -4052,11 +4052,11 @@ void BKE_image_release_ibuf(Image *ima, ImBuf *ibuf, void *lock)
if (lock) {
/* for getting image during threaded render / compositing, need to release */
if (lock == ima) {
- BLI_unlock_thread(LOCK_VIEWER); /* viewer image */
+ BLI_thread_unlock(LOCK_VIEWER); /* viewer image */
}
else if (lock) {
RE_ReleaseResultImage(lock); /* render result */
- BLI_unlock_thread(LOCK_VIEWER); /* view image imbuf */
+ BLI_thread_unlock(LOCK_VIEWER); /* view image imbuf */
}
}
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index c6515d0c47a..8e7b7f5456b 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -61,6 +61,7 @@
/* prototype */
struct EngineSettingsCB_Type;
+static void layer_collections_sync_flags(ListBase *layer_collections_dst, const ListBase *layer_collections_src);
static void layer_collection_free(ViewLayer *view_layer, LayerCollection *lc);
static void layer_collection_objects_populate(ViewLayer *view_layer, LayerCollection *lc, ListBase *objects);
static LayerCollection *layer_collection_add(ViewLayer *view_layer, LayerCollection *parent, SceneCollection *sc);
@@ -353,27 +354,95 @@ static SceneCollection *scene_collection_from_new_tree(
return NULL;
}
+static void layer_collection_sync_flags(
+ LayerCollection *layer_collection_dst,
+ const LayerCollection *layer_collection_src)
+{
+ layer_collection_dst->flag = layer_collection_src->flag;
+
+ if (layer_collection_dst->properties != NULL) {
+ IDP_FreeProperty(layer_collection_dst->properties);
+ MEM_SAFE_FREE(layer_collection_dst->properties);
+ }
+
+ if (layer_collection_src->properties != NULL) {
+ layer_collection_dst->properties = IDP_CopyProperty(layer_collection_src->properties);
+ }
+
+ layer_collections_sync_flags(&layer_collection_dst->layer_collections,
+ &layer_collection_src->layer_collections);
+}
+
static void layer_collections_sync_flags(ListBase *layer_collections_dst, const ListBase *layer_collections_src)
{
+ BLI_assert(BLI_listbase_count(layer_collections_dst) == BLI_listbase_count(layer_collections_src));
LayerCollection *layer_collection_dst = (LayerCollection *)layer_collections_dst->first;
const LayerCollection *layer_collection_src = (const LayerCollection *)layer_collections_src->first;
while (layer_collection_dst != NULL) {
- layer_collection_dst->flag = layer_collection_src->flag;
+ layer_collection_sync_flags(layer_collection_dst, layer_collection_src);
+ layer_collection_dst = layer_collection_dst->next;
+ layer_collection_src = layer_collection_src->next;
+ }
+}
- if (layer_collection_dst->properties != NULL) {
- IDP_FreeProperty(layer_collection_dst->properties);
- MEM_SAFE_FREE(layer_collection_dst->properties);
+static bool layer_collection_sync_if_match(
+ ListBase *lb,
+ const SceneCollection *scene_collection_dst,
+ const SceneCollection *scene_collection_src)
+{
+ for (LayerCollection *layer_collection = lb->first;
+ layer_collection;
+ layer_collection = layer_collection->next)
+ {
+ if (layer_collection->scene_collection == scene_collection_src) {
+ LayerCollection *layer_collection_dst =
+ BLI_findptr(
+ lb,
+ scene_collection_dst,
+ offsetof(LayerCollection, scene_collection));
+
+ if (layer_collection_dst != NULL) {
+ layer_collection_sync_flags(layer_collection_dst, layer_collection);
+ }
+ return true;
}
-
- if (layer_collection_src->properties != NULL) {
- layer_collection_dst->properties = IDP_CopyProperty(layer_collection_src->properties);
+ else {
+ if (layer_collection_sync_if_match(
+ &layer_collection->layer_collections,
+ scene_collection_dst,
+ scene_collection_src))
+ {
+ return true;
+ }
}
+ }
+ return false;
+}
- layer_collections_sync_flags(&layer_collection_dst->layer_collections,
- &layer_collection_src->layer_collections);
-
- layer_collection_dst = layer_collection_dst->next;
- layer_collection_src = layer_collection_src->next;
+/**
+ * Sync sibling collections across all view layers
+ *
+ * Make sure every linked instance of \a scene_collection_dst has the same values
+ * (flags, overrides, ...) as the corresponding scene_collection_src.
+ *
+ * \note expect scene_collection_dst to be scene_collection_src->next, and it also
+ * expects both collections to have the same ammount of sub-collections.
+ */
+void BKE_layer_collection_sync_flags(
+ ID *owner_id,
+ SceneCollection *scene_collection_dst,
+ SceneCollection *scene_collection_src)
+{
+ for (ViewLayer *view_layer = BKE_view_layer_first_from_id(owner_id); view_layer; view_layer = view_layer->next) {
+ for (LayerCollection *layer_collection = view_layer->layer_collections.first;
+ layer_collection;
+ layer_collection = layer_collection->next)
+ {
+ layer_collection_sync_if_match(
+ &layer_collection->layer_collections,
+ scene_collection_dst,
+ scene_collection_src);
+ }
}
}
@@ -438,6 +507,78 @@ void BKE_view_layer_copy_data(
}
}
+/**
+ * Find and return the ListBase of LayerCollection that has \a lc_child as one of its directly
+ * nested LayerCollection.
+ *
+ * \param lb_parent Initial ListBase of LayerCollection to look into recursively
+ * usually the view layer's collection list
+ */
+static ListBase *find_layer_collection_parent_list_base(ListBase *lb_parent, const LayerCollection *lc_child)
+{
+ for (LayerCollection *lc_nested = lb_parent->first; lc_nested; lc_nested = lc_nested->next) {
+ if (lc_nested == lc_child) {
+ return lb_parent;
+ }
+
+ ListBase *found = find_layer_collection_parent_list_base(&lc_nested->layer_collections, lc_child);
+ if (found != NULL) {
+ return found;
+ }
+ }
+
+ return NULL;
+}
+
+/**
+ * Makes a shallow copy of a LayerCollection
+ *
+ * Add a new collection in the same level as the old one (linking if necessary),
+ * and copy all the collection data across them.
+ */
+struct LayerCollection *BKE_layer_collection_duplicate(struct ID *owner_id, struct LayerCollection *layer_collection)
+{
+ SceneCollection *scene_collection, *scene_collection_new;
+
+ scene_collection = layer_collection->scene_collection;
+ scene_collection_new = BKE_collection_duplicate(owner_id, scene_collection);
+
+ LayerCollection *layer_collection_new = NULL;
+
+ /* If the original layer_collection was directly linked to the view layer
+ we need to link the new scene collection here as well. */
+ for (ViewLayer *view_layer = BKE_view_layer_first_from_id(owner_id); view_layer; view_layer = view_layer->next) {
+ if (BLI_findindex(&view_layer->layer_collections, layer_collection) != -1) {
+ layer_collection_new = BKE_collection_link(view_layer, scene_collection_new);
+ layer_collection_sync_flags(layer_collection_new, layer_collection);
+
+ if (layer_collection_new != layer_collection->next) {
+ BLI_remlink(&view_layer->layer_collections, layer_collection_new);
+ BLI_insertlinkafter(&view_layer->layer_collections, layer_collection, layer_collection_new);
+ }
+ break;
+ }
+ }
+
+ /* Otherwise just try to find the corresponding layer collection to return it back. */
+ if (layer_collection_new == NULL) {
+ for (ViewLayer *view_layer = BKE_view_layer_first_from_id(owner_id); view_layer; view_layer = view_layer->next) {
+ ListBase *layer_collections_parent;
+ layer_collections_parent = find_layer_collection_parent_list_base(
+ &view_layer->layer_collections,
+ layer_collection);
+ if (layer_collections_parent != NULL) {
+ layer_collection_new = BLI_findptr(
+ layer_collections_parent,
+ scene_collection_new,
+ offsetof(LayerCollection, scene_collection));
+ break;
+ }
+ }
+ }
+ return layer_collection_new;
+}
+
static void view_layer_object_base_unref(ViewLayer *view_layer, Base *base)
{
base->refcount--;
@@ -988,6 +1129,34 @@ void BKE_layer_collection_resync(const ID *owner_id, const SceneCollection *sc)
/* ---------------------------------------------------------------------- */
/**
+ * Select all the objects of this layer collection
+ *
+ * It also select the objects that are in nested collections.
+ * \note Recursive
+ */
+void BKE_layer_collection_objects_select(struct LayerCollection *layer_collection)
+{
+ if ((layer_collection->flag & COLLECTION_DISABLED) ||
+ ((layer_collection->flag & COLLECTION_SELECTABLE) == 0))
+ {
+ return;
+ }
+
+ for (LinkData *link = layer_collection->object_bases.first; link; link = link->next) {
+ Base *base = link->data;
+ if (base->flag & BASE_SELECTABLED) {
+ base->flag |= BASE_SELECTED;
+ }
+ }
+
+ for (LayerCollection *iter = layer_collection->layer_collections.first; iter; iter = iter->next) {
+ BKE_layer_collection_objects_select(iter);
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+/**
* Link a collection to a renderlayer
* The collection needs to be created separately
*/
@@ -1970,10 +2139,11 @@ void BKE_renderable_objects_iterator_begin(BLI_Iterator *iter, void *data_in)
{
ObjectsRenderableIteratorData *data = data_in;
+ /* Tag objects to prevent going over the same object twice. */
for (Scene *scene = data->scene; scene; scene = scene->set) {
for (ViewLayer *view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) {
for (Base *base = view_layer->object_bases.first; base; base = base->next) {
- base->object->id.flag |= LIB_TAG_DOIT;
+ base->object->id.flag |= LIB_TAG_DOIT;
}
}
}
@@ -1981,8 +2151,8 @@ void BKE_renderable_objects_iterator_begin(BLI_Iterator *iter, void *data_in)
ViewLayer *view_layer = data->scene->view_layers.first;
data->iter.view_layer = view_layer;
- Base base = {(Base *)view_layer->object_bases.first, NULL};
- data->iter.base = &base;
+ data->base_temp.next = view_layer->object_bases.first;
+ data->iter.base = &data->base_temp;
data->iter.set = NULL;
@@ -1992,6 +2162,9 @@ void BKE_renderable_objects_iterator_begin(BLI_Iterator *iter, void *data_in)
void BKE_renderable_objects_iterator_next(BLI_Iterator *iter)
{
+ /* Set it early in case we need to exit and we are running from within a loop. */
+ iter->skip = true;
+
ObjectsRenderableIteratorData *data = iter->data;
Base *base = data->iter.base->next;
@@ -1999,11 +2172,17 @@ void BKE_renderable_objects_iterator_next(BLI_Iterator *iter)
if (base != NULL) {
Object *ob = base->object;
- iter->current = ob;
+ /* We need to set the iter.base even if the rest fail otherwise
+ * we keep checking the exactly same base over and over again. */
data->iter.base = base;
- if ((base->flag & BASE_VISIBLED) == 0) {
- BKE_renderable_objects_iterator_next(iter);
+ if (ob->id.flag & LIB_TAG_DOIT) {
+ ob->id.flag &= ~LIB_TAG_DOIT;
+
+ if ((base->flag & BASE_VISIBLED) != 0) {
+ iter->skip = false;
+ iter->current = ob;
+ }
}
return;
}
@@ -2013,30 +2192,23 @@ void BKE_renderable_objects_iterator_next(BLI_Iterator *iter)
while ((data->iter.view_layer = data->iter.view_layer->next)) {
ViewLayer *view_layer = data->iter.view_layer;
if (view_layer->flag & VIEW_LAYER_RENDER) {
-
- Base base_iter = {(Base *)view_layer->object_bases.first, NULL};
- data->iter.base = &base_iter;
-
- BKE_renderable_objects_iterator_next(iter);
+ data->base_temp.next = view_layer->object_bases.first;
+ data->iter.base = &data->base_temp;
return;
}
}
/* Setup the "set" for the next iteration. */
- Scene scene = {.set = data->scene};
- data->iter.set = &scene;
- BKE_renderable_objects_iterator_next(iter);
+ data->scene_temp.set = data->scene;
+ data->iter.set = &data->scene_temp;
return;
}
/* Look for an object in the next set. */
while ((data->iter.set = data->iter.set->set)) {
ViewLayer *view_layer = BKE_view_layer_from_scene_get(data->iter.set);
-
- Base base_iter = {(Base *)view_layer->object_bases.first, NULL};
- data->iter.base = &base_iter;
-
- BKE_renderable_objects_iterator_next(iter);
+ data->base_temp.next = view_layer->object_bases.first;
+ data->iter.base = &data->base_temp;
return;
}
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index 066b3e34b0d..e0608efece2 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -2129,7 +2129,7 @@ void BKE_library_make_local(
GSet *loop_tags = BLI_gset_ptr_new(__func__);
for (LinkNode *it = todo_ids; it; it = it->next) {
library_make_local_copying_check(it->link, loop_tags, bmain->relations, done_ids);
- BLI_assert(BLI_gset_size(loop_tags) == 0);
+ BLI_assert(BLI_gset_len(loop_tags) == 0);
}
BLI_gset_free(loop_tags, NULL);
BLI_gset_free(done_ids, NULL);
diff --git a/source/blender/blenkernel/intern/library_query.c b/source/blender/blenkernel/intern/library_query.c
index 6c5931263d8..419ed8246db 100644
--- a/source/blender/blenkernel/intern/library_query.c
+++ b/source/blender/blenkernel/intern/library_query.c
@@ -51,7 +51,7 @@
#include "DNA_movieclip_types.h"
#include "DNA_mask_types.h"
#include "DNA_node_types.h"
-#include "DNA_object_force.h"
+#include "DNA_object_force_types.h"
#include "DNA_lightprobe_types.h"
#include "DNA_rigidbody_types.h"
#include "DNA_scene_types.h"
@@ -421,10 +421,6 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call
/* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
library_foreach_ID_as_subdata_link((ID **)&scene->nodetree, callback, user_data, flag, &data);
}
- /* DO NOT handle scene->basact here, it's doubling with the loop over whole scene->base later,
- * since basact is just a pointer to one of those items. */
- CALLBACK_INVOKE(scene->obedit, IDWALK_CB_NOP);
-
if (scene->ed) {
Sequence *seq;
SEQP_BEGIN(scene->ed, seq)
diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c
index 5a0ac86823f..cc801b2d8c3 100644
--- a/source/blender/blenkernel/intern/mball.c
+++ b/source/blender/blenkernel/intern/mball.c
@@ -549,9 +549,9 @@ void BKE_mball_eval_geometry(const struct EvaluationContext *UNUSED(eval_ctx),
/* Draw Engine */
/* use for draw-manager only. */
-void BKE_mball_element_calc_display_m3x4(float r_scale_xform[3][4],
- const float obmat[4][4],
- const float local_pos[3])
+void BKE_mball_element_calc_scale_xform(float r_scale_xform[3][4],
+ const float obmat[4][4],
+ const float local_pos[3])
{
float world_pos[3], scamat[3][3];
mul_v3_m4v3(world_pos, obmat, local_pos);
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 3217c234718..d3c74f71f78 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -1044,7 +1044,7 @@ static void make_edges_mdata_extend(MEdge **r_alledge, int *r_totedge,
BKE_mesh_poly_edgehash_insert(eh, mp, mloop + mp->loopstart);
}
- totedge_new = BLI_edgehash_size(eh);
+ totedge_new = BLI_edgehash_len(eh);
#ifdef DEBUG
/* ensure that theres no overlap! */
diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.c
index 00d1b29caf8..c7678be18c7 100644
--- a/source/blender/blenkernel/intern/mesh_evaluate.c
+++ b/source/blender/blenkernel/intern/mesh_evaluate.c
@@ -43,7 +43,7 @@
#include "BLI_math.h"
#include "BLI_edgehash.h"
#include "BLI_bitmap.h"
-#include "BLI_polyfill2d.h"
+#include "BLI_polyfill_2d.h"
#include "BLI_linklist.h"
#include "BLI_linklist_stack.h"
#include "BLI_alloca.h"
@@ -253,16 +253,6 @@ static void mesh_calc_normals_poly_prepare_cb(
}
}
-static void mesh_calc_normals_poly_accum_cb(
- void *__restrict userdata,
- const int lidx,
- const ParallelRangeTLS *__restrict UNUSED(tls))
-{
- MeshCalcNormalsData *data = userdata;
-
- add_v3_v3(data->vnors[data->mloop[lidx].v], data->lnors_weighted[lidx]);
-}
-
static void mesh_calc_normals_poly_finalize_cb(
void *__restrict userdata,
const int vidx,
@@ -327,7 +317,11 @@ void BKE_mesh_calc_normals_poly(
BLI_task_parallel_range(0, numPolys, &data, mesh_calc_normals_poly_prepare_cb, &settings);
/* Actually accumulate weighted loop normals into vertex ones. */
- BLI_task_parallel_range(0, numLoops, &data, mesh_calc_normals_poly_accum_cb, &settings);
+ /* Unfortunately, not possible to thread that (not in a reasonable, totally lock- and barrier-free fashion),
+ * since several loops will point to the same vertex... */
+ for (int lidx = 0; lidx < numLoops; lidx++) {
+ add_v3_v3(vnors[mloop[lidx].v], data.lnors_weighted[lidx]);
+ }
/* Normalize and validate computed vertex normals. */
BLI_task_parallel_range(0, numVerts, &data, mesh_calc_normals_poly_finalize_cb, &settings);
@@ -2798,9 +2792,22 @@ void BKE_mesh_recalc_looptri(
}
else if (mp_totloop == 4) {
ML_TO_MLT(0, 1, 2);
+ MLoopTri *mlt_a = mlt;
mlooptri_index++;
ML_TO_MLT(0, 2, 3);
+ MLoopTri *mlt_b = mlt;
mlooptri_index++;
+
+ if (UNLIKELY(is_quad_flip_v3_first_third_fast(
+ mvert[mloop[mlt_a->tri[0]].v].co,
+ mvert[mloop[mlt_a->tri[1]].v].co,
+ mvert[mloop[mlt_a->tri[2]].v].co,
+ mvert[mloop[mlt_b->tri[2]].v].co)))
+ {
+ /* flip out of degenerate 0-2 state. */
+ mlt_a->tri[2] = mlt_b->tri[2];
+ mlt_b->tri[0] = mlt_a->tri[1];
+ }
}
#endif /* USE_TESSFACE_SPEEDUP */
else {
diff --git a/source/blender/blenkernel/intern/mesh_remap.c b/source/blender/blenkernel/intern/mesh_remap.c
index f321c94bf00..0af4dae4506 100644
--- a/source/blender/blenkernel/intern/mesh_remap.c
+++ b/source/blender/blenkernel/intern/mesh_remap.c
@@ -36,7 +36,7 @@
#include "BLI_bitmap.h"
#include "BLI_math.h"
#include "BLI_memarena.h"
-#include "BLI_polyfill2d.h"
+#include "BLI_polyfill_2d.h"
#include "BLI_rand.h"
#include "BKE_bvhutils.h"
diff --git a/source/blender/blenkernel/intern/mesh_validate.c b/source/blender/blenkernel/intern/mesh_validate.c
index 54de843bc64..f7509d07ca4 100644
--- a/source/blender/blenkernel/intern/mesh_validate.c
+++ b/source/blender/blenkernel/intern/mesh_validate.c
@@ -1412,7 +1412,7 @@ void BKE_mesh_calc_edges(Mesh *mesh, bool update, const bool select)
}
}
- totedge = BLI_edgehash_size(eh);
+ totedge = BLI_edgehash_len(eh);
/* write new edges into a temporary CustomData */
CustomData_reset(&edata);
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index 8bfeacd256c..1604a017054 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -69,6 +69,8 @@
#include "BKE_main.h"
/* end */
+#include "DEG_depsgraph.h"
+
#include "MOD_modifiertypes.h"
static ModifierTypeInfo *modifier_types[NUM_MODIFIER_TYPES] = {NULL};
@@ -660,15 +662,15 @@ bool modifier_isCorrectableDeformed(ModifierData *md)
return (mti->deformMatricesEM != NULL);
}
-bool modifiers_isCorrectableDeformed(struct Scene *scene, Object *ob)
+bool modifiers_isCorrectableDeformed(const EvaluationContext *eval_ctx, struct Scene *scene, Object *ob)
{
VirtualModifierData virtualModifierData;
ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
int required_mode = eModifierMode_Realtime;
- if (ob->mode == OB_MODE_EDIT)
+ if (eval_ctx->object_mode == OB_MODE_EDIT) {
required_mode |= eModifierMode_Editmode;
-
+ }
for (; md; md = md->next) {
if (!modifier_isEnabled(scene, md, required_mode)) {
/* pass */
diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c
index 08df976941b..a416de07c6d 100644
--- a/source/blender/blenkernel/intern/movieclip.c
+++ b/source/blender/blenkernel/intern/movieclip.c
@@ -926,7 +926,7 @@ static ImBuf *movieclip_get_postprocessed_ibuf(MovieClip *clip,
/* cache isn't threadsafe itself and also loading of movies
* can't happen from concurrent threads that's why we use lock here */
- BLI_lock_thread(LOCK_MOVIECLIP);
+ BLI_thread_lock(LOCK_MOVIECLIP);
/* try to obtain cached postprocessed frame first */
if (need_postprocessed_frame(user, postprocess_flag)) {
@@ -976,7 +976,7 @@ static ImBuf *movieclip_get_postprocessed_ibuf(MovieClip *clip,
}
}
- BLI_unlock_thread(LOCK_MOVIECLIP);
+ BLI_thread_unlock(LOCK_MOVIECLIP);
return ibuf;
}
@@ -1410,13 +1410,13 @@ static void movieclip_build_proxy_ibuf(MovieClip *clip, ImBuf *ibuf, int cfra, i
* could be solved in a way that thread only prepares memory
* buffer and write to disk happens separately
*/
- BLI_lock_thread(LOCK_MOVIECLIP);
+ BLI_thread_lock(LOCK_MOVIECLIP);
BLI_make_existing_file(name);
if (IMB_saveiff(scaleibuf, name, IB_rect) == 0)
perror(name);
- BLI_unlock_thread(LOCK_MOVIECLIP);
+ BLI_thread_unlock(LOCK_MOVIECLIP);
IMB_freeImBuf(scaleibuf);
}
@@ -1560,9 +1560,9 @@ ImBuf *BKE_movieclip_anim_ibuf_for_frame(MovieClip *clip, MovieClipUser *user)
ImBuf *ibuf = NULL;
if (clip->source == MCLIP_SRC_MOVIE) {
- BLI_lock_thread(LOCK_MOVIECLIP);
+ BLI_thread_lock(LOCK_MOVIECLIP);
ibuf = movieclip_load_movie_file(clip, user, user->framenr, clip->flag);
- BLI_unlock_thread(LOCK_MOVIECLIP);
+ BLI_thread_unlock(LOCK_MOVIECLIP);
}
return ibuf;
@@ -1572,9 +1572,9 @@ bool BKE_movieclip_has_cached_frame(MovieClip *clip, MovieClipUser *user)
{
bool has_frame = false;
- BLI_lock_thread(LOCK_MOVIECLIP);
+ BLI_thread_lock(LOCK_MOVIECLIP);
has_frame = has_imbuf_cache(clip, user, clip->flag);
- BLI_unlock_thread(LOCK_MOVIECLIP);
+ BLI_thread_unlock(LOCK_MOVIECLIP);
return has_frame;
}
@@ -1585,9 +1585,9 @@ bool BKE_movieclip_put_frame_if_possible(MovieClip *clip,
{
bool result;
- BLI_lock_thread(LOCK_MOVIECLIP);
+ BLI_thread_lock(LOCK_MOVIECLIP);
result = put_imbuf_cache(clip, user, ibuf, clip->flag, false);
- BLI_unlock_thread(LOCK_MOVIECLIP);
+ BLI_thread_unlock(LOCK_MOVIECLIP);
return result;
}
diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c
index 55f11604710..e7c36685c42 100644
--- a/source/blender/blenkernel/intern/multires.c
+++ b/source/blender/blenkernel/intern/multires.c
@@ -60,6 +60,8 @@
#include "BKE_object.h"
+#include "DEG_depsgraph.h"
+
#include "CCGSubSurf.h"
#include <math.h>
@@ -336,12 +338,13 @@ MultiresModifierData *get_multires_modifier(Scene *scene, Object *ob, bool use_f
return mmd;
}
-static int multires_get_level(Object *ob, MultiresModifierData *mmd,
- bool render, bool ignore_simplify)
+static int multires_get_level(
+ MultiresModifierData *mmd,
+ bool render, bool ignore_simplify, eObjectMode object_mode)
{
if (render)
return (mmd->modifier.scene) ? get_render_subsurf_level(&mmd->modifier.scene->r, mmd->renderlvl, true) : mmd->renderlvl;
- else if (ob->mode == OB_MODE_SCULPT)
+ else if (object_mode == OB_MODE_SCULPT)
return mmd->sculptlvl;
else if (ignore_simplify)
return mmd->lvl;
@@ -349,12 +352,13 @@ static int multires_get_level(Object *ob, MultiresModifierData *mmd,
return (mmd->modifier.scene) ? get_render_subsurf_level(&mmd->modifier.scene->r, mmd->lvl, false) : mmd->lvl;
}
-void multires_set_tot_level(Object *ob, MultiresModifierData *mmd, int lvl)
+void multires_set_tot_level(MultiresModifierData *mmd, int lvl, eObjectMode object_mode)
{
mmd->totlvl = lvl;
- if (ob->mode != OB_MODE_SCULPT)
+ if (object_mode != OB_MODE_SCULPT) {
mmd->lvl = CLAMPIS(MAX2(mmd->lvl, lvl), 0, mmd->totlvl);
+ }
mmd->sculptlvl = CLAMPIS(MAX2(mmd->sculptlvl, lvl), 0, mmd->totlvl);
mmd->renderlvl = CLAMPIS(MAX2(mmd->renderlvl, lvl), 0, mmd->totlvl);
@@ -392,9 +396,9 @@ void multires_force_external_reload(Object *ob)
multires_force_update(ob);
}
-void multires_force_render_update(Object *ob)
+void multires_force_render_update(Object *ob, eObjectMode object_mode)
{
- if (ob && (ob->mode & OB_MODE_SCULPT) && modifiers_findByType(ob, eModifierType_Multires))
+ if (ob && (object_mode & OB_MODE_SCULPT) && modifiers_findByType(ob, eModifierType_Multires))
multires_force_update(ob);
}
@@ -434,7 +438,7 @@ int multiresModifier_reshapeFromDeformMod(const struct EvaluationContext *eval_c
int numVerts, result;
float (*deformedVerts)[3];
- if (multires_get_level(ob, mmd, false, true) == 0)
+ if (multires_get_level(mmd, false, true, eval_ctx->object_mode) == 0)
return 0;
/* Create DerivedMesh for deformation modifier */
@@ -614,7 +618,7 @@ static void multires_grid_paint_mask_downsample(GridPaintMask *gpm, int level)
}
}
-static void multires_del_higher(MultiresModifierData *mmd, Object *ob, int lvl)
+static void multires_del_higher(MultiresModifierData *mmd, Object *ob, int lvl, eObjectMode object_mode)
{
Mesh *me = (Mesh *)ob->data;
int levels = mmd->totlvl - lvl;
@@ -676,14 +680,14 @@ static void multires_del_higher(MultiresModifierData *mmd, Object *ob, int lvl)
}
}
- multires_set_tot_level(ob, mmd, lvl);
+ multires_set_tot_level(mmd, lvl, object_mode);
}
/* (direction = 1) for delete higher, (direction = 0) for lower (not implemented yet) */
-void multiresModifier_del_levels(MultiresModifierData *mmd, Object *ob, int direction)
+void multiresModifier_del_levels(MultiresModifierData *mmd, Object *ob, int direction, eObjectMode object_mode)
{
Mesh *me = BKE_mesh_from_object(ob);
- int lvl = multires_get_level(ob, mmd, false, true);
+ int lvl = multires_get_level(mmd, false, true, object_mode);
int levels = mmd->totlvl - lvl;
MDisps *mdisps;
@@ -694,13 +698,14 @@ void multiresModifier_del_levels(MultiresModifierData *mmd, Object *ob, int dire
multires_force_update(ob);
if (mdisps && levels > 0 && direction == 1) {
- multires_del_higher(mmd, ob, lvl);
+ multires_del_higher(mmd, ob, lvl, object_mode);
}
- multires_set_tot_level(ob, mmd, lvl);
+ multires_set_tot_level(mmd, lvl, object_mode);
}
-static DerivedMesh *multires_dm_create_local(Object *ob, DerivedMesh *dm, int lvl, int totlvl, int simple, bool alloc_paint_mask)
+static DerivedMesh *multires_dm_create_local(
+ Object *ob, DerivedMesh *dm, int lvl, int totlvl, int simple, bool alloc_paint_mask, eObjectMode object_mode)
{
MultiresModifierData mmd = {{NULL}};
MultiresFlags flags = MULTIRES_USE_LOCAL_MMD;
@@ -714,10 +719,12 @@ static DerivedMesh *multires_dm_create_local(Object *ob, DerivedMesh *dm, int lv
if (alloc_paint_mask)
flags |= MULTIRES_ALLOC_PAINT_MASK;
- return multires_make_derived_from_derived(dm, &mmd, ob, flags);
+ return multires_make_derived_from_derived(dm, &mmd, ob, flags, object_mode);
}
-static DerivedMesh *subsurf_dm_create_local(Object *ob, DerivedMesh *dm, int lvl, int simple, int optimal, int plain_uv, int alloc_paint_mask)
+static DerivedMesh *subsurf_dm_create_local(
+ DerivedMesh *dm, int lvl, int simple,
+ int optimal, int plain_uv, int alloc_paint_mask, eObjectMode object_mode)
{
SubsurfModifierData smd = {{NULL}};
SubsurfFlags flags = 0;
@@ -730,7 +737,7 @@ static DerivedMesh *subsurf_dm_create_local(Object *ob, DerivedMesh *dm, int lvl
if (optimal)
smd.flags |= eSubsurfModifierFlag_ControlEdges;
- if (ob->mode & OB_MODE_EDIT)
+ if (object_mode & OB_MODE_EDIT)
flags |= SUBSURF_IN_EDIT_MODE;
if (alloc_paint_mask)
@@ -750,7 +757,7 @@ static float v3_dist_from_plane(float v[3], float center[3], float no[3])
return dot_v3v3(s, no);
}
-void multiresModifier_base_apply(MultiresModifierData *mmd, Object *ob)
+void multiresModifier_base_apply(MultiresModifierData *mmd, Object *ob, eObjectMode object_mode)
{
DerivedMesh *cddm, *dispdm, *origdm;
Mesh *me;
@@ -772,7 +779,7 @@ void multiresModifier_base_apply(MultiresModifierData *mmd, Object *ob)
/* generate highest level with displacements */
cddm = CDDM_from_mesh(me);
DM_set_only_copy(cddm, CD_MASK_BAREMESH);
- dispdm = multires_dm_create_local(ob, cddm, totlvl, totlvl, 0, 0);
+ dispdm = multires_dm_create_local(ob, cddm, totlvl, totlvl, 0, 0, object_mode);
cddm->release(cddm);
/* copy the new locations of the base verts into the mesh */
@@ -868,7 +875,9 @@ void multiresModifier_base_apply(MultiresModifierData *mmd, Object *ob)
/* subdivide the mesh to highest level without displacements */
cddm = CDDM_from_mesh(me);
DM_set_only_copy(cddm, CD_MASK_BAREMESH);
- origdm = subsurf_dm_create_local(ob, cddm, totlvl, 0, 0, mmd->flags & eMultiresModifierFlag_PlainUv, 0);
+ origdm = subsurf_dm_create_local(
+ cddm, totlvl, 0,
+ 0, mmd->flags & eMultiresModifierFlag_PlainUv, 0, object_mode);
cddm->release(cddm);
/* calc disps */
@@ -878,7 +887,8 @@ void multiresModifier_base_apply(MultiresModifierData *mmd, Object *ob)
dispdm->release(dispdm);
}
-static void multires_subdivide(MultiresModifierData *mmd, Object *ob, int totlvl, int updateblock, int simple)
+static void multires_subdivide(
+ MultiresModifierData *mmd, Object *ob, int totlvl, int updateblock, int simple, eObjectMode object_mode)
{
Mesh *me = ob->data;
MDisps *mdisps;
@@ -907,11 +917,13 @@ static void multires_subdivide(MultiresModifierData *mmd, Object *ob, int totlvl
/* create subsurf DM from original mesh at high level */
cddm = CDDM_from_mesh(me);
DM_set_only_copy(cddm, CD_MASK_BAREMESH);
- highdm = subsurf_dm_create_local(ob, cddm, totlvl, simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, has_mask);
+ highdm = subsurf_dm_create_local(
+ cddm, totlvl, simple,
+ 0, mmd->flags & eMultiresModifierFlag_PlainUv, has_mask, object_mode);
ss = ((CCGDerivedMesh *)highdm)->ss;
/* create multires DM from original mesh at low level */
- lowdm = multires_dm_create_local(ob, cddm, lvl, lvl, simple, has_mask);
+ lowdm = multires_dm_create_local(ob, cddm, lvl, lvl, simple, has_mask, object_mode);
BLI_assert(lowdm != cddm);
cddm->release(cddm);
@@ -958,12 +970,13 @@ static void multires_subdivide(MultiresModifierData *mmd, Object *ob, int totlvl
multires_reallocate_mdisps(me->totloop, mdisps, totlvl);
}
- multires_set_tot_level(ob, mmd, totlvl);
+ multires_set_tot_level(mmd, totlvl, object_mode);
}
-void multiresModifier_subdivide(MultiresModifierData *mmd, Object *ob, int updateblock, int simple)
+void multiresModifier_subdivide(
+ MultiresModifierData *mmd, Object *ob, int updateblock, int simple, eObjectMode object_mode)
{
- multires_subdivide(mmd, ob, mmd->totlvl + 1, updateblock, simple);
+ multires_subdivide(mmd, ob, mmd->totlvl + 1, updateblock, simple, object_mode);
}
static void grid_tangent(const CCGKey *key, int x, int y, int axis, CCGElem *grid, float t[3])
@@ -1196,7 +1209,7 @@ static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, DerivedMesh *dm
}
}
-void multires_modifier_update_mdisps(struct DerivedMesh *dm)
+void multires_modifier_update_mdisps(struct DerivedMesh *dm, eObjectMode object_mode)
{
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
Object *ob;
@@ -1228,11 +1241,13 @@ void multires_modifier_update_mdisps(struct DerivedMesh *dm)
else cddm = CDDM_from_mesh(me);
DM_set_only_copy(cddm, CD_MASK_BAREMESH);
- highdm = subsurf_dm_create_local(ob, cddm, totlvl, mmd->simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, has_mask);
+ highdm = subsurf_dm_create_local(
+ cddm, totlvl, mmd->simple,
+ 0, mmd->flags & eMultiresModifierFlag_PlainUv, has_mask, object_mode);
ss = ((CCGDerivedMesh *)highdm)->ss;
/* create multires DM from original mesh and displacements */
- lowdm = multires_dm_create_local(ob, cddm, lvl, totlvl, mmd->simple, has_mask);
+ lowdm = multires_dm_create_local(ob, cddm, lvl, totlvl, mmd->simple, has_mask, object_mode);
cddm->release(cddm);
/* gather grid data */
@@ -1290,7 +1305,9 @@ void multires_modifier_update_mdisps(struct DerivedMesh *dm)
else cddm = CDDM_from_mesh(me);
DM_set_only_copy(cddm, CD_MASK_BAREMESH);
- subdm = subsurf_dm_create_local(ob, cddm, mmd->totlvl, mmd->simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, has_mask);
+ subdm = subsurf_dm_create_local(
+ cddm, mmd->totlvl, mmd->simple,
+ 0, mmd->flags & eMultiresModifierFlag_PlainUv, has_mask, object_mode);
cddm->release(cddm);
multiresModifier_disp_run(dm, me, NULL, CALC_DISPLACEMENTS, subdm->getGridData(subdm), mmd->totlvl);
@@ -1332,7 +1349,7 @@ void multires_modifier_update_hidden(DerivedMesh *dm)
}
}
-void multires_set_space(DerivedMesh *dm, Object *ob, int from, int to)
+void multires_set_space(DerivedMesh *dm, Object *ob, int from, int to, eObjectMode object_mode)
{
DerivedMesh *ccgdm = NULL, *subsurf = NULL;
CCGElem **gridData, **subGridData = NULL;
@@ -1353,10 +1370,11 @@ void multires_set_space(DerivedMesh *dm, Object *ob, int from, int to)
}
totlvl = mmd->totlvl;
- ccgdm = multires_dm_create_local(ob, dm, totlvl, totlvl, mmd->simple, false);
+ ccgdm = multires_dm_create_local(ob, dm, totlvl, totlvl, mmd->simple, false, object_mode);
- subsurf = subsurf_dm_create_local(ob, dm, totlvl,
- mmd->simple, mmd->flags & eMultiresModifierFlag_ControlEdges, mmd->flags & eMultiresModifierFlag_PlainUv, 0);
+ subsurf = subsurf_dm_create_local(
+ dm, totlvl, mmd->simple,
+ mmd->flags & eMultiresModifierFlag_ControlEdges, mmd->flags & eMultiresModifierFlag_PlainUv, 0, object_mode);
numGrids = subsurf->getNumGrids(subsurf);
gridSize = subsurf->getGridSize(subsurf);
@@ -1471,10 +1489,12 @@ void multires_stitch_grids(Object *ob)
}
}
-DerivedMesh *multires_make_derived_from_derived(DerivedMesh *dm,
- MultiresModifierData *mmd,
- Object *ob,
- MultiresFlags flags)
+DerivedMesh *multires_make_derived_from_derived(
+ DerivedMesh *dm,
+ MultiresModifierData *mmd,
+ Object *ob,
+ MultiresFlags flags,
+ eObjectMode object_mode)
{
Mesh *me = ob->data;
DerivedMesh *result;
@@ -1483,16 +1503,18 @@ DerivedMesh *multires_make_derived_from_derived(DerivedMesh *dm,
CCGKey key;
const bool render = (flags & MULTIRES_USE_RENDER_PARAMS) != 0;
const bool ignore_simplify = (flags & MULTIRES_IGNORE_SIMPLIFY) != 0;
- int lvl = multires_get_level(ob, mmd, render, ignore_simplify);
+ int lvl = multires_get_level(mmd, render, ignore_simplify, object_mode);
int i, gridSize, numGrids;
if (lvl == 0)
return dm;
- result = subsurf_dm_create_local(ob, dm, lvl,
- mmd->simple, mmd->flags & eMultiresModifierFlag_ControlEdges,
- mmd->flags & eMultiresModifierFlag_PlainUv,
- flags & MULTIRES_ALLOC_PAINT_MASK);
+ result = subsurf_dm_create_local(
+ dm, lvl, mmd->simple,
+ mmd->flags & eMultiresModifierFlag_ControlEdges,
+ mmd->flags & eMultiresModifierFlag_PlainUv,
+ flags & MULTIRES_ALLOC_PAINT_MASK,
+ object_mode);
if (!(flags & MULTIRES_USE_LOCAL_MMD)) {
ccgdm = (CCGDerivedMesh *)result;
@@ -2120,6 +2142,7 @@ void multires_load_old(Object *ob, Mesh *me)
DerivedMesh *dm, *orig;
CustomDataLayer *l;
int i;
+ const eObjectMode object_mode = OB_MODE_OBJECT;
/* Load original level into the mesh */
lvl = me->mr->levels.first;
@@ -2168,7 +2191,7 @@ void multires_load_old(Object *ob, Mesh *me)
BLI_insertlinkbefore(&ob->modifiers, md, mmd);
for (i = 0; i < me->mr->level_count - 1; ++i)
- multiresModifier_subdivide(mmd, ob, 1, 0);
+ multiresModifier_subdivide(mmd, ob, 1, 0, object_mode);
mmd->lvl = mmd->totlvl;
orig = CDDM_from_mesh(me);
@@ -2177,7 +2200,7 @@ void multires_load_old(Object *ob, Mesh *me)
* reference subsurfed dm with this option, before calling multiresModifier_disp_run(),
* which implicitly expects both subsurfs from its first dm and oldGridData parameters to
* be of the same "format"! */
- dm = multires_make_derived_from_derived(orig, mmd, ob, 0);
+ dm = multires_make_derived_from_derived(orig, mmd, ob, 0, object_mode);
multires_load_old_dm(dm, me, mmd->totlvl + 1);
@@ -2192,21 +2215,22 @@ void multires_load_old(Object *ob, Mesh *me)
/* If 'ob_src' and 'ob_dst' both have multires modifiers, synchronize them
* such that 'ob_dst' has the same total number of levels as 'ob_src'. */
-void multiresModifier_sync_levels_ex(Object *ob_dst, MultiresModifierData *mmd_src, MultiresModifierData *mmd_dst)
+void multiresModifier_sync_levels_ex(
+ Object *ob_dst, MultiresModifierData *mmd_src, MultiresModifierData *mmd_dst, eObjectMode object_mode)
{
if (mmd_src->totlvl == mmd_dst->totlvl) {
return;
}
if (mmd_src->totlvl > mmd_dst->totlvl) {
- multires_subdivide(mmd_dst, ob_dst, mmd_src->totlvl, false, mmd_dst->simple);
+ multires_subdivide(mmd_dst, ob_dst, mmd_src->totlvl, false, mmd_dst->simple, object_mode);
}
else {
- multires_del_higher(mmd_dst, ob_dst, mmd_src->totlvl);
+ multires_del_higher(mmd_dst, ob_dst, mmd_src->totlvl, object_mode);
}
}
-static void multires_sync_levels(Scene *scene, Object *ob_src, Object *ob_dst)
+static void multires_sync_levels(Scene *scene, Object *ob_src, Object *ob_dst, eObjectMode object_mode)
{
MultiresModifierData *mmd_src = get_multires_modifier(scene, ob_src, true);
MultiresModifierData *mmd_dst = get_multires_modifier(scene, ob_dst, true);
@@ -2221,7 +2245,7 @@ static void multires_sync_levels(Scene *scene, Object *ob_src, Object *ob_dst)
}
if (mmd_src && mmd_dst) {
- multiresModifier_sync_levels_ex(ob_dst, mmd_src, mmd_dst);
+ multiresModifier_sync_levels_ex(ob_dst, mmd_src, mmd_dst, object_mode);
}
}
@@ -2314,7 +2338,9 @@ static void multires_apply_smat(const struct EvaluationContext *eval_ctx, Scene
MEM_freeN(vertCos);
/* scaled ccgDM for tangent space of object with applied scale */
- dm = subsurf_dm_create_local(ob, cddm, high_mmd.totlvl, high_mmd.simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, 0);
+ dm = subsurf_dm_create_local(
+ cddm, high_mmd.totlvl, high_mmd.simple,
+ 0, mmd->flags & eMultiresModifierFlag_PlainUv, 0, eval_ctx->object_mode);
cddm->release(cddm);
gridSize = dm->getGridSize(dm);
@@ -2377,7 +2403,7 @@ void multiresModifier_scale_disp(const struct EvaluationContext *eval_ctx, Scene
void multiresModifier_prepare_join(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, Object *to_ob)
{
float smat[3][3], tmat[3][3], mat[3][3];
- multires_sync_levels(scene, to_ob, ob);
+ multires_sync_levels(scene, to_ob, ob, eval_ctx->object_mode);
/* construct scale matrix for displacement */
BKE_object_scale_to_mat3(to_ob, tmat);
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index cac2aab26dd..c2d74739beb 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -2787,7 +2787,7 @@ int BKE_node_instance_hash_haskey(bNodeInstanceHash *hash, bNodeInstanceKey key)
int BKE_node_instance_hash_size(bNodeInstanceHash *hash)
{
- return BLI_ghash_size(hash->ghash);
+ return BLI_ghash_len(hash->ghash);
}
void BKE_node_instance_hash_clear_tags(bNodeInstanceHash *hash)
@@ -3590,6 +3590,7 @@ static void registerShaderNodes(void)
register_node_type_sh_attribute();
register_node_type_sh_bevel();
register_node_type_sh_displacement();
+ register_node_type_sh_vector_displacement();
register_node_type_sh_geometry();
register_node_type_sh_light_path();
register_node_type_sh_light_falloff();
@@ -3819,6 +3820,7 @@ bool BKE_node_tree_iter_step(struct NodeTreeIterStore *ntreeiter,
void BKE_nodetree_remove_layer_n(bNodeTree *ntree, Scene *scene, const int layer_index)
{
+ BLI_assert(layer_index != -1);
for (bNode *node = ntree->nodes.first; node; node = node->next) {
if (node->type == CMP_NODE_R_LAYERS && (Scene *)node->id == scene) {
if (node->custom1 == layer_index) {
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 8c85a0413b8..a0d2e7d76c8 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -262,7 +262,9 @@ bool BKE_object_support_modifier_type_check(Object *ob, int modifier_type)
return true;
}
-void BKE_object_link_modifiers(struct Object *ob_dst, const struct Object *ob_src)
+void BKE_object_link_modifiers(
+ struct Object *ob_dst, const struct Object *ob_src,
+ eObjectMode object_mode)
{
ModifierData *md;
BKE_object_free_modifiers(ob_dst);
@@ -301,7 +303,8 @@ void BKE_object_link_modifiers(struct Object *ob_dst, const struct Object *ob_sr
if (md->type == eModifierType_Multires) {
/* Has to be done after mod creation, but *before* we actually copy its settings! */
- multiresModifier_sync_levels_ex(ob_dst, (MultiresModifierData *)md, (MultiresModifierData *)nmd);
+ multiresModifier_sync_levels_ex(
+ ob_dst, (MultiresModifierData *)md, (MultiresModifierData *)nmd, object_mode);
}
modifier_copyData(md, nmd);
@@ -486,7 +489,7 @@ void BKE_object_free(Object *ob)
}
/* actual check for internal data, not context or flags */
-bool BKE_object_is_in_editmode(Object *ob)
+bool BKE_object_is_in_editmode(const Object *ob)
{
if (ob->data == NULL)
return false;
@@ -535,11 +538,11 @@ bool BKE_object_is_in_editmode_vgroup(Object *ob)
BKE_object_is_in_editmode(ob));
}
-bool BKE_object_is_in_wpaint_select_vert(Object *ob)
+bool BKE_object_is_in_wpaint_select_vert(const Object *ob, eObjectMode object_mode)
{
if (ob->type == OB_MESH) {
- Mesh *me = ob->data;
- return ((ob->mode & OB_MODE_WEIGHT_PAINT) &&
+ const Mesh *me = ob->data;
+ return ((object_mode & OB_MODE_WEIGHT_PAINT) &&
(me->edit_btmesh == NULL) &&
(ME_EDIT_PAINT_SEL_MODE(me) == SCE_SELECT_VERTEX));
}
@@ -884,10 +887,10 @@ static LodLevel *lod_level_select(Object *ob, const float camera_position[3])
return current;
}
-bool BKE_object_lod_is_usable(Object *ob, ViewLayer *view_layer)
+bool BKE_object_lod_is_usable(Object *ob, ViewLayer *view_layer, const eObjectMode object_mode)
{
bool active = (view_layer) ? ob == OBACT(view_layer) : false;
- return (ob->mode == OB_MODE_OBJECT || !active);
+ return (object_mode == OB_MODE_OBJECT || !active);
}
void BKE_object_lod_update(Object *ob, const float camera_position[3])
@@ -900,11 +903,11 @@ void BKE_object_lod_update(Object *ob, const float camera_position[3])
}
}
-static Object *lod_ob_get(Object *ob, ViewLayer *view_layer, int flag)
+static Object *lod_ob_get(Object *ob, ViewLayer *view_layer, int flag, const eObjectMode object_mode)
{
LodLevel *current = ob->currentlod;
- if (!current || !BKE_object_lod_is_usable(ob, view_layer))
+ if (!current || !BKE_object_lod_is_usable(ob, view_layer, object_mode))
return ob;
while (current->prev && (!(current->flags & flag) || !current->source || current->source->type != OB_MESH)) {
@@ -914,14 +917,14 @@ static Object *lod_ob_get(Object *ob, ViewLayer *view_layer, int flag)
return current->source;
}
-struct Object *BKE_object_lod_meshob_get(Object *ob, ViewLayer *view_layer)
+struct Object *BKE_object_lod_meshob_get(Object *ob, ViewLayer *view_layer, const eObjectMode object_mode)
{
- return lod_ob_get(ob, view_layer, OB_LOD_USE_MESH);
+ return lod_ob_get(ob, view_layer, OB_LOD_USE_MESH, object_mode);
}
-struct Object *BKE_object_lod_matob_get(Object *ob, ViewLayer *view_layer)
+struct Object *BKE_object_lod_matob_get(Object *ob, ViewLayer *view_layer, const eObjectMode object_mode)
{
- return lod_ob_get(ob, view_layer, OB_LOD_USE_MAT);
+ return lod_ob_get(ob, view_layer, OB_LOD_USE_MAT, object_mode);
}
#endif /* WITH_GAMEENGINE */
@@ -1150,12 +1153,13 @@ static void copy_object_lod(Object *obn, const Object *ob, const int UNUSED(flag
obn->currentlod = (LodLevel *)obn->lodlevels.first;
}
-bool BKE_object_pose_context_check(Object *ob)
+bool BKE_object_pose_context_check_ex(Object *ob, bool selected)
{
if ((ob) &&
(ob->type == OB_ARMATURE) &&
(ob->pose) &&
- (ob->mode & OB_MODE_POSE))
+ /* Currently using selection when the object isn't active. */
+ ((selected == false) || (ob->flag & SELECT)))
{
return true;
}
@@ -1164,22 +1168,41 @@ bool BKE_object_pose_context_check(Object *ob)
}
}
+bool BKE_object_pose_context_check(Object *ob)
+{
+ return BKE_object_pose_context_check_ex(ob, false);
+}
+
Object *BKE_object_pose_armature_get(Object *ob)
{
if (ob == NULL)
return NULL;
- if (BKE_object_pose_context_check(ob))
+ if (BKE_object_pose_context_check_ex(ob, false))
return ob;
ob = modifiers_isDeformedByArmature(ob);
- if (BKE_object_pose_context_check(ob))
+ /* Only use selected check when non-active. */
+ if (BKE_object_pose_context_check_ex(ob, true))
return ob;
return NULL;
}
+Object *BKE_object_pose_armature_get_visible(Object *ob, ViewLayer *view_layer)
+{
+ Object *ob_armature = BKE_object_pose_armature_get(ob);
+ if (ob_armature) {
+ Base *base = BKE_view_layer_base_find(view_layer, ob_armature);
+ if (base) {
+ if (BASE_VISIBLE(base)) {
+ return ob_armature;
+ }
+ }
+ }
+ return NULL;
+}
void BKE_object_transform_copy(Object *ob_tar, const Object *ob_src)
{
copy_v3_v3(ob_tar->loc, ob_src->loc);
@@ -1241,7 +1264,6 @@ void BKE_object_copy_data(Main *UNUSED(bmain), Object *ob_dst, const Object *ob_
BKE_object_facemap_copy_list(&ob_dst->fmaps, &ob_src->fmaps);
BKE_constraints_copy_ex(&ob_dst->constraints, &ob_src->constraints, flag_subdata, true);
- ob_dst->mode = OB_MODE_OBJECT;
ob_dst->sculpt = NULL;
if (ob_src->pd) {
diff --git a/source/blender/blenkernel/intern/object_deform.c b/source/blender/blenkernel/intern/object_deform.c
index 754434eaef6..ffe45d42677 100644
--- a/source/blender/blenkernel/intern/object_deform.c
+++ b/source/blender/blenkernel/intern/object_deform.c
@@ -42,7 +42,7 @@
#include "DNA_mesh_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
-#include "DNA_object_force.h"
+#include "DNA_object_force_types.h"
#include "DNA_particle_types.h"
#include "DNA_scene_types.h"
@@ -542,7 +542,7 @@ bool *BKE_object_defgroup_validmap_get(Object *ob, const int defbase_tot)
BLI_ghash_insert(gh, dg->name, NULL);
}
- BLI_assert(BLI_ghash_size(gh) == defbase_tot);
+ BLI_assert(BLI_ghash_len(gh) == defbase_tot);
/* now loop through the armature modifiers and identify deform bones */
for (md = ob->modifiers.first; md; md = !md->next && step1 ? (step1 = 0), modifiers_getVirtualModifierList(ob, &virtualModifierData) : md->next) {
@@ -577,7 +577,7 @@ bool *BKE_object_defgroup_validmap_get(Object *ob, const int defbase_tot)
defgroup_validmap[i] = (BLI_ghash_lookup(gh, dg->name) != NULL);
}
- BLI_assert(i == BLI_ghash_size(gh));
+ BLI_assert(i == BLI_ghash_len(gh));
BLI_ghash_free(gh, NULL, NULL);
diff --git a/source/blender/blenkernel/intern/object_dupli.c b/source/blender/blenkernel/intern/object_dupli.c
index 13589866e48..2d655913b3e 100644
--- a/source/blender/blenkernel/intern/object_dupli.c
+++ b/source/blender/blenkernel/intern/object_dupli.c
@@ -74,6 +74,7 @@ typedef struct DupliContext {
bool do_update;
bool animated;
Group *group; /* XXX child objects are selected from this group if set, could be nicer */
+ Object *obedit; /* Only to check if the object is in edit-mode. */
Scene *scene;
ViewLayer *view_layer;
@@ -107,6 +108,7 @@ static void init_context(DupliContext *r_ctx, const EvaluationContext *eval_ctx,
r_ctx->animated = false;
r_ctx->group = NULL;
+ r_ctx->obedit = OBEDIT_FROM_EVAL_CTX(eval_ctx);
r_ctx->object = ob;
if (space_mat)
copy_m4_m4(r_ctx->space_mat, space_mat);
@@ -241,14 +243,13 @@ static bool is_child(const Object *ob, const Object *parent)
static void make_child_duplis(const DupliContext *ctx, void *userdata, MakeChildDuplisFunc make_child_duplis_cb)
{
Object *parent = ctx->object;
- Object *obedit = ctx->scene->obedit;
if (ctx->group) {
int groupid = 0;
FOREACH_GROUP_BASE(ctx->group, base)
{
Object *ob = base->object;
- if ((base->flag & BASE_VISIBLED) && ob != obedit && is_child(ob, parent)) {
+ if ((base->flag & BASE_VISIBLED) && ob != ctx->obedit && is_child(ob, parent)) {
DupliContext pctx;
copy_dupli_context(&pctx, ctx, ctx->object, NULL, groupid, false);
@@ -267,7 +268,7 @@ static void make_child_duplis(const DupliContext *ctx, void *userdata, MakeChild
ViewLayer *view_layer = ctx->view_layer;
for (Base *base = view_layer->object_bases.first; base; base = base->next, baseid++) {
Object *ob = base->object;
- if ((base->flag & BASE_VISIBLED) && ob != obedit && is_child(ob, parent)) {
+ if ((ob != ctx->obedit) && is_child(ob, parent)) {
DupliContext pctx;
copy_dupli_context(&pctx, ctx, ctx->object, NULL, baseid, false);
diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c
index bc183ba95a6..52c85011b6a 100644
--- a/source/blender/blenkernel/intern/object_update.c
+++ b/source/blender/blenkernel/intern/object_update.c
@@ -173,7 +173,7 @@ void BKE_object_handle_data_update(
switch (ob->type) {
case OB_MESH:
{
- BMEditMesh *em = (ob == scene->obedit) ? BKE_editmesh_from_object(ob) : NULL;
+ BMEditMesh *em = (eval_ctx->object_mode & OB_MODE_EDIT) ? BKE_editmesh_from_object(ob) : NULL;
uint64_t data_mask = scene->customdata_mask | CD_MASK_BAREMESH;
#ifdef WITH_FREESTYLE
/* make sure Freestyle edge/face marks appear in DM for render (see T40315) */
@@ -223,7 +223,7 @@ void BKE_object_handle_data_update(
}
/* particles */
- if (ob != scene->obedit && ob->particlesystem.first) {
+ if ((ob != OBEDIT_FROM_EVAL_CTX(eval_ctx)) && ob->particlesystem.first) {
ParticleSystem *tpsys, *psys;
DerivedMesh *dm;
ob->transflag &= ~OB_DUPLIPARTS;
diff --git a/source/blender/blenkernel/intern/ocean.c b/source/blender/blenkernel/intern/ocean.c
index 0b4bc39627e..2d8527f23d6 100644
--- a/source/blender/blenkernel/intern/ocean.c
+++ b/source/blender/blenkernel/intern/ocean.c
@@ -917,7 +917,7 @@ void BKE_ocean_init(struct Ocean *o, int M, int N, float Lx, float Lz, float V,
o->_fft_in = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in");
o->_htilda = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_htilda");
- BLI_lock_thread(LOCK_FFTW);
+ BLI_thread_lock(LOCK_FFTW);
if (o->_do_disp_y) {
o->_disp_y = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_disp_y");
@@ -963,7 +963,7 @@ void BKE_ocean_init(struct Ocean *o, int M, int N, float Lx, float Lz, float V,
o->_Jxz_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_jxz, o->_Jxz, FFTW_ESTIMATE);
}
- BLI_unlock_thread(LOCK_FFTW);
+ BLI_thread_unlock(LOCK_FFTW);
BLI_rw_mutex_unlock(&o->oceanmutex);
@@ -978,7 +978,7 @@ void BKE_ocean_free_data(struct Ocean *oc)
BLI_rw_mutex_lock(&oc->oceanmutex, THREAD_LOCK_WRITE);
- BLI_lock_thread(LOCK_FFTW);
+ BLI_thread_lock(LOCK_FFTW);
if (oc->_do_disp_y) {
fftw_destroy_plan(oc->_disp_y_plan);
@@ -1016,7 +1016,7 @@ void BKE_ocean_free_data(struct Ocean *oc)
MEM_freeN(oc->_Jxz);
}
- BLI_unlock_thread(LOCK_FFTW);
+ BLI_thread_unlock(LOCK_FFTW);
if (oc->_fft_in)
MEM_freeN(oc->_fft_in);
diff --git a/source/blender/blenkernel/intern/outliner_treehash.c b/source/blender/blenkernel/intern/outliner_treehash.c
index d9a602aa41e..9bbde607b80 100644
--- a/source/blender/blenkernel/intern/outliner_treehash.c
+++ b/source/blender/blenkernel/intern/outliner_treehash.c
@@ -133,7 +133,7 @@ static void fill_treehash(void *treehash, BLI_mempool *treestore)
void *BKE_outliner_treehash_create_from_treestore(BLI_mempool *treestore)
{
- GHash *treehash = BLI_ghash_new_ex(tse_hash, tse_cmp, "treehash", BLI_mempool_count(treestore));
+ GHash *treehash = BLI_ghash_new_ex(tse_hash, tse_cmp, "treehash", BLI_mempool_len(treestore));
fill_treehash(treehash, treestore);
return treehash;
}
@@ -147,7 +147,7 @@ void *BKE_outliner_treehash_rebuild_from_treestore(void *treehash, BLI_mempool *
{
BLI_assert(treehash);
- BLI_ghash_clear_ex(treehash, NULL, free_treehash_group, BLI_mempool_count(treestore));
+ BLI_ghash_clear_ex(treehash, NULL, free_treehash_group, BLI_mempool_len(treestore));
fill_treehash(treehash, treestore);
return treehash;
}
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index 152a882de97..81943d470dc 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -41,6 +41,7 @@
#include "DNA_scene_types.h"
#include "DNA_brush_types.h"
#include "DNA_space_types.h"
+#include "DNA_workspace_types.h"
#include "BLI_bitmap.h"
#include "BLI_utildefines.h"
@@ -75,27 +76,67 @@ const char PAINT_CURSOR_TEXTURE_PAINT[3] = {255, 255, 255};
static eOverlayControlFlags overlay_flags = 0;
-void BKE_paint_invalidate_overlay_tex(Scene *scene, ViewLayer *view_layer, const Tex *tex)
+/* Keep in sync with 'BKE_paint_get_active' */
+#define OB_MODE_HAS_PAINT_STRUCT(SEP) \
+ OB_MODE_SCULPT SEP \
+ OB_MODE_VERTEX_PAINT SEP \
+ OB_MODE_WEIGHT_PAINT SEP \
+ OB_MODE_TEXTURE_PAINT SEP \
+ OB_MODE_EDIT
+
+#define COMMA ,
+static const eObjectMode ob_mode_has_paint_struct = OB_MODE_HAS_PAINT_STRUCT(|);
+static const eObjectMode ob_mode_has_paint_struct_array[] = {OB_MODE_HAS_PAINT_STRUCT(COMMA)};
+#undef COMMA
+
+#define FOREACH_OB_MODE_PAINT_ITER_BEGIN(scene, view_layer, object_mode, p) \
+{ \
+ eObjectMode object_mode_test = object_mode & ob_mode_has_paint_struct; \
+ for (uint _i = 0; _i < ARRAY_SIZE(ob_mode_has_paint_struct_array) && object_mode_test; _i++) { \
+ eObjectMode object_mode_single = ob_mode_has_paint_struct_array[_i]; \
+ if (object_mode_test & object_mode_single) { \
+ object_mode_test &= ~object_mode_single; \
+ Paint *p = BKE_paint_get_active(scene, view_layer, object_mode_single); \
+ {
+
+#define FOREACH_OB_MODE_PAINT_ITER_END \
+ } \
+ } \
+ } \
+} ((void)0)
+
+void BKE_paint_invalidate_overlay_tex(
+ Scene *scene, ViewLayer *view_layer, const Tex *tex, eObjectMode object_mode)
{
- Paint *p = BKE_paint_get_active(scene, view_layer);
- Brush *br = p->brush;
-
- if (!br)
- return;
-
- if (br->mtex.tex == tex)
- overlay_flags |= PAINT_INVALID_OVERLAY_TEXTURE_PRIMARY;
- if (br->mask_mtex.tex == tex)
- overlay_flags |= PAINT_INVALID_OVERLAY_TEXTURE_SECONDARY;
+ FOREACH_OB_MODE_PAINT_ITER_BEGIN(scene, view_layer, object_mode, p)
+ {
+ Brush *br = p->brush;
+ if (br) {
+ if (br->mtex.tex == tex) {
+ overlay_flags |= PAINT_INVALID_OVERLAY_TEXTURE_PRIMARY;
+ }
+ if (br->mask_mtex.tex == tex) {
+ overlay_flags |= PAINT_INVALID_OVERLAY_TEXTURE_SECONDARY;
+ }
+ }
+ }
+ FOREACH_OB_MODE_PAINT_ITER_END;
}
-void BKE_paint_invalidate_cursor_overlay(Scene *scene, ViewLayer *view_layer, CurveMapping *curve)
+void BKE_paint_invalidate_cursor_overlay(
+ Scene *scene, ViewLayer *view_layer, CurveMapping *curve, eObjectMode object_mode)
{
- Paint *p = BKE_paint_get_active(scene, view_layer);
- Brush *br = p->brush;
-
- if (br && br->curve == curve)
- overlay_flags |= PAINT_INVALID_OVERLAY_CURVE;
+ FOREACH_OB_MODE_PAINT_ITER_BEGIN(scene, view_layer, object_mode, p)
+ {
+ Brush *br = p->brush;
+ if (br) {
+ if (br->curve == curve) {
+ overlay_flags |= PAINT_INVALID_OVERLAY_CURVE;
+ break;
+ }
+ }
+ }
+ FOREACH_OB_MODE_PAINT_ITER_END;
}
void BKE_paint_invalidate_overlay_all(void)
@@ -157,13 +198,13 @@ Paint *BKE_paint_get_active_from_paintmode(Scene *sce, ePaintMode mode)
return NULL;
}
-Paint *BKE_paint_get_active(Scene *sce, ViewLayer *view_layer)
+Paint *BKE_paint_get_active(Scene *sce, ViewLayer *view_layer, const eObjectMode object_mode)
{
if (sce && view_layer) {
ToolSettings *ts = sce->toolsettings;
if (view_layer->basact && view_layer->basact->object) {
- switch (view_layer->basact->object->mode) {
+ switch (object_mode) {
case OB_MODE_SCULPT:
return &ts->sculpt->paint;
case OB_MODE_VERTEX_PAINT:
@@ -176,6 +217,8 @@ Paint *BKE_paint_get_active(Scene *sce, ViewLayer *view_layer)
if (ts->use_uv_sculpt)
return &ts->uvsculpt->paint;
return &ts->imapaint.paint;
+ default:
+ break;
}
}
@@ -193,6 +236,7 @@ Paint *BKE_paint_get_active_from_context(const bContext *C)
SpaceImage *sima;
if (sce && view_layer) {
+ const WorkSpace *workspace = CTX_wm_workspace(C);
ToolSettings *ts = sce->toolsettings;
Object *obact = NULL;
@@ -200,7 +244,7 @@ Paint *BKE_paint_get_active_from_context(const bContext *C)
obact = view_layer->basact->object;
if ((sima = CTX_wm_space_image(C)) != NULL) {
- if (obact && obact->mode == OB_MODE_EDIT) {
+ if (obact && workspace->object_mode == OB_MODE_EDIT) {
if (sima->mode == SI_MODE_PAINT)
return &ts->imapaint.paint;
else if (ts->use_uv_sculpt)
@@ -211,7 +255,7 @@ Paint *BKE_paint_get_active_from_context(const bContext *C)
}
}
else if (obact) {
- switch (obact->mode) {
+ switch (workspace->object_mode) {
case OB_MODE_SCULPT:
return &ts->sculpt->paint;
case OB_MODE_VERTEX_PAINT:
@@ -244,6 +288,7 @@ ePaintMode BKE_paintmode_get_active_from_context(const bContext *C)
SpaceImage *sima;
if (sce && view_layer) {
+ const WorkSpace *workspace = CTX_wm_workspace(C);
ToolSettings *ts = sce->toolsettings;
Object *obact = NULL;
@@ -251,7 +296,7 @@ ePaintMode BKE_paintmode_get_active_from_context(const bContext *C)
obact = view_layer->basact->object;
if ((sima = CTX_wm_space_image(C)) != NULL) {
- if (obact && obact->mode == OB_MODE_EDIT) {
+ if (obact && workspace->object_mode == OB_MODE_EDIT) {
if (sima->mode == SI_MODE_PAINT)
return ePaintTexture2D;
else if (ts->use_uv_sculpt)
@@ -262,7 +307,7 @@ ePaintMode BKE_paintmode_get_active_from_context(const bContext *C)
}
}
else if (obact) {
- switch (obact->mode) {
+ switch (workspace->object_mode) {
case OB_MODE_SCULPT:
return ePaintSculpt;
case OB_MODE_VERTEX_PAINT:
@@ -453,24 +498,24 @@ bool BKE_palette_is_empty(const struct Palette *palette)
/* are we in vertex paint or weight pain face select mode? */
-bool BKE_paint_select_face_test(Object *ob)
+bool BKE_paint_select_face_test(Object *ob, eObjectMode object_mode)
{
return ( (ob != NULL) &&
(ob->type == OB_MESH) &&
(ob->data != NULL) &&
(((Mesh *)ob->data)->editflag & ME_EDIT_PAINT_FACE_SEL) &&
- (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT))
+ (object_mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT))
);
}
/* are we in weight paint vertex select mode? */
-bool BKE_paint_select_vert_test(Object *ob)
+bool BKE_paint_select_vert_test(Object *ob, eObjectMode object_mode)
{
return ( (ob != NULL) &&
(ob->type == OB_MESH) &&
(ob->data != NULL) &&
(((Mesh *)ob->data)->editflag & ME_EDIT_PAINT_VERT_SEL) &&
- (ob->mode & OB_MODE_WEIGHT_PAINT || ob->mode & OB_MODE_VERTEX_PAINT)
+ (object_mode & OB_MODE_WEIGHT_PAINT || object_mode & OB_MODE_VERTEX_PAINT)
);
}
@@ -478,10 +523,10 @@ bool BKE_paint_select_vert_test(Object *ob)
* used to check if selection is possible
* (when we don't care if its face or vert)
*/
-bool BKE_paint_select_elem_test(Object *ob)
+bool BKE_paint_select_elem_test(Object *ob, eObjectMode object_mode)
{
- return (BKE_paint_select_vert_test(ob) ||
- BKE_paint_select_face_test(ob));
+ return (BKE_paint_select_vert_test(ob, object_mode) ||
+ BKE_paint_select_face_test(ob, object_mode));
}
void BKE_paint_cavity_curve_preset(Paint *p, int preset)
@@ -499,7 +544,7 @@ void BKE_paint_cavity_curve_preset(Paint *p, int preset)
curvemapping_changed(p->cavity_curve, false);
}
-short BKE_paint_object_mode_from_paint_mode(ePaintMode mode)
+eObjectMode BKE_paint_object_mode_from_paint_mode(ePaintMode mode)
{
switch (mode) {
case ePaintSculpt:
@@ -529,7 +574,7 @@ void BKE_paint_init(Scene *sce, ePaintMode mode, const char col[3])
/* If there's no brush, create one */
brush = BKE_paint_brush(paint);
if (brush == NULL) {
- short ob_mode = BKE_paint_object_mode_from_paint_mode(mode);
+ eObjectMode ob_mode = BKE_paint_object_mode_from_paint_mode(mode);
brush = BKE_brush_first_search(G.main, ob_mode);
if (!brush) {
@@ -784,7 +829,7 @@ void BKE_sculptsession_free(Object *ob)
BM_log_free(ss->bm_log);
if (dm && dm->getPBVH)
- dm->getPBVH(NULL, dm); /* signal to clear */
+ dm->getPBVH(NULL, dm, OB_MODE_OBJECT); /* signal to clear */
if (ss->texcache)
MEM_freeN(ss->texcache);
@@ -921,7 +966,7 @@ void BKE_sculpt_update_mesh_elements(
dm = mesh_get_derived_final(eval_ctx, scene, ob, CD_MASK_BAREMESH);
/* VWPaint require mesh info for loop lookup, so require sculpt mode here */
- if (mmd && ob->mode & OB_MODE_SCULPT) {
+ if (mmd && eval_ctx->object_mode & OB_MODE_SCULPT) {
ss->multires = mmd;
ss->totvert = dm->getNumVerts(dm);
ss->totpoly = dm->getNumPolys(dm);
@@ -939,7 +984,7 @@ void BKE_sculpt_update_mesh_elements(
ss->vmask = CustomData_get_layer(&me->vdata, CD_PAINT_MASK);
}
- ss->pbvh = dm->getPBVH(ob, dm);
+ ss->pbvh = dm->getPBVH(ob, dm, eval_ctx->object_mode);
ss->pmap = (need_pmap && dm->getPolyMap) ? dm->getPolyMap(ob, dm) : NULL;
pbvh_show_diffuse_color_set(ss->pbvh, ss->show_diffuse_color);
@@ -1064,3 +1109,39 @@ int BKE_sculpt_mask_layers_ensure(Object *ob, MultiresModifierData *mmd)
return ret;
}
+
+void BKE_sculpt_toolsettings_data_ensure(struct Scene *scene)
+{
+ Sculpt *sd = scene->toolsettings->sculpt;
+ if (sd == NULL) {
+ sd = scene->toolsettings->sculpt = MEM_callocN(sizeof(Sculpt), __func__);
+
+ /* Turn on X plane mirror symmetry by default */
+ sd->paint.symmetry_flags |= PAINT_SYMM_X;
+ sd->paint.flags |= PAINT_SHOW_BRUSH;
+
+ /* Make sure at least dyntopo subdivision is enabled */
+ sd->flags |= SCULPT_DYNTOPO_SUBDIVIDE | SCULPT_DYNTOPO_COLLAPSE;
+ }
+
+ if (!sd->detail_size) {
+ sd->detail_size = 12;
+ }
+ if (!sd->detail_percent) {
+ sd->detail_percent = 25;
+ }
+ if (sd->constant_detail == 0.0f) {
+ sd->constant_detail = 3.0f;
+ }
+
+ /* Set sane default tiling offsets */
+ if (!sd->paint.tile_offset[0]) {
+ sd->paint.tile_offset[0] = 1.0f;
+ }
+ if (!sd->paint.tile_offset[1]) {
+ sd->paint.tile_offset[1] = 1.0f;
+ }
+ if (!sd->paint.tile_offset[2]) {
+ sd->paint.tile_offset[2] = 1.0f;
+ }
+}
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 5e2cd89a750..c9507ac1a36 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -90,6 +90,8 @@
#include "RE_render_ext.h"
+#include "particle_private.h"
+
unsigned int PSYS_FRAND_SEED_OFFSET[PSYS_FRAND_COUNT];
unsigned int PSYS_FRAND_SEED_MULTIPLIER[PSYS_FRAND_COUNT];
float PSYS_FRAND_BASE[PSYS_FRAND_COUNT];
@@ -109,9 +111,6 @@ static void get_child_modifier_parameters(ParticleSettings *part, ParticleThread
ChildParticle *cpa, short cpa_from, int cpa_num, float *cpa_fuv, float *orco, ParticleTexture *ptex);
static void get_cpa_texture(DerivedMesh *dm, ParticleSystem *psys, ParticleSettings *part, ParticleData *par,
int child_index, int face_index, const float fw[4], float *orco, ParticleTexture *ptex, int event, float cfra);
-extern void do_child_modifiers(ParticleThreadContext *ctx, ParticleSimulationData *sim,
- ParticleTexture *ptex, const float par_co[3], const float par_vel[3], const float par_rot[4], const float par_orco[3],
- ChildParticle *cpa, const float orco[3], float mat[4][4], ParticleKey *state, float t);
/* few helpers for countall etc. */
int count_particles(ParticleSystem *psys)
@@ -252,7 +251,7 @@ struct LatticeDeformData *psys_create_lattice_deform_data(ParticleSimulationData
{
struct LatticeDeformData *lattice_deform_data = NULL;
- if (psys_in_edit_mode(sim->eval_ctx->view_layer, sim->psys) == 0) {
+ if (psys_in_edit_mode(sim->eval_ctx, sim->eval_ctx->view_layer, sim->psys) == 0) {
Object *lattice = NULL;
ModifierData *md = (ModifierData *)psys_get_modifier(sim->ob, sim->psys);
int mode = G.is_rendering ? eModifierMode_Render : eModifierMode_Realtime;
@@ -289,11 +288,12 @@ void psys_enable_all(Object *ob)
psys->flag &= ~PSYS_DISABLED;
}
-bool psys_in_edit_mode(ViewLayer *view_layer, ParticleSystem *psys)
+bool psys_in_edit_mode(const EvaluationContext *eval_ctx, ViewLayer *view_layer, ParticleSystem *psys)
{
- return (view_layer->basact &&
- (view_layer->basact->object->mode & OB_MODE_PARTICLE_EDIT) &&
- psys == psys_get_current((view_layer->basact)->object) &&
+ /* TODO(mai): the check for view_layer shouldnt be needed, remove when render engine api is updated for this */
+ return (view_layer && view_layer->basact &&
+ (eval_ctx->object_mode & OB_MODE_PARTICLE_EDIT) &&
+ psys == psys_get_current(view_layer->basact->object) &&
(psys->edit || psys->pointcache->edit) &&
!psys->renderdata);
}
@@ -413,6 +413,8 @@ void BKE_particlesettings_free(ParticleSettings *part)
curvemapping_free(part->clumpcurve);
if (part->roughcurve)
curvemapping_free(part->roughcurve);
+ if (part->twistcurve)
+ curvemapping_free(part->twistcurve);
free_partdeflect(part->pd);
free_partdeflect(part->pd2);
@@ -1806,11 +1808,6 @@ void psys_particle_on_emitter(ParticleSystemModifierData *psmd, int from, int in
/* Path Cache */
/************************************************/
-extern void do_kink(ParticleKey *state, const float par_co[3], const float par_vel[3], const float par_rot[4], float time, float freq, float shape, float amplitude, float flat,
- short type, short axis, float obmat[4][4], int smooth_start);
-extern float do_clump(ParticleKey *state, const float par_co[3], float time, const float orco_offset[3], float clumpfac, float clumppow, float pa_clump,
- bool use_clump_noise, float clump_noise_size, CurveMapping *clumpcurve);
-
void precalc_guides(ParticleSimulationData *sim, ListBase *effectors)
{
EffectedPoint point;
@@ -2098,7 +2095,7 @@ static bool psys_thread_context_init_path(
psys_thread_context_init(ctx, sim);
/*---start figuring out what is actually wanted---*/
- if (psys_in_edit_mode(sim->eval_ctx->view_layer, psys)) {
+ if (psys_in_edit_mode(sim->eval_ctx, sim->eval_ctx->view_layer, psys)) {
ParticleEditSettings *pset = &scene->toolsettings->particle;
if ((psys->renderdata == 0 && use_render_params == 0) && (psys->edit == NULL || pset->flag & PE_DRAW_PART) == 0)
@@ -2149,6 +2146,7 @@ static bool psys_thread_context_init_path(
ctx->vg_rough1 = psys_cache_vgroup(ctx->dm, psys, PSYS_VG_ROUGH1);
ctx->vg_rough2 = psys_cache_vgroup(ctx->dm, psys, PSYS_VG_ROUGH2);
ctx->vg_roughe = psys_cache_vgroup(ctx->dm, psys, PSYS_VG_ROUGHE);
+ ctx->vg_twist = psys_cache_vgroup(ctx->dm, psys, PSYS_VG_TWIST);
if (psys->part->flag & PART_CHILD_EFFECT)
ctx->vg_effector = psys_cache_vgroup(ctx->dm, psys, PSYS_VG_EFFECTOR);
@@ -2167,6 +2165,13 @@ static bool psys_thread_context_init_path(
else {
ctx->roughcurve = NULL;
}
+ if ((part->child_flag & PART_CHILD_USE_TWIST_CURVE) && part->twistcurve) {
+ ctx->twistcurve = curvemapping_copy(part->twistcurve);
+ curvemapping_changed_all(ctx->twistcurve);
+ }
+ else {
+ ctx->twistcurve = NULL;
+ }
return true;
}
@@ -2187,7 +2192,7 @@ static void psys_thread_create_path(ParticleTask *task, struct ChildParticle *cp
ParticleSystem *psys = ctx->sim.psys;
ParticleSettings *part = psys->part;
ParticleCacheKey **cache = psys->childcache;
- ParticleCacheKey **pcache = psys_in_edit_mode(ctx->sim.eval_ctx->view_layer, psys) && psys->edit ? psys->edit->pathcache : psys->pathcache;
+ ParticleCacheKey **pcache = psys_in_edit_mode(ctx->sim.eval_ctx, ctx->sim.eval_ctx->view_layer, psys) && psys->edit ? psys->edit->pathcache : psys->pathcache;
ParticleCacheKey *child, *key[4];
ParticleTexture ptex;
float *cpa_fuv = 0, *par_rot = 0, rot[4];
@@ -2311,7 +2316,19 @@ static void psys_thread_create_path(ParticleTask *task, struct ChildParticle *cp
/* get the original coordinates (orco) for texture usage */
cpa_from = part->from;
- cpa_num = pa->num;
+
+ /*
+ * NOTE: Should in theory be the same as:
+ cpa_num = psys_particle_dm_face_lookup(
+ ctx->sim.psmd->dm_final,
+ ctx->sim.psmd->dm_deformed,
+ pa->num, pa->fuv,
+ NULL);
+ */
+ cpa_num = (ELEM(pa->num_dmcache, DMCACHE_ISCHILD, DMCACHE_NOTFOUND))
+ ? pa->num
+ : pa->num_dmcache;
+
/* XXX hack to avoid messed up particle num and subsequent crash (#40733) */
if (cpa_num > ctx->sim.psmd->dm_final->getNumTessFaces(ctx->sim.psmd->dm_final))
cpa_num = 0;
@@ -2564,7 +2581,9 @@ static void cache_key_incremental_rotation(ParticleCacheKey *key0, ParticleCache
void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_render_params)
{
PARTICLE_PSMD;
+#if 0
ParticleEditSettings *pset = &sim->scene->toolsettings->particle;
+#endif
ParticleSystem *psys = sim->psys;
ParticleSettings *part = psys->part;
ParticleCacheKey *ca, **cache;
@@ -2596,9 +2615,11 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re
if ((psys->flag & PSYS_HAIR_DONE || psys->flag & PSYS_KEYED || psys->pointcache) == 0)
return;
- if (psys_in_edit_mode(sim->eval_ctx->view_layer, psys))
+#if 0 /* TODO(mai): something is very wrong with these conditionals, they dont make sense and the cache isnt updating */
+ if (psys_in_edit_mode(sim->eval_ctx, sim->eval_ctx->view_layer, psys))
if (psys->renderdata == 0 && (psys->edit == NULL || pset->flag & PE_DRAW_PART) == 0)
return;
+#endif
keyed = psys->flag & PSYS_KEYED;
baked = psys->pointcache->mem_cache.first && psys->part->type != PART_HAIR;
@@ -3223,8 +3244,6 @@ void object_remove_particle_system(Scene *UNUSED(scene), Object *ob)
if (ob->particlesystem.first)
((ParticleSystem *) ob->particlesystem.first)->flag |= PSYS_CURRENT;
- else
- ob->mode &= ~OB_MODE_PARTICLE_EDIT;
DEG_relations_tag_update(G.main);
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
@@ -3354,6 +3373,18 @@ void BKE_particlesettings_rough_curve_init(ParticleSettings *part)
part->roughcurve = cumap;
}
+void BKE_particlesettings_twist_curve_init(ParticleSettings *part)
+{
+ CurveMapping *cumap = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
+
+ cumap->cm[0].curve[0].x = 0.0f;
+ cumap->cm[0].curve[0].y = 1.0f;
+ cumap->cm[0].curve[1].x = 1.0f;
+ cumap->cm[0].curve[1].y = 1.0f;
+
+ part->twistcurve = cumap;
+}
+
/**
* Only copy internal data of ParticleSettings ID from source to already allocated/initialized destination.
* You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
@@ -3376,6 +3407,9 @@ void BKE_particlesettings_copy_data(
if (part_src->roughcurve) {
part_dst->roughcurve = curvemapping_copy(part_src->roughcurve);
}
+ if (part_src->twistcurve) {
+ part_dst->twistcurve = curvemapping_copy(part_src->twistcurve);
+ }
part_dst->boids = boid_copy_settings(part_src->boids);
@@ -3495,6 +3529,7 @@ static void get_cpa_texture(DerivedMesh *dm, ParticleSystem *psys, ParticleSetti
ptex->ivel = ptex->life = ptex->exist = ptex->size = ptex->damp =
ptex->gravity = ptex->field = ptex->time = ptex->clump = ptex->kink_freq = ptex->kink_amp =
ptex->effector = ptex->rough1 = ptex->rough2 = ptex->roughe = 1.0f;
+ ptex->twist = 1.0f;
ptex->length = 1.0f - part->randlength * psys_frand(psys, child_index + 26);
ptex->length *= part->clength_thres < psys_frand(psys, child_index + 27) ? part->clength : 1.0f;
@@ -3547,6 +3582,7 @@ static void get_cpa_texture(DerivedMesh *dm, ParticleSystem *psys, ParticleSetti
SET_PARTICLE_TEXTURE(PAMAP_KINK_AMP, ptex->kink_amp, mtex->kinkampfac);
SET_PARTICLE_TEXTURE(PAMAP_KINK_FREQ, ptex->kink_freq, mtex->kinkfac);
SET_PARTICLE_TEXTURE(PAMAP_DENS, ptex->exist, mtex->padensfac);
+ SET_PARTICLE_TEXTURE(PAMAP_TWIST, ptex->twist, mtex->twistfac);
}
}
@@ -3572,6 +3608,7 @@ void psys_get_texture(ParticleSimulationData *sim, ParticleData *pa, ParticleTex
ptex->ivel = ptex->life = ptex->exist = ptex->size = ptex->damp =
ptex->gravity = ptex->field = ptex->length = ptex->clump = ptex->kink_freq = ptex->kink_amp =
ptex->effector = ptex->rough1 = ptex->rough2 = ptex->roughe = 1.0f;
+ ptex->twist = 1.0f;
ptex->time = (float)(pa - sim->psys->particles) / (float)sim->psys->totpart;
@@ -3646,6 +3683,7 @@ void psys_get_texture(ParticleSimulationData *sim, ParticleData *pa, ParticleTex
SET_PARTICLE_TEXTURE(PAMAP_GRAVITY, ptex->gravity, mtex->gravityfac);
SET_PARTICLE_TEXTURE(PAMAP_DAMP, ptex->damp, mtex->dampfac);
SET_PARTICLE_TEXTURE(PAMAP_LENGTH, ptex->length, mtex->lengthfac);
+ SET_PARTICLE_TEXTURE(PAMAP_TWIST, ptex->twist, mtex->twistfac);
}
}
@@ -3737,6 +3775,8 @@ static void get_child_modifier_parameters(ParticleSettings *part, ParticleThread
ptex->roughe *= psys_interpolate_value_from_verts(ctx->dm, cpa_from, cpa_num, cpa_fuv, ctx->vg_roughe);
if (ctx->vg_effector)
ptex->effector *= psys_interpolate_value_from_verts(ctx->dm, cpa_from, cpa_num, cpa_fuv, ctx->vg_effector);
+ if (ctx->vg_twist)
+ ptex->twist *= psys_interpolate_value_from_verts(ctx->dm, cpa_from, cpa_num, cpa_fuv, ctx->vg_twist);
}
/* get's hair (or keyed) particles state at the "path time" specified in state->time */
void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey *state, const bool vel)
@@ -3789,7 +3829,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey *
pind.bspline = (psys->part->flag & PART_HAIR_BSPLINE);
/* pind.dm disabled in editmode means we don't get effectors taken into
* account when subdividing for instance */
- pind.dm = psys_in_edit_mode(sim->eval_ctx->view_layer, psys) ? NULL : psys->hair_out_dm;
+ pind.dm = psys_in_edit_mode(sim->eval_ctx, sim->eval_ctx->view_layer, psys) ? NULL : psys->hair_out_dm;
init_particle_interpolation(sim->ob, psys, pa, &pind);
do_particle_interpolation(psys, p, pa, t, &pind, state);
@@ -3942,7 +3982,18 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey *
copy_particle_key(&tstate, state, 1);
/* apply different deformations to the child path */
- do_child_modifiers(NULL, sim, &ptex, par->co, par->vel, par->rot, par_orco, cpa, orco, hairmat, state, t);
+ ParticleChildModifierContext modifier_ctx = {NULL};
+ modifier_ctx.thread_ctx = NULL;
+ modifier_ctx.sim = sim;
+ modifier_ctx.ptex = &ptex;
+ modifier_ctx.cpa = cpa;
+ modifier_ctx.orco = orco;
+ modifier_ctx.par_co = par->co;
+ modifier_ctx.par_vel = par->vel;
+ modifier_ctx.par_rot = par->rot;
+ modifier_ctx.par_orco = par_orco;
+ modifier_ctx.parent_keys = psys->childcache ? psys->childcache[p - totpart] : NULL;
+ do_child_modifiers(&modifier_ctx, hairmat, state, t);
/* try to estimate correct velocity */
if (vel) {
@@ -4045,7 +4096,19 @@ int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *sta
CLAMP(t, 0.0f, 1.0f);
unit_m4(mat);
- do_child_modifiers(NULL, sim, NULL, key1->co, key1->vel, key1->rot, par_orco, cpa, cpa->fuv, mat, state, t);
+ ParticleChildModifierContext modifier_ctx = {NULL};
+ modifier_ctx.thread_ctx = NULL;
+ modifier_ctx.sim = sim;
+ modifier_ctx.ptex = NULL;
+ modifier_ctx.cpa = cpa;
+ modifier_ctx.orco = cpa->fuv;
+ modifier_ctx.par_co = key1->co;
+ modifier_ctx.par_vel = key1->vel;
+ modifier_ctx.par_rot = key1->rot;
+ modifier_ctx.par_orco = par_orco;
+ modifier_ctx.parent_keys = psys->childcache ? psys->childcache[p - totpart] : NULL;
+
+ do_child_modifiers(&modifier_ctx, mat, state, t);
if (psys->lattice_deform_data)
calc_latt_deform(psys->lattice_deform_data, state->co, psys->lattice_strength);
diff --git a/source/blender/blenkernel/intern/particle_child.c b/source/blender/blenkernel/intern/particle_child.c
index d2ad05c20b7..28bdde4e5f5 100644
--- a/source/blender/blenkernel/intern/particle_child.c
+++ b/source/blender/blenkernel/intern/particle_child.c
@@ -37,15 +37,9 @@
#include "BKE_colortools.h"
#include "BKE_particle.h"
-struct Material;
+#include "particle_private.h"
-void do_kink(ParticleKey *state, const float par_co[3], const float par_vel[3], const float par_rot[4], float time, float freq, float shape, float amplitude, float flat,
- short type, short axis, float obmat[4][4], int smooth_start);
-float do_clump(ParticleKey *state, const float par_co[3], float time, const float orco_offset[3], float clumpfac, float clumppow, float pa_clump,
- bool use_clump_noise, float clump_noise_size, CurveMapping *clumpcurve);
-void do_child_modifiers(ParticleThreadContext *ctx, ParticleSimulationData *sim,
- ParticleTexture *ptex, const float par_co[3], const float par_vel[3], const float par_rot[4], const float par_orco[3],
- ChildParticle *cpa, const float orco[3], float mat[4][4], ParticleKey *state, float t);
+struct Material;
static void get_strand_normal(Material *ma, const float surfnor[3], float surfdist, float nor[3])
{
@@ -67,7 +61,7 @@ static void get_strand_normal(Material *ma, const float surfnor[3], float surfdi
else {
copy_v3_v3(vnor, nor);
}
-
+
if (ma->strand_surfnor > 0.0f) {
if (ma->strand_surfnor > surfdist) {
blend = (ma->strand_surfnor - surfdist) / ma->strand_surfnor;
@@ -85,7 +79,7 @@ typedef struct ParticlePathIterator {
ParticleCacheKey *key;
int index;
float time;
-
+
ParticleCacheKey *parent_key;
float parent_rotation[4];
} ParticlePathIterator;
@@ -94,11 +88,11 @@ static void psys_path_iter_get(ParticlePathIterator *iter, ParticleCacheKey *key
ParticleCacheKey *parent, int index)
{
BLI_assert(index >= 0 && index < totkeys);
-
+
iter->key = keys + index;
iter->index = index;
iter->time = (float)index / (float)(totkeys - 1);
-
+
if (parent) {
iter->parent_key = parent + index;
if (index > 0)
@@ -114,7 +108,7 @@ static void psys_path_iter_get(ParticlePathIterator *iter, ParticleCacheKey *key
typedef struct ParticlePathModifier {
struct ParticlePathModifier *next, *prev;
-
+
void (*apply)(ParticleCacheKey *keys, int totkeys, ParticleCacheKey *parent_keys);
} ParticlePathModifier;
@@ -133,7 +127,7 @@ static void do_kink_spiral_deform(ParticleKey *state, const float dir[3], const
{
/* Creates a logarithmic spiral:
* r(theta) = a * exp(b * theta)
- *
+ *
* The "density" parameter b is defined by the shape parameter
* and goes up to the Golden Spiral for 1.0
* https://en.wikipedia.org/wiki/Golden_spiral
@@ -142,33 +136,33 @@ static void do_kink_spiral_deform(ParticleKey *state, const float dir[3], const
/* angle of the spiral against the curve (rotated opposite to make a smooth transition) */
const float start_angle = ((b != 0.0f) ? atanf(1.0f / b) :
(float)-M_PI_2) + (b > 0.0f ? -(float)M_PI_2 : (float)M_PI_2);
-
+
float spiral_axis[3], rot[3][3];
float vec[3];
-
+
float theta = freq * time * 2.0f * (float)M_PI;
float radius = amplitude * expf(b * theta);
-
+
/* a bit more intuitive than using negative frequency for this */
if (amplitude < 0.0f)
theta = -theta;
-
+
cross_v3_v3v3(spiral_axis, dir, kink);
normalize_v3(spiral_axis);
-
+
mul_v3_v3fl(vec, kink, -radius);
-
+
axis_angle_normalized_to_mat3(rot, spiral_axis, theta);
mul_m3_v3(rot, vec);
-
+
madd_v3_v3fl(vec, kink, amplitude);
-
+
axis_angle_normalized_to_mat3(rot, spiral_axis, -start_angle);
mul_m3_v3(rot, vec);
-
+
add_v3_v3v3(result, spiral_start, vec);
}
-
+
copy_v3_v3(state->co, result);
}
@@ -180,7 +174,7 @@ static void do_kink_spiral(ParticleThreadContext *ctx, ParticleTexture *ptex, co
const int seed = ctx->sim.psys->child_seed + (int)(cpa - ctx->sim.psys->child);
const int totkeys = ctx->segments + 1;
const int extrakeys = ctx->extra_segments;
-
+
float kink_amp_random = part->kink_amp_random;
float kink_amp = part->kink_amp * (1.0f - kink_amp_random * psys_frand(ctx->sim.psys, 93541 + seed));
float kink_freq = part->kink_freq;
@@ -189,11 +183,11 @@ static void do_kink_spiral(ParticleThreadContext *ctx, ParticleTexture *ptex, co
float rough1 = part->rough1;
float rough2 = part->rough2;
float rough_end = part->rough_end;
-
+
ParticlePathIterator iter;
ParticleCacheKey *key;
int k;
-
+
float dir[3];
float spiral_start[3] = {0.0f, 0.0f, 0.0f};
float spiral_start_time = 0.0f;
@@ -204,7 +198,7 @@ static void do_kink_spiral(ParticleThreadContext *ctx, ParticleTexture *ptex, co
float cut_time;
int start_index = 0, end_index = 0;
float kink_base[3];
-
+
if (ptex) {
kink_amp *= ptex->kink_amp;
kink_freq *= ptex->kink_freq;
@@ -212,44 +206,53 @@ static void do_kink_spiral(ParticleThreadContext *ctx, ParticleTexture *ptex, co
rough2 *= ptex->rough2;
rough_end *= ptex->roughe;
}
-
+
cut_time = (totkeys - 1) * ptex->length;
zero_v3(spiral_start);
-
+
for (k = 0, key = keys; k < totkeys-1; k++, key++) {
if ((float)(k + 1) >= cut_time) {
float fac = cut_time - (float)k;
ParticleCacheKey *par = parent_keys + k;
-
+
start_index = k + 1;
end_index = start_index + extrakeys;
-
+
spiral_start_time = ((float)k + fac) / (float)(totkeys - 1);
interp_v3_v3v3(spiral_start, key->co, (key+1)->co, fac);
-
+
interp_v3_v3v3(spiral_par_co, par->co, (par+1)->co, fac);
interp_v3_v3v3(spiral_par_vel, par->vel, (par+1)->vel, fac);
interp_qt_qtqt(spiral_par_rot, par->rot, (par+1)->rot, fac);
-
+
break;
}
}
-
+
zero_v3(dir);
-
+
zero_v3(kink_base);
kink_base[part->kink_axis] = 1.0f;
mul_mat3_m4_v3(ctx->sim.ob->obmat, kink_base);
-
+
+ /* Fill in invariant part of modifier context. */
+ ParticleChildModifierContext modifier_ctx = {NULL};
+ modifier_ctx.thread_ctx = ctx;
+ modifier_ctx.sim = &ctx->sim;
+ modifier_ctx.ptex = ptex;
+ modifier_ctx.cpa = cpa;
+ modifier_ctx.orco = orco;
+ modifier_ctx.parent_keys = parent_keys;
+
for (k = 0, key = keys; k < end_index; k++, key++) {
float par_time;
float *par_co, *par_vel, *par_rot;
-
+
psys_path_iter_get(&iter, keys, end_index, NULL, k);
if (k < start_index) {
sub_v3_v3v3(dir, (key+1)->co, key->co);
normalize_v3(dir);
-
+
par_time = (float)k / (float)(totkeys - 1);
par_co = parent_keys[k].co;
par_vel = parent_keys[k].vel;
@@ -258,36 +261,42 @@ static void do_kink_spiral(ParticleThreadContext *ctx, ParticleTexture *ptex, co
else {
float spiral_time = (float)(k - start_index) / (float)(extrakeys-1);
float kink[3], tmp[3];
-
+
/* use same time value for every point on the spiral */
par_time = spiral_start_time;
par_co = spiral_par_co;
par_vel = spiral_par_vel;
par_rot = spiral_par_rot;
-
+
project_v3_v3v3(tmp, kink_base, dir);
sub_v3_v3v3(kink, kink_base, tmp);
normalize_v3(kink);
-
+
if (kink_axis_random > 0.0f) {
float a = kink_axis_random * (psys_frand(ctx->sim.psys, 7112 + seed) * 2.0f - 1.0f) * (float)M_PI;
float rot[3][3];
-
+
axis_angle_normalized_to_mat3(rot, dir, a);
mul_m3_v3(rot, kink);
}
-
+
do_kink_spiral_deform((ParticleKey *)key, dir, kink, spiral_time, kink_freq, kink_shape, kink_amp, spiral_start);
}
-
- /* apply different deformations to the child path */
- do_child_modifiers(ctx, &ctx->sim, ptex, par_co, par_vel, par_rot, parent_orco, cpa, orco, hairmat, (ParticleKey *)key, par_time);
+
+ /* Fill in variant part of modifier context. */
+ modifier_ctx.par_co = par_co;
+ modifier_ctx.par_vel = par_vel;
+ modifier_ctx.par_rot = par_rot;
+ modifier_ctx.par_orco = parent_orco;
+
+ /* Apply different deformations to the child path/ */
+ do_child_modifiers(&modifier_ctx, hairmat, (ParticleKey *)key, par_time);
}
-
+
totlen = 0.0f;
for (k = 0, key = keys; k < end_index-1; k++, key++)
totlen += len_v3v3((key+1)->co, key->co);
-
+
*r_totkeys = end_index;
*r_max_length = totlen;
}
@@ -318,12 +327,12 @@ void psys_apply_child_modifiers(ParticleThreadContext *ctx, struct ListBase *mod
struct Material *ma = ctx->ma;
const bool draw_col_ma = (part->draw_col == PART_DRAW_COL_MAT);
const bool use_length_check = !ELEM(part->kink, PART_KINK_SPIRAL);
-
+
ParticlePathModifier *mod;
ParticleCacheKey *key;
int totkeys, k;
float max_length;
-
+
#if 0 /* TODO for the future: use true particle modifiers that work on the whole curve */
for (mod = modifiers->first; mod; mod = mod->next) {
mod->apply(keys, totkeys, parent_keys);
@@ -331,25 +340,38 @@ void psys_apply_child_modifiers(ParticleThreadContext *ctx, struct ListBase *mod
#else
(void)modifiers;
(void)mod;
-
+
if (part->kink == PART_KINK_SPIRAL) {
do_kink_spiral(ctx, ptex, parent_orco, cpa, orco, hairmat, keys, parent_keys, &totkeys, &max_length);
keys->segments = totkeys - 1;
}
else {
- ParticlePathIterator iter;
-
+ /* Fill in invariant part of modifier context. */
+ ParticleChildModifierContext modifier_ctx = {NULL};
+ modifier_ctx.thread_ctx = ctx;
+ modifier_ctx.sim = &ctx->sim;
+ modifier_ctx.ptex = ptex;
+ modifier_ctx.cpa = cpa;
+ modifier_ctx.orco = orco;
+ modifier_ctx.parent_keys = parent_keys;
+
totkeys = ctx->segments + 1;
max_length = ptex->length;
-
+
for (k = 0, key = keys; k < totkeys; k++, key++) {
- ParticleKey *par;
-
+ ParticlePathIterator iter;
psys_path_iter_get(&iter, keys, totkeys, parent_keys, k);
- par = (ParticleKey *)iter.parent_key;
-
- /* apply different deformations to the child path */
- do_child_modifiers(ctx, &ctx->sim, ptex, par->co, par->vel, iter.parent_rotation, parent_orco, cpa, orco, hairmat, (ParticleKey *)key, iter.time);
+
+ ParticleKey *par = (ParticleKey *)iter.parent_key;
+
+ /* Fill in variant part of modifier context. */
+ modifier_ctx.par_co = par->co;
+ modifier_ctx.par_vel = par->vel;
+ modifier_ctx.par_rot = iter.parent_rotation;
+ modifier_ctx.par_orco = parent_orco;
+
+ /* Apply different deformations to the child path. */
+ do_child_modifiers(&modifier_ctx, hairmat, (ParticleKey *)key, iter.time);
}
}
@@ -367,11 +389,11 @@ void psys_apply_child_modifiers(ParticleThreadContext *ctx, struct ListBase *mod
if (k >= 2) {
sub_v3_v3v3((key-1)->vel, key->co, (key-2)->co);
mul_v3_fl((key-1)->vel, 0.5);
-
+
if (ma && draw_col_ma)
get_strand_normal(ma, ornor, cur_length, (key-1)->vel);
}
-
+
if (use_length_check && k > 1) {
float dvec[3];
/* check if path needs to be cut before actual end of data points */
@@ -388,7 +410,7 @@ void psys_apply_child_modifiers(ParticleThreadContext *ctx, struct ListBase *mod
/* last key */
sub_v3_v3v3(key->vel, key->co, (key-1)->co);
}
-
+
if (ma && draw_col_ma) {
copy_v3_v3(key->col, &ma->r);
get_strand_normal(ma, ornor, cur_length, key->vel);
@@ -419,7 +441,7 @@ void do_kink(ParticleKey *state, const float par_co[3], const float par_vel[3],
}
t = time * freq * (float)M_PI;
-
+
if (smooth_start) {
dt = fabsf(t);
/* smooth the beginning of kink */
@@ -434,7 +456,7 @@ void do_kink(ParticleKey *state, const float par_co[3], const float par_vel[3],
if (obmat)
mul_mat3_m4_v3(obmat, kink);
-
+
mul_qt_v3(par_rot, kink);
/* make sure kink is normal to strand */
@@ -450,12 +472,12 @@ void do_kink(ParticleKey *state, const float par_co[3], const float par_vel[3],
case PART_KINK_CURL:
{
float curl_offset[3];
-
+
/* rotate kink vector around strand tangent */
mul_v3_v3fl(curl_offset, kink, amplitude);
axis_angle_to_quat(q1, par_vel, t);
mul_qt_v3(q1, curl_offset);
-
+
interp_v3_v3v3(par_vec, state->co, par_co, flat);
add_v3_v3v3(result, par_vec, curl_offset);
break;
@@ -494,7 +516,7 @@ void do_kink(ParticleKey *state, const float par_co[3], const float par_vel[3],
float z_vec[3] = {0.f, 0.f, 1.f};
float vec_one[3], state_co[3];
float inp_y, inp_z, length;
-
+
if (par_rot) {
mul_qt_v3(par_rot, y_vec);
mul_qt_v3(par_rot, z_vec);
@@ -563,10 +585,10 @@ static float do_clump_level(float result[3], const float co[3], const float par_
float clumpfac, float clumppow, float pa_clump, CurveMapping *clumpcurve)
{
float clump = 0.0f;
-
+
if (clumpcurve) {
- clump = pa_clump * (1.0f - CLAMPIS(curvemapping_evaluateF(clumpcurve, 0, time), 0.0f, 1.0f));
-
+ clump = pa_clump * (1.0f - clamp_f(curvemapping_evaluateF(clumpcurve, 0, time), 0.0f, 1.0f));
+
interp_v3_v3v3(result, co, par_co, clump);
}
else if (clumpfac != 0.0f) {
@@ -584,7 +606,7 @@ static float do_clump_level(float result[3], const float co[3], const float par_
interp_v3_v3v3(result, co, par_co, clump);
}
-
+
return clump;
}
@@ -592,21 +614,21 @@ float do_clump(ParticleKey *state, const float par_co[3], float time, const floa
bool use_clump_noise, float clump_noise_size, CurveMapping *clumpcurve)
{
float clump;
-
+
if (use_clump_noise && clump_noise_size != 0.0f) {
float center[3], noisevec[3];
float da[4], pa[12];
-
+
mul_v3_v3fl(noisevec, orco_offset, 1.0f / clump_noise_size);
voronoi(noisevec[0], noisevec[1], noisevec[2], da, pa, 1.0f, 0);
mul_v3_fl(&pa[0], clump_noise_size);
add_v3_v3v3(center, par_co, &pa[0]);
-
+
do_clump_level(state->co, state->co, center, time, clumpfac, clumppow, pa_clump, clumpcurve);
}
-
+
clump = do_clump_level(state->co, state->co, par_co, time, clumpfac, clumppow, pa_clump, clumpcurve);
-
+
return clump;
}
@@ -651,27 +673,117 @@ static void do_rough_curve(const float loc[3], float mat[4][4], float time, floa
{
float rough[3];
float rco[3];
-
+
if (!roughcurve)
return;
-
- fac *= CLAMPIS(curvemapping_evaluateF(roughcurve, 0, time), 0.0f, 1.0f);
-
+
+ fac *= clamp_f(curvemapping_evaluateF(roughcurve, 0, time), 0.0f, 1.0f);
+
copy_v3_v3(rco, loc);
mul_v3_fl(rco, time);
rough[0] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[0], rco[1], rco[2], 2, 0, 2);
rough[1] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[1], rco[2], rco[0], 2, 0, 2);
rough[2] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[2], rco[0], rco[1], 2, 0, 2);
-
+
madd_v3_v3fl(state->co, mat[0], fac * rough[0]);
madd_v3_v3fl(state->co, mat[1], fac * rough[1]);
madd_v3_v3fl(state->co, mat[2], fac * rough[2]);
}
-void do_child_modifiers(ParticleThreadContext *ctx, ParticleSimulationData *sim, ParticleTexture *ptex,
- const float par_co[3], const float par_vel[3], const float par_rot[4], const float par_orco[3],
- ChildParticle *cpa, const float orco[3], float mat[4][4], ParticleKey *state, float t)
+static int twist_num_segments(const ParticleChildModifierContext *modifier_ctx)
{
+ ParticleThreadContext *thread_ctx = modifier_ctx->thread_ctx;
+ return (thread_ctx != NULL) ? thread_ctx->segments
+ : modifier_ctx->sim->psys->part->draw_step;
+}
+
+static void twist_get_axis(const ParticleChildModifierContext *modifier_ctx,
+ const float time, float r_axis[3])
+{
+ const int num_segments = twist_num_segments(modifier_ctx);
+ const int index = clamp_i(time * num_segments, 0, num_segments);
+ if (index > 0) {
+ sub_v3_v3v3(r_axis,
+ modifier_ctx->parent_keys[index].co,
+ modifier_ctx->parent_keys[index - 1].co);
+ }
+ else {
+ sub_v3_v3v3(r_axis,
+ modifier_ctx->parent_keys[index + 1].co,
+ modifier_ctx->parent_keys[index].co);
+ }
+}
+
+static float curvemapping_integrate_clamped(CurveMapping *curve,
+ float start, float end, float step)
+{
+ float integral = 0.0f;
+ float x = start;
+ while (x < end) {
+ float y = curvemapping_evaluateF(curve, 0, x);
+ y = clamp_f(y, 0.0f, 1.0f);
+ /* TODO(sergey): Clamp last step to end. */
+ integral += y * step;
+ x += step;
+ }
+ return integral;
+}
+
+static void do_twist(const ParticleChildModifierContext *modifier_ctx,
+ ParticleKey *state, const float time)
+{
+ ParticleThreadContext *thread_ctx = modifier_ctx->thread_ctx;
+ ParticleSimulationData *sim = modifier_ctx->sim;
+ ParticleTexture *ptex = modifier_ctx->ptex;
+ ParticleSettings *part = sim->psys->part;
+ /* Early output checks. */
+ if (part->childtype != PART_CHILD_PARTICLES) {
+ /* Interpolated children behave weird with twist. */
+ return;
+ }
+ if (part->twist == 0.0f) {
+ /* No twist along the strand. */
+ return;
+ }
+ /* Dependent on whether it's threaded update or not, curve comes
+ * from different places.
+ */
+ CurveMapping *twist_curve = NULL;
+ if (part->child_flag & PART_CHILD_USE_TWIST_CURVE) {
+ twist_curve = (thread_ctx != NULL) ? thread_ctx->twistcurve
+ : part->twistcurve;
+ }
+ /* Axis of rotation. */
+ float axis[3];
+ twist_get_axis(modifier_ctx, time, axis);
+ /* Angle of rotation. */
+ float angle = part->twist;
+ if (ptex != NULL) {
+ angle *= (ptex->twist - 0.5f) * 2.0f;
+ }
+ if (twist_curve != NULL) {
+ const int num_segments = twist_num_segments(modifier_ctx);
+ angle *= curvemapping_integrate_clamped(twist_curve,
+ 0.0f, time,
+ 1.0f / num_segments);
+ }
+ else {
+ angle *= time;
+ }
+ /* Perform rotation around parent curve. */
+ float vec[3];
+ sub_v3_v3v3(vec, state->co, modifier_ctx->par_co);
+ rotate_v3_v3v3fl(state->co, vec, axis, angle * 2.0f * M_PI);
+ add_v3_v3(state->co, modifier_ctx->par_co);
+}
+
+void do_child_modifiers(const ParticleChildModifierContext *modifier_ctx,
+ float mat[4][4], ParticleKey *state, float t)
+{
+ ParticleThreadContext *ctx = modifier_ctx->thread_ctx;
+ ParticleSimulationData *sim = modifier_ctx->sim;
+ ParticleTexture *ptex = modifier_ctx->ptex;
+ ChildParticle *cpa = modifier_ctx->cpa;
ParticleSettings *part = sim->psys->part;
CurveMapping *clumpcurve = NULL, *roughcurve = NULL;
int i = cpa - sim->psys->child;
@@ -700,6 +812,8 @@ void do_child_modifiers(ParticleThreadContext *ctx, ParticleSimulationData *sim,
rough_end *= ptex->roughe;
}
+ do_twist(modifier_ctx, state, t);
+
if (part->flag & PART_CHILD_EFFECT)
/* state is safe to cast, since only co and vel are used */
guided = do_guides(sim->eval_ctx, sim->psys->part, sim->psys->effectors, (ParticleKey *)state, cpa->parent, t);
@@ -707,33 +821,51 @@ void do_child_modifiers(ParticleThreadContext *ctx, ParticleSimulationData *sim,
if (guided == 0) {
float orco_offset[3];
float clump;
-
- sub_v3_v3v3(orco_offset, orco, par_orco);
- clump = do_clump(state, par_co, t, orco_offset, part->clumpfac, part->clumppow, ptex ? ptex->clump : 1.f,
- part->child_flag & PART_CHILD_USE_CLUMP_NOISE, part->clump_noise_size, clumpcurve);
+
+ sub_v3_v3v3(orco_offset, modifier_ctx->orco, modifier_ctx->par_orco);
+ clump = do_clump(state,
+ modifier_ctx->par_co,
+ t,
+ orco_offset,
+ part->clumpfac,
+ part->clumppow,
+ ptex ? ptex->clump : 1.0f,
+ part->child_flag & PART_CHILD_USE_CLUMP_NOISE,
+ part->clump_noise_size,
+ clumpcurve);
if (kink_freq != 0.f) {
kink_amp *= (1.f - kink_amp_clump * clump);
-
- do_kink(state, par_co, par_vel, par_rot, t, kink_freq, part->kink_shape,
- kink_amp, part->kink_flat, part->kink, part->kink_axis,
- sim->ob->obmat, smooth_start);
+
+ do_kink(state,
+ modifier_ctx->par_co,
+ modifier_ctx->par_vel,
+ modifier_ctx->par_rot,
+ t,
+ kink_freq,
+ part->kink_shape,
+ kink_amp,
+ part->kink_flat,
+ part->kink,
+ part->kink_axis,
+ sim->ob->obmat,
+ smooth_start);
}
}
if (roughcurve) {
- do_rough_curve(orco, mat, t, rough1, part->rough1_size, roughcurve, state);
+ do_rough_curve(modifier_ctx->orco, mat, t, rough1, part->rough1_size, roughcurve, state);
}
else {
if (rough1 > 0.f)
- do_rough(orco, mat, t, rough1, part->rough1_size, 0.0, state);
-
+ do_rough(modifier_ctx->orco, mat, t, rough1, part->rough1_size, 0.0, state);
+
if (rough2 > 0.f) {
float vec[3];
psys_frand_vec(sim->psys, i + 27, vec);
do_rough(vec, mat, t, rough2, part->rough2_size, part->rough2_thres, state);
}
-
+
if (rough_end > 0.f) {
float vec[3];
psys_frand_vec(sim->psys, i + 27, vec);
diff --git a/source/blender/blenkernel/intern/particle_distribute.c b/source/blender/blenkernel/intern/particle_distribute.c
index ff8a638089f..767a17a34e7 100644
--- a/source/blender/blenkernel/intern/particle_distribute.c
+++ b/source/blender/blenkernel/intern/particle_distribute.c
@@ -36,7 +36,7 @@
#include "MEM_guardedalloc.h"
#include "BLI_utildefines.h"
-#include "BLI_jitter.h"
+#include "BLI_jitter_2d.h"
#include "BLI_kdtree.h"
#include "BLI_math.h"
#include "BLI_math_geom.h"
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index ac10ad44bf1..9bc4da6f0d5 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -48,7 +48,7 @@
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
-#include "DNA_object_force.h"
+#include "DNA_object_force_types.h"
#include "DNA_object_types.h"
#include "DNA_curve_types.h"
#include "DNA_scene_types.h"
@@ -58,7 +58,7 @@
#include "BLI_utildefines.h"
#include "BLI_edgehash.h"
#include "BLI_rand.h"
-#include "BLI_jitter.h"
+#include "BLI_jitter_2d.h"
#include "BLI_math.h"
#include "BLI_blenlib.h"
#include "BLI_kdtree.h"
@@ -98,7 +98,7 @@
/* fluid sim particle import */
#ifdef WITH_MOD_FLUID
-#include "DNA_object_fluidsim.h"
+#include "DNA_object_fluidsim_types.h"
#include "LBM_fluidsim.h"
#include <zlib.h>
#include <string.h>
@@ -499,6 +499,8 @@ void psys_thread_context_free(ParticleThreadContext *ctx)
MEM_freeN(ctx->vg_rough2);
if (ctx->vg_roughe)
MEM_freeN(ctx->vg_roughe);
+ if (ctx->vg_twist)
+ MEM_freeN(ctx->vg_twist);
if (ctx->sim.psys->lattice_deform_data) {
end_latt_deform(ctx->sim.psys->lattice_deform_data);
@@ -521,6 +523,9 @@ void psys_thread_context_free(ParticleThreadContext *ctx)
if (ctx->roughcurve != NULL) {
curvemapping_free(ctx->roughcurve);
}
+ if (ctx->twistcurve != NULL) {
+ curvemapping_free(ctx->twistcurve);
+ }
}
static void initialize_particle_texture(ParticleSimulationData *sim, ParticleData *pa, int p)
@@ -2898,14 +2903,19 @@ static void psys_update_path_cache(ParticleSimulationData *sim, float cfra, cons
{
ParticleSystem *psys = sim->psys;
ParticleSettings *part = psys->part;
+#if 0
ParticleEditSettings *pset = &sim->scene->toolsettings->particle;
+#endif
int distr=0, alloc=0, skip=0;
if ((psys->part->childtype && psys->totchild != psys_get_tot_child(sim->scene, psys)) || psys->recalc&PSYS_RECALC_RESET)
alloc=1;
- if (alloc || psys->recalc&PSYS_RECALC_CHILD || (psys->vgroup[PSYS_VG_DENSITY] && (sim->ob && sim->ob->mode & OB_MODE_WEIGHT_PAINT)))
+ if (alloc || psys->recalc&PSYS_RECALC_CHILD ||
+ (psys->vgroup[PSYS_VG_DENSITY] && (sim->ob && sim->eval_ctx->object_mode & OB_MODE_WEIGHT_PAINT)))
+ {
distr=1;
+ }
if (distr) {
if (alloc)
@@ -2933,12 +2943,15 @@ static void psys_update_path_cache(ParticleSimulationData *sim, float cfra, cons
skip = 1; /* draw visualization */
else if (psys->pointcache->flag & PTCACHE_BAKING)
skip = 1; /* no need to cache paths while baking dynamics */
- else if (psys_in_edit_mode(sim->eval_ctx->view_layer, psys)) {
+
+#if 0 /* TODO(mai): something is very wrong with these conditionals, they dont make sense and the cache isnt updating */
+ else if (psys_in_edit_mode(sim->eval_ctx, sim->eval_ctx->view_layer, psys)) {
if ((pset->flag & PE_DRAW_PART)==0)
skip = 1;
else if (part->childtype==0 && (psys->flag & PSYS_HAIR_DYNAMICS && psys->pointcache->flag & PTCACHE_BAKED)==0)
skip = 1; /* in edit mode paths are needed for child particles and dynamic hair */
}
+#endif
}
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index 63f2c7e5452..14e0cfa75b5 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -1296,7 +1296,7 @@ void BKE_pbvh_get_grid_updates(PBVH *bvh, bool clear, void ***r_gridfaces, int *
pbvh_iter_end(&iter);
- const int tot = BLI_gset_size(face_set);
+ const int tot = BLI_gset_len(face_set);
if (tot == 0) {
*r_totface = 0;
*r_gridfaces = NULL;
@@ -1435,8 +1435,8 @@ void BKE_pbvh_node_num_verts(
if (r_uniquevert) *r_uniquevert = node->uniq_verts;
break;
case PBVH_BMESH:
- tot = BLI_gset_size(node->bm_unique_verts);
- if (r_totvert) *r_totvert = tot + BLI_gset_size(node->bm_other_verts);
+ tot = BLI_gset_len(node->bm_unique_verts);
+ if (r_totvert) *r_totvert = tot + BLI_gset_len(node->bm_other_verts);
if (r_uniquevert) *r_uniquevert = tot;
break;
}
diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c
index e77edb21798..6b6f2605dc3 100644
--- a/source/blender/blenkernel/intern/pbvh_bmesh.c
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -255,7 +255,7 @@ static void pbvh_bmesh_node_split(PBVH *bvh, const BBC *bbc_array, int node_inde
const int cd_face_node_offset = bvh->cd_face_node_offset;
PBVHNode *n = &bvh->nodes[node_index];
- if (BLI_gset_size(n->bm_faces) <= bvh->leaf_limit) {
+ if (BLI_gset_len(n->bm_faces) <= bvh->leaf_limit) {
/* Node limit not exceeded */
pbvh_bmesh_node_finalize(bvh, node_index, cd_vert_node_offset, cd_face_node_offset);
return;
@@ -289,8 +289,8 @@ static void pbvh_bmesh_node_split(PBVH *bvh, const BBC *bbc_array, int node_inde
*c2 = &bvh->nodes[children + 1];
c1->flag |= PBVH_Leaf;
c2->flag |= PBVH_Leaf;
- c1->bm_faces = BLI_gset_ptr_new_ex("bm_faces", BLI_gset_size(n->bm_faces) / 2);
- c2->bm_faces = BLI_gset_ptr_new_ex("bm_faces", BLI_gset_size(n->bm_faces) / 2);
+ c1->bm_faces = BLI_gset_ptr_new_ex("bm_faces", BLI_gset_len(n->bm_faces) / 2);
+ c2->bm_faces = BLI_gset_ptr_new_ex("bm_faces", BLI_gset_len(n->bm_faces) / 2);
/* Partition the parent node's faces between the two children */
GSET_ITER (gs_iter, n->bm_faces) {
@@ -305,11 +305,11 @@ static void pbvh_bmesh_node_split(PBVH *bvh, const BBC *bbc_array, int node_inde
/* Enforce at least one primitive in each node */
GSet *empty = NULL, *other;
- if (BLI_gset_size(c1->bm_faces) == 0) {
+ if (BLI_gset_len(c1->bm_faces) == 0) {
empty = c1->bm_faces;
other = c2->bm_faces;
}
- else if (BLI_gset_size(c2->bm_faces) == 0) {
+ else if (BLI_gset_len(c2->bm_faces) == 0) {
empty = c2->bm_faces;
other = c1->bm_faces;
}
@@ -375,7 +375,7 @@ static void pbvh_bmesh_node_split(PBVH *bvh, const BBC *bbc_array, int node_inde
static bool pbvh_bmesh_node_limit_ensure(PBVH *bvh, int node_index)
{
GSet *bm_faces = bvh->nodes[node_index].bm_faces;
- const int bm_faces_size = BLI_gset_size(bm_faces);
+ const int bm_faces_size = BLI_gset_len(bm_faces);
if (bm_faces_size <= bvh->leaf_limit) {
/* Node limit not exceeded */
return false;
@@ -1238,7 +1238,7 @@ static bool pbvh_bmesh_subdivide_long_edges(
bool any_subdivided = false;
while (!BLI_heap_is_empty(eq_ctx->q->heap)) {
- BMVert **pair = BLI_heap_popmin(eq_ctx->q->heap);
+ BMVert **pair = BLI_heap_pop_min(eq_ctx->q->heap);
BMVert *v1 = pair[0], *v2 = pair[1];
BMEdge *e;
@@ -1326,7 +1326,7 @@ static void pbvh_bmesh_collapse_edge(
/* Note: this could be done with BM_vert_splice(), but that
* requires handling other issues like duplicate edges, so doesn't
* really buy anything. */
- BLI_buffer_empty(deleted_faces);
+ BLI_buffer_clear(deleted_faces);
BMLoop *l;
@@ -1455,7 +1455,7 @@ static bool pbvh_bmesh_collapse_short_edges(
GHash *deleted_verts = BLI_ghash_ptr_new("deleted_verts");
while (!BLI_heap_is_empty(eq_ctx->q->heap)) {
- BMVert **pair = BLI_heap_popmin(eq_ctx->q->heap);
+ BMVert **pair = BLI_heap_pop_min(eq_ctx->q->heap);
BMVert *v1 = pair[0], *v2 = pair[1];
BLI_mempool_free(eq_ctx->pool, pair);
pair = NULL;
@@ -2011,10 +2011,10 @@ void BKE_pbvh_bmesh_node_save_orig(PBVHNode *node)
if (node->bm_orco)
return;
- const int totvert = BLI_gset_size(node->bm_unique_verts) +
- BLI_gset_size(node->bm_other_verts);
+ const int totvert = BLI_gset_len(node->bm_unique_verts) +
+ BLI_gset_len(node->bm_other_verts);
- const int tottri = BLI_gset_size(node->bm_faces);
+ const int tottri = BLI_gset_len(node->bm_faces);
node->bm_orco = MEM_mallocN(sizeof(*node->bm_orco) * totvert, __func__);
node->bm_ortri = MEM_mallocN(sizeof(*node->bm_ortri) * tottri, __func__);
@@ -2189,12 +2189,12 @@ static void pbvh_bmesh_verify(PBVH *bvh)
int totface = 0, totvert = 0;
for (int i = 0; i < bvh->totnode; i++) {
PBVHNode *n = &bvh->nodes[i];
- totface += n->bm_faces ? BLI_gset_size(n->bm_faces) : 0;
- totvert += n->bm_unique_verts ? BLI_gset_size(n->bm_unique_verts) : 0;
+ totface += n->bm_faces ? BLI_gset_len(n->bm_faces) : 0;
+ totvert += n->bm_unique_verts ? BLI_gset_len(n->bm_unique_verts) : 0;
}
- BLI_assert(totface == BLI_gset_size(faces_all));
- BLI_assert(totvert == BLI_gset_size(verts_all));
+ BLI_assert(totface == BLI_gset_len(faces_all));
+ BLI_assert(totvert == BLI_gset_len(verts_all));
}
{
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index b794fcfd929..169b1b10024 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -40,7 +40,7 @@
#include "DNA_dynamicpaint_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
-#include "DNA_object_force.h"
+#include "DNA_object_force_types.h"
#include "DNA_particle_types.h"
#include "DNA_rigidbody_types.h"
#include "DNA_scene_types.h"
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index bd4b817c8cd..4a52c4f7d14 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -50,7 +50,7 @@
#include "DNA_group_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
-#include "DNA_object_force.h"
+#include "DNA_object_force_types.h"
#include "DNA_rigidbody_types.h"
#include "DNA_scene_types.h"
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 16e9844241d..899a911270f 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -166,7 +166,6 @@ void BKE_scene_copy_data(Main *bmain, Scene *sce_dst, const Scene *sce_src, cons
sce_dst->ed = NULL;
sce_dst->depsgraph_hash = NULL;
- sce_dst->obedit = NULL;
sce_dst->fps_info = NULL;
/* layers and collections */
@@ -618,7 +617,7 @@ void BKE_scene_init(Scene *sce)
*/
sce->r.color_mgt_flag |= R_COLOR_MANAGEMENT;
- sce->r.gauss = 1.0;
+ sce->r.gauss = 1.5f;
/* deprecated but keep for upwards compat */
sce->r.postgamma = 1.0;
@@ -982,10 +981,6 @@ void BKE_scene_set_background(Main *bmain, Scene *scene)
/* check for cyclic sets, for reading old files but also for definite security (py?) */
BKE_scene_validate_setscene(bmain, scene);
- /* can happen when switching modes in other scenes */
- if (scene->obedit && !(scene->obedit->mode & OB_MODE_EDIT))
- scene->obedit = NULL;
-
/* deselect objects (for dataselect) */
for (ob = bmain->object.first; ob; ob = ob->id.next)
ob->flag &= ~(SELECT | OB_FROMGROUP);
@@ -1381,7 +1376,7 @@ static bool check_rendered_viewport_visible(Main *bmain)
return false;
}
-static void prepare_mesh_for_viewport_render(Main *bmain, Scene *scene)
+static void prepare_mesh_for_viewport_render(Main *bmain, const EvaluationContext *eval_ctx)
{
/* This is needed to prepare mesh to be used by the render
* engine from the viewport rendering. We do loading here
@@ -1392,7 +1387,7 @@ static void prepare_mesh_for_viewport_render(Main *bmain, Scene *scene)
* call loading of the edit data for the mesh objects.
*/
- Object *obedit = scene->obedit;
+ Object *obedit = OBEDIT_FROM_EVAL_CTX(eval_ctx);
if (obedit) {
Mesh *mesh = obedit->data;
if ((obedit->type == OB_MESH) &&
@@ -1401,7 +1396,11 @@ static void prepare_mesh_for_viewport_render(Main *bmain, Scene *scene)
{
if (check_rendered_viewport_visible(bmain)) {
BMesh *bm = mesh->edit_btmesh->bm;
- BM_mesh_bm_to_me(bm, mesh, (&(struct BMeshToMeshParams){0}));
+ BM_mesh_bm_to_me(
+ bm, mesh,
+ (&(struct BMeshToMeshParams){
+ .calc_object_remap = true,
+ }));
DEG_id_tag_update(&mesh->id, 0);
}
}
@@ -1430,7 +1429,7 @@ void BKE_scene_graph_update_tagged(EvaluationContext *eval_ctx,
/* Uncomment this to check if graph was properly tagged for update. */
// DEG_debug_graph_relations_validate(depsgraph, bmain, scene);
/* Flush editing data if needed. */
- prepare_mesh_for_viewport_render(bmain, scene);
+ prepare_mesh_for_viewport_render(bmain, eval_ctx);
/* Flush recalc flags to dependencies. */
DEG_graph_flush_update(bmain, depsgraph);
/* Update all objects: drivers, matrices, displists, etc. flags set
diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c
index ef9c22f1661..9f475dbd439 100644
--- a/source/blender/blenkernel/intern/screen.c
+++ b/source/blender/blenkernel/intern/screen.c
@@ -182,7 +182,7 @@ ARegion *BKE_area_region_copy(SpaceType *st, ARegion *ar)
BLI_listbase_clear(&newar->panels_category);
BLI_listbase_clear(&newar->panels_category_active);
BLI_listbase_clear(&newar->ui_lists);
- newar->swinid = 0;
+ newar->visible = 0;
newar->manipulator_map = NULL;
newar->regiontimer = NULL;
newar->headerstr = NULL;
diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c
index 618f495dbf1..e91c3e43b83 100644
--- a/source/blender/blenkernel/intern/shrinkwrap.c
+++ b/source/blender/blenkernel/intern/shrinkwrap.c
@@ -57,6 +57,8 @@
#include "BLI_strict_flags.h"
+#include "DEG_depsgraph.h"
+
/* for timing... */
#if 0
# include "PIL_time_utildefines.h"
@@ -614,8 +616,9 @@ static void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc)
}
/* Main shrinkwrap function */
-void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, Object *ob, DerivedMesh *dm,
- float (*vertexCos)[3], int numVerts, bool for_render)
+void shrinkwrapModifier_deform(
+ const EvaluationContext *eval_ctx, ShrinkwrapModifierData *smd, Object *ob, DerivedMesh *dm,
+ float (*vertexCos)[3], int numVerts, bool for_render)
{
DerivedMesh *ss_mesh = NULL;
@@ -670,7 +673,8 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, Object *ob, DerivedM
ssmd.subdivType = ME_CC_SUBSURF; /* catmull clark */
ssmd.levels = smd->subsurfLevels; /* levels */
- ss_mesh = subsurf_make_derived_from_derived(dm, &ssmd, NULL, (ob->mode & OB_MODE_EDIT) ? SUBSURF_IN_EDIT_MODE : 0);
+ ss_mesh = subsurf_make_derived_from_derived(
+ dm, &ssmd, NULL, (eval_ctx->object_mode & OB_MODE_EDIT) ? SUBSURF_IN_EDIT_MODE : 0);
if (ss_mesh) {
calc.vert = ss_mesh->getVertDataArray(ss_mesh, CD_MVERT);
diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c
index 9f9818127bc..9b11b66cedd 100644
--- a/source/blender/blenkernel/intern/smoke.c
+++ b/source/blender/blenkernel/intern/smoke.c
@@ -170,11 +170,11 @@ void smoke_reallocate_highres_fluid(SmokeDomainSettings *sds, float dx, int res[
}
/* smoke_turbulence_init uses non-threadsafe functions from fftw3 lib (like fftw_plan & co). */
- BLI_lock_thread(LOCK_FFTW);
+ BLI_thread_lock(LOCK_FFTW);
sds->wt = smoke_turbulence_init(res, sds->amplify + 1, sds->noise, BKE_tempdir_session(), use_fire, use_colors);
- BLI_unlock_thread(LOCK_FFTW);
+ BLI_thread_unlock(LOCK_FFTW);
sds->res_wt[0] = res[0] * (sds->amplify + 1);
sds->res_wt[1] = res[1] * (sds->amplify + 1);
@@ -1287,6 +1287,8 @@ static void emit_from_particles(
curvemapping_changed_all(psys->part->clumpcurve);
if ((psys->part->child_flag & PART_CHILD_USE_ROUGH_CURVE) && psys->part->roughcurve)
curvemapping_changed_all(psys->part->roughcurve);
+ if ((psys->part->child_flag & PART_CHILD_USE_TWIST_CURVE) && psys->part->twistcurve)
+ curvemapping_changed_all(psys->part->twistcurve);
/* initialize particle cache */
if (psys->part->type == PART_HAIR) {
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index 3cfa8787f4b..1fb95bd3115 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -1580,12 +1580,12 @@ static void sb_sfesf_threads_run(const struct EvaluationContext *eval_ctx, Scene
sb_threads[i].tot= totthread;
}
if (totthread > 1) {
- BLI_init_threads(&threads, exec_scan_for_ext_spring_forces, totthread);
+ BLI_threadpool_init(&threads, exec_scan_for_ext_spring_forces, totthread);
for (i=0; i<totthread; i++)
- BLI_insert_thread(&threads, &sb_threads[i]);
+ BLI_threadpool_insert(&threads, &sb_threads[i]);
- BLI_end_threads(&threads);
+ BLI_threadpool_end(&threads);
}
else
exec_scan_for_ext_spring_forces(&sb_threads[0]);
@@ -2192,12 +2192,12 @@ static void sb_cf_threads_run(Scene *scene, Object *ob, float forcetime, float t
if (totthread > 1) {
- BLI_init_threads(&threads, exec_softbody_calc_forces, totthread);
+ BLI_threadpool_init(&threads, exec_softbody_calc_forces, totthread);
for (i=0; i<totthread; i++)
- BLI_insert_thread(&threads, &sb_threads[i]);
+ BLI_threadpool_insert(&threads, &sb_threads[i]);
- BLI_end_threads(&threads);
+ BLI_threadpool_end(&threads);
}
else
exec_softbody_calc_forces(&sb_threads[0]);
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index 1c3ff352126..10792b7d579 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -85,6 +85,8 @@
#include "CCGSubSurf.h"
+#include "DEG_depsgraph.h"
+
#ifdef WITH_OPENSUBDIV
# include "opensubdiv_capi.h"
#endif
@@ -361,7 +363,7 @@ static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm,
#ifdef USE_DYNSIZE
CCGVertHDL fverts[nverts];
#else
- BLI_array_empty(fverts);
+ BLI_array_clear(fverts);
BLI_array_grow_items(fverts, nverts);
#endif
@@ -400,7 +402,7 @@ static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm,
#ifdef USE_DYNSIZE
CCGVertHDL fverts[nverts];
#else
- BLI_array_empty(fverts);
+ BLI_array_clear(fverts);
BLI_array_grow_items(fverts, nverts);
#endif
@@ -744,7 +746,7 @@ static void ss_sync_ccg_from_derivedmesh(CCGSubSurf *ss,
#ifdef USE_DYNSIZE
CCGVertHDL fVerts[mp->totloop];
#else
- BLI_array_empty(fVerts);
+ BLI_array_clear(fVerts);
BLI_array_grow_items(fVerts, mp->totloop);
#endif
@@ -3788,12 +3790,14 @@ static void ccgDM_release(DerivedMesh *dm)
{
ccgdm->multires.mmd = NULL;
}
-
if (ccgdm->multires.mmd) {
- if (ccgdm->multires.modified_flags & MULTIRES_COORDS_MODIFIED)
- multires_modifier_update_mdisps(dm);
- if (ccgdm->multires.modified_flags & MULTIRES_HIDDEN_MODIFIED)
+ if (ccgdm->multires.modified_flags & MULTIRES_COORDS_MODIFIED) {
+ /* TODO/OBMODE, pass real mode? */
+ multires_modifier_update_mdisps(dm, OB_MODE_OBJECT);
+ }
+ if (ccgdm->multires.modified_flags & MULTIRES_HIDDEN_MODIFIED) {
multires_modifier_update_hidden(dm);
+ }
}
}
@@ -4187,7 +4191,8 @@ static int ccgDM_use_grid_pbvh(CCGDerivedMesh *ccgdm)
return 1;
}
-static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
+static struct PBVH *ccgDM_getPBVH(
+ Object *ob, DerivedMesh *dm, eObjectMode object_mode)
{
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
CCGKey key;
@@ -4204,7 +4209,7 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
return NULL;
bool grid_pbvh = ccgDM_use_grid_pbvh(ccgdm);
- if ((ob->mode & OB_MODE_SCULPT) == 0) {
+ if ((object_mode & OB_MODE_SCULPT) == 0) {
/* In vwpaint, we may use a grid_pbvh for multires/subsurf, under certain conditions.
* More complex cases break 'history' trail back to original vertices, in that case we fall back to
* deformed cage only (i.e. original deformed mesh). */
@@ -4583,7 +4588,7 @@ static void set_ccgdm_all_geometry(CCGDerivedMesh *ccgdm,
*((int *)ccgSubSurf_getFaceUserData(ss, f)) = vertNum;
#ifndef USE_DYNSIZE
- BLI_array_empty(loopidx);
+ BLI_array_clear(loopidx);
BLI_array_grow_items(loopidx, numVerts);
#endif
for (s = 0; s < numVerts; s++) {
@@ -4591,7 +4596,7 @@ static void set_ccgdm_all_geometry(CCGDerivedMesh *ccgdm,
}
#ifndef USE_DYNSIZE
- BLI_array_empty(vertidx);
+ BLI_array_clear(vertidx);
BLI_array_grow_items(vertidx, numVerts);
#endif
for (s = 0; s < numVerts; s++) {
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index fcedd880615..71b90641e02 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -412,6 +412,7 @@ void BKE_texture_mtex_default(MTex *mtex)
mtex->kinkfac = 1.0f;
mtex->kinkampfac = 1.0f;
mtex->roughfac = 1.0f;
+ mtex->twistfac = 1.0f;
mtex->padensfac = 1.0f;
mtex->lifefac = 1.0f;
mtex->sizefac = 1.0f;
diff --git a/source/blender/blenkernel/intern/tracking_util.c b/source/blender/blenkernel/intern/tracking_util.c
index d8e98291117..8c1b846db84 100644
--- a/source/blender/blenkernel/intern/tracking_util.c
+++ b/source/blender/blenkernel/intern/tracking_util.c
@@ -787,9 +787,9 @@ static ImBuf *accessor_get_ibuf(TrackingImageAccessor *accessor,
* in the cache which is nice on the one hand (faster re-use of the
* frames) but on the other hand it bumps the memory usage up.
*/
- BLI_lock_thread(LOCK_MOVIECLIP);
+ BLI_thread_lock(LOCK_MOVIECLIP);
IMB_float_from_rect(orig_ibuf);
- BLI_unlock_thread(LOCK_MOVIECLIP);
+ BLI_thread_unlock(LOCK_MOVIECLIP);
final_ibuf = orig_ibuf;
}
/* Downscale if needed. */
diff --git a/source/blender/blenkernel/intern/workspace.c b/source/blender/blenkernel/intern/workspace.c
index 8554cf0fb28..9251c6630a5 100644
--- a/source/blender/blenkernel/intern/workspace.c
+++ b/source/blender/blenkernel/intern/workspace.c
@@ -38,6 +38,7 @@
#include "BKE_main.h"
#include "BKE_scene.h"
#include "BKE_screen.h"
+#include "BKE_object.h"
#include "BKE_workspace.h"
#include "DNA_object_types.h"
@@ -45,6 +46,8 @@
#include "DNA_screen_types.h"
#include "DNA_workspace_types.h"
+#include "DEG_depsgraph.h"
+
#include "MEM_guardedalloc.h"
@@ -353,22 +356,22 @@ WorkSpaceLayout *BKE_workspace_layout_iter_circular(
WorkSpaceLayout *iter_layout;
if (iter_backward) {
- BLI_LISTBASE_CIRCULAR_BACKWARD_BEGIN(&workspace->layouts, iter_layout, start)
+ LISTBASE_CIRCULAR_BACKWARD_BEGIN(&workspace->layouts, iter_layout, start)
{
if (!callback(iter_layout, arg)) {
return iter_layout;
}
}
- BLI_LISTBASE_CIRCULAR_BACKWARD_END(&workspace->layouts, iter_layout, start);
+ LISTBASE_CIRCULAR_BACKWARD_END(&workspace->layouts, iter_layout, start);
}
else {
- BLI_LISTBASE_CIRCULAR_FORWARD_BEGIN(&workspace->layouts, iter_layout, start)
+ LISTBASE_CIRCULAR_FORWARD_BEGIN(&workspace->layouts, iter_layout, start)
{
if (!callback(iter_layout, arg)) {
return iter_layout;
}
}
- BLI_LISTBASE_CIRCULAR_FORWARD_END(&workspace->layouts, iter_layout, start)
+ LISTBASE_CIRCULAR_FORWARD_END(&workspace->layouts, iter_layout, start)
}
return NULL;
@@ -413,21 +416,6 @@ void BKE_workspace_active_screen_set(WorkSpaceInstanceHook *hook, WorkSpace *wor
BKE_workspace_hook_layout_for_workspace_set(hook, workspace, layout);
}
-#ifdef USE_WORKSPACE_MODE
-eObjectMode BKE_workspace_object_mode_get(const WorkSpace *workspace, const Scene *scene)
-{
- Base *active_base = BKE_workspace_active_base_get(workspace, scene);
- return active_base ? active_base->object->mode : OB_MODE_OBJECT;
-}
-void BKE_workspace_object_mode_set(WorkSpace *workspace, Scene *scene, const eObjectMode mode)
-{
- Base *active_base = BKE_workspace_active_base_get(workspace, scene);
- if (active_base) {
- active_base->object->mode = mode;
- }
-}
-#endif
-
Base *BKE_workspace_active_base_get(const WorkSpace *workspace, const Scene *scene)
{
ViewLayer *view_layer = BKE_workspace_view_layer_get(workspace, scene);
@@ -521,3 +509,29 @@ void BKE_workspace_update_tagged(struct EvaluationContext *eval_ctx,
true);
BKE_scene_graph_update_tagged(eval_ctx, depsgraph, bmain, scene, view_layer);
}
+
+void BKE_workspace_update_object_mode(
+ struct EvaluationContext *eval_ctx,
+ WorkSpace *workspace)
+{
+ /* TODO(campbell): Investigate how this should work exactly,
+ * for now without this 'bmain->eval_ctx' is never set. */
+
+ eval_ctx->object_mode = workspace->object_mode;
+}
+
+Object *BKE_workspace_edit_object(WorkSpace *workspace, Scene *scene)
+{
+ if (workspace->object_mode & OB_MODE_EDIT) {
+ ViewLayer *view_layer = BKE_workspace_view_layer_get(workspace, scene);
+ if (view_layer) {
+ Object *obedit = OBACT(view_layer);
+ if (obedit) {
+ BLI_assert(BKE_object_is_in_editmode(obedit));
+ return obedit;
+ }
+ }
+ }
+ return NULL;
+}
+
diff --git a/source/blender/blenkernel/particle_private.h b/source/blender/blenkernel/particle_private.h
new file mode 100644
index 00000000000..2189527118b
--- /dev/null
+++ b/source/blender/blenkernel/particle_private.h
@@ -0,0 +1,54 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2018 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenkernel/particle_private.h
+ * \ingroup bke
+ */
+
+#ifndef __PARTICLE_PRIVATE_H__
+#define __PARTICLE_PRIVATE_H__
+
+typedef struct ParticleChildModifierContext {
+ ParticleThreadContext *thread_ctx;
+ ParticleSimulationData *sim;
+ ParticleTexture *ptex;
+ ChildParticle *cpa;
+ const float *par_co; /* float3 */
+ const float *par_vel; /* float3 */
+ const float *par_rot; /* float4 */
+ const float *par_orco; /* float3 */
+ const float *orco; /* float3 */
+ ParticleCacheKey *parent_keys;
+} ParticleChildModifierContext;
+
+void do_kink(ParticleKey *state, const float par_co[3], const float par_vel[3], const float par_rot[4], float time, float freq, float shape, float amplitude, float flat,
+ short type, short axis, float obmat[4][4], int smooth_start);
+float do_clump(ParticleKey *state, const float par_co[3], float time, const float orco_offset[3], float clumpfac, float clumppow, float pa_clump,
+ bool use_clump_noise, float clump_noise_size, CurveMapping *clumpcurve);
+void do_child_modifiers(const ParticleChildModifierContext *modifier_ctx,
+ float mat[4][4], ParticleKey *state, float t);
+
+#endif /* __PARTICLE_PRIVATE_H__ */
diff --git a/source/blender/blenlib/BLI_array.h b/source/blender/blenlib/BLI_array.h
index 3ffca818c0d..825acb18e91 100644
--- a/source/blender/blenlib/BLI_array.h
+++ b/source/blender/blenlib/BLI_array.h
@@ -151,7 +151,7 @@ void _bli_array_grow_func(void **arr_p, const void *arr_static,
/**
* resets the logical size of an array to zero, but doesn't
* free the memory. */
-#define BLI_array_empty(arr) \
+#define BLI_array_clear(arr) \
{ _##arr##_count = 0; } (void)0
/**
diff --git a/source/blender/blenlib/BLI_boxpack2d.h b/source/blender/blenlib/BLI_boxpack_2d.h
index b02e3423f88..80e89bdb04f 100644
--- a/source/blender/blenlib/BLI_boxpack2d.h
+++ b/source/blender/blenlib/BLI_boxpack_2d.h
@@ -25,10 +25,10 @@
* ***** END GPL LICENSE BLOCK *****
*/
-#ifndef __BLI_BOXPACK2D_H__
-#define __BLI_BOXPACK2D_H__
+#ifndef __BLI_BOXPACK_2D_H__
+#define __BLI_BOXPACK_2D_H__
-/** \file BLI_boxpack2d.h
+/** \file BLI_boxpack_2d.h
* \ingroup bli
*/
@@ -39,7 +39,7 @@ typedef struct BoxPack {
float y;
float w;
float h;
-
+
/* Verts this box uses
* (BL,TR,TL,BR) / 0,1,2,3 */
struct BoxVert *v[4];
@@ -49,5 +49,5 @@ typedef struct BoxPack {
void BLI_box_pack_2d(BoxPack *boxarray, const unsigned int len, float *tot_width, float *tot_height);
-#endif
+#endif /* __BLI_BOXPACK_2D_H__ */
diff --git a/source/blender/blenlib/BLI_buffer.h b/source/blender/blenlib/BLI_buffer.h
index 0c0845daf19..0d2ef0dc9b3 100644
--- a/source/blender/blenlib/BLI_buffer.h
+++ b/source/blender/blenlib/BLI_buffer.h
@@ -77,7 +77,7 @@ enum {
(BLI_buffer_at(buffer_, type_, (buffer_)->count - 1) = val_) \
)
-#define BLI_buffer_empty(buffer_) { \
+#define BLI_buffer_clear(buffer_) { \
(buffer_)->count = 0; \
} (void)0
diff --git a/source/blender/blenlib/BLI_convexhull2d.h b/source/blender/blenlib/BLI_convexhull_2d.h
index 4b82071ede8..000d28acdde 100644
--- a/source/blender/blenlib/BLI_convexhull2d.h
+++ b/source/blender/blenlib/BLI_convexhull_2d.h
@@ -18,10 +18,10 @@
* ***** END GPL LICENSE BLOCK *****
*/
-#ifndef __BLI_CONVEXHULL2D_H__
-#define __BLI_CONVEXHULL2D_H__
+#ifndef __BLI_CONVEXHULL_2D_H__
+#define __BLI_CONVEXHULL_2D_H__
-/** \file BLI_convexhull2d.h
+/** \file BLI_convexhull_2d.h
* \ingroup bli
*/
@@ -31,4 +31,4 @@ int BLI_convexhull_2d(const float (*points)[2], const int n, int r_points[]);
float BLI_convexhull_aabb_fit_hull_2d(const float (*points_hull)[2], unsigned int n);
float BLI_convexhull_aabb_fit_points_2d(const float (*points)[2], unsigned int n);
-#endif /* __BLI_CONVEXHULL2D_H__ */
+#endif /* __BLI_CONVEXHULL_2D_H__ */
diff --git a/source/blender/blenlib/BLI_dial.h b/source/blender/blenlib/BLI_dial_2d.h
index 71ab57bb61a..dbd71a8ad3f 100644
--- a/source/blender/blenlib/BLI_dial.h
+++ b/source/blender/blenlib/BLI_dial_2d.h
@@ -18,10 +18,10 @@
* ***** END GPL LICENSE BLOCK *****
*/
-#ifndef __BLI_DIAL_H__
-#define __BLI_DIAL_H__
+#ifndef __BLI_DIAL_2D_H__
+#define __BLI_DIAL_2D_H__
-/** \file BLI_dial.h
+/** \file BLI_dial_2d.h
* \ingroup bli
*
* \note dials act similar to old rotation based phones and output an angle.
@@ -56,4 +56,4 @@ Dial *BLI_dial_initialize(const float start_position[2], float threshold);
float BLI_dial_angle(Dial *dial, const float current_position[2]);
-#endif /* __BLI_DIAL_H__ */
+#endif /* __BLI_DIAL_2D_H__ */
diff --git a/source/blender/blenlib/BLI_edgehash.h b/source/blender/blenlib/BLI_edgehash.h
index 20272dd97cd..41789201265 100644
--- a/source/blender/blenlib/BLI_edgehash.h
+++ b/source/blender/blenlib/BLI_edgehash.h
@@ -59,7 +59,7 @@ bool BLI_edgehash_remove(EdgeHash *eh, unsigned int v0, unsigned int
void *BLI_edgehash_popkey(EdgeHash *eh, unsigned int v0, unsigned int v1) ATTR_WARN_UNUSED_RESULT;
bool BLI_edgehash_haskey(EdgeHash *eh, unsigned int v0, unsigned int v1) ATTR_WARN_UNUSED_RESULT;
-int BLI_edgehash_size(EdgeHash *eh) ATTR_WARN_UNUSED_RESULT;
+int BLI_edgehash_len(EdgeHash *eh) ATTR_WARN_UNUSED_RESULT;
void BLI_edgehash_clear_ex(EdgeHash *eh, EdgeHashFreeFP valfreefp,
const unsigned int nentries_reserve);
void BLI_edgehash_clear(EdgeHash *eh, EdgeHashFreeFP valfreefp);
@@ -104,7 +104,7 @@ typedef struct EdgeSetIterator EdgeSetIterator;
EdgeSet *BLI_edgeset_new_ex(const char *info,
const unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
EdgeSet *BLI_edgeset_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
-int BLI_edgeset_size(EdgeSet *es) ATTR_WARN_UNUSED_RESULT;
+int BLI_edgeset_len(EdgeSet *es) ATTR_WARN_UNUSED_RESULT;
bool BLI_edgeset_add(EdgeSet *es, unsigned int v0, unsigned int v1);
void BLI_edgeset_insert(EdgeSet *es, unsigned int v0, unsigned int v1);
bool BLI_edgeset_haskey(EdgeSet *eh, unsigned int v0, unsigned int v1) ATTR_WARN_UNUSED_RESULT;
diff --git a/source/blender/blenlib/BLI_fileops.h b/source/blender/blenlib/BLI_fileops.h
index 5c1fa57886a..bb23c63bdb3 100644
--- a/source/blender/blenlib/BLI_fileops.h
+++ b/source/blender/blenlib/BLI_fileops.h
@@ -35,6 +35,7 @@
#include <stdio.h>
#include <sys/stat.h>
+#include <stdint.h>
#ifdef __cplusplus
extern "C" {
diff --git a/source/blender/blenlib/BLI_ghash.h b/source/blender/blenlib/BLI_ghash.h
index b4819ff4e55..ec591c6bb48 100644
--- a/source/blender/blenlib/BLI_ghash.h
+++ b/source/blender/blenlib/BLI_ghash.h
@@ -81,7 +81,10 @@ enum {
#endif
};
-/* *** */
+/** \name GHash API
+ *
+ * Defined in ``BLI_ghash.c``
+ * \{ */
GHash *BLI_ghash_new_ex(
GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info,
@@ -110,11 +113,14 @@ void BLI_ghash_clear_ex(
void *BLI_ghash_popkey(GHash *gh, const void *key, GHashKeyFreeFP keyfreefp) ATTR_WARN_UNUSED_RESULT;
bool BLI_ghash_haskey(GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT;
bool BLI_ghash_pop(GHash *gh, GHashIterState *state, void **r_key, void **r_val) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-unsigned int BLI_ghash_size(GHash *gh) ATTR_WARN_UNUSED_RESULT;
+unsigned int BLI_ghash_len(GHash *gh) ATTR_WARN_UNUSED_RESULT;
void BLI_ghash_flag_set(GHash *gh, unsigned int flag);
void BLI_ghash_flag_clear(GHash *gh, unsigned int flag);
-/* *** */
+/** \} */
+
+/** \name GHash Iterator
+ * \{ */
GHashIterator *BLI_ghashIterator_new(GHash *gh) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
@@ -149,94 +155,15 @@ BLI_INLINE bool BLI_ghashIterator_done(GHashIterator *ghi) { return !ghi
BLI_ghashIterator_done(&gh_iter_) == false; \
BLI_ghashIterator_step(&gh_iter_), i_++)
-/** \name Callbacks for GHash
- *
- * \note '_p' suffix denotes void pointer arg,
- * so we can have functions that take correctly typed args too.
- * \{ */
-
-unsigned int BLI_ghashutil_ptrhash(const void *key);
-bool BLI_ghashutil_ptrcmp(const void *a, const void *b);
-
-unsigned int BLI_ghashutil_strhash_n(const char *key, size_t n);
-#define BLI_ghashutil_strhash(key) ( \
- CHECK_TYPE_ANY(key, char *, const char *, const char * const), \
- BLI_ghashutil_strhash_p(key))
-unsigned int BLI_ghashutil_strhash_p(const void *key);
-unsigned int BLI_ghashutil_strhash_p_murmur(const void *key);
-bool BLI_ghashutil_strcmp(const void *a, const void *b);
-
-#define BLI_ghashutil_inthash(key) ( \
- CHECK_TYPE_ANY(&(key), int *, const int *), \
- BLI_ghashutil_uinthash((unsigned int)key))
-unsigned int BLI_ghashutil_uinthash(unsigned int key);
-unsigned int BLI_ghashutil_inthash_p(const void *ptr);
-unsigned int BLI_ghashutil_inthash_p_murmur(const void *ptr);
-unsigned int BLI_ghashutil_inthash_p_simple(const void *ptr);
-bool BLI_ghashutil_intcmp(const void *a, const void *b);
-
-size_t BLI_ghashutil_combine_hash(size_t hash_a, size_t hash_b);
-
-
-unsigned int BLI_ghashutil_uinthash_v4(const unsigned int key[4]);
-#define BLI_ghashutil_inthash_v4(key) ( \
- CHECK_TYPE_ANY(key, int *, const int *), \
- BLI_ghashutil_uinthash_v4((const unsigned int *)key))
-#define BLI_ghashutil_inthash_v4_p \
- ((GSetHashFP)BLI_ghashutil_uinthash_v4)
-#define BLI_ghashutil_uinthash_v4_p \
- ((GSetHashFP)BLI_ghashutil_uinthash_v4)
-unsigned int BLI_ghashutil_uinthash_v4_murmur(const unsigned int key[4]);
-#define BLI_ghashutil_inthash_v4_murmur(key) ( \
- CHECK_TYPE_ANY(key, int *, const int *), \
- BLI_ghashutil_uinthash_v4_murmur((const unsigned int *)key))
-#define BLI_ghashutil_inthash_v4_p_murmur \
- ((GSetHashFP)BLI_ghashutil_uinthash_v4_murmur)
-#define BLI_ghashutil_uinthash_v4_p_murmur \
- ((GSetHashFP)BLI_ghashutil_uinthash_v4_murmur)
-bool BLI_ghashutil_uinthash_v4_cmp(const void *a, const void *b);
-#define BLI_ghashutil_inthash_v4_cmp \
- BLI_ghashutil_uinthash_v4_cmp
-
/** \} */
-GHash *BLI_ghash_ptr_new_ex(
- const char *info,
- const unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
-GHash *BLI_ghash_ptr_new(
- const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
-GHash *BLI_ghash_str_new_ex(
- const char *info,
- const unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
-GHash *BLI_ghash_str_new(
- const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
-GHash *BLI_ghash_int_new_ex(
- const char *info,
- const unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
-GHash *BLI_ghash_int_new(
- const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
-GHash *BLI_ghash_pair_new_ex(
- const char *info,
- const unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
-GHash *BLI_ghash_pair_new(
- const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
-
-typedef struct GHashPair {
- const void *first;
- const void *second;
-} GHashPair;
-
-GHashPair *BLI_ghashutil_pairalloc(const void *first, const void *second);
-unsigned int BLI_ghashutil_pairhash(const void *ptr);
-bool BLI_ghashutil_paircmp(const void *a, const void *b);
-void BLI_ghashutil_pairfree(void *ptr);
-
-/**
- * GSet is a 'set' implementation (unordered collection of unique elements).
+/** \name GSet API
+ * A 'set' implementation (unordered collection of unique elements).
*
* Internally this is a 'GHash' without any keys,
* which is why this API's are in the same header & source file.
- */
+ *
+ * \{ */
typedef struct GSet GSet;
@@ -247,21 +174,12 @@ typedef GHashKeyCopyFP GSetKeyCopyFP;
typedef GHashIterState GSetIterState;
-/* so we can cast but compiler sees as different */
-typedef struct GSetIterator {
- GHashIterator _ghi
-#ifdef __GNUC__
- __attribute__ ((deprecated))
-#endif
- ;
-} GSetIterator;
-
GSet *BLI_gset_new_ex(
GSetHashFP hashfp, GSetCmpFP cmpfp, const char *info,
const unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
GSet *BLI_gset_new(GSetHashFP hashfp, GSetCmpFP cmpfp, const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
GSet *BLI_gset_copy(GSet *gs, GSetKeyCopyFP keycopyfp) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
-unsigned int BLI_gset_size(GSet *gs) ATTR_WARN_UNUSED_RESULT;
+unsigned int BLI_gset_len(GSet *gs) ATTR_WARN_UNUSED_RESULT;
void BLI_gset_flag_set(GSet *gs, unsigned int flag);
void BLI_gset_flag_clear(GSet *gs, unsigned int flag);
void BLI_gset_free(GSet *gs, GSetKeyFreeFP keyfreefp);
@@ -281,14 +199,20 @@ void BLI_gset_clear(GSet *gs, GSetKeyFreeFP keyfreefp);
void *BLI_gset_lookup(GSet *gh, const void *key) ATTR_WARN_UNUSED_RESULT;
void *BLI_gset_pop_key(GSet *gs, const void *key) ATTR_WARN_UNUSED_RESULT;
-GSet *BLI_gset_ptr_new_ex(const char *info, const unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
-GSet *BLI_gset_ptr_new(const char *info);
-GSet *BLI_gset_str_new_ex(const char *info, const unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
-GSet *BLI_gset_str_new(const char *info);
-GSet *BLI_gset_pair_new_ex(const char *info, const unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
-GSet *BLI_gset_pair_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
+/** \name GSet Iterator
+ * \{ */
/* rely on inline api for now */
+
+/* so we can cast but compiler sees as different */
+typedef struct GSetIterator {
+ GHashIterator _ghi
+#ifdef __GNUC__
+ __attribute__ ((deprecated))
+#endif
+ ;
+} GSetIterator;
+
BLI_INLINE GSetIterator *BLI_gsetIterator_new(GSet *gs) { return (GSetIterator *)BLI_ghashIterator_new((GHash *)gs); }
BLI_INLINE void BLI_gsetIterator_init(GSetIterator *gsi, GSet *gs) { BLI_ghashIterator_init((GHashIterator *)gsi, (GHash *)gs); }
BLI_INLINE void BLI_gsetIterator_free(GSetIterator *gsi) { BLI_ghashIterator_free((GHashIterator *)gsi); }
@@ -306,11 +230,15 @@ BLI_INLINE bool BLI_gsetIterator_done(GSetIterator *gsi) { return BLI_ghashItera
BLI_gsetIterator_done(&gs_iter_) == false; \
BLI_gsetIterator_step(&gs_iter_), i_++)
+/** \} */
+
+/** \name GHash/GSet Debugging API's
+ * \{ */
/* For testing, debugging only */
#ifdef GHASH_INTERNAL_API
-int BLI_ghash_buckets_size(GHash *gh);
-int BLI_gset_buckets_size(GSet *gs);
+int BLI_ghash_buckets_len(GHash *gh);
+int BLI_gset_buckets_len(GSet *gs);
double BLI_ghash_calc_quality_ex(
GHash *gh, double *r_load, double *r_variance,
@@ -321,6 +249,10 @@ double BLI_gset_calc_quality_ex(
double BLI_ghash_calc_quality(GHash *gh);
double BLI_gset_calc_quality(GSet *gs);
#endif /* GHASH_INTERNAL_API */
+/** \} */
+
+/** \name GHash/GSet Macros
+ * \{ */
#define GHASH_FOREACH_BEGIN(type, var, what) \
do { \
@@ -342,6 +274,113 @@ double BLI_gset_calc_quality(GSet *gs);
} \
} while(0)
+/** \} */
+
+/** \name GHash/GSet Utils
+ *
+ * Defined in ``BLI_ghash_utils.c``
+ * \{ */
+
+/**
+ * Callbacks for GHash (``BLI_ghashutil_``)
+ *
+ * \note '_p' suffix denotes void pointer arg,
+ * so we can have functions that take correctly typed args too.
+ * \{ */
+
+unsigned int BLI_ghashutil_ptrhash(const void *key);
+bool BLI_ghashutil_ptrcmp(const void *a, const void *b);
+
+unsigned int BLI_ghashutil_strhash_n(const char *key, size_t n);
+#define BLI_ghashutil_strhash(key) ( \
+ CHECK_TYPE_ANY(key, char *, const char *, const char * const), \
+ BLI_ghashutil_strhash_p(key))
+unsigned int BLI_ghashutil_strhash_p(const void *key);
+unsigned int BLI_ghashutil_strhash_p_murmur(const void *key);
+bool BLI_ghashutil_strcmp(const void *a, const void *b);
+
+#define BLI_ghashutil_inthash(key) ( \
+ CHECK_TYPE_ANY(&(key), int *, const int *), \
+ BLI_ghashutil_uinthash((unsigned int)key))
+unsigned int BLI_ghashutil_uinthash(unsigned int key);
+unsigned int BLI_ghashutil_inthash_p(const void *ptr);
+unsigned int BLI_ghashutil_inthash_p_murmur(const void *ptr);
+unsigned int BLI_ghashutil_inthash_p_simple(const void *ptr);
+bool BLI_ghashutil_intcmp(const void *a, const void *b);
+
+size_t BLI_ghashutil_combine_hash(size_t hash_a, size_t hash_b);
+
+
+unsigned int BLI_ghashutil_uinthash_v4(const unsigned int key[4]);
+#define BLI_ghashutil_inthash_v4(key) ( \
+ CHECK_TYPE_ANY(key, int *, const int *), \
+ BLI_ghashutil_uinthash_v4((const unsigned int *)key))
+#define BLI_ghashutil_inthash_v4_p \
+ ((GSetHashFP)BLI_ghashutil_uinthash_v4)
+#define BLI_ghashutil_uinthash_v4_p \
+ ((GSetHashFP)BLI_ghashutil_uinthash_v4)
+unsigned int BLI_ghashutil_uinthash_v4_murmur(const unsigned int key[4]);
+#define BLI_ghashutil_inthash_v4_murmur(key) ( \
+ CHECK_TYPE_ANY(key, int *, const int *), \
+ BLI_ghashutil_uinthash_v4_murmur((const unsigned int *)key))
+#define BLI_ghashutil_inthash_v4_p_murmur \
+ ((GSetHashFP)BLI_ghashutil_uinthash_v4_murmur)
+#define BLI_ghashutil_uinthash_v4_p_murmur \
+ ((GSetHashFP)BLI_ghashutil_uinthash_v4_murmur)
+bool BLI_ghashutil_uinthash_v4_cmp(const void *a, const void *b);
+#define BLI_ghashutil_inthash_v4_cmp \
+ BLI_ghashutil_uinthash_v4_cmp
+
+typedef struct GHashPair {
+ const void *first;
+ const void *second;
+} GHashPair;
+
+GHashPair *BLI_ghashutil_pairalloc(const void *first, const void *second);
+unsigned int BLI_ghashutil_pairhash(const void *ptr);
+bool BLI_ghashutil_paircmp(const void *a, const void *b);
+void BLI_ghashutil_pairfree(void *ptr);
+
+/**
+ * Wrapper GHash Creation Functions
+ */
+
+GHash *BLI_ghash_ptr_new_ex(
+ const char *info,
+ const unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
+GHash *BLI_ghash_ptr_new(
+ const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
+GHash *BLI_ghash_str_new_ex(
+ const char *info,
+ const unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
+GHash *BLI_ghash_str_new(
+ const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
+GHash *BLI_ghash_int_new_ex(
+ const char *info,
+ const unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
+GHash *BLI_ghash_int_new(
+ const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
+GHash *BLI_ghash_pair_new_ex(
+ const char *info,
+ const unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
+GHash *BLI_ghash_pair_new(
+ const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
+
+GSet *BLI_gset_ptr_new_ex(
+ const char *info, const unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
+GSet *BLI_gset_ptr_new(
+ const char *info);
+GSet *BLI_gset_str_new_ex(
+ const char *info, const unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
+GSet *BLI_gset_str_new(
+ const char *info);
+GSet *BLI_gset_pair_new_ex(
+ const char *info, const unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
+GSet *BLI_gset_pair_new(
+ const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
+
+/** \} */
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenlib/BLI_gsqueue.h b/source/blender/blenlib/BLI_gsqueue.h
index 4600d6f6325..ef0e0f3ab31 100644
--- a/source/blender/blenlib/BLI_gsqueue.h
+++ b/source/blender/blenlib/BLI_gsqueue.h
@@ -36,11 +36,11 @@ typedef struct _GSQueue GSQueue;
GSQueue *BLI_gsqueue_new(size_t elem_size);
bool BLI_gsqueue_is_empty(GSQueue *gq);
-int BLI_gsqueue_size(GSQueue *gq);
+int BLI_gsqueue_len(GSQueue *gq);
void BLI_gsqueue_peek(GSQueue *gq, void *r_item);
void BLI_gsqueue_pop(GSQueue *gq, void *r_item);
void BLI_gsqueue_push(GSQueue *gq, const void *item);
-void BLI_gsqueue_pushback(GSQueue *gq, const void *item);
+void BLI_gsqueue_push_back(GSQueue *gq, const void *item);
void BLI_gsqueue_free(GSQueue *gq);
#endif /* __BLI_GSQUEUE_H__ */
diff --git a/source/blender/blenlib/BLI_hash.h b/source/blender/blenlib/BLI_hash.h
index e849e5f8f61..fa79481e25c 100644
--- a/source/blender/blenlib/BLI_hash.h
+++ b/source/blender/blenlib/BLI_hash.h
@@ -63,4 +63,9 @@ BLI_INLINE unsigned int BLI_hash_int(unsigned int k)
return BLI_hash_int_2d(k, 0);
}
+BLI_INLINE float BLI_hash_int_01(unsigned int k)
+{
+ return (float)BLI_hash_int(k) * (1.0f / (float)0xFFFFFFFF);
+}
+
#endif // __BLI_HASH_H__
diff --git a/source/blender/blenlib/BLI_heap.h b/source/blender/blenlib/BLI_heap.h
index d3f6d44e164..19e162d777f 100644
--- a/source/blender/blenlib/BLI_heap.h
+++ b/source/blender/blenlib/BLI_heap.h
@@ -41,9 +41,9 @@ HeapNode *BLI_heap_insert(Heap *heap, float value, void *ptr) ATTR_NONNULL
void BLI_heap_insert_or_update(Heap *heap, HeapNode **node_p, float value, void *ptr) ATTR_NONNULL(1, 2);
void BLI_heap_remove(Heap *heap, HeapNode *node) ATTR_NONNULL(1, 2);
bool BLI_heap_is_empty(const Heap *heap) ATTR_NONNULL(1);
-unsigned int BLI_heap_size(const Heap *heap) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1);
+unsigned int BLI_heap_len(const Heap *heap) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1);
HeapNode *BLI_heap_top(const Heap *heap) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1);
-void *BLI_heap_popmin(Heap *heap) ATTR_NONNULL(1);
+void *BLI_heap_pop_min(Heap *heap) ATTR_NONNULL(1);
void BLI_heap_node_value_update(Heap *heap, HeapNode *node, float value) ATTR_NONNULL(1, 2);
void BLI_heap_node_value_update_ptr(Heap *heap, HeapNode *node, float value, void *ptr) ATTR_NONNULL(1, 2);
diff --git a/source/blender/blenlib/BLI_jitter.h b/source/blender/blenlib/BLI_jitter_2d.h
index 769fb445678..e2b1f21800c 100644
--- a/source/blender/blenlib/BLI_jitter.h
+++ b/source/blender/blenlib/BLI_jitter_2d.h
@@ -25,10 +25,10 @@
* ***** END GPL LICENSE BLOCK *****
*/
-#ifndef __BLI_JITTER_H__
-#define __BLI_JITTER_H__
+#ifndef __BLI_JITTER_2D_H__
+#define __BLI_JITTER_2D_H__
-/** \file BLI_jitter.h
+/** \file BLI_jitter_2d.h
* \ingroup bli
*/
@@ -36,5 +36,5 @@ void BLI_jitter_init(float (*jitarr)[2], int num);
void BLI_jitterate1(float (*jit1)[2], float (*jit2)[2], int num, float radius1);
void BLI_jitterate2(float (*jit1)[2], float (*jit2)[2], int num, float radius2);
-#endif
+#endif /* __BLI_JITTER_2D_H__ */
diff --git a/source/blender/blenlib/BLI_kdopbvh.h b/source/blender/blenlib/BLI_kdopbvh.h
index 564659ad21e..db53035dc7b 100644
--- a/source/blender/blenlib/BLI_kdopbvh.h
+++ b/source/blender/blenlib/BLI_kdopbvh.h
@@ -129,7 +129,7 @@ BVHTreeOverlap *BLI_bvhtree_overlap(
const BVHTree *tree1, const BVHTree *tree2, unsigned int *r_overlap_tot,
BVHTree_OverlapCallback callback, void *userdata);
-int BLI_bvhtree_get_size(const BVHTree *tree);
+int BLI_bvhtree_get_len(const BVHTree *tree);
float BLI_bvhtree_get_epsilon(const BVHTree *tree);
diff --git a/source/blender/blenlib/BLI_lasso.h b/source/blender/blenlib/BLI_lasso_2d.h
index 28f21e5bd85..3644224f1d7 100644
--- a/source/blender/blenlib/BLI_lasso.h
+++ b/source/blender/blenlib/BLI_lasso_2d.h
@@ -25,10 +25,10 @@
* ***** END GPL LICENSE BLOCK *****
*/
-#ifndef __BLI_LASSO_H__
-#define __BLI_LASSO_H__
+#ifndef __BLI_LASSO_2D_H__
+#define __BLI_LASSO_2D_H__
-/** \file BLI_lasso.h
+/** \file BLI_lasso_2d.h
* \ingroup bli
*/
@@ -38,4 +38,4 @@ void BLI_lasso_boundbox(struct rcti *rect, const int mcords[][2], const unsigned
bool BLI_lasso_is_point_inside(const int mcords[][2], const unsigned int moves, const int sx, const int sy, const int error_value);
bool BLI_lasso_is_edge_inside(const int mcords[][2], const unsigned int moves, int x0, int y0, int x1, int y1, const int error_value);
-#endif
+#endif /* __BLI_LASSO_2D_H__ */
diff --git a/source/blender/blenlib/BLI_linklist_stack.h b/source/blender/blenlib/BLI_linklist_stack.h
index dd92dcec936..dd6d737f111 100644
--- a/source/blender/blenlib/BLI_linklist_stack.h
+++ b/source/blender/blenlib/BLI_linklist_stack.h
@@ -60,7 +60,7 @@
} (void)0
#define BLI_LINKSTACK_SIZE(var) \
- BLI_mempool_count(var##_pool_)
+ BLI_mempool_len(var##_pool_)
/* check for typeof() */
#ifdef __GNUC__
diff --git a/source/blender/blenlib/BLI_listbase.h b/source/blender/blenlib/BLI_listbase.h
index 2a0f4e6f814..6be9408ac1e 100644
--- a/source/blender/blenlib/BLI_listbase.h
+++ b/source/blender/blenlib/BLI_listbase.h
@@ -103,32 +103,33 @@ struct LinkData *BLI_genericNodeN(void *data);
*
* \code{.c}
*
- * BLI_LISTBASE_CIRCULAR_FORWARD_BEGIN (listbase, item, item_init) {
+ * LISTBASE_CIRCULAR_FORWARD_BEGIN(listbase, item, item_init)
+ * {
* ...operate on marker...
* }
- * BLI_LISTBASE_CIRCULAR_FORWARD_END (listbase, item, item_init);
+ * LISTBASE_CIRCULAR_FORWARD_END (listbase, item, item_init);
*
* \endcode
*/
-#define BLI_LISTBASE_CIRCULAR_FORWARD_BEGIN(lb, lb_iter, lb_init) \
+#define LISTBASE_CIRCULAR_FORWARD_BEGIN(lb, lb_iter, lb_init) \
if ((lb)->first && (lb_init || (lb_init = (lb)->first))) { \
lb_iter = lb_init; \
do {
-#define BLI_LISTBASE_CIRCULAR_FORWARD_END(lb, lb_iter, lb_init) \
+#define LISTBASE_CIRCULAR_FORWARD_END(lb, lb_iter, lb_init) \
} while ((lb_iter = (lb_iter)->next ? (lb_iter)->next : (lb)->first), \
(lb_iter != lb_init)); \
}
-#define BLI_LISTBASE_CIRCULAR_BACKWARD_BEGIN(lb, lb_iter, lb_init) \
+#define LISTBASE_CIRCULAR_BACKWARD_BEGIN(lb, lb_iter, lb_init) \
if ((lb)->last && (lb_init || (lb_init = (lb)->last))) { \
lb_iter = lb_init; \
do {
-#define BLI_LISTBASE_CIRCULAR_BACKWARD_END(lb, lb_iter, lb_init) \
+#define LISTBASE_CIRCULAR_BACKWARD_END(lb, lb_iter, lb_init) \
} while ((lb_iter = (lb_iter)->prev ? (lb_iter)->prev : (lb)->last), \
(lb_iter != lb_init)); \
}
-#define BLI_LISTBASE_FOREACH(type, var, list) \
+#define LISTBASE_FOREACH(type, var, list) \
for (type var = (type)((list)->first); \
var != NULL; \
var = (type)(((Link*)(var))->next))
diff --git a/source/blender/blenlib/BLI_math_base.h b/source/blender/blenlib/BLI_math_base.h
index 377b9325717..3b24cae018d 100644
--- a/source/blender/blenlib/BLI_math_base.h
+++ b/source/blender/blenlib/BLI_math_base.h
@@ -132,6 +132,10 @@ MINLINE int max_iiii(int a, int b, int c, int d);
MINLINE size_t min_zz(size_t a, size_t b);
MINLINE size_t max_zz(size_t a, size_t b);
+MINLINE int clamp_i(int value, int min, int max);
+MINLINE float clamp_f(float value, float min, float max);
+MINLINE size_t clamp_z(size_t value, size_t min, size_t max);
+
MINLINE int compare_ff(float a, float b, const float max_diff);
MINLINE int compare_ff_relative(float a, float b, const float max_diff, const int max_ulps);
diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h
index 933e31ba84b..ffe0ce11cef 100644
--- a/source/blender/blenlib/BLI_math_geom.h
+++ b/source/blender/blenlib/BLI_math_geom.h
@@ -85,6 +85,7 @@ bool is_quad_convex_v3(const float v1[3], const float v2[3], const float v3[3],
bool is_quad_convex_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2]);
bool is_poly_convex_v2(const float verts[][2], unsigned int nr);
int is_quad_flip_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3]);
+bool is_quad_flip_v3_first_third_fast(const float v0[3], const float v1[3], const float v2[3], const float v3[3]);
/********************************* Distance **********************************/
diff --git a/source/blender/blenlib/BLI_mempool.h b/source/blender/blenlib/BLI_mempool.h
index b68ca6b1f2b..45efb8d7ef1 100644
--- a/source/blender/blenlib/BLI_mempool.h
+++ b/source/blender/blenlib/BLI_mempool.h
@@ -53,7 +53,7 @@ void BLI_mempool_clear_ex(BLI_mempool *pool,
const int totelem_reserve) ATTR_NONNULL(1);
void BLI_mempool_clear(BLI_mempool *pool) ATTR_NONNULL(1);
void BLI_mempool_destroy(BLI_mempool *pool) ATTR_NONNULL(1);
-int BLI_mempool_count(BLI_mempool *pool) ATTR_NONNULL(1);
+int BLI_mempool_len(BLI_mempool *pool) ATTR_NONNULL(1);
void *BLI_mempool_findelem(BLI_mempool *pool, unsigned int index) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1);
void BLI_mempool_as_table(BLI_mempool *pool, void **data) ATTR_NONNULL(1, 2);
diff --git a/source/blender/blenlib/BLI_polyfill2d.h b/source/blender/blenlib/BLI_polyfill_2d.h
index 798055f9240..099f08d4663 100644
--- a/source/blender/blenlib/BLI_polyfill2d.h
+++ b/source/blender/blenlib/BLI_polyfill_2d.h
@@ -18,8 +18,8 @@
* ***** END GPL LICENSE BLOCK *****
*/
-#ifndef __BLI_POLYFILL2D_H__
-#define __BLI_POLYFILL2D_H__
+#ifndef __BLI_POLYFILL_2D_H__
+#define __BLI_POLYFILL_2D_H__
struct MemArena;
@@ -40,4 +40,4 @@ void BLI_polyfill_calc(
/* default size of polyfill arena */
#define BLI_POLYFILL_ARENA_SIZE MEM_SIZE_OPTIMAL(1 << 14)
-#endif /* __BLI_POLYFILL2D_H__ */
+#endif /* __BLI_POLYFILL_2D_H__ */
diff --git a/source/blender/blenlib/BLI_polyfill2d_beautify.h b/source/blender/blenlib/BLI_polyfill_2d_beautify.h
index 278771e9611..278771e9611 100644
--- a/source/blender/blenlib/BLI_polyfill2d_beautify.h
+++ b/source/blender/blenlib/BLI_polyfill_2d_beautify.h
diff --git a/source/blender/blenlib/BLI_smallhash.h b/source/blender/blenlib/BLI_smallhash.h
index e096354e5b1..495fc94a53c 100644
--- a/source/blender/blenlib/BLI_smallhash.h
+++ b/source/blender/blenlib/BLI_smallhash.h
@@ -66,7 +66,7 @@ bool BLI_smallhash_remove(SmallHash *sh, uintptr_t key) ATTR_NONNULL(1);
void *BLI_smallhash_lookup(const SmallHash *sh, uintptr_t key) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT;
void **BLI_smallhash_lookup_p(const SmallHash *sh, uintptr_t key) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT;
bool BLI_smallhash_haskey(const SmallHash *sh, uintptr_t key) ATTR_NONNULL(1);
-int BLI_smallhash_count(const SmallHash *sh) ATTR_NONNULL(1);
+int BLI_smallhash_len(const SmallHash *sh) ATTR_NONNULL(1);
void *BLI_smallhash_iternext(SmallHashIter *iter, uintptr_t *key) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT;
void **BLI_smallhash_iternext_p(SmallHashIter *iter, uintptr_t *key) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT;
void *BLI_smallhash_iternew(const SmallHash *sh, SmallHashIter *iter, uintptr_t *key) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT;
diff --git a/source/blender/blenlib/BLI_threads.h b/source/blender/blenlib/BLI_threads.h
index 60da6b39cbe..66eb5cfd22b 100644
--- a/source/blender/blenlib/BLI_threads.h
+++ b/source/blender/blenlib/BLI_threads.h
@@ -55,19 +55,19 @@ void BLI_threadapi_exit(void);
struct TaskScheduler *BLI_task_scheduler_get(void);
-void BLI_init_threads(struct ListBase *threadbase, void *(*do_thread)(void *), int tot);
+void BLI_threadpool_init(struct ListBase *threadbase, void *(*do_thread)(void *), int tot);
int BLI_available_threads(struct ListBase *threadbase);
-int BLI_available_thread_index(struct ListBase *threadbase);
-void BLI_insert_thread(struct ListBase *threadbase, void *callerdata);
-void BLI_remove_thread(struct ListBase *threadbase, void *callerdata);
-void BLI_remove_thread_index(struct ListBase *threadbase, int index);
-void BLI_remove_threads(struct ListBase *threadbase);
-void BLI_end_threads(struct ListBase *threadbase);
+int BLI_threadpool_available_thread_index(struct ListBase *threadbase);
+void BLI_threadpool_insert(struct ListBase *threadbase, void *callerdata);
+void BLI_threadpool_remove(struct ListBase *threadbase, void *callerdata);
+void BLI_threadpool_remove_index(struct ListBase *threadbase, int index);
+void BLI_threadpool_clear(struct ListBase *threadbase);
+void BLI_threadpool_end(struct ListBase *threadbase);
int BLI_thread_is_main(void);
-void BLI_begin_threaded_malloc(void);
-void BLI_end_threaded_malloc(void);
+void BLI_threaded_malloc_begin(void);
+void BLI_threaded_malloc_end(void);
/* System Information */
@@ -91,8 +91,8 @@ int BLI_system_num_threads_override_get(void);
#define LOCK_FFTW 9
#define LOCK_VIEW3D 10
-void BLI_lock_thread(int type);
-void BLI_unlock_thread(int type);
+void BLI_thread_lock(int type);
+void BLI_thread_unlock(int type);
/* Mutex Lock */
@@ -177,7 +177,7 @@ void BLI_thread_queue_free(ThreadQueue *queue);
void BLI_thread_queue_push(ThreadQueue *queue, void *work);
void *BLI_thread_queue_pop(ThreadQueue *queue);
void *BLI_thread_queue_pop_timeout(ThreadQueue *queue, int ms);
-int BLI_thread_queue_size(ThreadQueue *queue);
+int BLI_thread_queue_len(ThreadQueue *queue);
bool BLI_thread_queue_is_empty(ThreadQueue *queue);
void BLI_thread_queue_wait_finish(ThreadQueue *queue);
diff --git a/source/blender/blenlib/BLI_voronoi.h b/source/blender/blenlib/BLI_voronoi_2d.h
index 9d32061bf97..51d1d5aa88e 100644
--- a/source/blender/blenlib/BLI_voronoi.h
+++ b/source/blender/blenlib/BLI_voronoi_2d.h
@@ -28,7 +28,7 @@
struct ListBase;
-/** \file BLI_voronoi.h
+/** \file BLI_voronoi_2d.h
* \ingroup bli
*/
diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt
index 9e7b4ed8b6f..ef36b5ac6bd 100644
--- a/source/blender/blenlib/CMakeLists.txt
+++ b/source/blender/blenlib/CMakeLists.txt
@@ -41,10 +41,11 @@ set(INC_SYS
set(SRC
intern/BLI_args.c
intern/BLI_array.c
- intern/BLI_dial.c
+ intern/BLI_dial_2d.c
intern/BLI_dynstr.c
intern/BLI_filelist.c
intern/BLI_ghash.c
+ intern/BLI_ghash_utils.c
intern/BLI_heap.c
intern/BLI_kdopbvh.c
intern/BLI_kdtree.c
@@ -58,10 +59,10 @@ set(SRC
intern/array_utils.c
intern/astar.c
intern/bitmap_draw_2d.c
- intern/boxpack2d.c
+ intern/boxpack_2d.c
intern/buffer.c
intern/callbacks.c
- intern/convexhull2d.c
+ intern/convexhull_2d.c
intern/dynlib.c
intern/easing.c
intern/edgehash.c
@@ -73,8 +74,8 @@ set(SRC
intern/gsqueue.c
intern/hash_md5.c
intern/hash_mm2a.c
- intern/jitter.c
- intern/lasso.c
+ intern/jitter_2d.c
+ intern/lasso_2d.c
intern/list_sort_impl.h
intern/listbase.c
intern/math_base.c
@@ -95,8 +96,8 @@ set(SRC
intern/memory_utils.c
intern/noise.c
intern/path_util.c
- intern/polyfill2d.c
- intern/polyfill2d_beautify.c
+ intern/polyfill_2d.c
+ intern/polyfill_2d_beautify.c
intern/quadric.c
intern/rand.c
intern/rct.c
@@ -117,7 +118,7 @@ set(SRC
intern/time.c
intern/timecode.c
intern/uvproject.c
- intern/voronoi.c
+ intern/voronoi_2d.c
intern/voxel.c
intern/winstuff.c
intern/winstuff_dir.c
@@ -132,14 +133,14 @@ set(SRC
BLI_bitmap.h
BLI_bitmap_draw_2d.h
BLI_blenlib.h
- BLI_boxpack2d.h
+ BLI_boxpack_2d.h
BLI_buffer.h
BLI_callbacks.h
BLI_compiler_attrs.h
BLI_compiler_compat.h
BLI_compiler_typecheck.h
- BLI_convexhull2d.h
- BLI_dial.h
+ BLI_convexhull_2d.h
+ BLI_dial_2d.h
BLI_dlrbTree.h
BLI_dynlib.h
BLI_dynstr.h
@@ -158,10 +159,10 @@ set(SRC
BLI_hash_mm2a.h
BLI_heap.h
BLI_iterator.h
- BLI_jitter.h
+ BLI_jitter_2d.h
BLI_kdopbvh.h
BLI_kdtree.h
- BLI_lasso.h
+ BLI_lasso_2d.h
BLI_link_utils.h
BLI_linklist.h
BLI_linklist_stack.h
@@ -185,8 +186,8 @@ set(SRC
BLI_mempool.h
BLI_noise.h
BLI_path_util.h
- BLI_polyfill2d.h
- BLI_polyfill2d_beautify.h
+ BLI_polyfill_2d.h
+ BLI_polyfill_2d_beautify.h
BLI_quadric.h
BLI_rand.h
BLI_rect.h
@@ -211,7 +212,7 @@ set(SRC
BLI_utildefines_variadic.h
BLI_uvproject.h
BLI_vfontdata.h
- BLI_voronoi.h
+ BLI_voronoi_2d.h
BLI_voxel.h
BLI_winstuff.h
PIL_time.h
diff --git a/source/blender/blenlib/intern/BLI_dial.c b/source/blender/blenlib/intern/BLI_dial_2d.c
index 89f18fa10b4..d31367c5e87 100644
--- a/source/blender/blenlib/intern/BLI_dial.c
+++ b/source/blender/blenlib/intern/BLI_dial_2d.c
@@ -18,7 +18,11 @@
* ***** END GPL LICENSE BLOCK *****
*/
-#include "BLI_dial.h"
+/** \file blender/blenlib/intern/BLI_dial_2d.c
+ * \ingroup bli
+ */
+
+#include "BLI_dial_2d.h"
#include "BLI_math.h"
#include "MEM_guardedalloc.h"
diff --git a/source/blender/blenlib/intern/BLI_ghash.c b/source/blender/blenlib/intern/BLI_ghash.c
index bf2f25fae69..fc8e786e5ff 100644
--- a/source/blender/blenlib/intern/BLI_ghash.c
+++ b/source/blender/blenlib/intern/BLI_ghash.c
@@ -43,11 +43,12 @@
#include "BLI_sys_types.h" /* for intptr_t support */
#include "BLI_utildefines.h"
-#include "BLI_hash_mm2a.h"
#include "BLI_mempool.h"
#define GHASH_INTERNAL_API
-#include "BLI_ghash.h"
+#include "BLI_ghash.h" /* own include */
+
+/* keep last */
#include "BLI_strict_flags.h"
/* -------------------------------------------------------------------- */
@@ -741,7 +742,7 @@ void BLI_ghash_reserve(GHash *gh, const uint nentries_reserve)
/**
* \return size of the GHash.
*/
-uint BLI_ghash_size(GHash *gh)
+uint BLI_ghash_len(GHash *gh)
{
return gh->nentries;
}
@@ -1010,7 +1011,7 @@ void BLI_ghash_clear(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfree
*/
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
{
- BLI_assert((int)gh->nentries == BLI_mempool_count(gh->entrypool));
+ BLI_assert((int)gh->nentries == BLI_mempool_len(gh->entrypool));
if (keyfreefp || valfreefp)
ghash_free_cb(gh, keyfreefp, valfreefp);
@@ -1044,7 +1045,7 @@ void BLI_ghash_flag_clear(GHash *gh, uint flag)
/**
* Create a new GHashIterator. The hash table must not be mutated
* while the iterator is in use, and the iterator will step exactly
- * BLI_ghash_size(gh) times before becoming done.
+ * BLI_ghash_len(gh) times before becoming done.
*
* \param gh The GHash to iterate over.
* \return Pointer to a new DynStr.
@@ -1059,7 +1060,7 @@ GHashIterator *BLI_ghashIterator_new(GHash *gh)
/**
* Init an already allocated GHashIterator. The hash table must not
* be mutated while the iterator is in use, and the iterator will
- * step exactly BLI_ghash_size(gh) times before becoming done.
+ * step exactly BLI_ghash_len(gh) times before becoming done.
*
* \param ghi The GHashIterator to initialize.
* \param gh The GHash to iterate over.
@@ -1161,219 +1162,6 @@ bool BLI_ghashIterator_done(GHashIterator *ghi)
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Generic Key Hash & Comparison Functions
- * \{ */
-
-/***/
-
-#if 0
-/* works but slower */
-uint BLI_ghashutil_ptrhash(const void *key)
-{
- return (uint)(intptr_t)key;
-}
-#else
-/* based python3.3's pointer hashing function */
-uint BLI_ghashutil_ptrhash(const void *key)
-{
- size_t y = (size_t)key;
- /* bottom 3 or 4 bits are likely to be 0; rotate y by 4 to avoid
- * excessive hash collisions for dicts and sets */
- y = (y >> 4) | (y << (8 * sizeof(void *) - 4));
- return (uint)y;
-}
-#endif
-bool BLI_ghashutil_ptrcmp(const void *a, const void *b)
-{
- return (a != b);
-}
-
-uint BLI_ghashutil_uinthash_v4(const uint key[4])
-{
- uint hash;
- hash = key[0];
- hash *= 37;
- hash += key[1];
- hash *= 37;
- hash += key[2];
- hash *= 37;
- hash += key[3];
- return hash;
-}
-uint BLI_ghashutil_uinthash_v4_murmur(const uint key[4])
-{
- return BLI_hash_mm2((const unsigned char *)key, sizeof(int) * 4 /* sizeof(key) */, 0);
-}
-
-bool BLI_ghashutil_uinthash_v4_cmp(const void *a, const void *b)
-{
- return (memcmp(a, b, sizeof(uint[4])) != 0);
-}
-
-uint BLI_ghashutil_uinthash(uint key)
-{
- key += ~(key << 16);
- key ^= (key >> 5);
- key += (key << 3);
- key ^= (key >> 13);
- key += ~(key << 9);
- key ^= (key >> 17);
-
- return key;
-}
-
-uint BLI_ghashutil_inthash_p(const void *ptr)
-{
- uintptr_t key = (uintptr_t)ptr;
-
- key += ~(key << 16);
- key ^= (key >> 5);
- key += (key << 3);
- key ^= (key >> 13);
- key += ~(key << 9);
- key ^= (key >> 17);
-
- return (uint)(key & 0xffffffff);
-}
-
-uint BLI_ghashutil_inthash_p_murmur(const void *ptr)
-{
- uintptr_t key = (uintptr_t)ptr;
-
- return BLI_hash_mm2((const unsigned char *)&key, sizeof(key), 0);
-}
-
-uint BLI_ghashutil_inthash_p_simple(const void *ptr)
-{
- return GET_UINT_FROM_POINTER(ptr);
-}
-
-bool BLI_ghashutil_intcmp(const void *a, const void *b)
-{
- return (a != b);
-}
-
-size_t BLI_ghashutil_combine_hash(size_t hash_a, size_t hash_b)
-{
- return hash_a ^ (hash_b + 0x9e3779b9 + (hash_a << 6) + (hash_a >> 2));
-}
-
-/**
- * This function implements the widely used "djb" hash apparently posted
- * by Daniel Bernstein to comp.lang.c some time ago. The 32 bit
- * unsigned hash value starts at 5381 and for each byte 'c' in the
- * string, is updated: ``hash = hash * 33 + c``. This
- * function uses the signed value of each byte.
- *
- * note: this is the same hash method that glib 2.34.0 uses.
- */
-uint BLI_ghashutil_strhash_n(const char *key, size_t n)
-{
- const signed char *p;
- uint h = 5381;
-
- for (p = (const signed char *)key; n-- && *p != '\0'; p++) {
- h = (uint)((h << 5) + h) + (uint)*p;
- }
-
- return h;
-}
-uint BLI_ghashutil_strhash_p(const void *ptr)
-{
- const signed char *p;
- uint h = 5381;
-
- for (p = ptr; *p != '\0'; p++) {
- h = (uint)((h << 5) + h) + (uint)*p;
- }
-
- return h;
-}
-uint BLI_ghashutil_strhash_p_murmur(const void *ptr)
-{
- const unsigned char *key = ptr;
-
- return BLI_hash_mm2(key, strlen((const char *)key) + 1, 0);
-}
-bool BLI_ghashutil_strcmp(const void *a, const void *b)
-{
- return (a == b) ? false : !STREQ(a, b);
-}
-
-GHashPair *BLI_ghashutil_pairalloc(const void *first, const void *second)
-{
- GHashPair *pair = MEM_mallocN(sizeof(GHashPair), "GHashPair");
- pair->first = first;
- pair->second = second;
- return pair;
-}
-
-uint BLI_ghashutil_pairhash(const void *ptr)
-{
- const GHashPair *pair = ptr;
- uint hash = BLI_ghashutil_ptrhash(pair->first);
- return hash ^ BLI_ghashutil_ptrhash(pair->second);
-}
-
-bool BLI_ghashutil_paircmp(const void *a, const void *b)
-{
- const GHashPair *A = a;
- const GHashPair *B = b;
-
- return (BLI_ghashutil_ptrcmp(A->first, B->first) ||
- BLI_ghashutil_ptrcmp(A->second, B->second));
-}
-
-void BLI_ghashutil_pairfree(void *ptr)
-{
- MEM_freeN(ptr);
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Convenience GHash Creation Functions
- * \{ */
-
-GHash *BLI_ghash_ptr_new_ex(const char *info, const uint nentries_reserve)
-{
- return BLI_ghash_new_ex(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, info, nentries_reserve);
-}
-GHash *BLI_ghash_ptr_new(const char *info)
-{
- return BLI_ghash_ptr_new_ex(info, 0);
-}
-
-GHash *BLI_ghash_str_new_ex(const char *info, const uint nentries_reserve)
-{
- return BLI_ghash_new_ex(BLI_ghashutil_strhash_p, BLI_ghashutil_strcmp, info, nentries_reserve);
-}
-GHash *BLI_ghash_str_new(const char *info)
-{
- return BLI_ghash_str_new_ex(info, 0);
-}
-
-GHash *BLI_ghash_int_new_ex(const char *info, const uint nentries_reserve)
-{
- return BLI_ghash_new_ex(BLI_ghashutil_inthash_p, BLI_ghashutil_intcmp, info, nentries_reserve);
-}
-GHash *BLI_ghash_int_new(const char *info)
-{
- return BLI_ghash_int_new_ex(info, 0);
-}
-
-GHash *BLI_ghash_pair_new_ex(const char *info, const uint nentries_reserve)
-{
- return BLI_ghash_new_ex(BLI_ghashutil_pairhash, BLI_ghashutil_paircmp, info, nentries_reserve);
-}
-GHash *BLI_ghash_pair_new(const char *info)
-{
- return BLI_ghash_pair_new_ex(info, 0);
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
/** \name GSet Public API
*
* Use ghash API to give 'set' functionality
@@ -1398,7 +1186,7 @@ GSet *BLI_gset_copy(GSet *gs, GHashKeyCopyFP keycopyfp)
return (GSet *)ghash_copy((GHash *)gs, keycopyfp, NULL);
}
-uint BLI_gset_size(GSet *gs)
+uint BLI_gset_len(GSet *gs)
{
return ((GHash *)gs)->nentries;
}
@@ -1577,39 +1365,6 @@ void *BLI_gset_pop_key(GSet *gs, const void *key)
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Convenience GSet Creation Functions
- * \{ */
-
-GSet *BLI_gset_ptr_new_ex(const char *info, const uint nentries_reserve)
-{
- return BLI_gset_new_ex(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, info, nentries_reserve);
-}
-GSet *BLI_gset_ptr_new(const char *info)
-{
- return BLI_gset_ptr_new_ex(info, 0);
-}
-
-GSet *BLI_gset_str_new_ex(const char *info, const uint nentries_reserve)
-{
- return BLI_gset_new_ex(BLI_ghashutil_strhash_p, BLI_ghashutil_strcmp, info, nentries_reserve);
-}
-GSet *BLI_gset_str_new(const char *info)
-{
- return BLI_gset_str_new_ex(info, 0);
-}
-
-GSet *BLI_gset_pair_new_ex(const char *info, const uint nentries_reserve)
-{
- return BLI_gset_new_ex(BLI_ghashutil_pairhash, BLI_ghashutil_paircmp, info, nentries_reserve);
-}
-GSet *BLI_gset_pair_new(const char *info)
-{
- return BLI_gset_pair_new_ex(info, 0);
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
/** \name Debugging & Introspection
* \{ */
@@ -1618,13 +1373,13 @@ GSet *BLI_gset_pair_new(const char *info)
/**
* \return number of buckets in the GHash.
*/
-int BLI_ghash_buckets_size(GHash *gh)
+int BLI_ghash_buckets_len(GHash *gh)
{
return (int)gh->nbuckets;
}
-int BLI_gset_buckets_size(GSet *gs)
+int BLI_gset_buckets_len(GSet *gs)
{
- return BLI_ghash_buckets_size((GHash *)gs);
+ return BLI_ghash_buckets_len((GHash *)gs);
}
/**
diff --git a/source/blender/blenlib/intern/BLI_ghash_utils.c b/source/blender/blenlib/intern/BLI_ghash_utils.c
new file mode 100644
index 00000000000..6554ee7c92f
--- /dev/null
+++ b/source/blender/blenlib/intern/BLI_ghash_utils.c
@@ -0,0 +1,288 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenlib/intern/BLI_ghash_utils.c
+ * \ingroup bli
+ *
+ * Helper functions and implementations of standard data types for #GHash
+ * (not it's implementation).
+ */
+
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_hash_mm2a.h"
+#include "BLI_ghash.h" /* own include */
+
+/* keep last */
+#include "BLI_strict_flags.h"
+
+/* -------------------------------------------------------------------- */
+/** \name Generic Key Hash & Comparison Functions
+ * \{ */
+
+#if 0
+/* works but slower */
+uint BLI_ghashutil_ptrhash(const void *key)
+{
+ return (uint)(intptr_t)key;
+}
+#else
+/* based python3.3's pointer hashing function */
+uint BLI_ghashutil_ptrhash(const void *key)
+{
+ size_t y = (size_t)key;
+ /* bottom 3 or 4 bits are likely to be 0; rotate y by 4 to avoid
+ * excessive hash collisions for dicts and sets */
+ y = (y >> 4) | (y << (8 * sizeof(void *) - 4));
+ return (uint)y;
+}
+#endif
+bool BLI_ghashutil_ptrcmp(const void *a, const void *b)
+{
+ return (a != b);
+}
+
+uint BLI_ghashutil_uinthash_v4(const uint key[4])
+{
+ uint hash;
+ hash = key[0];
+ hash *= 37;
+ hash += key[1];
+ hash *= 37;
+ hash += key[2];
+ hash *= 37;
+ hash += key[3];
+ return hash;
+}
+uint BLI_ghashutil_uinthash_v4_murmur(const uint key[4])
+{
+ return BLI_hash_mm2((const unsigned char *)key, sizeof(int) * 4 /* sizeof(key) */, 0);
+}
+
+bool BLI_ghashutil_uinthash_v4_cmp(const void *a, const void *b)
+{
+ return (memcmp(a, b, sizeof(uint[4])) != 0);
+}
+
+uint BLI_ghashutil_uinthash(uint key)
+{
+ key += ~(key << 16);
+ key ^= (key >> 5);
+ key += (key << 3);
+ key ^= (key >> 13);
+ key += ~(key << 9);
+ key ^= (key >> 17);
+
+ return key;
+}
+
+uint BLI_ghashutil_inthash_p(const void *ptr)
+{
+ uintptr_t key = (uintptr_t)ptr;
+
+ key += ~(key << 16);
+ key ^= (key >> 5);
+ key += (key << 3);
+ key ^= (key >> 13);
+ key += ~(key << 9);
+ key ^= (key >> 17);
+
+ return (uint)(key & 0xffffffff);
+}
+
+uint BLI_ghashutil_inthash_p_murmur(const void *ptr)
+{
+ uintptr_t key = (uintptr_t)ptr;
+
+ return BLI_hash_mm2((const unsigned char *)&key, sizeof(key), 0);
+}
+
+uint BLI_ghashutil_inthash_p_simple(const void *ptr)
+{
+ return GET_UINT_FROM_POINTER(ptr);
+}
+
+bool BLI_ghashutil_intcmp(const void *a, const void *b)
+{
+ return (a != b);
+}
+
+size_t BLI_ghashutil_combine_hash(size_t hash_a, size_t hash_b)
+{
+ return hash_a ^ (hash_b + 0x9e3779b9 + (hash_a << 6) + (hash_a >> 2));
+}
+
+/**
+ * This function implements the widely used "djb" hash apparently posted
+ * by Daniel Bernstein to comp.lang.c some time ago. The 32 bit
+ * unsigned hash value starts at 5381 and for each byte 'c' in the
+ * string, is updated: ``hash = hash * 33 + c``. This
+ * function uses the signed value of each byte.
+ *
+ * note: this is the same hash method that glib 2.34.0 uses.
+ */
+uint BLI_ghashutil_strhash_n(const char *key, size_t n)
+{
+ const signed char *p;
+ uint h = 5381;
+
+ for (p = (const signed char *)key; n-- && *p != '\0'; p++) {
+ h = (uint)((h << 5) + h) + (uint)*p;
+ }
+
+ return h;
+}
+uint BLI_ghashutil_strhash_p(const void *ptr)
+{
+ const signed char *p;
+ uint h = 5381;
+
+ for (p = ptr; *p != '\0'; p++) {
+ h = (uint)((h << 5) + h) + (uint)*p;
+ }
+
+ return h;
+}
+uint BLI_ghashutil_strhash_p_murmur(const void *ptr)
+{
+ const unsigned char *key = ptr;
+
+ return BLI_hash_mm2(key, strlen((const char *)key) + 1, 0);
+}
+bool BLI_ghashutil_strcmp(const void *a, const void *b)
+{
+ return (a == b) ? false : !STREQ(a, b);
+}
+
+GHashPair *BLI_ghashutil_pairalloc(const void *first, const void *second)
+{
+ GHashPair *pair = MEM_mallocN(sizeof(GHashPair), "GHashPair");
+ pair->first = first;
+ pair->second = second;
+ return pair;
+}
+
+uint BLI_ghashutil_pairhash(const void *ptr)
+{
+ const GHashPair *pair = ptr;
+ uint hash = BLI_ghashutil_ptrhash(pair->first);
+ return hash ^ BLI_ghashutil_ptrhash(pair->second);
+}
+
+bool BLI_ghashutil_paircmp(const void *a, const void *b)
+{
+ const GHashPair *A = a;
+ const GHashPair *B = b;
+
+ return (BLI_ghashutil_ptrcmp(A->first, B->first) ||
+ BLI_ghashutil_ptrcmp(A->second, B->second));
+}
+
+void BLI_ghashutil_pairfree(void *ptr)
+{
+ MEM_freeN(ptr);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Convenience GHash Creation Functions
+ * \{ */
+
+GHash *BLI_ghash_ptr_new_ex(const char *info, const uint nentries_reserve)
+{
+ return BLI_ghash_new_ex(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, info, nentries_reserve);
+}
+GHash *BLI_ghash_ptr_new(const char *info)
+{
+ return BLI_ghash_ptr_new_ex(info, 0);
+}
+
+GHash *BLI_ghash_str_new_ex(const char *info, const uint nentries_reserve)
+{
+ return BLI_ghash_new_ex(BLI_ghashutil_strhash_p, BLI_ghashutil_strcmp, info, nentries_reserve);
+}
+GHash *BLI_ghash_str_new(const char *info)
+{
+ return BLI_ghash_str_new_ex(info, 0);
+}
+
+GHash *BLI_ghash_int_new_ex(const char *info, const uint nentries_reserve)
+{
+ return BLI_ghash_new_ex(BLI_ghashutil_inthash_p, BLI_ghashutil_intcmp, info, nentries_reserve);
+}
+GHash *BLI_ghash_int_new(const char *info)
+{
+ return BLI_ghash_int_new_ex(info, 0);
+}
+
+GHash *BLI_ghash_pair_new_ex(const char *info, const uint nentries_reserve)
+{
+ return BLI_ghash_new_ex(BLI_ghashutil_pairhash, BLI_ghashutil_paircmp, info, nentries_reserve);
+}
+GHash *BLI_ghash_pair_new(const char *info)
+{
+ return BLI_ghash_pair_new_ex(info, 0);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Convenience GSet Creation Functions
+ * \{ */
+
+GSet *BLI_gset_ptr_new_ex(const char *info, const uint nentries_reserve)
+{
+ return BLI_gset_new_ex(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, info, nentries_reserve);
+}
+GSet *BLI_gset_ptr_new(const char *info)
+{
+ return BLI_gset_ptr_new_ex(info, 0);
+}
+
+GSet *BLI_gset_str_new_ex(const char *info, const uint nentries_reserve)
+{
+ return BLI_gset_new_ex(BLI_ghashutil_strhash_p, BLI_ghashutil_strcmp, info, nentries_reserve);
+}
+GSet *BLI_gset_str_new(const char *info)
+{
+ return BLI_gset_str_new_ex(info, 0);
+}
+
+GSet *BLI_gset_pair_new_ex(const char *info, const uint nentries_reserve)
+{
+ return BLI_gset_new_ex(BLI_ghashutil_pairhash, BLI_ghashutil_paircmp, info, nentries_reserve);
+}
+GSet *BLI_gset_pair_new(const char *info)
+{
+ return BLI_gset_pair_new_ex(info, 0);
+}
+
+/** \} */
diff --git a/source/blender/blenlib/intern/BLI_heap.c b/source/blender/blenlib/intern/BLI_heap.c
index 7c249344541..0c71e75e40f 100644
--- a/source/blender/blenlib/intern/BLI_heap.c
+++ b/source/blender/blenlib/intern/BLI_heap.c
@@ -303,7 +303,7 @@ bool BLI_heap_is_empty(const Heap *heap)
return (heap->size == 0);
}
-uint BLI_heap_size(const Heap *heap)
+uint BLI_heap_len(const Heap *heap)
{
return heap->size;
}
@@ -320,7 +320,7 @@ HeapNode *BLI_heap_top(const Heap *heap)
/**
* Pop the top node off the heap and return it's pointer.
*/
-void *BLI_heap_popmin(Heap *heap)
+void *BLI_heap_pop_min(Heap *heap)
{
BLI_assert(heap->size != 0);
@@ -348,7 +348,7 @@ void BLI_heap_remove(Heap *heap, HeapNode *node)
i = p;
}
- BLI_heap_popmin(heap);
+ BLI_heap_pop_min(heap);
}
/**
diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c
index 9c055a227a9..d6c58780603 100644
--- a/source/blender/blenlib/intern/BLI_kdopbvh.c
+++ b/source/blender/blenlib/intern/BLI_kdopbvh.c
@@ -1147,7 +1147,7 @@ void BLI_bvhtree_update_tree(BVHTree *tree)
* Number of times #BLI_bvhtree_insert has been called.
* mainly useful for asserts functions to check we added the correct number.
*/
-int BLI_bvhtree_get_size(const BVHTree *tree)
+int BLI_bvhtree_get_len(const BVHTree *tree)
{
return tree->totleaf;
}
diff --git a/source/blender/blenlib/intern/BLI_mempool.c b/source/blender/blenlib/intern/BLI_mempool.c
index 5b13f129ad4..3a65e6c42ca 100644
--- a/source/blender/blenlib/intern/BLI_mempool.c
+++ b/source/blender/blenlib/intern/BLI_mempool.c
@@ -474,7 +474,7 @@ void BLI_mempool_free(BLI_mempool *pool, void *addr)
}
}
-int BLI_mempool_count(BLI_mempool *pool)
+int BLI_mempool_len(BLI_mempool *pool)
{
return (int)pool->totused;
}
diff --git a/source/blender/blenlib/intern/array_store.c b/source/blender/blenlib/intern/array_store.c
index 5b1715bbb3d..acf15b1c892 100644
--- a/source/blender/blenlib/intern/array_store.c
+++ b/source/blender/blenlib/intern/array_store.c
@@ -1759,7 +1759,7 @@ bool BLI_array_store_is_valid(
goto user_finally;
}
}
- if (!(BLI_mempool_count(bs->memory.chunk_list) == (int)BLI_ghash_size(chunk_list_map))) {
+ if (!(BLI_mempool_len(bs->memory.chunk_list) == (int)BLI_ghash_len(chunk_list_map))) {
ok = false;
goto user_finally;
}
@@ -1772,11 +1772,11 @@ bool BLI_array_store_is_valid(
totrefs += 1;
}
}
- if (!(BLI_mempool_count(bs->memory.chunk) == (int)BLI_ghash_size(chunk_map))) {
+ if (!(BLI_mempool_len(bs->memory.chunk) == (int)BLI_ghash_len(chunk_map))) {
ok = false;
goto user_finally;
}
- if (!(BLI_mempool_count(bs->memory.chunk_ref) == totrefs)) {
+ if (!(BLI_mempool_len(bs->memory.chunk_ref) == totrefs)) {
ok = false;
goto user_finally;
}
diff --git a/source/blender/blenlib/intern/astar.c b/source/blender/blenlib/intern/astar.c
index 0020dbe4612..1b57dc5a683 100644
--- a/source/blender/blenlib/intern/astar.c
+++ b/source/blender/blenlib/intern/astar.c
@@ -231,7 +231,7 @@ bool BLI_astar_graph_solve(
SET_INT_IN_POINTER(node_index_src));
while (!BLI_heap_is_empty(todo_nodes)) {
- const int node_curr_idx = GET_INT_FROM_POINTER(BLI_heap_popmin(todo_nodes));
+ const int node_curr_idx = GET_INT_FROM_POINTER(BLI_heap_pop_min(todo_nodes));
BLI_AStarGNode *node_curr = &as_graph->nodes[node_curr_idx];
LinkData *ld;
diff --git a/source/blender/blenlib/intern/boxpack2d.c b/source/blender/blenlib/intern/boxpack_2d.c
index ff17d2ac28b..b3beff0b78b 100644
--- a/source/blender/blenlib/intern/boxpack2d.c
+++ b/source/blender/blenlib/intern/boxpack_2d.c
@@ -30,7 +30,7 @@
#include "MEM_guardedalloc.h"
#include "BLI_utildefines.h"
-#include "BLI_boxpack2d.h" /* own include */
+#include "BLI_boxpack_2d.h" /* own include */
#include "BLI_sort.h" /* qsort_r */
#define qsort_r BLI_qsort_r
diff --git a/source/blender/blenlib/intern/convexhull2d.c b/source/blender/blenlib/intern/convexhull_2d.c
index 1f1f214ce32..38928dbbaa0 100644
--- a/source/blender/blenlib/intern/convexhull2d.c
+++ b/source/blender/blenlib/intern/convexhull_2d.c
@@ -18,7 +18,7 @@
* ***** END GPL LICENSE BLOCK *****
*/
-/** \file blender/blenlib/intern/convexhull2d.c
+/** \file blender/blenlib/intern/convexhull_2d.c
* \ingroup bli
*/
@@ -28,7 +28,7 @@
#include "MEM_guardedalloc.h"
-#include "BLI_convexhull2d.h"
+#include "BLI_convexhull_2d.h"
#include "BLI_math.h"
#include "BLI_strict_flags.h"
#include "BLI_utildefines.h"
diff --git a/source/blender/blenlib/intern/edgehash.c b/source/blender/blenlib/intern/edgehash.c
index 772c8bd6247..7074a776aaf 100644
--- a/source/blender/blenlib/intern/edgehash.c
+++ b/source/blender/blenlib/intern/edgehash.c
@@ -527,7 +527,7 @@ bool BLI_edgehash_haskey(EdgeHash *eh, uint v0, uint v1)
/**
* Return number of keys in hash.
*/
-int BLI_edgehash_size(EdgeHash *eh)
+int BLI_edgehash_len(EdgeHash *eh)
{
return (int)eh->nentries;
}
@@ -565,7 +565,7 @@ void BLI_edgehash_clear(EdgeHash *eh, EdgeHashFreeFP valfreefp)
void BLI_edgehash_free(EdgeHash *eh, EdgeHashFreeFP valfreefp)
{
- BLI_assert((int)eh->nentries == BLI_mempool_count(eh->epool));
+ BLI_assert((int)eh->nentries == BLI_mempool_len(eh->epool));
if (valfreefp)
edgehash_free_cb(eh, valfreefp);
@@ -599,7 +599,7 @@ void BLI_edgehash_flag_clear(EdgeHash *eh, uint flag)
/**
* Create a new EdgeHashIterator. The hash table must not be mutated
* while the iterator is in use, and the iterator will step exactly
- * BLI_edgehash_size(eh) times before becoming done.
+ * BLI_edgehash_len(eh) times before becoming done.
*/
EdgeHashIterator *BLI_edgehashIterator_new(EdgeHash *eh)
{
@@ -611,7 +611,7 @@ EdgeHashIterator *BLI_edgehashIterator_new(EdgeHash *eh)
/**
* Init an already allocated EdgeHashIterator. The hash table must not
* be mutated while the iterator is in use, and the iterator will
- * step exactly BLI_edgehash_size(eh) times before becoming done.
+ * step exactly BLI_edgehash_len(eh) times before becoming done.
*
* \param ehi The EdgeHashIterator to initialize.
* \param eh The EdgeHash to iterate over.
@@ -729,7 +729,7 @@ EdgeSet *BLI_edgeset_new(const char *info)
return BLI_edgeset_new_ex(info, 0);
}
-int BLI_edgeset_size(EdgeSet *es)
+int BLI_edgeset_len(EdgeSet *es)
{
return (int)((EdgeHash *)es)->nentries;
}
diff --git a/source/blender/blenlib/intern/gsqueue.c b/source/blender/blenlib/intern/gsqueue.c
index 25da7701924..5c8c43ab92a 100644
--- a/source/blender/blenlib/intern/gsqueue.c
+++ b/source/blender/blenlib/intern/gsqueue.c
@@ -81,7 +81,7 @@ bool BLI_gsqueue_is_empty(GSQueue *gq)
/**
* Query number elements in the queue
*/
-int BLI_gsqueue_size(GSQueue *gq)
+int BLI_gsqueue_len(GSQueue *gq)
{
GSQueueElem *elem;
int size = 0;
@@ -162,7 +162,7 @@ void BLI_gsqueue_push(GSQueue *gq, const void *item)
* \param item A pointer to an appropriately
* sized structure (the size passed to BLI_gsqueue_new).
*/
-void BLI_gsqueue_pushback(GSQueue *gq, const void *item)
+void BLI_gsqueue_push_back(GSQueue *gq, const void *item)
{
GSQueueElem *elem = MEM_mallocN(sizeof(*elem) + gq->elem_size, "gqueue_push");
memcpy(elem->data, item, gq->elem_size);
diff --git a/source/blender/blenlib/intern/jitter.c b/source/blender/blenlib/intern/jitter_2d.c
index bc2b5677fa5..6c51eeb36d9 100644
--- a/source/blender/blenlib/intern/jitter.c
+++ b/source/blender/blenlib/intern/jitter_2d.c
@@ -35,7 +35,7 @@
#include "MEM_guardedalloc.h"
#include "BLI_rand.h"
-#include "BLI_jitter.h"
+#include "BLI_jitter_2d.h"
#include "BLI_strict_flags.h"
diff --git a/source/blender/blenlib/intern/lasso.c b/source/blender/blenlib/intern/lasso_2d.c
index 710da09521a..663f3ffea22 100644
--- a/source/blender/blenlib/intern/lasso.c
+++ b/source/blender/blenlib/intern/lasso_2d.c
@@ -26,7 +26,7 @@
*
*/
-/** \file blender/blenlib/intern/lasso.c
+/** \file blender/blenlib/intern/lasso_2d.c
* \ingroup bli
*/
@@ -35,7 +35,7 @@
#include "BLI_math.h"
#include "BLI_strict_flags.h"
-#include "BLI_lasso.h" /* own include */
+#include "BLI_lasso_2d.h" /* own include */
void BLI_lasso_boundbox(rcti *rect, const int mcords[][2], const unsigned int moves)
{
diff --git a/source/blender/blenlib/intern/math_base_inline.c b/source/blender/blenlib/intern/math_base_inline.c
index 2f5b0f420b1..1f517471407 100644
--- a/source/blender/blenlib/intern/math_base_inline.c
+++ b/source/blender/blenlib/intern/math_base_inline.c
@@ -324,6 +324,27 @@ MINLINE size_t max_zz(size_t a, size_t b)
return (b < a) ? a : b;
}
+MINLINE int clamp_i(int value, int min, int max)
+{
+ return min_ii(max_ii(value, min), max);
+}
+
+MINLINE float clamp_f(float value, float min, float max)
+{
+ if (value > max) {
+ return max;
+ }
+ else if (value < min) {
+ return min;
+ }
+ return value;
+}
+
+MINLINE size_t clamp_z(size_t value, size_t min, size_t max)
+{
+ return min_zz(max_zz(value, min), max);
+}
+
/**
* Almost-equal for IEEE floats, using absolute difference method.
*
diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c
index d3080e5530f..a3d850f9551 100644
--- a/source/blender/blenlib/intern/math_geom.c
+++ b/source/blender/blenlib/intern/math_geom.c
@@ -4903,6 +4903,18 @@ int is_quad_flip_v3(const float v1[3], const float v2[3], const float v3[3], con
return ret;
}
+bool is_quad_flip_v3_first_third_fast(const float v1[3], const float v2[3], const float v3[3], const float v4[3])
+{
+ float d_12[3], d_13[3], d_14[3];
+ float cross_a[3], cross_b[3];
+ sub_v3_v3v3(d_12, v2, v1);
+ sub_v3_v3v3(d_13, v3, v1);
+ sub_v3_v3v3(d_14, v4, v1);
+ cross_v3_v3v3(cross_a, d_12, d_13);
+ cross_v3_v3v3(cross_b, d_14, d_13);
+ return dot_v3v3(cross_a, cross_b) > 0.0f;
+}
+
/**
* Return the value which the distance between points will need to be scaled by,
* to define a handle, given both points are on a perfect circle.
diff --git a/source/blender/blenlib/intern/math_vector.c b/source/blender/blenlib/intern/math_vector.c
index 05562502278..d6e48fa59e7 100644
--- a/source/blender/blenlib/intern/math_vector.c
+++ b/source/blender/blenlib/intern/math_vector.c
@@ -890,6 +890,8 @@ void rotate_normalized_v3_v3v3fl(float out[3], const float p[3], const float axi
void rotate_v3_v3v3fl(float r[3], const float p[3], const float axis[3], const float angle)
{
+ BLI_assert(r != p);
+
float axis_n[3];
normalize_v3_v3(axis_n, axis);
diff --git a/source/blender/blenlib/intern/polyfill2d.c b/source/blender/blenlib/intern/polyfill_2d.c
index 018e2f9be5a..8c0870f0c07 100644
--- a/source/blender/blenlib/intern/polyfill2d.c
+++ b/source/blender/blenlib/intern/polyfill_2d.c
@@ -18,7 +18,7 @@
* ***** END GPL LICENSE BLOCK *****
*/
-/** \file blender/blenlib/intern/polyfill2d.c
+/** \file blender/blenlib/intern/polyfill_2d.c
* \ingroup bli
*
* An ear clipping algorithm to triangulate single boundary polygons.
@@ -53,7 +53,7 @@
#include "BLI_memarena.h"
#include "BLI_alloca.h"
-#include "BLI_polyfill2d.h" /* own include */
+#include "BLI_polyfill_2d.h" /* own include */
#include "BLI_strict_flags.h"
diff --git a/source/blender/blenlib/intern/polyfill2d_beautify.c b/source/blender/blenlib/intern/polyfill_2d_beautify.c
index c0c95da5c63..93bfb02bce4 100644
--- a/source/blender/blenlib/intern/polyfill2d_beautify.c
+++ b/source/blender/blenlib/intern/polyfill_2d_beautify.c
@@ -44,7 +44,7 @@
#include "BLI_memarena.h"
#include "BLI_heap.h"
-#include "BLI_polyfill2d_beautify.h" /* own include */
+#include "BLI_polyfill_2d_beautify.h" /* own include */
#include "BLI_strict_flags.h"
@@ -401,7 +401,7 @@ void BLI_polyfill_beautify(
}
while (BLI_heap_is_empty(eheap) == false) {
- struct HalfEdge *e = BLI_heap_popmin(eheap);
+ struct HalfEdge *e = BLI_heap_pop_min(eheap);
eheap_table[e->base_index] = NULL;
polyedge_rotate(half_edges, e);
diff --git a/source/blender/blenlib/intern/smallhash.c b/source/blender/blenlib/intern/smallhash.c
index 1b862ffe005..56d77abed24 100644
--- a/source/blender/blenlib/intern/smallhash.c
+++ b/source/blender/blenlib/intern/smallhash.c
@@ -310,7 +310,7 @@ bool BLI_smallhash_haskey(const SmallHash *sh, uintptr_t key)
return (e != NULL);
}
-int BLI_smallhash_count(const SmallHash *sh)
+int BLI_smallhash_len(const SmallHash *sh)
{
return (int)sh->nentries;
}
diff --git a/source/blender/blenlib/intern/task.c b/source/blender/blenlib/intern/task.c
index 05cfe4f3972..53c0c560c0d 100644
--- a/source/blender/blenlib/intern/task.c
+++ b/source/blender/blenlib/intern/task.c
@@ -696,7 +696,7 @@ static TaskPool *task_pool_create_ex(TaskScheduler *scheduler,
* and malloc could be non-thread safe at this point because
* no other jobs are running.
*/
- BLI_begin_threaded_malloc();
+ BLI_threaded_malloc_begin();
return pool;
}
@@ -763,7 +763,7 @@ void BLI_task_pool_free(TaskPool *pool)
MEM_freeN(pool);
- BLI_end_threaded_malloc();
+ BLI_threaded_malloc_end();
}
BLI_INLINE bool task_can_use_local_queues(TaskPool *pool, int thread_id)
@@ -1329,7 +1329,7 @@ void BLI_task_parallel_mempool(
ParallelMempoolState state;
int i, num_threads, num_tasks;
- if (BLI_mempool_count(mempool) == 0) {
+ if (BLI_mempool_len(mempool) == 0) {
return;
}
diff --git a/source/blender/blenlib/intern/threads.c b/source/blender/blenlib/intern/threads.c
index 2f961701801..761f3982e28 100644
--- a/source/blender/blenlib/intern/threads.c
+++ b/source/blender/blenlib/intern/threads.c
@@ -83,13 +83,13 @@ static TaskScheduler *task_scheduler = NULL;
* int maxthreads = 2;
* int cont = 1;
*
- * BLI_init_threads(&lb, do_something_func, maxthreads);
+ * BLI_threadpool_init(&lb, do_something_func, maxthreads);
*
* while (cont) {
* if (BLI_available_threads(&lb) && !(escape loop event)) {
* // get new job (data pointer)
* // tag job 'processed
- * BLI_insert_thread(&lb, job);
+ * BLI_threadpool_insert(&lb, job);
* }
* else PIL_sleep_ms(50);
*
@@ -98,7 +98,7 @@ static TaskScheduler *task_scheduler = NULL;
* for (go over all jobs)
* if (job is ready) {
* if (job was not removed) {
- * BLI_remove_thread(&lb, job);
+ * BLI_threadpool_remove(&lb, job);
* }
* }
* else cont = 1;
@@ -110,7 +110,7 @@ static TaskScheduler *task_scheduler = NULL;
* }
* }
*
- * BLI_end_threads(&lb);
+ * BLI_threadpool_end(&lb);
*
************************************************ */
static SpinLock _malloc_lock;
@@ -183,7 +183,7 @@ TaskScheduler *BLI_task_scheduler_get(void)
* problem otherwise: scene render will kill of the mutex!
*/
-void BLI_init_threads(ListBase *threadbase, void *(*do_thread)(void *), int tot)
+void BLI_threadpool_init(ListBase *threadbase, void *(*do_thread)(void *), int tot)
{
int a;
@@ -228,7 +228,7 @@ int BLI_available_threads(ListBase *threadbase)
}
/* returns thread number, for sample patterns or threadsafe tables */
-int BLI_available_thread_index(ListBase *threadbase)
+int BLI_threadpool_available_thread_index(ListBase *threadbase)
{
ThreadSlot *tslot;
int counter = 0;
@@ -258,7 +258,7 @@ int BLI_thread_is_main(void)
return pthread_equal(pthread_self(), mainid);
}
-void BLI_insert_thread(ListBase *threadbase, void *callerdata)
+void BLI_threadpool_insert(ListBase *threadbase, void *callerdata)
{
ThreadSlot *tslot;
@@ -273,7 +273,7 @@ void BLI_insert_thread(ListBase *threadbase, void *callerdata)
printf("ERROR: could not insert thread slot\n");
}
-void BLI_remove_thread(ListBase *threadbase, void *callerdata)
+void BLI_threadpool_remove(ListBase *threadbase, void *callerdata)
{
ThreadSlot *tslot;
@@ -286,7 +286,7 @@ void BLI_remove_thread(ListBase *threadbase, void *callerdata)
}
}
-void BLI_remove_thread_index(ListBase *threadbase, int index)
+void BLI_threadpool_remove_index(ListBase *threadbase, int index)
{
ThreadSlot *tslot;
int counter = 0;
@@ -301,7 +301,7 @@ void BLI_remove_thread_index(ListBase *threadbase, int index)
}
}
-void BLI_remove_threads(ListBase *threadbase)
+void BLI_threadpool_clear(ListBase *threadbase)
{
ThreadSlot *tslot;
@@ -314,7 +314,7 @@ void BLI_remove_threads(ListBase *threadbase)
}
}
-void BLI_end_threads(ListBase *threadbase)
+void BLI_threadpool_end(ListBase *threadbase)
{
ThreadSlot *tslot;
@@ -418,12 +418,12 @@ static ThreadMutex *global_mutex_from_type(const int type)
}
}
-void BLI_lock_thread(int type)
+void BLI_thread_lock(int type)
{
pthread_mutex_lock(global_mutex_from_type(type));
}
-void BLI_unlock_thread(int type)
+void BLI_thread_unlock(int type)
{
pthread_mutex_unlock(global_mutex_from_type(type));
}
@@ -773,12 +773,12 @@ void *BLI_thread_queue_pop_timeout(ThreadQueue *queue, int ms)
return work;
}
-int BLI_thread_queue_size(ThreadQueue *queue)
+int BLI_thread_queue_len(ThreadQueue *queue)
{
int size;
pthread_mutex_lock(&queue->mutex);
- size = BLI_gsqueue_size(queue->queue);
+ size = BLI_gsqueue_len(queue->queue);
pthread_mutex_unlock(&queue->mutex);
return size;
@@ -819,7 +819,7 @@ void BLI_thread_queue_wait_finish(ThreadQueue *queue)
/* ************************************************ */
-void BLI_begin_threaded_malloc(void)
+void BLI_threaded_malloc_begin(void)
{
unsigned int level = atomic_fetch_and_add_u(&thread_levels, 1);
if (level == 0) {
@@ -832,7 +832,7 @@ void BLI_begin_threaded_malloc(void)
}
}
-void BLI_end_threaded_malloc(void)
+void BLI_threaded_malloc_end(void)
{
unsigned int level = atomic_sub_and_fetch_u(&thread_levels, 1);
if (level == 0) {
diff --git a/source/blender/blenlib/intern/voronoi.c b/source/blender/blenlib/intern/voronoi_2d.c
index e0cbe278ffb..40e98d5914c 100644
--- a/source/blender/blenlib/intern/voronoi.c
+++ b/source/blender/blenlib/intern/voronoi_2d.c
@@ -23,20 +23,18 @@
* ***** END GPL LICENSE BLOCK *****
*/
-/*
+/** \file blender/blenlib/intern/voronoi_2d.c
+ * \ingroup bli
+ *
* Fortune's algorithm implemented using explanation and some code snippets from
* http://blog.ivank.net/fortunes-algorithm-and-implementation.html
*/
-/** \file blender/blenlib/intern/voronoi.c
- * \ingroup bli
- */
-
#include "MEM_guardedalloc.h"
#include "BLI_listbase.h"
#include "BLI_math.h"
-#include "BLI_voronoi.h"
+#include "BLI_voronoi_2d.h"
#include "BLI_utildefines.h"
#define VORONOI_EPS 1e-2f
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 54444ff5151..e5708ec4df0 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -86,7 +86,7 @@
#include "DNA_meshdata_types.h"
#include "DNA_nla_types.h"
#include "DNA_node_types.h"
-#include "DNA_object_fluidsim.h" // NT
+#include "DNA_object_fluidsim_types.h"
#include "DNA_object_types.h"
#include "DNA_packedFile_types.h"
#include "DNA_particle_types.h"
@@ -4406,6 +4406,9 @@ static void direct_link_particlesettings(FileData *fd, ParticleSettings *part)
part->roughcurve = newdataadr(fd, part->roughcurve);
if (part->roughcurve)
direct_link_curvemapping(fd, part->roughcurve);
+ part->twistcurve = newdataadr(fd, part->twistcurve);
+ if (part->twistcurve)
+ direct_link_curvemapping(fd, part->twistcurve);
part->effector_weights = newdataadr(fd, part->effector_weights);
if (!part->effector_weights)
@@ -4940,8 +4943,7 @@ static void lib_link_object(FileData *fd, Main *main)
#else
MEM_freeN(ob->pose);
#endif
- ob->pose= NULL;
- ob->mode &= ~OB_MODE_POSE;
+ ob->pose = NULL;
}
}
for (a=0; a < ob->totcol; a++)
@@ -5548,19 +5550,6 @@ static void direct_link_object(FileData *fd, Object *ob)
/* XXX This should not be needed - but seems like it can happen in some cases, so for now play safe... */
ob->proxy_from = NULL;
-
- /* loading saved files with editmode enabled works, but for undo we like
- * to stay in object mode during undo presses so keep editmode disabled.
- *
- * Also when linking in a file don't allow edit and pose modes.
- * See [#34776, #42780] for more information.
- */
- if (fd->memfile || (ob->id.tag & (LIB_TAG_EXTERN | LIB_TAG_INDIRECT))) {
- ob->mode &= ~(OB_MODE_EDIT | OB_MODE_PARTICLE_EDIT);
- if (!fd->memfile) {
- ob->mode &= ~OB_MODE_POSE;
- }
- }
ob->adt = newdataadr(fd, ob->adt);
direct_link_animdata(fd, ob->adt);
@@ -6230,7 +6219,6 @@ static void direct_link_scene(FileData *fd, Scene *sce, Main *bmain)
SceneRenderLayer *srl;
sce->depsgraph_hash = NULL;
- sce->obedit = NULL;
sce->fps_info = NULL;
sce->customdata_mask_modal = 0;
sce->lay_updated = 0;
@@ -6618,7 +6606,6 @@ static void direct_link_region(FileData *fd, ARegion *ar, int spacetype)
BLI_listbase_clear(&ar->handlers);
BLI_listbase_clear(&ar->uiblocks);
ar->headerstr = NULL;
- ar->swinid = 0;
ar->type = NULL;
ar->swap = 0;
ar->do_draw = 0;
@@ -7096,7 +7083,6 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm)
win->ghostwin = NULL;
win->eventstate = NULL;
- win->curswin = NULL;
win->tweak = NULL;
#ifdef WIN32
win->ime_data = NULL;
@@ -7105,7 +7091,6 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm)
BLI_listbase_clear(&win->queue);
BLI_listbase_clear(&win->handlers);
BLI_listbase_clear(&win->modalhandlers);
- BLI_listbase_clear(&win->subwindows);
BLI_listbase_clear(&win->gesture);
BLI_listbase_clear(&win->drawdata);
@@ -7118,7 +7103,6 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm)
win->modalcursor = 0;
win->grabcursor = 0;
win->addmousemove = true;
- win->multisamples = 0;
win->stereo3d_format = newdataadr(fd, win->stereo3d_format);
/* multiview always fallback to anaglyph at file opening
@@ -7639,8 +7623,7 @@ static bool direct_link_screen(FileData *fd, bScreen *sc)
link_list(fd, &(sc->areabase));
sc->regionbase.first = sc->regionbase.last= NULL;
sc->context = NULL;
-
- sc->mainwin = sc->subwinactive= 0; /* indices */
+ sc->active_region = NULL;
sc->swap = 0;
sc->preview = direct_link_preview_image(fd, sc->preview);
@@ -7690,12 +7673,20 @@ static void direct_link_library(FileData *fd, Library *lib, Main *main)
BLI_remlink(&main->library, lib);
MEM_freeN(lib);
-
-
+
+ /* Now, since Blender always expect **latest** Main pointer from fd->mainlist to be the active library
+ * Main pointer, where to add all non-library data-blocks found in file next, we have to switch that
+ * 'dupli' found Main to latest position in the list!
+ * Otherwise, you get weird disappearing linked data on a rather unconsistant basis.
+ * See also T53977 for reproducible case. */
+ BLI_remlink(fd->mainlist, newmain);
+ BLI_addtail(fd->mainlist, newmain);
+
return;
}
}
}
+
/* make sure we have full path in lib->filepath */
BLI_strncpy(lib->filepath, lib->name, sizeof(lib->name));
BLI_cleanup_path(fd->relabase, lib->filepath);
@@ -10481,7 +10472,6 @@ static void link_object_postprocess(ID *id, Scene *scene, ViewLayer *view_layer,
SceneCollection *sc;
ob = (Object *)id;
- ob->mode = OB_MODE_OBJECT;
sc = get_scene_collection_active_or_create(scene, view_layer, flag);
BKE_collection_object_add(&scene->id, sc, ob);
@@ -10524,8 +10514,6 @@ void BLO_library_link_copypaste(Main *mainl, BlendHandle *bh)
if (bhead->code == ID_OB) {
/* Instead of instancing Base's directly, postpone until after groups are loaded
* otherwise the base's flag is set incorrectly when groups are used */
- Object *ob = (Object *)id;
- ob->mode = OB_MODE_OBJECT;
/* ensure give_base_to_objects runs on this object */
BLI_assert(id->us == 0);
}
@@ -10822,6 +10810,7 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
Main *mainl = mainlist->first;
Main *mainptr;
ListBase *lbarray[MAX_LIBARRAY];
+ GHash *loaded_ids = BLI_ghash_str_new(__func__);
int a;
bool do_it = true;
@@ -10835,7 +10824,7 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
mainptr= mainl->next;
while (mainptr) {
if (mainvar_id_tag_any_check(mainptr, LIB_TAG_READ)) {
- // printf("found LIB_TAG_READ %s\n", mainptr->curlib->name);
+ // printf("found LIB_TAG_READ %s (%s)\n", mainptr->curlib->id.name, mainptr->curlib->name);
FileData *fd = mainptr->curlib->filedata;
@@ -10933,25 +10922,38 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
a = set_listbasepointers(mainptr, lbarray);
while (a--) {
ID *id = lbarray[a]->first;
+ ListBase pending_free_ids = {NULL};
while (id) {
ID *idn = id->next;
if (id->tag & LIB_TAG_READ) {
- ID *realid = NULL;
BLI_remlink(lbarray[a], id);
- link_id_part(basefd->reports, fd, mainptr, id, &realid);
+ /* When playing with lib renaming and such, you may end with cases where you have
+ * more than one linked ID of the same data-block from same library.
+ * This is absolutely horrible, hence we use a ghash to ensure we go back to a single
+ * linked data when loading the file... */
+ ID **realid = NULL;
+ if (!BLI_ghash_ensure_p(loaded_ids, id->name, (void ***)&realid)) {
+ link_id_part(basefd->reports, fd, mainptr, id, realid);
+ }
/* realid shall never be NULL - unless some source file/lib is broken
* (known case: some directly linked shapekey from a missing lib...). */
- /* BLI_assert(realid != NULL); */
+ /* BLI_assert(*realid != NULL); */
- change_idid_adr(mainlist, basefd, id, realid);
+ change_idid_adr(mainlist, basefd, id, *realid);
- MEM_freeN(id);
+ /* We cannot free old lib-ref placeholder ID here anymore, since we use its name
+ * as key in loaded_ids hass. */
+ BLI_addtail(&pending_free_ids, id);
}
id = idn;
}
+
+ /* Clear GHash and free all lib-ref placeholders IDs of that type now. */
+ BLI_ghash_clear(loaded_ids, NULL, NULL);
+ BLI_freelistN(&pending_free_ids);
}
BLO_expand_main(fd, mainptr);
}
@@ -10959,7 +10961,10 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
mainptr = mainptr->next;
}
}
-
+
+ BLI_ghash_free(loaded_ids, NULL, NULL);
+ loaded_ids = NULL;
+
/* test if there are unread libblocks */
/* XXX This code block is kept for 2.77, until we are sure it never gets reached anymore. Can be removed later. */
for (mainptr = mainl->next; mainptr; mainptr = mainptr->next) {
diff --git a/source/blender/blenloader/intern/versioning_250.c b/source/blender/blenloader/intern/versioning_250.c
index 7036470c8e4..59dc6e9d6b7 100644
--- a/source/blender/blenloader/intern/versioning_250.c
+++ b/source/blender/blenloader/intern/versioning_250.c
@@ -52,7 +52,7 @@
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_node_types.h"
-#include "DNA_object_fluidsim.h" // NT
+#include "DNA_object_fluidsim_types.h"
#include "DNA_object_types.h"
#include "DNA_view3d_types.h"
#include "DNA_screen_types.h"
@@ -1087,8 +1087,6 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
if (main->versionfile < 250 || (main->versionfile == 250 && main->subversionfile < 2)) {
Scene *sce;
- Object *ob;
-
for (sce = main->scene.first; sce; sce = sce->id.next) {
if (fd->fileflags & G_FILE_ENABLE_ALL_FRAMES)
sce->gm.flag |= GAME_ENABLE_ALL_FRAMES;
@@ -1120,11 +1118,6 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
else
sce->gm.matmode = GAME_MAT_TEXFACE;
}
-
- for (ob = main->object.first; ob; ob = ob->id.next) {
- if (ob->flag & 8192) // OB_POSEMODE = 8192
- ob->mode |= OB_MODE_POSE;
- }
}
if (main->versionfile < 250 || (main->versionfile == 250 && main->subversionfile < 4)) {
diff --git a/source/blender/blenloader/intern/versioning_260.c b/source/blender/blenloader/intern/versioning_260.c
index 3ac934f7de7..f7301fe4664 100644
--- a/source/blender/blenloader/intern/versioning_260.c
+++ b/source/blender/blenloader/intern/versioning_260.c
@@ -41,7 +41,7 @@
#include "DNA_linestyle_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
-#include "DNA_object_fluidsim.h" // NT
+#include "DNA_object_fluidsim_types.h"
#include "DNA_object_types.h"
#include "DNA_property_types.h"
#include "DNA_text_types.h"
diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c
index 0800437c3d2..044c47847be 100644
--- a/source/blender/blenloader/intern/versioning_270.c
+++ b/source/blender/blenloader/intern/versioning_270.c
@@ -45,7 +45,7 @@
#include "DNA_sequence_types.h"
#include "DNA_space_types.h"
#include "DNA_screen_types.h"
-#include "DNA_object_force.h"
+#include "DNA_object_force_types.h"
#include "DNA_object_types.h"
#include "DNA_mask_types.h"
#include "DNA_mesh_types.h"
diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c
index aef1621c93f..224bfc6aefb 100644
--- a/source/blender/blenloader/intern/versioning_280.c
+++ b/source/blender/blenloader/intern/versioning_280.c
@@ -558,6 +558,18 @@ void do_versions_after_linking_280(Main *main)
}
}
+ if (!MAIN_VERSION_ATLEAST(main, 280, 3)) {
+ /* Due to several changes to particle RNA and draw code particles from older files may no longer
+ * be visible. Here we correct this by setting a default draw size for those files. */
+ for (Object *object = main->object.first; object; object = object->id.next) {
+ for (ParticleSystem *psys = object->particlesystem.first; psys; psys=psys->next) {
+ if(psys->part->draw_size == 0.0f) {
+ psys->part->draw_size = 0.1f;
+ }
+ }
+ }
+ }
+
{
for (WorkSpace *workspace = main->workspaces.first; workspace; workspace = workspace->id.next) {
if (workspace->view_layer) {
@@ -623,7 +635,7 @@ void do_versions_after_linking_280(Main *main)
#endif
if (object->particlesystem.first) {
object->duplicator_visibility_flag = OB_DUPLI_FLAG_VIEWPORT;
- for (ParticleSystem *psys = object->particlesystem.first; psys; psys=psys->next) {
+ for (ParticleSystem *psys = object->particlesystem.first; psys; psys = psys->next) {
if (psys->part->draw & PART_DRAW_EMITTER) {
object->duplicator_visibility_flag |= OB_DUPLI_FLAG_RENDER;
#ifndef VERSION_280_SUBVERSION_4
@@ -713,6 +725,10 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
}
+
+ for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
+ scene->r.gauss = 1.5f;
+ }
}
if (!MAIN_VERSION_ATLEAST(main, 280, 1)) {
@@ -910,11 +926,11 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main)
SpaceOops *so = (SpaceOops *)sl;
if (!ELEM(so->outlinevis,
- SO_SCENES,
- SO_GROUPS,
- SO_LIBRARIES,
- SO_SEQUENCE,
- SO_DATABLOCKS,
+ SO_SCENES,
+ SO_GROUPS,
+ SO_LIBRARIES,
+ SO_SEQUENCE,
+ SO_DATABLOCKS,
SO_ID_ORPHANS,
SO_VIEW_LAYER,
SO_COLLECTIONS))
diff --git a/source/blender/blenloader/intern/versioning_legacy.c b/source/blender/blenloader/intern/versioning_legacy.c
index 0af1c3951ad..fa2287ff6da 100644
--- a/source/blender/blenloader/intern/versioning_legacy.c
+++ b/source/blender/blenloader/intern/versioning_legacy.c
@@ -58,7 +58,7 @@
#include "DNA_meshdata_types.h"
#include "DNA_nla_types.h"
#include "DNA_node_types.h"
-#include "DNA_object_fluidsim.h" // NT
+#include "DNA_object_fluidsim_types.h"
#include "DNA_object_types.h"
#include "DNA_property_types.h"
#include "DNA_view3d_types.h"
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index c5690376305..f3b6b157413 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -132,7 +132,7 @@
#include "DNA_material_types.h"
#include "DNA_node_types.h"
#include "DNA_object_types.h"
-#include "DNA_object_force.h"
+#include "DNA_object_force_types.h"
#include "DNA_packedFile_types.h"
#include "DNA_particle_types.h"
#include "DNA_lightprobe_types.h"
@@ -1176,7 +1176,7 @@ static void write_renderinfo(WriteData *wd, Main *mainvar)
}
}
-static void write_keymapitem(WriteData *wd, wmKeyMapItem *kmi)
+static void write_keymapitem(WriteData *wd, const wmKeyMapItem *kmi)
{
writestruct(wd, DATA, wmKeyMapItem, 1, kmi);
if (kmi->properties) {
@@ -1184,26 +1184,18 @@ static void write_keymapitem(WriteData *wd, wmKeyMapItem *kmi)
}
}
-static void write_userdef(WriteData *wd)
+static void write_userdef(WriteData *wd, const UserDef *userdef)
{
- bTheme *btheme;
- wmKeyMap *keymap;
- wmKeyMapItem *kmi;
- wmKeyMapDiffItem *kmdi;
- bAddon *bext;
- bPathCompare *path_cmp;
- uiStyle *style;
+ writestruct(wd, USER, UserDef, 1, userdef);
- writestruct(wd, USER, UserDef, 1, &U);
-
- for (btheme = U.themes.first; btheme; btheme = btheme->next) {
+ for (const bTheme *btheme = userdef->themes.first; btheme; btheme = btheme->next) {
writestruct(wd, DATA, bTheme, 1, btheme);
}
- for (keymap = U.user_keymaps.first; keymap; keymap = keymap->next) {
+ for (const wmKeyMap *keymap = userdef->user_keymaps.first; keymap; keymap = keymap->next) {
writestruct(wd, DATA, wmKeyMap, 1, keymap);
- for (kmdi = keymap->diff_items.first; kmdi; kmdi = kmdi->next) {
+ for (const wmKeyMapDiffItem *kmdi = keymap->diff_items.first; kmdi; kmdi = kmdi->next) {
writestruct(wd, DATA, wmKeyMapDiffItem, 1, kmdi);
if (kmdi->remove_item) {
write_keymapitem(wd, kmdi->remove_item);
@@ -1213,23 +1205,23 @@ static void write_userdef(WriteData *wd)
}
}
- for (kmi = keymap->items.first; kmi; kmi = kmi->next) {
+ for (const wmKeyMapItem *kmi = keymap->items.first; kmi; kmi = kmi->next) {
write_keymapitem(wd, kmi);
}
}
- for (bext = U.addons.first; bext; bext = bext->next) {
+ for (const bAddon *bext = userdef->addons.first; bext; bext = bext->next) {
writestruct(wd, DATA, bAddon, 1, bext);
if (bext->prop) {
IDP_WriteProperty(bext->prop, wd);
}
}
- for (path_cmp = U.autoexec_paths.first; path_cmp; path_cmp = path_cmp->next) {
+ for (const bPathCompare *path_cmp = userdef->autoexec_paths.first; path_cmp; path_cmp = path_cmp->next) {
writestruct(wd, DATA, bPathCompare, 1, path_cmp);
}
- for (style = U.uistyles.first; style; style = style->next) {
+ for (const uiStyle *style = userdef->uistyles.first; style; style = style->next) {
writestruct(wd, DATA, uiStyle, 1, style);
}
}
@@ -1345,6 +1337,9 @@ static void write_particlesettings(WriteData *wd, ParticleSettings *part)
if (part->roughcurve) {
write_curvemapping(wd, part->roughcurve);
}
+ if (part->twistcurve) {
+ write_curvemapping(wd, part->twistcurve);
+ }
for (ParticleDupliWeight *dw = part->dupliweights.first; dw; dw = dw->next) {
/* update indices, but only if dw->ob is set (can be NULL after loading e.g.) */
@@ -2912,7 +2907,7 @@ static void write_soops(WriteData *wd, SpaceOops *so)
if (ts) {
SpaceOops so_flat = *so;
- int elems = BLI_mempool_count(ts);
+ int elems = BLI_mempool_len(ts);
/* linearize mempool to array */
TreeStoreElem *data = elems ? BLI_mempool_as_arrayN(ts, "TreeStoreElem") : NULL;
@@ -4134,7 +4129,7 @@ static bool write_file_handle(
mywrite_flush(wd);
if (write_flags & G_FILE_USERPREFS) {
- write_userdef(wd);
+ write_userdef(wd, &U);
}
/* Write DNA last, because (to be implemented) test for which structs are written.
diff --git a/source/blender/blentranslation/msgfmt/msgfmt.c b/source/blender/blentranslation/msgfmt/msgfmt.c
index 49f850f200c..a155cce53a5 100644
--- a/source/blender/blentranslation/msgfmt/msgfmt.c
+++ b/source/blender/blentranslation/msgfmt/msgfmt.c
@@ -186,7 +186,7 @@ typedef struct Offset {
/* Return the generated binary output. */
static char *generate(GHash *messages, size_t *r_output_size)
{
- const uint32_t num_keys = BLI_ghash_size(messages);
+ const uint32_t num_keys = BLI_ghash_len(messages);
/* Get list of sorted keys. */
char **keys = get_keys_sorted(messages, num_keys);
diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c
index 36b2f9cadf7..aba0160622f 100644
--- a/source/blender/bmesh/intern/bmesh_core.c
+++ b/source/blender/bmesh/intern/bmesh_core.c
@@ -2423,9 +2423,10 @@ static void bmesh_kernel_vert_separate__cleanup(BMesh *bm, LinkNode *edges_separ
/* don't visit again */
n_prev->next = n_step->next;
}
- } while ((void)
- (n_prev = n_step),
- (n_step = n_step->next));
+ else {
+ n_prev = n_step;
+ }
+ } while ((n_step = n_step->next));
} while ((n_orig = n_orig->next) && n_orig->next);
} while ((edges_separate = edges_separate->next));
diff --git a/source/blender/bmesh/intern/bmesh_iterators.c b/source/blender/bmesh/intern/bmesh_iterators.c
index 96154f051f9..9fe28561b93 100644
--- a/source/blender/bmesh/intern/bmesh_iterators.c
+++ b/source/blender/bmesh/intern/bmesh_iterators.c
@@ -430,7 +430,7 @@ int BM_iter_mesh_count_flag(const char itype, BMesh *bm, const char hflag, const
void bmiter__elem_of_mesh_begin(struct BMIter__elem_of_mesh *iter)
{
#ifdef USE_IMMUTABLE_ASSERT
- ((BMIter *)iter)->count = BLI_mempool_count(iter->pooliter.pool);
+ ((BMIter *)iter)->count = BLI_mempool_len(iter->pooliter.pool);
#endif
BLI_mempool_iternew(iter->pooliter.pool, &iter->pooliter);
}
@@ -438,7 +438,7 @@ void bmiter__elem_of_mesh_begin(struct BMIter__elem_of_mesh *iter)
void *bmiter__elem_of_mesh_step(struct BMIter__elem_of_mesh *iter)
{
#ifdef USE_IMMUTABLE_ASSERT
- BLI_assert(((BMIter *)iter)->count <= BLI_mempool_count(iter->pooliter.pool));
+ BLI_assert(((BMIter *)iter)->count <= BLI_mempool_len(iter->pooliter.pool));
#endif
return BLI_mempool_iterstep(&iter->pooliter);
}
diff --git a/source/blender/bmesh/intern/bmesh_log.c b/source/blender/bmesh/intern/bmesh_log.c
index 1d16dbc1836..5ae72851c7e 100644
--- a/source/blender/bmesh/intern/bmesh_log.c
+++ b/source/blender/bmesh/intern/bmesh_log.c
@@ -990,11 +990,11 @@ void BM_log_all_added(BMesh *bm, BMLog *log)
BMFace *f;
/* avoid unnecessary resizing on initialization */
- if (BLI_ghash_size(log->current_entry->added_verts) == 0) {
+ if (BLI_ghash_len(log->current_entry->added_verts) == 0) {
BLI_ghash_reserve(log->current_entry->added_verts, (uint)bm->totvert);
}
- if (BLI_ghash_size(log->current_entry->added_faces) == 0) {
+ if (BLI_ghash_len(log->current_entry->added_faces) == 0) {
BLI_ghash_reserve(log->current_entry->added_faces, (uint)bm->totface);
}
diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c
index 67db51446df..8533083af22 100644
--- a/source/blender/bmesh/intern/bmesh_mesh.c
+++ b/source/blender/bmesh/intern/bmesh_mesh.c
@@ -1019,7 +1019,8 @@ void BM_loops_calc_normal_vcos(
}
}
-static void UNUSED_FUNCTION(bm_mdisps_space_set)(Object *ob, BMesh *bm, int from, int to)
+static void UNUSED_FUNCTION(bm_mdisps_space_set)(
+ Object *ob, BMesh *bm, int from, int to, eObjectMode object_mode)
{
/* switch multires data out of tangent space */
if (CustomData_has_layer(&bm->ldata, CD_MDISPS)) {
@@ -1030,7 +1031,7 @@ static void UNUSED_FUNCTION(bm_mdisps_space_set)(Object *ob, BMesh *bm, int from
BMIter iter;
// int i = 0; // UNUSED
- multires_set_space(dm, ob, from, to);
+ multires_set_space(dm, ob, from, to, object_mode);
mdisps = CustomData_get_layer(&dm->loopData, CD_MDISPS);
diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.c b/source/blender/bmesh/intern/bmesh_mesh_conv.c
index 6cc1f37db43..fd32119cb5f 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_conv.c
+++ b/source/blender/bmesh/intern/bmesh_mesh_conv.c
@@ -708,7 +708,7 @@ void BM_mesh_bm_to_me(
}
/* patch hook indices and vertex parents */
- if (ototvert > 0) {
+ if (params->calc_object_remap && (ototvert > 0)) {
Object *ob;
ModifierData *md;
BMVert **vertMap = NULL;
@@ -765,11 +765,7 @@ void BM_mesh_bm_to_me(
if (vertMap) MEM_freeN(vertMap);
}
- if (params->calc_tessface) {
- BKE_mesh_tessface_calc(me);
- }
-
- BKE_mesh_update_customdata_pointers(me, params->calc_tessface);
+ BKE_mesh_update_customdata_pointers(me, false);
{
BMEditSelection *selected;
diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.h b/source/blender/bmesh/intern/bmesh_mesh_conv.h
index 1974d364171..6e9d62349ea 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_conv.h
+++ b/source/blender/bmesh/intern/bmesh_mesh_conv.h
@@ -55,7 +55,8 @@ void BM_mesh_bm_from_me(
ATTR_NONNULL(1, 3);
struct BMeshToMeshParams {
- uint calc_tessface : 1;
+ /** Update object hook indices & vertex parents. */
+ uint calc_object_remap : 1;
int64_t cd_mask_extra;
};
void BM_mesh_bm_to_me(
diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c
index 8e0e905cf88..4847ae4be42 100644
--- a/source/blender/bmesh/intern/bmesh_opdefines.c
+++ b/source/blender/bmesh/intern/bmesh_opdefines.c
@@ -843,7 +843,6 @@ static BMOpDefine bmo_bmesh_to_mesh_def = {
{"mesh", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_MESH}},
/* pointer to an object structure */
{"object", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_OBJECT}},
- {"skip_tessface", BMO_OP_SLOT_BOOL}, /* don't calculate mfaces */
{{'\0'}},
},
{{{'\0'}}}, /* no output */
diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c
index 0f672a9ff2a..f814767a200 100644
--- a/source/blender/bmesh/intern/bmesh_operators.c
+++ b/source/blender/bmesh/intern/bmesh_operators.c
@@ -673,7 +673,7 @@ int BMO_slot_map_count(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_na
{
BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
BLI_assert(slot->slot_type == BMO_OP_SLOT_MAPPING);
- return BLI_ghash_size(slot->data.ghash);
+ return BLI_ghash_len(slot->data.ghash);
}
/* inserts a key/value mapping into a mapping slot. note that it copies the
diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c
index 66fcd739839..bcb940f8b96 100644
--- a/source/blender/bmesh/intern/bmesh_polygon.c
+++ b/source/blender/bmesh/intern/bmesh_polygon.c
@@ -36,8 +36,8 @@
#include "BLI_alloca.h"
#include "BLI_math.h"
#include "BLI_memarena.h"
-#include "BLI_polyfill2d.h"
-#include "BLI_polyfill2d_beautify.h"
+#include "BLI_polyfill_2d.h"
+#include "BLI_polyfill_2d_beautify.h"
#include "BLI_linklist.h"
#include "BLI_edgehash.h"
#include "BLI_heap.h"
@@ -1426,6 +1426,17 @@ void BM_mesh_calc_tessellation(BMesh *bm, BMLoop *(*looptris)[3], int *r_looptri
(l_ptr_a[2] = l_ptr_b[1] = l = l->next);
( l_ptr_b[2] = l->next);
#endif
+
+ if (UNLIKELY(is_quad_flip_v3_first_third_fast(
+ l_ptr_a[0]->v->co,
+ l_ptr_a[1]->v->co,
+ l_ptr_a[2]->v->co,
+ l_ptr_b[2]->v->co)))
+ {
+ /* flip out of degenerate 0-2 state. */
+ l_ptr_a[2] = l_ptr_b[2];
+ l_ptr_b[0] = l_ptr_a[1];
+ }
}
#endif /* USE_TESSFACE_SPEEDUP */
diff --git a/source/blender/bmesh/operators/bmo_connect_concave.c b/source/blender/bmesh/operators/bmo_connect_concave.c
index 80774323d31..d1811ac6a83 100644
--- a/source/blender/bmesh/operators/bmo_connect_concave.c
+++ b/source/blender/bmesh/operators/bmo_connect_concave.c
@@ -39,8 +39,8 @@
#include "BLI_alloca.h"
#include "BLI_memarena.h"
#include "BLI_heap.h"
-#include "BLI_polyfill2d.h"
-#include "BLI_polyfill2d_beautify.h"
+#include "BLI_polyfill_2d.h"
+#include "BLI_polyfill_2d_beautify.h"
#include "BLI_linklist.h"
#include "bmesh.h"
diff --git a/source/blender/bmesh/operators/bmo_connect_pair.c b/source/blender/bmesh/operators/bmo_connect_pair.c
index 60fd9808fcb..b9e5cd927c3 100644
--- a/source/blender/bmesh/operators/bmo_connect_pair.c
+++ b/source/blender/bmesh/operators/bmo_connect_pair.c
@@ -662,11 +662,11 @@ void bmo_connect_vert_pair_exec(BMesh *bm, BMOperator *op)
while (!BLI_heap_is_empty(pc.states)) {
#ifdef DEBUG_PRINT
- printf("\n%s: stepping %u\n", __func__, BLI_heap_size(pc.states));
+ printf("\n%s: stepping %u\n", __func__, BLI_heap_len(pc.states));
#endif
while (!BLI_heap_is_empty(pc.states)) {
- PathLinkState *state = BLI_heap_popmin(pc.states);
+ PathLinkState *state = BLI_heap_pop_min(pc.states);
/* either we insert this into 'pc.states' or its freed */
bool continue_search;
diff --git a/source/blender/bmesh/operators/bmo_dissolve.c b/source/blender/bmesh/operators/bmo_dissolve.c
index 2df8e73c2b8..5a2f07be70a 100644
--- a/source/blender/bmesh/operators/bmo_dissolve.c
+++ b/source/blender/bmesh/operators/bmo_dissolve.c
@@ -166,7 +166,7 @@ void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op)
continue;
}
- BLI_array_empty(faces);
+ BLI_array_clear(faces);
faces = NULL; /* forces different allocatio */
BMW_init(&regwalker, bm, BMW_ISLAND_MANIFOLD,
diff --git a/source/blender/bmesh/operators/bmo_edgenet.c b/source/blender/bmesh/operators/bmo_edgenet.c
index 64b092da5c8..744ef866128 100644
--- a/source/blender/bmesh/operators/bmo_edgenet.c
+++ b/source/blender/bmesh/operators/bmo_edgenet.c
@@ -186,7 +186,7 @@ void bmo_edgenet_prepare_exec(BMesh *bm, BMOperator *op)
BLI_array_count_set(edges2, BLI_array_count(edges));
}
- BLI_array_empty(edges);
+ BLI_array_clear(edges);
count++;
}
diff --git a/source/blender/bmesh/operators/bmo_hull.c b/source/blender/bmesh/operators/bmo_hull.c
index 81ec2860cf7..d52cb00e172 100644
--- a/source/blender/bmesh/operators/bmo_hull.c
+++ b/source/blender/bmesh/operators/bmo_hull.c
@@ -521,7 +521,7 @@ static void hull_from_bullet(
int j;
/* Get face vertex indices */
- BLI_array_empty(fvi);
+ BLI_array_clear(fvi);
BLI_array_grow_items(fvi, len);
plConvexHullGetFaceVertices(hull, i, fvi);
diff --git a/source/blender/bmesh/operators/bmo_mesh_conv.c b/source/blender/bmesh/operators/bmo_mesh_conv.c
index 0eb9bf90ca8..7311ed5ce64 100644
--- a/source/blender/bmesh/operators/bmo_mesh_conv.c
+++ b/source/blender/bmesh/operators/bmo_mesh_conv.c
@@ -62,15 +62,18 @@ void bmo_object_load_bmesh_exec(BMesh *bm, BMOperator *op)
Mesh *me = ob->data;
BMO_op_callf(bm, op->flag,
- "bmesh_to_mesh mesh=%p object=%p skip_tessface=%b",
- me, ob, true);
+ "bmesh_to_mesh mesh=%p object=%p",
+ me, ob);
}
void bmo_bmesh_to_mesh_exec(BMesh *bm, BMOperator *op)
{
Mesh *me = BMO_slot_ptr_get(op->slots_in, "mesh");
/* Object *ob = BMO_slot_ptr_get(op, "object"); */
- const bool dotess = !BMO_slot_bool_get(op->slots_in, "skip_tessface");
- BM_mesh_bm_to_me(bm, me, (&(struct BMeshToMeshParams){ .calc_tessface = dotess, }));
+ BM_mesh_bm_to_me(
+ bm, me,
+ (&(struct BMeshToMeshParams){
+ .calc_object_remap = true,
+ }));
}
diff --git a/source/blender/bmesh/operators/bmo_rotate_edges.c b/source/blender/bmesh/operators/bmo_rotate_edges.c
index 9832fdb57d3..75e31c68dae 100644
--- a/source/blender/bmesh/operators/bmo_rotate_edges.c
+++ b/source/blender/bmesh/operators/bmo_rotate_edges.c
@@ -180,7 +180,7 @@ static void bm_rotate_edges_shared(
const int edges_len_rotate_prev = edges_len_rotate;
while (!BLI_heap_is_empty(heap)) {
- BMEdge *e_best = BLI_heap_popmin(heap);
+ BMEdge *e_best = BLI_heap_pop_min(heap);
eheap_table[BM_elem_index_get(e_best)] = NULL;
/* No problem if this fails, re-evaluate if faces connected to this edge are touched. */
diff --git a/source/blender/bmesh/operators/bmo_subdivide.c b/source/blender/bmesh/operators/bmo_subdivide.c
index 894129b4a33..7d3419b5910 100644
--- a/source/blender/bmesh/operators/bmo_subdivide.c
+++ b/source/blender/bmesh/operators/bmo_subdivide.c
@@ -1011,8 +1011,8 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
/* figure out which pattern to use */
- BLI_array_empty(edges);
- BLI_array_empty(verts);
+ BLI_array_clear(edges);
+ BLI_array_clear(verts);
BLI_array_grow_items(edges, face->len);
BLI_array_grow_items(verts, face->len);
@@ -1140,7 +1140,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
face = fd->face;
/* figure out which pattern to use */
- BLI_array_empty(verts);
+ BLI_array_clear(verts);
pat = fd->pat;
@@ -1148,8 +1148,8 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
int vlen;
/* ok, no pattern. we still may be able to do something */
- BLI_array_empty(loops);
- BLI_array_empty(loops_split);
+ BLI_array_clear(loops);
+ BLI_array_clear(loops_split);
/* for case of two edges, connecting them shouldn't be too hard */
BLI_array_grow_items(loops, face->len);
diff --git a/source/blender/bmesh/operators/bmo_subdivide_edgering.c b/source/blender/bmesh/operators/bmo_subdivide_edgering.c
index adcc0c71629..e6881f6d8b1 100644
--- a/source/blender/bmesh/operators/bmo_subdivide_edgering.c
+++ b/source/blender/bmesh/operators/bmo_subdivide_edgering.c
@@ -269,7 +269,7 @@ static GSet *bm_edgering_pair_calc(BMesh *bm, ListBase *eloops_rim)
BLI_ghash_free(vert_eloop_gh, NULL, NULL);
- if (BLI_gset_size(eloop_pair_gs) == 0) {
+ if (BLI_gset_len(eloop_pair_gs) == 0) {
BLI_gset_free(eloop_pair_gs, NULL);
eloop_pair_gs = NULL;
}
@@ -1193,7 +1193,7 @@ void bmo_subdivide_edgering_exec(BMesh *bm, BMOperator *op)
goto cleanup;
}
- lpair_arr = BLI_array_alloca(lpair_arr, BLI_gset_size(eloop_pairs_gs));
+ lpair_arr = BLI_array_alloca(lpair_arr, BLI_gset_len(eloop_pairs_gs));
/* first cache pairs */
GSET_ITER_INDEX (gs_iter, eloop_pairs_gs, i) {
diff --git a/source/blender/bmesh/operators/bmo_triangulate.c b/source/blender/bmesh/operators/bmo_triangulate.c
index 4e8bace59e0..2cdc2646649 100644
--- a/source/blender/bmesh/operators/bmo_triangulate.c
+++ b/source/blender/bmesh/operators/bmo_triangulate.c
@@ -106,7 +106,7 @@ void bmo_triangle_fill_exec(BMesh *bm, BMOperator *op)
/* sf_edge = */ BLI_scanfill_edge_add(&sf_ctx, UNPACK2(sf_verts));
/* sf_edge->tmp.p = e; */ /* UNUSED */
}
- nors_tot = BLI_ghash_size(sf_vert_map);
+ nors_tot = BLI_ghash_len(sf_vert_map);
BLI_ghash_free(sf_vert_map, NULL, NULL);
diff --git a/source/blender/bmesh/tools/bmesh_beautify.c b/source/blender/bmesh/tools/bmesh_beautify.c
index 6e6242fc9f9..d3972363bb4 100644
--- a/source/blender/bmesh/tools/bmesh_beautify.c
+++ b/source/blender/bmesh/tools/bmesh_beautify.c
@@ -37,7 +37,7 @@
#include "BLI_math.h"
#include "BLI_heap.h"
-#include "BLI_polyfill2d_beautify.h"
+#include "BLI_polyfill_2d_beautify.h"
#include "MEM_guardedalloc.h"
@@ -392,7 +392,7 @@ void BM_mesh_beautify_fill(
bm->elem_index_dirty |= BM_EDGE;
while (BLI_heap_is_empty(eheap) == false) {
- BMEdge *e = BLI_heap_popmin(eheap);
+ BMEdge *e = BLI_heap_pop_min(eheap);
i = BM_elem_index_get(e);
eheap_table[i] = NULL;
diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c
index 35167835646..beee9065ece 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.c
+++ b/source/blender/bmesh/tools/bmesh_bevel.c
@@ -1879,7 +1879,7 @@ static void build_boundary(BevelParams *bp, BevVert *bv, bool construct)
}
}
-#if 0
+#ifdef DEBUG_ADJUST
static void print_adjust_stats(BoundVert *vstart)
{
BoundVert *v;
@@ -1921,21 +1921,25 @@ static void print_adjust_stats(BoundVert *vstart)
if (v->adjchain != NULL) {
eright = v->efirst;
eleft = v->adjchain->elast;
- delta = fabs(eright->offset_r - eright->offset_r_spec);
+ delta = eright->offset_r - eright->offset_r_spec;
delta_pct = 100.0 * delta / eright->offset_r_spec;
- printf("e%d r(%f) vs r spec(%f): abs(delta)=%f, delta_pct=%f\n",
+ printf("e%d r(%f) vs r spec(%f): delta=%f, delta_pct=%f\n",
BM_elem_index_get(eright->e), eright->offset_r, eright->offset_r_spec, delta, delta_pct);
spec_residual2 += delta * delta;
+ delta = fabs(delta);
+ delta_pct = fabs(delta_pct);
if (delta > max_spec_r)
max_spec_r = delta;
if (delta_pct > max_spec_r_pct)
max_spec_r_pct = delta_pct;
- delta = fabs(eleft->offset_l - eleft->offset_l_spec);
+ delta = eleft->offset_l - eleft->offset_l_spec;
delta_pct = 100.0 * delta / eright->offset_l_spec;
- printf("e%d l(%f) vs l spec(%f): abs(delta)=%f, delta_pct=%f\n",
+ printf("e%d l(%f) vs l spec(%f): delta=%f, delta_pct=%f\n",
BM_elem_index_get(eright->e), eleft->offset_l, eleft->offset_l_spec, delta, delta_pct);
spec_residual2 += delta * delta;
+ delta = fabs(delta);
+ delta_pct = fabs(delta_pct);
if (delta > max_spec_r)
max_spec_r = delta;
if (delta_pct > max_spec_r_pct)
@@ -1951,6 +1955,15 @@ static void print_adjust_stats(BoundVert *vstart)
}
#endif
+#ifdef FAST_ADJUST_CODE
+/* This code uses a direct solution to the adjustment problem for chains and certain cycles.
+ * It is a two-step approach: first solve for the exact solution of the 'match widths' constraints
+ * using the one degree of freedom that allows for expressing all other widths in terms of that.
+ * And then minimize the spec-matching constraints using the derivative of the least squares
+ * residual in terms of that one degree of freedom.
+ * Unfortunately, the results are in some cases worse than the general least squares solution
+ * for the combined (with weights) problem, so this code is not used.
+ * But keep it here for a while in case peformance issues demand that it be used sometimes. */
static bool adjust_the_cycle_or_chain_fast(BoundVert *vstart, int np, bool iscycle)
{
BoundVert *v;
@@ -1985,6 +1998,7 @@ static bool adjust_the_cycle_or_chain_fast(BoundVert *vstart, int np, bool iscyc
g_prod[i] = gprod;
gprod_sum += gprod;
}
+ g_prod[0] = 1.0f;
if (iscycle) {
gprod *= g[0];
if (fabs(gprod - 1.0f) > BEVEL_EPSILON) {
@@ -1993,8 +2007,6 @@ static bool adjust_the_cycle_or_chain_fast(BoundVert *vstart, int np, bool iscyc
MEM_freeN(g_prod);
return false;
}
- else
- g_prod[0] = 1.0f;
}
if (gprod_sum == 0.0f) {
MEM_freeN(g);
@@ -2028,6 +2040,7 @@ static bool adjust_the_cycle_or_chain_fast(BoundVert *vstart, int np, bool iscyc
MEM_freeN(g_prod);
return true;
}
+#endif
/* Adjust the offsets for a single cycle or chain.
* For chains and some cycles, a fast solution exists.
@@ -2039,22 +2052,35 @@ static bool adjust_the_cycle_or_chain_fast(BoundVert *vstart, int np, bool iscyc
static void adjust_the_cycle_or_chain(BoundVert *vstart, bool iscycle)
{
BoundVert *v;
- EdgeHalf *eleft, *eright;
+ EdgeHalf *eleft, *eright, *enextleft;
LinearSolver *solver;
double weight, val;
int i, np, nrows, row;
np = 0;
+#ifdef DEBUG_ADJUST
+ printf("\nadjust the %s (with eigen)\n", iscycle ? "cycle" : "chain");
+#endif
v = vstart;
do {
+#ifdef DEBUG_ADJUST
+ eleft = v->elast;
+ eright = v->efirst;
+ printf(" (left=e%d, right=e%d)", BM_elem_index_get(eleft->e), BM_elem_index_get(eright->e));
+#endif
np++;
v = v->adjchain;
} while (v && v != vstart);
+#ifdef DEBUG_ADJUST
+ printf(" -> %d parms\n", np);
+#endif
+#ifdef FAST_ADJUST_CODE
if (adjust_the_cycle_or_chain_fast(vstart, np, iscycle))
return;
+#endif
- nrows = iscycle ? 2 * np : 2 * np - 1;
+ nrows = iscycle ? 3 * np : 3 * np - 3;
solver = EIG_linear_least_squares_solver_new(nrows, np, 1);
@@ -2063,9 +2089,15 @@ static void adjust_the_cycle_or_chain(BoundVert *vstart, bool iscycle)
weight = BEVEL_MATCH_SPEC_WEIGHT; /* sqrt of factor to weight down importance of spec match */
do {
/* except at end of chain, v's indep variable is offset_r of v->efirst */
- if (iscycle || v->adjchain != NULL) {
+ if (iscycle || i < np - 1) {
eright = v->efirst;
eleft = v->elast;
+ enextleft = v->adjchain->elast;
+#ifdef DEBUG_ADJUST
+ printf("p%d: e%d->offset_r = %f\n", i, BM_elem_index_get(eright->e), eright->offset_r);
+ if (iscycle || v != vstart)
+ printf(" dependent: e%d->offset_l = %f * p%d\n", BM_elem_index_get(eleft->e), v->sinratio, i);
+#endif
/* residue i: width difference between eright and eleft of next */
EIG_linear_solver_matrix_add(solver, i, i, 1.0);
@@ -2074,53 +2106,87 @@ static void adjust_the_cycle_or_chain(BoundVert *vstart, bool iscycle)
EIG_linear_solver_matrix_add(solver, i > 0 ? i - 1 : np - 1, i, -v->sinratio);
}
else {
- if (i > 0)
+ if (i > 0) {
EIG_linear_solver_matrix_add(solver, i - 1, i, -v->sinratio);
+ }
}
- /* residue np + i (if cycle) else np - 1 + i:
+ /* residue np + 2*i (if cycle) else np - 1 + 2*i:
* right offset for parm i matches its spec; weighted */
- row = iscycle ? np + i : np - 1 + i;
+ row = iscycle ? np + 2 * i : np - 1 + 2 * i;
EIG_linear_solver_matrix_add(solver, row, i, weight);
EIG_linear_solver_right_hand_side_add(solver, 0, row, weight * eright->offset_r);
+#ifdef DEBUG_ADJUST
+ printf("b[%d]=%f * %f, for e%d->offset_r\n", row, weight, eright->offset_r, BM_elem_index_get(eright->e));
+#endif
+
+ /* residue np + 2*i + 1 (if cycle) else np - 1 + 2*i + 1:
+ * left offset for parm i matches its spec; weighted */
+ row = row + 1;
+ EIG_linear_solver_matrix_add(solver, row, (i == np - 1) ? 0 : i + 1, weight * v->adjchain->sinratio);
+ EIG_linear_solver_right_hand_side_add(solver, 0, row, weight * enextleft->offset_l);
+#ifdef DEBUG_ADJUST
+ printf("b[%d]=%f * %f, for e%d->offset_l\n", row, weight, enextleft->offset_l,
+ BM_elem_index_get(enextleft->e));
+#endif
}
else {
/* not a cycle, and last of chain */
eleft = v->elast;
+#ifdef DEBUG_ADJUST
+ printf("p%d: e%d->offset_l = %f\n", i, BM_elem_index_get(eleft->e), eleft->offset_l);
+#endif
/* second part of residue i for last i */
EIG_linear_solver_matrix_add(solver, i - 1, i, -1.0);
- /* residue 2 * np -2 : last spec match residue is for left offset of final parm */
- row = 2 * np - 2;
- EIG_linear_solver_matrix_add(solver, row, i, weight);
- EIG_linear_solver_right_hand_side_add(solver, 0, row, weight * eleft->offset_l);
}
i++;
v = v->adjchain;
} while (v && v != vstart);
EIG_linear_solver_solve(solver);
+#ifdef DEBUG_ADJUST
+ /* Note: this print only works after solve, but by that time b has been cleared */
+ EIG_linear_solver_print_matrix(solver);
+ printf("\nSolution:\n");
+ for (i = 0; i < np; i++)
+ printf("p%d = %f\n", i, EIG_linear_solver_variable_get(solver, 0, i));
+#endif
/* Use the solution to set new widths */
v = vstart;
i = 0;
do {
val = EIG_linear_solver_variable_get(solver, 0, i);
- if (iscycle || v->adjchain != NULL) {
+ if (iscycle || i < np - 1) {
eright = v->efirst;
eleft = v->elast;
eright->offset_r = (float)val;
+#ifdef DEBUG_ADJUST
+ printf("e%d->offset_r = %f\n", BM_elem_index_get(eright->e), eright->offset_r);
+#endif
if (iscycle || v != vstart) {
eleft->offset_l = (float)(v->sinratio * val);
+#ifdef DEBUG_ADJUST
+ printf("e%d->offset_l = %f\n", BM_elem_index_get(eleft->e), eleft->offset_l);
+#endif
}
}
else {
/* not a cycle, and last of chain */
eleft = v->elast;
eleft->offset_l = (float)val;
+#ifdef DEBUG_ADJUST
+ printf("e%d->offset_l = %f\n", BM_elem_index_get(eleft->e), eleft->offset_l);
+#endif
}
i++;
v = v->adjchain;
} while (v && v != vstart);
+#ifdef DEBUG_ADJUST
+ print_adjust_stats(vstart);
+ EIG_linear_solver_print_matrix(solver);
+#endif
+
EIG_linear_solver_delete(solver);
}
@@ -2163,7 +2229,7 @@ static void adjust_offsets(BevelParams *bp)
/* first follow paired edges in left->right direction */
v = vchainstart = vanchor;
iscycle = false;
- while(v->eon && !v->visited && !iscycle) {
+ while (v->eon && !v->visited && !iscycle) {
enext = find_other_end_edge_half(bp, v->efirst, &bvcur);
BLI_assert(enext != NULL);
vnext = enext->leftv;
@@ -2171,7 +2237,6 @@ static void adjust_offsets(BevelParams *bp)
v->visited = true;
if (vnext->visited) {
if (vnext != vchainstart) {
- printf("WHOOPS, adjusting offsets, expected cycle!\n");
break;
}
adjust_the_cycle_or_chain(vchainstart, true);
@@ -2191,7 +2256,7 @@ static void adjust_offsets(BevelParams *bp)
vchainstart = vnext;
v->visited = true;
v = vnext;
- } while(!v->visited && v->eon);
+ } while (!v->visited && v->eon);
adjust_the_cycle_or_chain(vchainstart, false);
}
} while ((vanchor = vanchor->next) != bv->vmesh->boundstart);
@@ -3188,6 +3253,173 @@ static void build_square_in_vmesh(BevelParams *bp, BMesh *bm, BevVert *bv, VMesh
}
}
+/* copy whichever of a and b is closer to v into r */
+static void closer_v3_v3v3v3(float r[3], float a[3], float b[3], float v[3])
+{
+ if (len_squared_v3v3(a, v) <= len_squared_v3v3(b, v))
+ copy_v3_v3(r, a);
+ else
+ copy_v3_v3(r, b);
+}
+
+/* Special case of VMesh when profile == 1 and there are 3 or more beveled edges.
+ * We want the effect of parallel offset lines (n/2 of them) on each side of the center, for even n.
+ * Wherever they intersect with each other between two successive beveled edges, those intersections
+ * are part of the vmesh rings.
+ * We have to move the boundary edges too -- the usual method is to make one profile plane between
+ * successive BoundVerts, but for the effect we want here, there will be two planes, one on each side
+ * of the original edge.
+ */
+static VMesh *square_out_adj_vmesh(BevelParams *bp, BevVert *bv)
+{
+ int n, ns, ns2, odd, i, j, k, ikind, im1, clstride;
+ float bndco[3], dir1[3], dir2[3], co1[3], co2[3], meet1[3], meet2[3], v1co[3], v2co[3];
+ float *on_edge_cur, *on_edge_prev, *p;
+ float ns2inv, finalfrac, ang;
+ BoundVert *bndv;
+ EdgeHalf *e1, *e2;
+ VMesh *vm;
+ float *centerline;
+
+ n = bv->vmesh->count;
+ ns = bv->vmesh->seg;
+ ns2 = ns / 2;
+ odd = ns % 2;
+ ns2inv = 1.0f / (float) ns2;
+ vm = new_adj_vmesh(bp->mem_arena, n, ns, bv->vmesh->boundstart);
+ clstride = 3 * (ns2 + 1);
+ centerline = MEM_mallocN(clstride * n * sizeof(float), "bevel");
+
+ /* find on_edge, place on bndv[i]'s elast where offset line would meet,
+ * averaging with position where next sector's offset line would meet */
+ bndv = vm->boundstart;
+ for (i = 0; i < n; i++) {
+ copy_v3_v3(bndco, bndv->nv.co);
+ e1 = bndv->efirst;
+ e2 = bndv->elast;
+ sub_v3_v3v3(dir1, e1->e->v1->co, e1->e->v2->co);
+ sub_v3_v3v3(dir2, e2->e->v1->co, e2->e->v2->co);
+ add_v3_v3v3(co1, bndco, dir1);
+ add_v3_v3v3(co2, bndco, dir2);
+ /* intersect e1 with line through bndv parallel to e2 to get v1co */
+ ikind = isect_line_line_v3(e1->e->v1->co, e1->e->v2->co, bndco, co2, meet1, meet2);
+
+ if (ikind == 0) {
+ /* Placeholder: this should get eliminated by min dist test with adjacent edge */
+ mid_v3_v3v3(v1co, e1->e->v1->co, e1->e->v2->co);
+ }
+ else {
+ /* if the lines are skew (ikind == 2), want meet1 which is on e1 */
+ copy_v3_v3(v1co, meet1);
+ }
+ /* intersect e2 with line through bndv parallel to e1 to get v2co */
+ ikind = isect_line_line_v3(e2->e->v1->co, e2->e->v2->co, bndco, co1, meet1, meet2);
+ if (ikind == 0) {
+ mid_v3_v3v3(v2co, e2->e->v1->co, e2->e->v2->co);
+ }
+ else {
+ copy_v3_v3(v2co, meet1);
+ }
+
+ /* want on_edge[i] to be min dist to bv->v of v2co and the v1co of next iteration */
+ on_edge_cur = centerline + clstride * i;
+ on_edge_prev = centerline + clstride * ((i == 0) ? n - 1 : i - 1);
+ if (i == 0) {
+ copy_v3_v3(on_edge_cur, v2co);
+ copy_v3_v3(on_edge_prev, v1co);
+ }
+ else if (i == n - 1) {
+ closer_v3_v3v3v3(on_edge_cur, on_edge_cur, v2co, bv->v->co);
+ closer_v3_v3v3v3(on_edge_prev, on_edge_prev, v1co, bv->v->co);
+ }
+ else {
+ copy_v3_v3(on_edge_cur, v2co);
+ closer_v3_v3v3v3(on_edge_prev, on_edge_prev, v1co, bv->v->co);
+ }
+ bndv = bndv->next;
+ }
+
+ /* fill in rest of centerlines by interpolation */
+ copy_v3_v3(co2, bv->v->co);
+ bndv = vm->boundstart;
+ for (i = 0; i < n; i++) {
+ if (odd) {
+ ang = 0.5f * angle_v3v3v3(bndv->nv.co, co1, bndv->next->nv.co);
+ if (ang > BEVEL_SMALL_ANG) {
+ /* finalfrac is length along arms of isoceles triangle with top angle 2*ang
+ * such that the base of the triangle is 1.
+ * This is used in interpolation along centerline in odd case.
+ * To avoid too big a drop from bv, cap finalfrac a 0.8 arbitrarily */
+ finalfrac = 0.5f / sin(ang);
+ if (finalfrac > 0.8f)
+ finalfrac = 0.8f;
+ }
+ else {
+ finalfrac = 0.8f;
+ }
+ ns2inv = 1.0f / (ns2 + finalfrac);
+ }
+
+ p = centerline + clstride * i;
+ copy_v3_v3(co1, p);
+ p += 3;
+ for (j = 1; j <= ns2; j++) {
+ interp_v3_v3v3(p, co1, co2, j * ns2inv);
+ p += 3;
+ }
+ bndv = bndv->next;
+ }
+
+ /* coords of edges and mid or near-mid line */
+ bndv = vm->boundstart;
+ for (i = 0; i < n; i++) {
+ copy_v3_v3(co1, bndv->nv.co);
+ copy_v3_v3(co2, centerline + clstride * (i == 0 ? n - 1 : i - 1));
+ for (j = 0; j < ns2 + odd; j++) {
+ interp_v3_v3v3(mesh_vert(vm, i, j, 0)->co, co1, co2, j * ns2inv);
+ }
+ copy_v3_v3(co2, centerline + clstride * i);
+ for (k = 1; k <= ns2; k++) {
+ interp_v3_v3v3(mesh_vert(vm, i, 0, k)->co, co1, co2, k * ns2inv);
+ }
+ bndv = bndv->next;
+ }
+ if (!odd)
+ copy_v3_v3(mesh_vert(vm, 0, ns2, ns2)->co, bv->v->co);
+ vmesh_copy_equiv_verts(vm);
+
+ /* fill in interior points by interpolation from edges to centerlines */
+ bndv = vm->boundstart;
+ for (i = 0; i < n; i++) {
+ im1 = (i == 0) ? n - 1 : i - 1;
+ for (j = 1; j < ns2 + odd; j++) {
+ for (k = 1; k <= ns2; k++) {
+ ikind = isect_line_line_v3(
+ mesh_vert(vm, i, 0, k)->co, centerline + clstride * im1 + 3 * k,
+ mesh_vert(vm, i, j, 0)->co, centerline + clstride * i + 3 * j,
+ meet1, meet2);
+ if (ikind == 0) {
+ /* how can this happen? fall back on interpolation in one direction if it does */
+ interp_v3_v3v3(mesh_vert(vm, i, j, k)->co,
+ mesh_vert(vm, i, 0, k)->co, centerline + clstride * im1 + 3 * k, j * ns2inv);
+ }
+ else if (ikind == 1) {
+ copy_v3_v3(mesh_vert(vm, i, j, k)->co, meet1);
+ }
+ else {
+ mid_v3_v3v3(mesh_vert(vm, i, j, k)->co, meet1, meet2);
+ }
+ }
+ }
+ bndv = bndv->next;
+ }
+
+ vmesh_copy_equiv_verts(vm);
+
+ MEM_freeN(centerline);
+ return vm;
+}
+
/*
* Given that the boundary is built and the boundary BMVerts have been made,
* calculate the positions of the interior mesh points for the M_ADJ pattern,
@@ -3210,9 +3442,13 @@ static void bevel_build_rings(BevelParams *bp, BMesh *bm, BevVert *bv)
odd = ns % 2;
BLI_assert(n >= 3 && ns > 1);
+
vpipe = pipe_test(bv);
- if (vpipe) {
+ if (bp->pro_super_r == PRO_SQUARE_R && bv->selcount >= 3 && !odd) {
+ vm1 = square_out_adj_vmesh(bp, bv);
+ }
+ else if (vpipe) {
vm1 = pipe_adj_vmesh(bp, bv, vpipe);
}
else if (tri_corner_test(bp, bv)) {
@@ -3737,7 +3973,7 @@ static int bevel_edge_order_extend(BMesh *bm, BevVert *bv, int i)
tryj = bevel_edge_order_extend(bm, bv, j + 1);
if (tryj > bestj || (tryj == bestj && edges_face_connected_at_vert(bv->edges[tryj].e, bv->edges[0].e))) {
bestj = tryj;
- BLI_array_empty(save_path);
+ BLI_array_clear(save_path);
for (k = j + 1; k <= bestj; k++) {
BLI_array_append(save_path, bv->edges[k].e);
}
diff --git a/source/blender/bmesh/tools/bmesh_decimate_collapse.c b/source/blender/bmesh/tools/bmesh_decimate_collapse.c
index 0a1271c2aa9..c1b2bc2625b 100644
--- a/source/blender/bmesh/tools/bmesh_decimate_collapse.c
+++ b/source/blender/bmesh/tools/bmesh_decimate_collapse.c
@@ -38,8 +38,8 @@
#include "BLI_alloca.h"
#include "BLI_memarena.h"
#include "BLI_edgehash.h"
-#include "BLI_polyfill2d.h"
-#include "BLI_polyfill2d_beautify.h"
+#include "BLI_polyfill_2d.h"
+#include "BLI_polyfill_2d_beautify.h"
#include "BLI_utildefines_stack.h"
@@ -1357,7 +1357,7 @@ void BM_mesh_decimate_collapse(
(BLI_heap_node_value(BLI_heap_top(eheap)) != COST_INVALID))
{
// const float value = BLI_heap_node_value(BLI_heap_top(eheap));
- BMEdge *e = BLI_heap_popmin(eheap);
+ BMEdge *e = BLI_heap_pop_min(eheap);
float optimize_co[3];
BLI_assert(BM_elem_index_get(e) < tot_edge_orig); /* handy to detect corruptions elsewhere */
@@ -1388,7 +1388,7 @@ void BM_mesh_decimate_collapse(
* - edges sharing a vertex are ignored, so the pivot vertex isnt moved to one side.
*/
- BMEdge *e = BLI_heap_popmin(eheap);
+ BMEdge *e = BLI_heap_pop_min(eheap);
const int e_index = BM_elem_index_get(e);
const int e_index_mirr = edge_symmetry_map[e_index];
BMEdge *e_mirr = NULL;
diff --git a/source/blender/bmesh/tools/bmesh_edgenet.c b/source/blender/bmesh/tools/bmesh_edgenet.c
index 193a032b46e..df9d07036af 100644
--- a/source/blender/bmesh/tools/bmesh_edgenet.c
+++ b/source/blender/bmesh/tools/bmesh_edgenet.c
@@ -335,7 +335,7 @@ static LinkNode *bm_edgenet_path_calc(
BLI_linklist_free_pool(v_ls_next, NULL, path_pool);
BLI_linklist_free_pool(v_ls_prev, NULL, path_pool);
- // BLI_assert(BLI_mempool_count(path_pool) == 0);
+ // BLI_assert(BLI_mempool_len(path_pool) == 0);
path_len = bm_edgenet_path_from_pass(e_found->v1, &path, vnet_info, path_pool);
BLI_linklist_reverse(&path);
@@ -505,7 +505,7 @@ void BM_mesh_edgenet(
}
BLI_linklist_free_pool(path, NULL, path_pool);
- BLI_assert(BLI_mempool_count(path_pool) == 0);
+ BLI_assert(BLI_mempool_len(path_pool) == 0);
}
bm->elem_index_dirty |= BM_FACE | BM_LOOP;
diff --git a/source/blender/bmesh/tools/bmesh_intersect.c b/source/blender/bmesh/tools/bmesh_intersect.c
index 82545a5e011..cc8511c65f1 100644
--- a/source/blender/bmesh/tools/bmesh_intersect.c
+++ b/source/blender/bmesh/tools/bmesh_intersect.c
@@ -1265,8 +1265,8 @@ bool BM_mesh_intersect(
}
}
- splice_ls = MEM_mallocN(BLI_gset_size(s.wire_edges) * sizeof(*splice_ls), __func__);
- STACK_INIT(splice_ls, BLI_gset_size(s.wire_edges));
+ splice_ls = MEM_mallocN(BLI_gset_len(s.wire_edges) * sizeof(*splice_ls), __func__);
+ STACK_INIT(splice_ls, BLI_gset_len(s.wire_edges));
for (node = s.vert_dissolve; node; node = node->next) {
BMEdge *e_pair[2];
@@ -1669,7 +1669,7 @@ bool BM_mesh_intersect(
}
}
- has_edit_isect = (BLI_ghash_size(s.face_edges) != 0);
+ has_edit_isect = (BLI_ghash_len(s.face_edges) != 0);
/* cleanup */
BLI_ghash_free(s.edgetri_cache, NULL, NULL);
diff --git a/source/blender/bmesh/tools/bmesh_path.c b/source/blender/bmesh/tools/bmesh_path.c
index 85c591b6684..cc5ac6dd8ce 100644
--- a/source/blender/bmesh/tools/bmesh_path.c
+++ b/source/blender/bmesh/tools/bmesh_path.c
@@ -174,7 +174,7 @@ LinkNode *BM_mesh_calc_path_vert(
cost[BM_elem_index_get(v_src)] = 0.0f;
while (!BLI_heap_is_empty(heap)) {
- v = BLI_heap_popmin(heap);
+ v = BLI_heap_pop_min(heap);
if (v == v_dst)
break;
@@ -346,7 +346,7 @@ LinkNode *BM_mesh_calc_path_edge(
cost[BM_elem_index_get(e_src)] = 0.0f;
while (!BLI_heap_is_empty(heap)) {
- e = BLI_heap_popmin(heap);
+ e = BLI_heap_pop_min(heap);
if (e == e_dst)
break;
@@ -532,7 +532,7 @@ LinkNode *BM_mesh_calc_path_face(
cost[BM_elem_index_get(f_src)] = 0.0f;
while (!BLI_heap_is_empty(heap)) {
- f = BLI_heap_popmin(heap);
+ f = BLI_heap_pop_min(heap);
if (f == f_dst)
break;
diff --git a/source/blender/bmesh/tools/bmesh_region_match.c b/source/blender/bmesh/tools/bmesh_region_match.c
index 2abf8f2c46e..e83ba73ad01 100644
--- a/source/blender/bmesh/tools/bmesh_region_match.c
+++ b/source/blender/bmesh/tools/bmesh_region_match.c
@@ -421,8 +421,8 @@ static void bm_uuidwalk_rehash(
UUID_Int *uuid_store;
uint i;
- uint rehash_store_len_new = MAX2(BLI_ghash_size(uuidwalk->verts_uuid),
- BLI_ghash_size(uuidwalk->faces_uuid));
+ uint rehash_store_len_new = MAX2(BLI_ghash_len(uuidwalk->verts_uuid),
+ BLI_ghash_len(uuidwalk->faces_uuid));
bm_uuidwalk_rehash_reserve(uuidwalk, rehash_store_len_new);
uuid_store = uuidwalk->cache.rehash_store;
@@ -520,8 +520,8 @@ static void bm_uuidwalk_pass_add(
verts_uuid_pass = uuidwalk->cache.verts_uuid;
faces_step_next = uuidwalk->cache.faces_step;
- BLI_assert(BLI_ghash_size(verts_uuid_pass) == 0);
- BLI_assert(BLI_gset_size(faces_step_next) == 0);
+ BLI_assert(BLI_ghash_len(verts_uuid_pass) == 0);
+ BLI_assert(BLI_gset_len(faces_step_next) == 0);
/* Add the face_step data from connected faces, creating new passes */
fstep = BLI_mempool_alloc(uuidwalk->step_pool);
@@ -659,7 +659,7 @@ static bool bm_uuidwalk_facestep_begin(
LinkNode *f_link, *f_link_next, **f_link_prev_p;
bool ok = false;
- BLI_assert(BLI_ghash_size(uuidwalk->cache.faces_from_uuid) == 0);
+ BLI_assert(BLI_ghash_len(uuidwalk->cache.faces_from_uuid) == 0);
BLI_assert(BLI_listbase_is_empty(&fstep->items));
f_link_prev_p = &fstep->faces;
@@ -864,7 +864,7 @@ static BMFace **bm_mesh_region_match_pair(
break;
}
- found = (BLI_ghash_size(w_dst->faces_uuid) == faces_src_region_len);
+ found = (BLI_ghash_len(w_dst->faces_uuid) == faces_src_region_len);
if (found) {
break;
}
@@ -877,7 +877,7 @@ static BMFace **bm_mesh_region_match_pair(
if (found) {
GHashIterator gh_iter;
- const uint faces_result_len = BLI_ghash_size(w_dst->faces_uuid);
+ const uint faces_result_len = BLI_ghash_len(w_dst->faces_uuid);
uint i;
faces_result = MEM_mallocN(sizeof(*faces_result) * (faces_result_len + 1), __func__);
diff --git a/source/blender/bmesh/tools/bmesh_separate.c b/source/blender/bmesh/tools/bmesh_separate.c
index 287b4125330..b3d0c339885 100644
--- a/source/blender/bmesh/tools/bmesh_separate.c
+++ b/source/blender/bmesh/tools/bmesh_separate.c
@@ -122,7 +122,7 @@ void BM_mesh_separate_faces(
/* Perform the split */
BM_face_loop_separate_multi(bm, loop_split.data, loop_split.count);
- BLI_buffer_empty(&loop_split);
+ BLI_buffer_clear(&loop_split);
}
} while ((l_iter = l_iter->next) != l_first);
}
diff --git a/source/blender/bmesh/tools/bmesh_triangulate.c b/source/blender/bmesh/tools/bmesh_triangulate.c
index bd201fa89bf..a3a3355d20f 100644
--- a/source/blender/bmesh/tools/bmesh_triangulate.c
+++ b/source/blender/bmesh/tools/bmesh_triangulate.c
@@ -38,8 +38,8 @@
#include "BLI_linklist.h"
/* only for defines */
-#include "BLI_polyfill2d.h"
-#include "BLI_polyfill2d_beautify.h"
+#include "BLI_polyfill_2d.h"
+#include "BLI_polyfill_2d_beautify.h"
#include "bmesh.h"
diff --git a/source/blender/collada/AnimationExporter.cpp b/source/blender/collada/AnimationExporter.cpp
index 6e59a404e47..cc772535e37 100644
--- a/source/blender/collada/AnimationExporter.cpp
+++ b/source/blender/collada/AnimationExporter.cpp
@@ -178,7 +178,7 @@ void AnimationExporter::export_morph_animation(Object *ob)
void AnimationExporter::make_anim_frames_from_targets(Object *ob, std::vector<float> &frames )
{
- ListBase *conlist = get_active_constraints(ob);
+ ListBase *conlist = get_active_constraints(this->eval_ctx, ob);
if (conlist == NULL) return;
bConstraint *con;
for (con = (bConstraint *)conlist->first; con; con = con->next) {
@@ -989,6 +989,9 @@ std::string AnimationExporter::create_4x4_source(std::vector<float> &frames, Obj
double outmat[4][4];
converter.mat4_to_dae_double(outmat, mat);
+ if (this->export_settings->limit_precision)
+ bc_sanitize_mat(outmat, 6);
+
source.appendValues(outmat);
j++;
@@ -1539,7 +1542,7 @@ bool AnimationExporter::validateConstraints(bConstraint *con)
void AnimationExporter::calc_ob_mat_at_time(Object *ob, float ctime , float mat[][4])
{
- ListBase *conlist = get_active_constraints(ob);
+ ListBase *conlist = get_active_constraints(this->eval_ctx, ob);
bConstraint *con;
for (con = (bConstraint *)conlist->first; con; con = con->next) {
ListBase targets = {NULL, NULL};
diff --git a/source/blender/collada/AnimationImporter.cpp b/source/blender/collada/AnimationImporter.cpp
index 65acce41046..e63b70edcf5 100644
--- a/source/blender/collada/AnimationImporter.cpp
+++ b/source/blender/collada/AnimationImporter.cpp
@@ -780,6 +780,9 @@ void AnimationImporter::apply_matrix_curves(Object *ob, std::vector<FCurve *>& a
std::vector<float>::iterator it;
+ float qref[4];
+ unit_qt(qref);
+
// sample values at each frame
for (it = frames.begin(); it != frames.end(); it++) {
float fra = *it;
@@ -814,8 +817,11 @@ void AnimationImporter::apply_matrix_curves(Object *ob, std::vector<FCurve *>& a
}
float rot[4], loc[3], scale[3];
+ transpose_m4(mat);
+
+ bc_rotate_from_reference_quat(rot, qref, mat);
+ copy_qt_qt(qref, rot);
- mat4_to_quat(rot, mat);
#if 0
for (int i = 0 ; i < 4; i++) {
rot[i] = RAD2DEGF(rot[i]);
@@ -1190,6 +1196,9 @@ void AnimationImporter::add_bone_animation_sampled(Object *ob, std::vector<FCurv
std::sort(frames.begin(), frames.end());
+ float qref[4];
+ unit_qt(qref);
+
std::vector<float>::iterator it;
// sample values at each frame
@@ -1223,7 +1232,9 @@ void AnimationImporter::add_bone_animation_sampled(Object *ob, std::vector<FCurv
float rot[4], loc[3], scale[3];
- mat4_to_quat(rot, mat);
+ bc_rotate_from_reference_quat(rot, qref, mat);
+ copy_qt_qt(qref, rot);
+
copy_v3_v3(loc, mat[3]);
mat4_to_size(scale, mat);
diff --git a/source/blender/collada/DocumentExporter.cpp b/source/blender/collada/DocumentExporter.cpp
index ce0c52cdcd1..1741312af5f 100644
--- a/source/blender/collada/DocumentExporter.cpp
+++ b/source/blender/collada/DocumentExporter.cpp
@@ -299,15 +299,15 @@ int DocumentExporter::exportCurrentScene(const EvaluationContext *eval_ctx, Scen
// <library_visual_scenes>
SceneExporter se(writer, &arm_exporter, this->export_settings);
-#if 0
- /* The following code seems to be an obsolete workaround
- Comment out until it proofs correct that we no longer need it.
- */
// <library_animations>
AnimationExporter ae(writer, this->export_settings);
- bool has_animations = ae.exportAnimations(eval_ctx, sce);
+#if 0
+ bool has_animations = ae.exportAnimations(eval_ctx, sce);
+ /* The following code seems to be an obsolete workaround
+ Comment out until it proofs correct that we no longer need it.
+ */
if (has_animations && this->export_settings->export_transformation_type == BC_TRANSFORMATION_TYPE_MATRIX) {
// channels adressing <matrix> objects is not (yet) supported
// So we force usage of <location>, <translation> and <scale>
@@ -320,6 +320,7 @@ int DocumentExporter::exportCurrentScene(const EvaluationContext *eval_ctx, Scen
se.setExportTransformationType(this->export_settings->export_transformation_type);
}
#else
+ ae.exportAnimations(eval_ctx, sce);
se.setExportTransformationType(this->export_settings->export_transformation_type);
#endif
se.exportScene(eval_ctx, sce);
diff --git a/source/blender/collada/ErrorHandler.cpp b/source/blender/collada/ErrorHandler.cpp
index 32aa5636e08..7e18328f000 100644
--- a/source/blender/collada/ErrorHandler.cpp
+++ b/source/blender/collada/ErrorHandler.cpp
@@ -49,7 +49,10 @@ ErrorHandler::~ErrorHandler()
//--------------------------------------------------------------------
bool ErrorHandler::handleError(const COLLADASaxFWL::IError *error)
{
- bool isError = false;
+ /* This method must return true when Collada should continue.
+ See https://github.com/KhronosGroup/OpenCOLLADA/issues/442
+ */
+ bool isWarning = false;
if (error->getErrorClass() == COLLADASaxFWL::IError::ERROR_SAXPARSER) {
COLLADASaxFWL::SaxParserError *saxParserError = (COLLADASaxFWL::SaxParserError *) error;
@@ -58,14 +61,14 @@ bool ErrorHandler::handleError(const COLLADASaxFWL::IError *error)
// Workaround to avoid wrong error
if (parserError.getErrorType() == GeneratedSaxParser::ParserError::ERROR_VALIDATION_MIN_OCCURS_UNMATCHED) {
if (STREQ(parserError.getElement(), "effect")) {
- isError = false;
+ isWarning = true;
}
}
if (parserError.getErrorType() == GeneratedSaxParser::ParserError::ERROR_VALIDATION_SEQUENCE_PREVIOUS_SIBLING_NOT_PRESENT) {
if (!(STREQ(parserError.getElement(), "extra") &&
STREQ(parserError.getAdditionalText().c_str(), "sibling: fx_profile_abstract")))
{
- isError = false;
+ isWarning = true;
}
}
@@ -81,14 +84,12 @@ bool ErrorHandler::handleError(const COLLADASaxFWL::IError *error)
* Accept non critical errors as warnings (i.e. texture not found)
* This makes the importer more graceful, so it now imports what makes sense.
*/
- isError = (saxFWLError->getSeverity() != COLLADASaxFWL::IError::SEVERITY_ERROR_NONCRITICAL);
+ isWarning = (saxFWLError->getSeverity() == COLLADASaxFWL::IError::SEVERITY_ERROR_NONCRITICAL);
std::cout << "Sax FWL Error: " << saxFWLError->getErrorMessage() << std::endl;
}
else {
std::cout << "opencollada error: " << error->getFullErrorMessage() << std::endl;
}
- mError |= isError;
-
- return isError; // let OpenCollada decide when to abort
+ return isWarning;
}
diff --git a/source/blender/collada/SkinInfo.cpp b/source/blender/collada/SkinInfo.cpp
index a2cb8237d08..24b47f8db3c 100644
--- a/source/blender/collada/SkinInfo.cpp
+++ b/source/blender/collada/SkinInfo.cpp
@@ -227,7 +227,7 @@ void SkinInfo::link_armature(bContext *C, Object *ob, std::map<COLLADAFW::Unique
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
- ModifierData *md = ED_object_modifier_add(NULL, bmain, scene, ob, NULL, eModifierType_Armature);
+ ModifierData *md = ED_object_modifier_add(NULL, bmain, scene, ob, OB_MODE_OBJECT, NULL, eModifierType_Armature);
ArmatureModifierData *amd = (ArmatureModifierData *)md;
amd->object = ob_arm;
diff --git a/source/blender/collada/collada_utils.cpp b/source/blender/collada/collada_utils.cpp
index f351ebf7952..117e2ef7f76 100644
--- a/source/blender/collada/collada_utils.cpp
+++ b/source/blender/collada/collada_utils.cpp
@@ -384,6 +384,35 @@ void bc_decompose(float mat[4][4], float *loc, float eul[3], float quat[4], floa
}
}
+/*
+* Create rotation_quaternion from a delta rotation and a reference quat
+*
+* Input:
+* mat_from: The rotation matrix before rotation
+* mat_to : The rotation matrix after rotation
+* qref : the quat corresponding to mat_from
+*
+* Output:
+* rot : the calculated result (quaternion)
+*
+*/
+void bc_rotate_from_reference_quat(float quat_to[4], float quat_from[4], float mat_to[4][4])
+{
+ float qd[4];
+ float matd[4][4];
+ float mati[4][4];
+ float mat_from[4][4];
+ quat_to_mat4(mat_from, quat_from);
+
+ // Calculate the difference matrix matd between mat_from and mat_to
+ invert_m4_m4(mati, mat_from);
+ mul_m4_m4m4(matd, mati, mat_to);
+
+ mat4_to_quat(qd, matd);
+
+ mul_qt_qtqt(quat_to, qd, quat_from); // rot is the final rotation corresponding to mat_to
+}
+
void bc_triangulate_mesh(Mesh *me)
{
bool use_beauty = false;
@@ -841,3 +870,11 @@ void bc_sanitize_mat(float mat[4][4], int precision)
for (int j = 0; j < 4; j++)
mat[i][j] = double_round(mat[i][j], precision);
}
+
+void bc_sanitize_mat(double mat[4][4], int precision)
+{
+ for (int i = 0; i < 4; i++)
+ for (int j = 0; j < 4; j++)
+ mat[i][j] = double_round(mat[i][j], precision);
+}
+
diff --git a/source/blender/collada/collada_utils.h b/source/blender/collada/collada_utils.h
index 5d6e836b9c3..e3a16105861 100644
--- a/source/blender/collada/collada_utils.h
+++ b/source/blender/collada/collada_utils.h
@@ -93,6 +93,7 @@ extern void bc_match_scale(Object *ob, UnitConverter &bc_unit, bool scale_to_sce
extern void bc_match_scale(std::vector<Object *> *objects_done, UnitConverter &unit_converter, bool scale_to_scene);
extern void bc_decompose(float mat[4][4], float *loc, float eul[3], float quat[4], float *size);
+extern void bc_rotate_from_reference_quat(float quat_to[4], float quat_from[4], float mat_to[4][4]);
extern void bc_triangulate_mesh(Mesh *me);
extern bool bc_is_leaf_bone(Bone *bone);
@@ -100,6 +101,7 @@ extern EditBone *bc_get_edit_bone(bArmature * armature, char *name);
extern int bc_set_layer(int bitfield, int layer, bool enable);
extern int bc_set_layer(int bitfield, int layer);
extern void bc_sanitize_mat(float mat[4][4], int precision);
+extern void bc_sanitize_mat(double mat[4][4], int precision);
extern IDProperty *bc_get_IDProperty(Bone *bone, std::string key);
extern void bc_set_IDProperty(EditBone *ebone, const char *key, float value);
diff --git a/source/blender/compositor/intern/COM_WorkScheduler.cpp b/source/blender/compositor/intern/COM_WorkScheduler.cpp
index 68f934008a4..e2dc289eb1c 100644
--- a/source/blender/compositor/intern/COM_WorkScheduler.cpp
+++ b/source/blender/compositor/intern/COM_WorkScheduler.cpp
@@ -131,18 +131,18 @@ void WorkScheduler::start(CompositorContext &context)
#if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE
unsigned int index;
g_cpuqueue = BLI_thread_queue_init();
- BLI_init_threads(&g_cputhreads, thread_execute_cpu, g_cpudevices.size());
+ BLI_threadpool_init(&g_cputhreads, thread_execute_cpu, g_cpudevices.size());
for (index = 0; index < g_cpudevices.size(); index++) {
Device *device = g_cpudevices[index];
- BLI_insert_thread(&g_cputhreads, device);
+ BLI_threadpool_insert(&g_cputhreads, device);
}
#ifdef COM_OPENCL_ENABLED
if (context.getHasActiveOpenCLDevices()) {
g_gpuqueue = BLI_thread_queue_init();
- BLI_init_threads(&g_gputhreads, thread_execute_gpu, g_gpudevices.size());
+ BLI_threadpool_init(&g_gputhreads, thread_execute_gpu, g_gpudevices.size());
for (index = 0; index < g_gpudevices.size(); index++) {
Device *device = g_gpudevices[index];
- BLI_insert_thread(&g_gputhreads, device);
+ BLI_threadpool_insert(&g_gputhreads, device);
}
g_openclActive = true;
}
@@ -172,13 +172,13 @@ void WorkScheduler::stop()
{
#if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE
BLI_thread_queue_nowait(g_cpuqueue);
- BLI_end_threads(&g_cputhreads);
+ BLI_threadpool_end(&g_cputhreads);
BLI_thread_queue_free(g_cpuqueue);
g_cpuqueue = NULL;
#ifdef COM_OPENCL_ENABLED
if (g_openclActive) {
BLI_thread_queue_nowait(g_gpuqueue);
- BLI_end_threads(&g_gputhreads);
+ BLI_threadpool_end(&g_gputhreads);
BLI_thread_queue_free(g_gpuqueue);
g_gpuqueue = NULL;
}
diff --git a/source/blender/compositor/operations/COM_CompositorOperation.cpp b/source/blender/compositor/operations/COM_CompositorOperation.cpp
index 15ffff2fc90..fe13f3d60a2 100644
--- a/source/blender/compositor/operations/COM_CompositorOperation.cpp
+++ b/source/blender/compositor/operations/COM_CompositorOperation.cpp
@@ -108,9 +108,9 @@ void CompositorOperation::deinitExecution()
re = NULL;
}
- BLI_lock_thread(LOCK_DRAW_IMAGE);
+ BLI_thread_lock(LOCK_DRAW_IMAGE);
BKE_image_signal(BKE_image_verify_viewer(IMA_TYPE_R_RESULT, "Render Result"), NULL, IMA_SIGNAL_FREE);
- BLI_unlock_thread(LOCK_DRAW_IMAGE);
+ BLI_thread_unlock(LOCK_DRAW_IMAGE);
}
else {
if (this->m_outputBuffer) {
diff --git a/source/blender/compositor/operations/COM_KeyingScreenOperation.h b/source/blender/compositor/operations/COM_KeyingScreenOperation.h
index b1a5c0c39c7..45195b1e98d 100644
--- a/source/blender/compositor/operations/COM_KeyingScreenOperation.h
+++ b/source/blender/compositor/operations/COM_KeyingScreenOperation.h
@@ -35,7 +35,7 @@
#include "BLI_string.h"
extern "C" {
-# include "BLI_voronoi.h"
+# include "BLI_voronoi_2d.h"
}
/**
diff --git a/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cpp b/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cpp
index 1145abd076a..75a85ad7e33 100644
--- a/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cpp
+++ b/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cpp
@@ -28,7 +28,7 @@ extern "C" {
#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_math_color.h"
-#include "BLI_jitter.h"
+#include "BLI_jitter_2d.h"
#include "BKE_movieclip.h"
#include "BKE_node.h"
diff --git a/source/blender/compositor/operations/COM_ViewerOperation.cpp b/source/blender/compositor/operations/COM_ViewerOperation.cpp
index aa47d3427d0..42fe24120dc 100644
--- a/source/blender/compositor/operations/COM_ViewerOperation.cpp
+++ b/source/blender/compositor/operations/COM_ViewerOperation.cpp
@@ -135,14 +135,14 @@ void ViewerOperation::initImage()
BKE_image_verify_viewer_views(this->m_rd, ima, this->m_imageUser);
}
- BLI_lock_thread(LOCK_DRAW_IMAGE);
+ BLI_thread_lock(LOCK_DRAW_IMAGE);
/* local changes to the original ImageUser */
iuser.multi_index = BKE_scene_multiview_view_id_get(this->m_rd, this->m_viewName);
ibuf = BKE_image_acquire_ibuf(ima, &iuser, &lock);
if (!ibuf) {
- BLI_unlock_thread(LOCK_DRAW_IMAGE);
+ BLI_thread_unlock(LOCK_DRAW_IMAGE);
return;
}
if (ibuf->x != (int)getWidth() || ibuf->y != (int)getHeight()) {
@@ -176,7 +176,7 @@ void ViewerOperation::initImage()
BKE_image_release_ibuf(this->m_image, this->m_ibuf, lock);
- BLI_unlock_thread(LOCK_DRAW_IMAGE);
+ BLI_thread_unlock(LOCK_DRAW_IMAGE);
}
void ViewerOperation::updateImage(rcti *rect)
diff --git a/source/blender/depsgraph/DEG_depsgraph.h b/source/blender/depsgraph/DEG_depsgraph.h
index 4d3f36b5fba..8110899048d 100644
--- a/source/blender/depsgraph/DEG_depsgraph.h
+++ b/source/blender/depsgraph/DEG_depsgraph.h
@@ -75,6 +75,8 @@ typedef enum eEvaluationMode {
DAG_EVAL_RENDER = 2, /* evaluate for render purposes */
} eEvaluationMode;
+#include "DNA_object_enums.h"
+
/* Dependency graph evaluation context
*
* This structure stores all the local dependency graph data,
@@ -83,6 +85,7 @@ typedef enum eEvaluationMode {
typedef struct EvaluationContext {
eEvaluationMode mode;
float ctime;
+ eObjectMode object_mode;
struct Depsgraph *depsgraph;
struct ViewLayer *view_layer;
@@ -213,11 +216,13 @@ struct EvaluationContext *DEG_evaluation_context_new(eEvaluationMode mode);
*/
void DEG_evaluation_context_init(struct EvaluationContext *eval_ctx,
eEvaluationMode mode);
-void DEG_evaluation_context_init_from_scene(struct EvaluationContext *eval_ctx,
- struct Scene *scene,
- struct ViewLayer *view_layer,
- struct RenderEngineType *engine_type,
- eEvaluationMode mode);
+void DEG_evaluation_context_init_from_scene(
+ struct EvaluationContext *eval_ctx,
+ struct Scene *scene,
+ struct ViewLayer *view_layer,
+ struct RenderEngineType *engine_type,
+ const eObjectMode object_mode,
+ eEvaluationMode mode);
/* Free evaluation context. */
void DEG_evaluation_context_free(struct EvaluationContext *eval_ctx);
diff --git a/source/blender/depsgraph/DEG_depsgraph_query.h b/source/blender/depsgraph/DEG_depsgraph_query.h
index adfda27117e..fffdccf3efc 100644
--- a/source/blender/depsgraph/DEG_depsgraph_query.h
+++ b/source/blender/depsgraph/DEG_depsgraph_query.h
@@ -91,6 +91,7 @@ typedef struct DEGObjectIterData {
int flag;
eDepsObjectIteratorMode mode;
+ int visibility_check; /* eObjectVisibilityCheck. */
/* **** Iteration over dupli-list. *** */
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
index ddae761cea0..b65c16591dc 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
@@ -90,6 +90,7 @@ extern "C" {
#include "BKE_node.h"
#include "BKE_object.h"
#include "BKE_particle.h"
+#include "BKE_pointcache.h"
#include "BKE_rigidbody.h"
#include "BKE_sound.h"
#include "BKE_tracking.h"
@@ -196,7 +197,7 @@ IDDepsNode *DepsgraphNodeBuilder::add_id_node(ID *id, bool do_tag)
*
* NOTE: Zero number of components indicates that ID node was just created.
*/
- if (BLI_ghash_size(id_node->components) == 0) {
+ if (BLI_ghash_len(id_node->components) == 0) {
ComponentDepsNode *comp_cow =
id_node->add_component(DEG_NODE_TYPE_COPY_ON_WRITE);
OperationDepsNode *op_cow = comp_cow->add_operation(
@@ -429,7 +430,7 @@ void DepsgraphNodeBuilder::build_group(Group *group)
}
group_id->tag |= LIB_TAG_DOIT;
/* Build group objects. */
- BLI_LISTBASE_FOREACH (Base *, base, &group->view_layer->object_bases) {
+ LISTBASE_FOREACH (Base *, base, &group->view_layer->object_bases) {
build_object(NULL, base->object, DEG_ID_LINKED_INDIRECTLY);
}
/* Operation to evaluate the whole view layer.
@@ -699,7 +700,7 @@ void DepsgraphNodeBuilder::build_animdata(ID *id)
}
/* drivers */
- BLI_LISTBASE_FOREACH (FCurve *, fcu, &adt->drivers) {
+ LISTBASE_FOREACH (FCurve *, fcu, &adt->drivers) {
/* create driver */
build_driver(id, fcu);
}
@@ -817,7 +818,7 @@ void DepsgraphNodeBuilder::build_rigidbody(Scene *scene)
/* objects - simulation participants */
if (rbw->group) {
- BLI_LISTBASE_FOREACH (Base *, base, &rbw->group->view_layer->object_bases) {
+ LISTBASE_FOREACH (Base *, base, &rbw->group->view_layer->object_bases) {
Object *object = base->object;
if (!object || (object->type != OB_MESH))
@@ -853,8 +854,7 @@ void DepsgraphNodeBuilder::build_particles(Object *object)
* blackbox evaluation step for one particle system referenced by
* the particle systems stack. All dependencies link to this operation.
*/
-
- /* component for all particle systems */
+ /* Component for all particle systems. */
ComponentDepsNode *psys_comp =
add_component_node(&object->id, DEG_NODE_TYPE_EVAL_PARTICLES);
@@ -868,17 +868,14 @@ void DepsgraphNodeBuilder::build_particles(Object *object)
scene_cow,
ob_cow),
DEG_OPCODE_PARTICLE_SYSTEM_EVAL_INIT);
-
- /* particle systems */
- BLI_LISTBASE_FOREACH (ParticleSystem *, psys, &object->particlesystem) {
+ /* Build all particle systems. */
+ LISTBASE_FOREACH (ParticleSystem *, psys, &object->particlesystem) {
ParticleSettings *part = psys->part;
-
/* Build particle settings operations.
*
* NOTE: The call itself ensures settings are only build once.
*/
build_particle_settings(part);
-
/* Update on particle settings change. */
add_operation_node(psys_comp,
function_bind(BKE_particle_system_settings_eval,
@@ -886,15 +883,36 @@ void DepsgraphNodeBuilder::build_particles(Object *object)
psys),
DEG_OPCODE_PARTICLE_SETTINGS_EVAL,
psys->name);
-
/* Particle system evaluation. */
add_operation_node(psys_comp,
NULL,
DEG_OPCODE_PARTICLE_SYSTEM_EVAL,
psys->name);
+ /* Visualization of particle system. */
+ switch (part->ren_as) {
+ case PART_DRAW_OB:
+ if (part->dup_ob != NULL) {
+ build_object(NULL,
+ part->dup_ob,
+ DEG_ID_LINKED_INDIRECTLY);
+ }
+ break;
+ case PART_DRAW_GR:
+ if (part->dup_group != NULL) {
+ build_group(part->dup_group);
+ }
+ break;
+ }
}
/* TODO(sergey): Do we need a point cache operations here? */
+ add_operation_node(&object->id,
+ DEG_NODE_TYPE_CACHE,
+ function_bind(BKE_ptcache_object_reset,
+ scene_cow,
+ ob_cow,
+ PTCACHE_RESET_DEPSGRAPH),
+ DEG_OPCODE_POINT_CACHE_RESET);
}
void DepsgraphNodeBuilder::build_particle_settings(ParticleSettings *part) {
@@ -986,7 +1004,7 @@ void DepsgraphNodeBuilder::build_obdata_geom(Object *object)
// TODO: "Done" operation
/* Cloth modifier. */
- BLI_LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
+ LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
if (md->type == eModifierType_Cloth) {
build_cloth(object);
}
@@ -1231,7 +1249,7 @@ void DepsgraphNodeBuilder::build_nodetree(bNodeTree *ntree)
ntree),
DEG_OPCODE_MATERIAL_UPDATE);
/* nodetree's nodes... */
- BLI_LISTBASE_FOREACH (bNode *, bnode, &ntree->nodes) {
+ LISTBASE_FOREACH (bNode *, bnode, &ntree->nodes) {
ID *id = bnode->id;
if (id == NULL) {
continue;
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_layer_collection.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_layer_collection.cc
index 137a79e7276..2ee526b7128 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_layer_collection.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_layer_collection.cc
@@ -94,7 +94,7 @@ void DepsgraphNodeBuilder::build_layer_collections(ID *owner_id,
ListBase *layer_collections,
LayerCollectionState *state)
{
- BLI_LISTBASE_FOREACH (LayerCollection *, layer_collection, layer_collections) {
+ LISTBASE_FOREACH (LayerCollection *, layer_collection, layer_collections) {
build_layer_collection(owner_id, layer_collection, state);
}
}
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc
index 2fc42efa440..c3116db6146 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc
@@ -247,7 +247,7 @@ void DepsgraphNodeBuilder::build_rig(Object *object)
op_node->set_as_exit();
/* bones */
- BLI_LISTBASE_FOREACH (bPoseChannel *, pchan, &object_cow->pose->chanbase) {
+ LISTBASE_FOREACH (bPoseChannel *, pchan, &object_cow->pose->chanbase) {
/* Node for bone evaluation. */
op_node = add_operation_node(&object->id, DEG_NODE_TYPE_BONE, pchan->name, NULL,
DEG_OPCODE_BONE_LOCAL);
@@ -293,7 +293,7 @@ void DepsgraphNodeBuilder::build_rig(Object *object)
* as in ik-tree building
* - Animated chain-lengths are a problem.
*/
- BLI_LISTBASE_FOREACH (bConstraint *, con, &pchan->constraints) {
+ LISTBASE_FOREACH (bConstraint *, con, &pchan->constraints) {
switch (con->type) {
case CONSTRAINT_TYPE_KINEMATIC:
build_ik_pose(object, pchan, con);
@@ -347,8 +347,8 @@ void DepsgraphNodeBuilder::build_proxy_rig(Object *object)
object_cow),
DEG_OPCODE_POSE_INIT);
op_node->set_as_entry();
- BLI_LISTBASE_FOREACH (bPoseChannel *, pchan, &object_cow->pose->chanbase) {
- /* Local bone transform. */
+
+ LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
op_node = add_operation_node(&object->id,
DEG_NODE_TYPE_BONE,
pchan->name,
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 4ca19f4e14f..7a0fc790780 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
@@ -84,7 +84,7 @@ void DepsgraphNodeBuilder::build_view_layer(
* otherwise remapping will not replace objects with their CoW versions
* for CoW bases.
*/
- BLI_LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
Object *object = base->object;
add_id_node(&object->id, false);
}
@@ -145,15 +145,15 @@ void DepsgraphNodeBuilder::build_view_layer(
build_gpencil(scene->gpd);
}
/* Cache file. */
- BLI_LISTBASE_FOREACH (CacheFile *, cachefile, &bmain_->cachefiles) {
+ LISTBASE_FOREACH (CacheFile *, cachefile, &bmain_->cachefiles) {
build_cachefile(cachefile);
}
/* Masks. */
- BLI_LISTBASE_FOREACH (Mask *, mask, &bmain_->mask) {
+ LISTBASE_FOREACH (Mask *, mask, &bmain_->mask) {
build_mask(mask);
}
/* Movie clips. */
- BLI_LISTBASE_FOREACH (MovieClip *, clip, &bmain_->movieclip) {
+ LISTBASE_FOREACH (MovieClip *, clip, &bmain_->movieclip) {
build_movieclip(clip);
}
/* Collections. */
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index cfb73ecc2ad..cff6c926278 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -67,7 +67,7 @@ extern "C" {
#include "DNA_scene_types.h"
#include "DNA_texture_types.h"
#include "DNA_world_types.h"
-#include "DNA_object_force.h"
+#include "DNA_object_force_types.h"
#include "BKE_action.h"
#include "BKE_armature.h"
@@ -194,7 +194,7 @@ static bool particle_system_depends_on_time(ParticleSystem *psys)
static bool object_particles_depends_on_time(Object *object)
{
- BLI_LISTBASE_FOREACH (ParticleSystem *, psys, &object->particlesystem) {
+ LISTBASE_FOREACH (ParticleSystem *, psys, &object->particlesystem) {
if (particle_system_depends_on_time(psys)) {
return true;
}
@@ -347,7 +347,7 @@ void DepsgraphRelationBuilder::add_forcefield_relations(
{
ListBase *effectors = pdInitEffectors(NULL, scene, object, psys, eff, false);
if (effectors != NULL) {
- BLI_LISTBASE_FOREACH (EffectorCache *, eff, effectors) {
+ LISTBASE_FOREACH (EffectorCache *, eff, effectors) {
if (eff->ob != object) {
ComponentKey eff_key(&eff->ob->id, DEG_NODE_TYPE_TRANSFORM);
add_relation(eff_key, key, name);
@@ -423,20 +423,20 @@ void DepsgraphRelationBuilder::build_group(Object *object, Group *group)
{
ID *group_id = &group->id;
bool group_done = (group_id->tag & LIB_TAG_DOIT) != 0;
- OperationKey object_local_transform_key(&object->id,
+ OperationKey object_local_transform_key(object != NULL ? &object->id : NULL,
DEG_NODE_TYPE_TRANSFORM,
DEG_OPCODE_TRANSFORM_LOCAL);
-
if (!group_done) {
- BLI_LISTBASE_FOREACH (Base *, base, &group->view_layer->object_bases) {
+ LISTBASE_FOREACH (Base *, base, &group->view_layer->object_bases) {
build_object(NULL, base->object);
}
group_id->tag |= LIB_TAG_DOIT;
}
-
- BLI_LISTBASE_FOREACH (Base *, base, &group->view_layer->object_bases) {
- ComponentKey dupli_transform_key(&base->object->id, DEG_NODE_TYPE_TRANSFORM);
- add_relation(dupli_transform_key, object_local_transform_key, "Dupligroup");
+ if (object != NULL) {
+ LISTBASE_FOREACH (Base *, base, &group->view_layer->object_bases) {
+ ComponentKey dupli_transform_key(&base->object->id, DEG_NODE_TYPE_TRANSFORM);
+ add_relation(dupli_transform_key, object_local_transform_key, "Dupligroup");
+ }
}
}
@@ -776,7 +776,7 @@ void DepsgraphRelationBuilder::build_constraints(ID *id,
else if (cti->get_constraint_targets) {
ListBase targets = {NULL, NULL};
cti->get_constraint_targets(con, &targets);
- BLI_LISTBASE_FOREACH (bConstraintTarget *, ct, &targets) {
+ LISTBASE_FOREACH (bConstraintTarget *, ct, &targets) {
if (ct->tar == NULL) {
continue;
}
@@ -939,18 +939,7 @@ void DepsgraphRelationBuilder::build_animdata_curves(ID *id)
ComponentKey adt_key(id, DEG_NODE_TYPE_ANIMATION);
TimeSourceKey time_src_key;
add_relation(time_src_key, adt_key, "TimeSrc -> Animation");
- /* Build relations from animation operation to properties it changes. */
- build_animdata_curves_targets(id);
-}
-
-void DepsgraphRelationBuilder::build_animdata_curves_targets(ID *id)
-{
- AnimData *adt = BKE_animdata_from_id(id);
- if (adt == NULL || adt->action == NULL) {
- return;
- }
- /* Get source operation. */
- ComponentKey adt_key(id, DEG_NODE_TYPE_ANIMATION);
+ /* Get source operations. */
DepsNode *node_from = get_node(adt_key);
BLI_assert(node_from != NULL);
if (node_from == NULL) {
@@ -958,10 +947,28 @@ void DepsgraphRelationBuilder::build_animdata_curves_targets(ID *id)
}
OperationDepsNode *operation_from = node_from->get_exit_operation();
BLI_assert(operation_from != NULL);
+ /* Build relations from animation operation to properties it changes. */
+ if (adt->action != NULL) {
+ build_animdata_curves_targets(id, adt_key,
+ operation_from,
+ &adt->action->curves);
+ }
+ LISTBASE_FOREACH(NlaTrack *, nlt, &adt->nla_tracks) {
+ build_animdata_nlastrip_targets(id, adt_key,
+ operation_from,
+ &nlt->strips);
+ }
+}
+
+void DepsgraphRelationBuilder::build_animdata_curves_targets(
+ ID *id, ComponentKey &adt_key,
+ OperationDepsNode *operation_from,
+ ListBase *curves)
+{
/* Iterate over all curves and build relations. */
PointerRNA id_ptr;
RNA_id_pointer_create(id, &id_ptr);
- BLI_LISTBASE_FOREACH (FCurve *, fcu, &adt->action->curves) {
+ LISTBASE_FOREACH(FCurve *, fcu, curves) {
PointerRNA ptr;
PropertyRNA *prop;
int index;
@@ -1004,6 +1011,25 @@ void DepsgraphRelationBuilder::build_animdata_curves_targets(ID *id)
}
}
+void DepsgraphRelationBuilder::build_animdata_nlastrip_targets(
+ ID *id, ComponentKey &adt_key,
+ OperationDepsNode *operation_from,
+ ListBase *strips)
+{
+ LISTBASE_FOREACH(NlaStrip *, strip, strips) {
+ if (strip->act != NULL) {
+ build_animdata_curves_targets(id, adt_key,
+ operation_from,
+ &strip->act->curves);
+ }
+ else if (strip->strips.first != NULL) {
+ build_animdata_nlastrip_targets(id, adt_key,
+ operation_from,
+ &strip->strips);
+ }
+ }
+}
+
void DepsgraphRelationBuilder::build_animdata_drivers(ID *id)
{
AnimData *adt = BKE_animdata_from_id(id);
@@ -1011,7 +1037,7 @@ void DepsgraphRelationBuilder::build_animdata_drivers(ID *id)
return;
}
ComponentKey adt_key(id, DEG_NODE_TYPE_ANIMATION);
- BLI_LISTBASE_FOREACH (FCurve *, fcu, &adt->drivers) {
+ LISTBASE_FOREACH (FCurve *, fcu, &adt->drivers) {
OperationKey driver_key(id,
DEG_NODE_TYPE_PARAMETERS,
DEG_OPCODE_DRIVER,
@@ -1034,7 +1060,7 @@ void DepsgraphRelationBuilder::build_animdata_drivers(ID *id)
*/
if (fcu->array_index > 0) {
FCurve *fcu_prev = NULL;
- BLI_LISTBASE_FOREACH (FCurve *, fcu_candidate, &adt->drivers) {
+ LISTBASE_FOREACH (FCurve *, fcu_candidate, &adt->drivers) {
/* Writing to different RNA paths is */
const char *rna_path = fcu->rna_path ? fcu->rna_path : "";
if (!STREQ(fcu_candidate->rna_path, rna_path)) {
@@ -1183,7 +1209,7 @@ void DepsgraphRelationBuilder::build_driver_variables(ID *id, FCurve *fcu)
const char *rna_path = fcu->rna_path ? fcu->rna_path : "";
const RNAPathKey self_key(id, rna_path);
- BLI_LISTBASE_FOREACH (DriverVar *, dvar, &driver->variables) {
+ LISTBASE_FOREACH (DriverVar *, dvar, &driver->variables) {
/* Only used targets. */
DRIVER_TARGETS_USED_LOOPER(dvar)
{
@@ -1298,7 +1324,7 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene)
/* objects - simulation participants */
if (rbw->group) {
- BLI_LISTBASE_FOREACH (Base *, base, &rbw->group->view_layer->object_bases) {
+ LISTBASE_FOREACH (Base *, base, &rbw->group->view_layer->object_bases) {
Object *object = base->object;
if (object == NULL || object->type != OB_MESH) {
continue;
@@ -1352,7 +1378,7 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene)
/* constraints */
if (rbw->constraints) {
- BLI_LISTBASE_FOREACH (Base *, base, &rbw->constraints->view_layer->object_bases) {
+ LISTBASE_FOREACH (Base *, base, &rbw->constraints->view_layer->object_bases) {
Object *object = base->object;
if (object == NULL || !object->rigidbody_constraint) {
continue;
@@ -1387,8 +1413,8 @@ void DepsgraphRelationBuilder::build_particles(Object *object)
DEG_NODE_TYPE_EVAL_PARTICLES,
DEG_OPCODE_PARTICLE_SYSTEM_EVAL_INIT);
- /* particle systems */
- BLI_LISTBASE_FOREACH (ParticleSystem *, psys, &object->particlesystem) {
+ /* Particle systems. */
+ LISTBASE_FOREACH (ParticleSystem *, psys, &object->particlesystem) {
ParticleSettings *part = psys->part;
/* Build particle settings relations.
@@ -1420,20 +1446,13 @@ void DepsgraphRelationBuilder::build_particles(Object *object)
add_relation(psys_key,
particle_settings_recalc_clear_key,
"Particle Settings Recalc Clear");
-
- /* XXX: if particle system is later re-enabled, we must do full rebuild? */
- if (!psys_check_enabled(object, psys, G.is_rendering))
- continue;
-
add_relation(eval_init_key, psys_key, "Init -> PSys");
-
/* TODO(sergey): Currently particle update is just a placeholder,
* hook it to the ubereval node so particle system is getting updated
* on playback.
*/
add_relation(psys_key, obdata_ubereval_key, "PSys -> UberEval");
-
- /* collisions */
+ /* Collisions */
if (part->type != PART_HAIR) {
add_collision_relations(psys_key,
scene_,
@@ -1453,8 +1472,7 @@ void DepsgraphRelationBuilder::build_particles(Object *object)
true,
"Hair Collision");
}
-
- /* effectors */
+ /* Effectors. */
add_forcefield_relations(psys_key,
scene_,
object,
@@ -1462,35 +1480,46 @@ void DepsgraphRelationBuilder::build_particles(Object *object)
part->effector_weights,
part->type == PART_HAIR,
"Particle Field");
-
- /* boids */
+ /* Boids .*/
if (part->boids) {
- BLI_LISTBASE_FOREACH (BoidState *, state, &part->boids->states) {
- BLI_LISTBASE_FOREACH (BoidRule *, rule, &state->rules) {
+ LISTBASE_FOREACH (BoidState *, state, &part->boids->states) {
+ LISTBASE_FOREACH (BoidRule *, rule, &state->rules) {
Object *ruleob = NULL;
- if (rule->type == eBoidRuleType_Avoid)
+ if (rule->type == eBoidRuleType_Avoid) {
ruleob = ((BoidRuleGoalAvoid *)rule)->ob;
- else if (rule->type == eBoidRuleType_FollowLeader)
+ }
+ else if (rule->type == eBoidRuleType_FollowLeader) {
ruleob = ((BoidRuleFollowLeader *)rule)->ob;
-
+ }
if (ruleob) {
- ComponentKey ruleob_key(&ruleob->id, DEG_NODE_TYPE_TRANSFORM);
+ ComponentKey ruleob_key(&ruleob->id,
+ DEG_NODE_TYPE_TRANSFORM);
add_relation(ruleob_key, psys_key, "Boid Rule");
}
}
}
}
-
- if (part->ren_as == PART_DRAW_OB && part->dup_ob) {
- ComponentKey dup_ob_key(&part->dup_ob->id, DEG_NODE_TYPE_TRANSFORM);
- add_relation(dup_ob_key, psys_key, "Particle Object Visualization");
- if (part->dup_ob->type == OB_MBALL) {
- ComponentKey dup_geometry_key(&part->dup_ob->id,
- DEG_NODE_TYPE_GEOMETRY);
- add_relation(obdata_ubereval_key,
- dup_geometry_key,
- "Particle MBall Visualization");
- }
+ switch (part->ren_as) {
+ case PART_DRAW_OB:
+ if (part->dup_ob != NULL) {
+ /* Make sure object's relations are all built. */
+ build_object(NULL, part->dup_ob);
+ /* Build relation for the particle visualization. */
+ build_particles_visualization_object(object,
+ psys,
+ part->dup_ob);
+ }
+ break;
+ case PART_DRAW_GR:
+ if (part->dup_group != NULL) {
+ build_group(NULL, part->dup_group);
+ LISTBASE_FOREACH (GroupObject *, go, &part->dup_group->gobject) {
+ build_particles_visualization_object(object,
+ psys,
+ go->ob);
+ }
+ }
+ break;
}
}
@@ -1503,7 +1532,11 @@ void DepsgraphRelationBuilder::build_particles(Object *object)
ComponentKey transform_key(&object->id, DEG_NODE_TYPE_TRANSFORM);
add_relation(transform_key, obdata_ubereval_key, "Partcile Eval");
- /* TODO(sergey): Do we need a point cache operations here? */
+ OperationKey point_cache_reset_key(&object->id,
+ DEG_NODE_TYPE_CACHE,
+ DEG_OPCODE_POINT_CACHE_RESET);
+ add_relation(transform_key, point_cache_reset_key, "Object Transform -> Point Cache Reset");
+ add_relation(point_cache_reset_key, obdata_ubereval_key, "Point Cache Reset -> UberEval");
}
void DepsgraphRelationBuilder::build_particle_settings(ParticleSettings *part)
@@ -1526,6 +1559,28 @@ void DepsgraphRelationBuilder::build_particle_settings(ParticleSettings *part)
add_relation(eval_key, recalc_clear_key, "Particle Settings Clear Recalc");
}
+void DepsgraphRelationBuilder::build_particles_visualization_object(
+ Object *object,
+ ParticleSystem *psys,
+ Object *draw_object)
+{
+ OperationKey psys_key(&object->id,
+ DEG_NODE_TYPE_EVAL_PARTICLES,
+ DEG_OPCODE_PARTICLE_SYSTEM_EVAL,
+ psys->name);
+ OperationKey obdata_ubereval_key(&object->id,
+ DEG_NODE_TYPE_GEOMETRY,
+ DEG_OPCODE_GEOMETRY_UBEREVAL);
+ ComponentKey dup_ob_key(&draw_object->id, DEG_NODE_TYPE_TRANSFORM);
+ add_relation(dup_ob_key, psys_key, "Particle Object Visualization");
+ if (draw_object->type == OB_MBALL) {
+ ComponentKey dup_geometry_key(&draw_object->id, DEG_NODE_TYPE_GEOMETRY);
+ add_relation(obdata_ubereval_key,
+ dup_geometry_key,
+ "Particle MBall Visualization");
+ }
+}
+
void DepsgraphRelationBuilder::build_cloth(Object *object,
ModifierData * /*md*/)
{
@@ -1613,7 +1668,7 @@ void DepsgraphRelationBuilder::build_obdata_geom(Object *object)
/* Modifiers */
if (object->modifiers.first != NULL) {
- BLI_LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
+ LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
const ModifierTypeInfo *mti = modifierType_getInfo((ModifierType)md->type);
if (mti->updateDepsgraph) {
DepsNodeHandle handle = create_node_handle(obdata_ubereval_key);
@@ -1834,7 +1889,7 @@ void DepsgraphRelationBuilder::build_nodetree(bNodeTree *ntree)
build_animdata(ntree_id);
ComponentKey shading_key(ntree_id, DEG_NODE_TYPE_SHADING);
/* nodetree's nodes... */
- BLI_LISTBASE_FOREACH (bNode *, bnode, &ntree->nodes) {
+ LISTBASE_FOREACH (bNode *, bnode, &ntree->nodes) {
ID *id = bnode->id;
if (id == NULL) {
continue;
@@ -2050,6 +2105,22 @@ void DepsgraphRelationBuilder::build_copy_on_write_relations(IDDepsNode *id_node
if (op_node->inlinks.size() == 0) {
graph_->add_new_relation(op_cow, op_node, "CoW Dependency");
}
+ else {
+ bool has_same_id_dependency = false;
+ foreach (DepsRelation *rel, op_node->inlinks) {
+ if (rel->from->type != DEG_NODE_TYPE_OPERATION) {
+ continue;
+ }
+ OperationDepsNode *op_node_from = (OperationDepsNode *)rel->from;
+ if (op_node_from->owner->owner == op_node->owner->owner) {
+ has_same_id_dependency = true;
+ break;
+ }
+ }
+ if (!has_same_id_dependency) {
+ graph_->add_new_relation(op_cow, op_node, "CoW Dependency");
+ }
+ }
}
GHASH_FOREACH_END();
/* NOTE: We currently ignore implicit relations to an external
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h
index 30b3219f989..ea7e23eca79 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h
@@ -67,13 +67,13 @@ struct bNodeTree;
struct Object;
struct bPoseChannel;
struct bConstraint;
+struct ParticleSystem;
+struct ParticleSettings;
struct Scene;
struct ViewLayer;
struct Tex;
struct World;
struct EffectorWeights;
-struct ParticleSystem;
-struct ParticleSettings;
struct PropertyRNA;
@@ -205,7 +205,14 @@ struct DepsgraphRelationBuilder
RootPChanMap *root_map);
void build_animdata(ID *id);
void build_animdata_curves(ID *id);
- void build_animdata_curves_targets(ID *id);
+ void build_animdata_curves_targets(ID *id,
+ ComponentKey &adt_key,
+ OperationDepsNode *operation_from,
+ ListBase *curves);
+ void build_animdata_nlastrip_targets(ID *id,
+ ComponentKey &adt_key,
+ OperationDepsNode *operation_from,
+ ListBase *strips);
void build_animdata_drivers(ID *id);
void build_driver(ID *id, FCurve *fcurve);
void build_driver_data(ID *id, FCurve *fcurve);
@@ -214,6 +221,9 @@ struct DepsgraphRelationBuilder
void build_rigidbody(Scene *scene);
void build_particles(Object *object);
void build_particle_settings(ParticleSettings *part);
+ void build_particles_visualization_object(Object *object,
+ ParticleSystem *psys,
+ Object *draw_object);
void build_cloth(Object *object, ModifierData *md);
void build_ik_pose(Object *object,
bPoseChannel *pchan,
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_layer_collection.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_layer_collection.cc
index 9cf82b5fb47..e2154558ed7 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations_layer_collection.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_layer_collection.cc
@@ -92,7 +92,7 @@ void DepsgraphRelationBuilder::build_layer_collections(
ListBase *layer_collections,
LayerCollectionState *state)
{
- BLI_LISTBASE_FOREACH (LayerCollection *, layer_collection, layer_collections) {
+ LISTBASE_FOREACH (LayerCollection *, layer_collection, layer_collections) {
/* Recurs into the layer. */
build_layer_collection(owner_id, layer_collection, state);
}
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 ad812a4b505..f3c3772e512 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc
@@ -341,8 +341,8 @@ void DepsgraphRelationBuilder::build_rig(Object *object)
*/
RootPChanMap root_map;
bool pose_depends_on_local_transform = false;
- BLI_LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
- BLI_LISTBASE_FOREACH (bConstraint *, con, &pchan->constraints) {
+ LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
+ LISTBASE_FOREACH (bConstraint *, con, &pchan->constraints) {
switch (con->type) {
case CONSTRAINT_TYPE_KINEMATIC:
build_ik_pose(object, pchan, con, &root_map);
@@ -382,7 +382,7 @@ void DepsgraphRelationBuilder::build_rig(Object *object)
}
/* links between operations for each bone */
- BLI_LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
+ LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
OperationKey bone_local_key(&object->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_LOCAL);
OperationKey bone_pose_key(&object->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_POSE_PARENT);
OperationKey bone_ready_key(&object->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_READY);
@@ -443,16 +443,43 @@ void DepsgraphRelationBuilder::build_rig(Object *object)
void DepsgraphRelationBuilder::build_proxy_rig(Object *object)
{
- OperationKey pose_init_key(&object->id, DEG_NODE_TYPE_EVAL_POSE, DEG_OPCODE_POSE_INIT);
- OperationKey pose_done_key(&object->id, DEG_NODE_TYPE_EVAL_POSE, DEG_OPCODE_POSE_DONE);
- BLI_LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
- OperationKey bone_local_key(&object->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_LOCAL);
- OperationKey bone_ready_key(&object->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_READY);
- OperationKey bone_done_key(&object->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_DONE);
+ Object *proxy_from = object->proxy_from;
+ OperationKey pose_init_key(&object->id,
+ DEG_NODE_TYPE_EVAL_POSE,
+ DEG_OPCODE_POSE_INIT);
+ OperationKey pose_done_key(&object->id,
+ DEG_NODE_TYPE_EVAL_POSE,
+ DEG_OPCODE_POSE_DONE);
+ LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
+ OperationKey bone_local_key(&object->id,
+ DEG_NODE_TYPE_BONE, pchan->name,
+ DEG_OPCODE_BONE_LOCAL);
+ OperationKey bone_ready_key(&object->id,
+ DEG_NODE_TYPE_BONE,
+ pchan->name,
+ DEG_OPCODE_BONE_READY);
+ OperationKey bone_done_key(&object->id,
+ DEG_NODE_TYPE_BONE,
+ pchan->name,
+ DEG_OPCODE_BONE_DONE);
add_relation(pose_init_key, bone_local_key, "Pose Init -> Bone Local");
add_relation(bone_local_key, bone_ready_key, "Local -> Ready");
add_relation(bone_ready_key, bone_done_key, "Ready -> Done");
add_relation(bone_done_key, pose_done_key, "Bone Done -> Pose Done");
+
+ if (pchan->prop != NULL) {
+ OperationKey bone_parameters(&object->id,
+ DEG_NODE_TYPE_PARAMETERS,
+ DEG_OPCODE_PARAMETERS_EVAL,
+ pchan->name);
+ OperationKey from_bone_parameters(&proxy_from->id,
+ DEG_NODE_TYPE_PARAMETERS,
+ DEG_OPCODE_PARAMETERS_EVAL,
+ pchan->name);
+ add_relation(from_bone_parameters,
+ bone_parameters,
+ "Proxy Bone Parameters");
+ }
}
}
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 cfb98fe2f79..074d20bb750 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
@@ -78,7 +78,7 @@ void DepsgraphRelationBuilder::build_view_layer(Scene *scene, ViewLayer *view_la
* passed to the evaluation functions. During relations builder we only
* do NULL-pointer check of the base, so it's fine to pass original one.
*/
- BLI_LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
build_object(base, base->object);
}
if (scene->camera != NULL) {
@@ -105,11 +105,11 @@ void DepsgraphRelationBuilder::build_view_layer(Scene *scene, ViewLayer *view_la
build_gpencil(scene->gpd);
}
/* Masks. */
- BLI_LISTBASE_FOREACH (Mask *, mask, &bmain_->mask) {
+ LISTBASE_FOREACH (Mask *, mask, &bmain_->mask) {
build_mask(mask);
}
/* Movie clips. */
- BLI_LISTBASE_FOREACH (MovieClip *, clip, &bmain_->movieclip) {
+ LISTBASE_FOREACH (MovieClip *, clip, &bmain_->movieclip) {
build_movieclip(clip);
}
/* Collections. */
diff --git a/source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc b/source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc
index 8fc4c0bcec1..ee40ca50ab5 100644
--- a/source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc
+++ b/source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc
@@ -346,7 +346,7 @@ static void deg_debug_graphviz_node(const DebugContext &ctx,
case DEG_NODE_TYPE_ID_REF:
{
const IDDepsNode *id_node = (const IDDepsNode *)node;
- if (BLI_ghash_size(id_node->components) == 0) {
+ if (BLI_ghash_len(id_node->components) == 0) {
deg_debug_graphviz_node_single(ctx, node);
}
else {
@@ -405,7 +405,7 @@ static bool deg_debug_graphviz_is_cluster(const DepsNode *node)
case DEG_NODE_TYPE_ID_REF:
{
const IDDepsNode *id_node = (const IDDepsNode *)node;
- return BLI_ghash_size(id_node->components) > 0;
+ return BLI_ghash_len(id_node->components) > 0;
}
case DEG_NODE_TYPE_PARAMETERS:
case DEG_NODE_TYPE_ANIMATION:
@@ -467,7 +467,7 @@ static void deg_debug_graphviz_node_relations(const DebugContext &ctx,
deg_debug_fprintf(ctx, "[");
/* Note: without label an id seem necessary to avoid bugs in graphviz/dot */
deg_debug_fprintf(ctx, "id=\"%s\"", rel->name);
- deg_debug_fprintf(ctx, "label=\"%s\"", rel->name);
+ // deg_debug_fprintf(ctx, "label=\"%s\"", rel->name);
deg_debug_fprintf(ctx, ",color="); deg_debug_graphviz_relation_color(ctx, rel);
deg_debug_fprintf(ctx, ",penwidth=\"%f\"", penwidth);
/* NOTE: edge from node to own cluster is not possible and gives graphviz
diff --git a/source/blender/depsgraph/intern/depsgraph.cc b/source/blender/depsgraph/intern/depsgraph.cc
index 3a78c9050f7..3b5ea2bfc3f 100644
--- a/source/blender/depsgraph/intern/depsgraph.cc
+++ b/source/blender/depsgraph/intern/depsgraph.cc
@@ -167,7 +167,7 @@ static bool pointer_to_component_node_criteria(
return true;
}
else if (object->pose != NULL) {
- BLI_LISTBASE_FOREACH(bPoseChannel *, pchan, &object->pose->chanbase) {
+ LISTBASE_FOREACH(bPoseChannel *, pchan, &object->pose->chanbase) {
if (BLI_findindex(&pchan->constraints, con) != -1) {
/* bone transforms */
*type = DEG_NODE_TYPE_BONE;
@@ -220,6 +220,10 @@ static bool pointer_to_component_node_criteria(
*subdata = seq->name; // xxx?
return true;
}
+ else if (RNA_struct_is_a(ptr->type, &RNA_NodeSocket)) {
+ *type = DEG_NODE_TYPE_SHADING;
+ return true;
+ }
if (prop != NULL) {
/* All unknown data effectively falls under "parameter evaluation". */
*type = DEG_NODE_TYPE_PARAMETERS;
diff --git a/source/blender/depsgraph/intern/depsgraph_build.cc b/source/blender/depsgraph/intern/depsgraph_build.cc
index 902cbe039cd..377f2d3b4c5 100644
--- a/source/blender/depsgraph/intern/depsgraph_build.cc
+++ b/source/blender/depsgraph/intern/depsgraph_build.cc
@@ -47,7 +47,7 @@ extern "C" {
#include "DNA_cachefile_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
-#include "DNA_object_force.h"
+#include "DNA_object_force_types.h"
#include "BKE_main.h"
#include "BKE_collision.h"
@@ -215,7 +215,7 @@ void DEG_graph_build_from_view_layer(Depsgraph *graph,
* This now could happen for both visible scene is changed and extra
* dependency graph was created for render engine.
*/
- const bool need_on_visible_update = (deg_graph->scene == NULL);
+ const bool need_on_visible_update = (deg_graph->id_nodes.size() == 0);
/* 1) Generate all the nodes in the graph first */
DEG::DepsgraphNodeBuilder node_builder(bmain, deg_graph);
@@ -294,8 +294,8 @@ void DEG_graph_relations_update(Depsgraph *graph,
void DEG_relations_tag_update(Main *bmain)
{
DEG_DEBUG_PRINTF("%s: Tagging relations for update.\n", __func__);
- BLI_LISTBASE_FOREACH (Scene *, scene, &bmain->scene) {
- BLI_LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
+ LISTBASE_FOREACH (Scene *, scene, &bmain->scene) {
+ LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
Depsgraph *depsgraph =
(Depsgraph *)BKE_scene_get_depsgraph(scene,
view_layer,
diff --git a/source/blender/depsgraph/intern/depsgraph_eval.cc b/source/blender/depsgraph/intern/depsgraph_eval.cc
index ad1a850a807..4fb5a8ff580 100644
--- a/source/blender/depsgraph/intern/depsgraph_eval.cc
+++ b/source/blender/depsgraph/intern/depsgraph_eval.cc
@@ -76,17 +76,20 @@ void DEG_evaluation_context_init(EvaluationContext *eval_ctx,
eval_ctx->mode = mode;
}
-void DEG_evaluation_context_init_from_scene(EvaluationContext *eval_ctx,
- Scene *scene,
- ViewLayer *view_layer,
- RenderEngineType *engine_type,
- eEvaluationMode mode)
+void DEG_evaluation_context_init_from_scene(
+ EvaluationContext *eval_ctx,
+ Scene *scene,
+ ViewLayer *view_layer,
+ RenderEngineType *engine_type,
+ eObjectMode object_mode,
+ eEvaluationMode mode)
{
DEG_evaluation_context_init(eval_ctx, mode);
eval_ctx->depsgraph = BKE_scene_get_depsgraph(scene, view_layer, true);
eval_ctx->view_layer = view_layer;
eval_ctx->engine_type = engine_type;
eval_ctx->ctime = BKE_scene_frame_get(scene);
+ eval_ctx->object_mode = object_mode;
}
/* Free evaluation context. */
@@ -125,5 +128,5 @@ void DEG_evaluate_on_framechange(EvaluationContext *eval_ctx,
bool DEG_needs_eval(Depsgraph *graph)
{
DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(graph);
- return BLI_gset_size(deg_graph->entry_tags) != 0;
+ return BLI_gset_len(deg_graph->entry_tags) != 0;
}
diff --git a/source/blender/depsgraph/intern/depsgraph_query_iter.cc b/source/blender/depsgraph/intern/depsgraph_query_iter.cc
index 30c9d9f10be..fd54030a4e0 100644
--- a/source/blender/depsgraph/intern/depsgraph_query_iter.cc
+++ b/source/blender/depsgraph/intern/depsgraph_query_iter.cc
@@ -110,10 +110,18 @@ static 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->transflag &= ~OB_DUPLI;
temp_dupli_object->select_color = dupli_parent->select_color;
temp_dupli_object->base_flag = dupli_parent->base_flag | BASE_FROMDUPLI;
+ /* Duplicated elements shouldn't care whether their original collection is visible or not. */
+ temp_dupli_object->base_flag |= BASE_VISIBLED;
+
+ if (BKE_object_is_visible(temp_dupli_object, (eObjectVisibilityCheck)data->visibility_check) == false) {
+ continue;
+ }
+
+ temp_dupli_object->transflag &= ~OB_DUPLI;
+
if (dob->collection_properties != NULL) {
temp_dupli_object->base_collection_properties = dob->collection_properties;
IDP_MergeGroup(temp_dupli_object->base_collection_properties,
@@ -181,11 +189,7 @@ static void DEG_iterator_objects_step(BLI_Iterator *iter, DEG::IDDepsNode *id_no
data->dupli_parent = object;
data->dupli_list = object_duplilist(&data->eval_ctx, data->scene, object);
data->dupli_object_next = (DupliObject *)data->dupli_list->first;
- const eObjectVisibilityCheck mode =
- (data->mode == DEG_ITER_OBJECT_MODE_RENDER)
- ? OB_VISIBILITY_CHECK_FOR_RENDER
- : OB_VISIBILITY_CHECK_FOR_VIEWPORT;
- if (BKE_object_is_visible(object, mode) == false) {
+ if (BKE_object_is_visible(object, (eObjectVisibilityCheck)data->visibility_check) == false) {
return;
}
}
@@ -220,6 +224,9 @@ void DEG_iterator_objects_begin(BLI_Iterator *iter, DEGObjectIterData *data)
data->scene = DEG_get_evaluated_scene(depsgraph);
data->id_node_index = 0;
data->num_id_nodes = num_id_nodes;
+ data->visibility_check = (data->mode == DEG_ITER_OBJECT_MODE_RENDER)
+ ? OB_VISIBILITY_CHECK_FOR_RENDER
+ : OB_VISIBILITY_CHECK_FOR_VIEWPORT;
DEG::IDDepsNode *id_node = deg_graph->id_nodes[data->id_node_index];
DEG_iterator_objects_step(iter, id_node);
diff --git a/source/blender/depsgraph/intern/depsgraph_tag.cc b/source/blender/depsgraph/intern/depsgraph_tag.cc
index 38f43f5720b..b0b3cbe0f8c 100644
--- a/source/blender/depsgraph/intern/depsgraph_tag.cc
+++ b/source/blender/depsgraph/intern/depsgraph_tag.cc
@@ -40,12 +40,15 @@
#include "BLI_task.h"
extern "C" {
+#include "DNA_curve_types.h"
+#include "DNA_key_types.h"
+#include "DNA_lattice_types.h"
+#include "DNA_mesh_types.h"
#include "DNA_object_types.h"
#include "DNA_particle_types.h"
#include "DNA_screen_types.h"
#include "DNA_windowmanager_types.h"
-
#include "BKE_idcode.h"
#include "BKE_library.h"
#include "BKE_main.h"
@@ -92,6 +95,7 @@ void depsgraph_geometry_tag_to_component(const ID *id,
case OB_CURVE:
case OB_SURF:
case OB_FONT:
+ case OB_LATTICE:
case OB_MBALL:
*component_type = DEG_NODE_TYPE_GEOMETRY;
break;
@@ -294,11 +298,50 @@ void deg_graph_id_tag_legacy_compat(Main *bmain,
ID *id,
eDepsgraph_Tag tag)
{
- if (tag == DEG_TAG_GEOMETRY && GS(id->name) == ID_OB) {
- Object *object = (Object *)id;
- ID *data_id = (ID *)object->data;
- if (data_id != NULL) {
- DEG_id_tag_update_ex(bmain, data_id, 0);
+ if (tag == DEG_TAG_GEOMETRY || tag == 0) {
+ switch (GS(id->name)) {
+ case ID_OB:
+ {
+ Object *object = (Object *)id;
+ ID *data_id = (ID *)object->data;
+ if (data_id != NULL) {
+ DEG_id_tag_update_ex(bmain, data_id, 0);
+ }
+ break;
+ }
+ /* TODO(sergey): Shape keys are annoying, maybe we should find a
+ * way to chain geometry evaluation to them, so we don't need extra
+ * tagging here.
+ */
+ case ID_ME:
+ {
+ Mesh *mesh = (Mesh *)id;
+ ID *key_id = &mesh->key->id;
+ if (key_id != NULL) {
+ DEG_id_tag_update_ex(bmain, key_id, 0);
+ }
+ break;
+ }
+ case ID_LT:
+ {
+ Lattice *lattice = (Lattice *)id;
+ ID *key_id = &lattice->key->id;
+ if (key_id != NULL) {
+ DEG_id_tag_update_ex(bmain, key_id, 0);
+ }
+ break;
+ }
+ case ID_CU:
+ {
+ Curve *curve = (Curve *)id;
+ ID *key_id = &curve->key->id;
+ if (key_id != NULL) {
+ DEG_id_tag_update_ex(bmain, key_id, 0);
+ }
+ break;
+ }
+ default:
+ break;
}
}
}
@@ -364,6 +407,7 @@ void deg_graph_id_tag_update(Main *bmain, Depsgraph *graph, ID *id, int flag)
if (id_node != NULL) {
id_node->tag_update(graph);
}
+ deg_graph_id_tag_legacy_compat(bmain, id, (eDepsgraph_Tag)0);
}
int current_flag = flag;
while (current_flag != 0) {
@@ -396,8 +440,8 @@ void deg_ensure_scene_view_layer(Depsgraph *graph,
void deg_id_tag_update(Main *bmain, ID *id, int flag)
{
deg_graph_id_tag_update(bmain, NULL, id, flag);
- BLI_LISTBASE_FOREACH (Scene *, scene, &bmain->scene) {
- BLI_LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
+ LISTBASE_FOREACH (Scene *, scene, &bmain->scene) {
+ LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
Depsgraph *depsgraph =
(Depsgraph *)BKE_scene_get_depsgraph(scene,
view_layer,
@@ -437,8 +481,12 @@ void deg_graph_on_visible_update(Main *bmain, Depsgraph *graph)
scene_iter = scene_iter->set)
{
IDDepsNode *scene_id_node = graph->find_id_node(&scene_iter->id);
- BLI_assert(scene_id_node != NULL);
- scene_id_node->tag_update(graph);
+ if (scene_id_node != NULL) {
+ scene_id_node->tag_update(graph);
+ }
+ else {
+ BLI_assert(graph->need_update);
+ }
}
}
@@ -507,8 +555,8 @@ void DEG_graph_on_visible_update(Main *bmain, Depsgraph *depsgraph)
void DEG_on_visible_update(Main *bmain, const bool UNUSED(do_time))
{
- BLI_LISTBASE_FOREACH (Scene *, scene, &bmain->scene) {
- BLI_LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
+ LISTBASE_FOREACH (Scene *, scene, &bmain->scene) {
+ LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
Depsgraph *depsgraph =
(Depsgraph *)BKE_scene_get_depsgraph(scene,
view_layer,
diff --git a/source/blender/depsgraph/intern/depsgraph_type_defines.cc b/source/blender/depsgraph/intern/depsgraph_type_defines.cc
index 22df3161428..886601225c7 100644
--- a/source/blender/depsgraph/intern/depsgraph_type_defines.cc
+++ b/source/blender/depsgraph/intern/depsgraph_type_defines.cc
@@ -119,6 +119,8 @@ static const char *stringify_opcode(eDepsOperation_Code opcode)
STRINGIFY_OPCODE(PARTICLE_SYSTEM_EVAL);
STRINGIFY_OPCODE(PARTICLE_SETTINGS_EVAL);
STRINGIFY_OPCODE(PARTICLE_SETTINGS_RECALC_CLEAR);
+ /* Point Cache. */
+ STRINGIFY_OPCODE(POINT_CACHE_RESET);
/* Batch cache. */
STRINGIFY_OPCODE(GEOMETRY_SELECT_UPDATE);
/* Masks. */
diff --git a/source/blender/depsgraph/intern/depsgraph_types.h b/source/blender/depsgraph/intern/depsgraph_types.h
index d091f42bf80..3f4df21b8d6 100644
--- a/source/blender/depsgraph/intern/depsgraph_types.h
+++ b/source/blender/depsgraph/intern/depsgraph_types.h
@@ -240,6 +240,9 @@ typedef enum eDepsOperation_Code {
DEG_OPCODE_PARTICLE_SETTINGS_EVAL,
DEG_OPCODE_PARTICLE_SETTINGS_RECALC_CLEAR,
+ /* Point Cache. ------------------------------------- */
+ DEG_OPCODE_POINT_CACHE_RESET,
+
/* Collections. ------------------------------------- */
DEG_OPCODE_VIEW_LAYER_INIT,
DEG_OPCODE_VIEW_LAYER_EVAL,
diff --git a/source/blender/depsgraph/intern/eval/deg_eval.cc b/source/blender/depsgraph/intern/eval/deg_eval.cc
index a6c6a16a528..c3aa84943d3 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval.cc
@@ -231,7 +231,7 @@ void deg_evaluate_on_refresh(EvaluationContext *eval_ctx,
Depsgraph *graph)
{
/* Nothing to update, early out. */
- if (BLI_gset_size(graph->entry_tags) == 0) {
+ if (BLI_gset_len(graph->entry_tags) == 0) {
return;
}
/* Set time for the current graph evaluation context. */
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 a6668208574..8bdc68d9351 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
@@ -63,8 +63,10 @@ extern "C" {
#include "DNA_object_types.h"
#ifdef NESTED_ID_NASTY_WORKAROUND
+# include "DNA_curve_types.h"
# include "DNA_key_types.h"
# include "DNA_lamp_types.h"
+# include "DNA_lattice_types.h"
# include "DNA_linestyle_types.h"
# include "DNA_material_types.h"
# include "DNA_node_types.h"
@@ -91,8 +93,10 @@ namespace {
#ifdef NESTED_ID_NASTY_WORKAROUND
union NestedIDHackTempStorage {
+ Curve curve;
FreestyleLineStyle linestyle;
Lamp lamp;
+ Lattice lattice;
Material material;
Mesh mesh;
Scene scene;
@@ -118,6 +122,8 @@ void nested_id_hack_discard_pointers(ID *id_cow)
SPECIAL_CASE(ID_TE, Tex, nodetree)
SPECIAL_CASE(ID_WO, World, nodetree)
+ SPECIAL_CASE(ID_CU, Curve, key)
+ SPECIAL_CASE(ID_LT, Lattice, key)
SPECIAL_CASE(ID_ME, Mesh, key)
# undef SPECIAL_CASE
@@ -150,6 +156,8 @@ const ID *nested_id_hack_get_discarded_pointers(NestedIDHackTempStorage *storage
SPECIAL_CASE(ID_TE, Tex, nodetree, tex)
SPECIAL_CASE(ID_WO, World, nodetree, world)
+ SPECIAL_CASE(ID_CU, Curve, key, curve)
+ SPECIAL_CASE(ID_LT, Lattice, key, lattice)
SPECIAL_CASE(ID_ME, Mesh, key, mesh)
# undef SPECIAL_CASE
@@ -182,6 +190,8 @@ void nested_id_hack_restore_pointers(const ID *old_id, ID *new_id)
SPECIAL_CASE(ID_TE, Tex, nodetree)
SPECIAL_CASE(ID_WO, World, nodetree)
+ SPECIAL_CASE(ID_CU, Curve, key)
+ SPECIAL_CASE(ID_LT, Lattice, key)
SPECIAL_CASE(ID_ME, Mesh, key)
#undef SPECIAL_CASE
@@ -218,6 +228,8 @@ void ntree_hack_remap_pointers(const Depsgraph *depsgraph, ID *id_cow)
SPECIAL_CASE(ID_TE, Tex, nodetree, bNodeTree)
SPECIAL_CASE(ID_WO, World, nodetree, bNodeTree)
+ SPECIAL_CASE(ID_CU, Curve, key, Key)
+ SPECIAL_CASE(ID_LT, Lattice, key, Key)
SPECIAL_CASE(ID_ME, Mesh, key, Key)
#undef SPECIAL_CASE
@@ -424,11 +436,9 @@ void update_special_pointers(const Depsgraph *depsgraph,
* new copy of the object.
*/
Object *object_cow = (Object *)id_cow;
- const Object *object_orig = (const Object *)id_orig;
(void) object_cow; /* Ignored for release builds. */
BLI_assert(object_cow->derivedFinal == NULL);
BLI_assert(object_cow->derivedDeform == NULL);
- object_cow->mode = object_orig->mode;
break;
}
case ID_ME:
@@ -451,18 +461,6 @@ void update_special_pointers(const Depsgraph *depsgraph,
}
break;
}
- case ID_SCE:
- {
- const Scene *scene_orig = (const Scene *)id_orig;
- Scene *scene_cow = (Scene *)id_cow;
- if (scene_orig->obedit != NULL) {
- scene_cow->obedit = (Object *)depsgraph->get_cow_id(&scene_orig->obedit->id);
- }
- else {
- scene_cow->obedit = NULL;
- }
- break;
- }
default:
break;
}
@@ -612,13 +610,6 @@ void update_copy_on_write_scene(const Depsgraph *depsgraph,
update_copy_on_write_view_layers(depsgraph, scene_cow, scene_orig);
update_copy_on_write_scene_collection(scene_cow->collection,
scene_orig->collection);
- // Update edit object pointer.
- if (scene_orig->obedit != NULL) {
- scene_cow->obedit = (Object *)depsgraph->get_cow_id(&scene_orig->obedit->id);
- }
- else {
- scene_cow->obedit = NULL;
- }
/* Synchronize active render engine. */
BLI_strncpy(scene_cow->view_render.engine_id,
scene_orig->view_render.engine_id,
@@ -640,7 +631,6 @@ void update_copy_on_write_object(const Depsgraph * /*depsgraph*/,
extract_pose_from_pose(pose_cow, pose_orig);
/* Update object itself. */
BKE_object_transform_copy(object_cow, object_orig);
- object_cow->mode = object_orig->mode;
}
/* Update copy-on-write version of datablock from it's original ID without re-building
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
index c0d5e08b80f..b4e1c2f4e1a 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
@@ -214,7 +214,7 @@ void flush_engine_data_update(ID *id)
return;
}
Object *object = (Object *)id;
- BLI_LISTBASE_FOREACH(ObjectEngineData *, engine_data, &object->drawdata) {
+ LISTBASE_FOREACH(ObjectEngineData *, engine_data, &object->drawdata) {
engine_data->recalc |= id->recalc;
}
}
@@ -271,7 +271,7 @@ void deg_graph_flush_updates(Main *bmain, Depsgraph *graph)
BLI_assert(bmain != NULL);
BLI_assert(graph != NULL);
/* Nothing to update, early out. */
- if (BLI_gset_size(graph->entry_tags) == 0) {
+ if (BLI_gset_len(graph->entry_tags) == 0) {
return;
}
/* Reset all flags, get ready for the flush. */
diff --git a/source/blender/depsgraph/intern/nodes/deg_node_component.cc b/source/blender/depsgraph/intern/nodes/deg_node_component.cc
index 1f56edd1f87..6c33856555e 100644
--- a/source/blender/depsgraph/intern/nodes/deg_node_component.cc
+++ b/source/blender/depsgraph/intern/nodes/deg_node_component.cc
@@ -301,7 +301,7 @@ OperationDepsNode *ComponentDepsNode::get_entry_operation()
if (entry_operation) {
return entry_operation;
}
- else if (operations_map != NULL && BLI_ghash_size(operations_map) == 1) {
+ else if (operations_map != NULL && BLI_ghash_len(operations_map) == 1) {
OperationDepsNode *op_node = NULL;
/* TODO(sergey): This is somewhat slow. */
GHASH_FOREACH_BEGIN(OperationDepsNode *, tmp, operations_map)
@@ -324,7 +324,7 @@ OperationDepsNode *ComponentDepsNode::get_exit_operation()
if (exit_operation) {
return exit_operation;
}
- else if (operations_map != NULL && BLI_ghash_size(operations_map) == 1) {
+ else if (operations_map != NULL && BLI_ghash_len(operations_map) == 1) {
OperationDepsNode *op_node = NULL;
/* TODO(sergey): This is somewhat slow. */
GHASH_FOREACH_BEGIN(OperationDepsNode *, tmp, operations_map)
@@ -344,7 +344,7 @@ OperationDepsNode *ComponentDepsNode::get_exit_operation()
void ComponentDepsNode::finalize_build(Depsgraph * /*graph*/)
{
- operations.reserve(BLI_ghash_size(operations_map));
+ operations.reserve(BLI_ghash_len(operations_map));
GHASH_FOREACH_BEGIN(OperationDepsNode *, op_node, operations_map)
{
operations.push_back(op_node);
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 1bff4b875ce..51b3db695c2 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -92,6 +92,7 @@ set(SRC
engines/eevee/eevee_lightprobes.c
engines/eevee/eevee_lights.c
engines/eevee/eevee_materials.c
+ engines/eevee/eevee_mist.c
engines/eevee/eevee_motion_blur.c
engines/eevee/eevee_occlusion.c
engines/eevee/eevee_render.c
@@ -161,6 +162,7 @@ data_to_c_simple(engines/eevee/shaders/effect_downsample_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/effect_downsample_cube_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/effect_gtao_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/effect_minmaxz_frag.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/effect_mist_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/effect_motion_blur_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/effect_ssr_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/effect_subsurface_frag.glsl SRC)
diff --git a/source/blender/draw/DRW_engine.h b/source/blender/draw/DRW_engine.h
index c4946e2a4b8..9baad113c42 100644
--- a/source/blender/draw/DRW_engine.h
+++ b/source/blender/draw/DRW_engine.h
@@ -26,6 +26,8 @@
#ifndef __DRW_ENGINE_H__
#define __DRW_ENGINE_H__
+#include "BLI_sys_types.h" /* for bool */
+
struct ARegion;
struct CollectionEngineSettings;
struct Depsgraph;
@@ -50,7 +52,7 @@ struct RenderEngine;
struct RenderEngineType;
struct WorkSpace;
-#include "BLI_sys_types.h" /* for bool */
+#include "DNA_object_enums.h"
/* Buffer and textures used by the viewport by default */
typedef struct DefaultFramebufferList {
@@ -91,25 +93,25 @@ void DRW_draw_view(const struct bContext *C);
void DRW_draw_render_loop_ex(
struct Depsgraph *depsgraph,
struct RenderEngineType *engine_type,
- struct ARegion *ar, struct View3D *v3d,
+ struct ARegion *ar, struct View3D *v3d, const eObjectMode object_mode,
const struct bContext *evil_C);
void DRW_draw_render_loop(
struct Depsgraph *depsgraph,
- struct ARegion *ar, struct View3D *v3d);
+ struct ARegion *ar, struct View3D *v3d, const eObjectMode object_mode);
void DRW_draw_render_loop_offscreen(
struct Depsgraph *depsgraph,
struct RenderEngineType *engine_type,
- struct ARegion *ar, struct View3D *v3d,
+ struct ARegion *ar, struct View3D *v3d, const eObjectMode object_mode,
const bool draw_background,
struct GPUOffScreen *ofs,
struct GPUViewport *viewport);
void DRW_draw_select_loop(
struct Depsgraph *depsgraph,
- struct ARegion *ar, struct View3D *v3d,
+ struct ARegion *ar, struct View3D *v3d, const eObjectMode object_mode,
bool use_obedit_skip, bool use_nearest, const struct rcti *rect);
void DRW_draw_depth_loop(
struct Depsgraph *depsgraph,
- struct ARegion *ar, struct View3D *v3d);
+ struct ARegion *ar, struct View3D *v3d, const eObjectMode object_mode);
/* This is here because GPUViewport needs it */
void DRW_pass_free(struct DRWPass *pass);
diff --git a/source/blender/draw/engines/clay/clay_engine.c b/source/blender/draw/engines/clay/clay_engine.c
index d2bf164efdc..4b554f776a6 100644
--- a/source/blender/draw/engines/clay/clay_engine.c
+++ b/source/blender/draw/engines/clay/clay_engine.c
@@ -116,8 +116,6 @@ typedef struct CLAY_Storage {
typedef struct CLAY_StorageList {
struct CLAY_Storage *storage;
- struct GPUUniformBuffer *mat_ubo;
- struct GPUUniformBuffer *hair_mat_ubo;
struct CLAY_PrivateData *g_data;
} CLAY_StorageList;
@@ -146,6 +144,9 @@ typedef struct CLAY_Data {
typedef struct CLAY_ViewLayerData {
struct GPUTexture *jitter_tx;
+ struct GPUUniformBuffer *mat_ubo;
+ struct GPUUniformBuffer *matcaps_ubo;
+ struct GPUUniformBuffer *hair_mat_ubo;
struct GPUUniformBuffer *sampling_ubo;
int cached_sample_num;
} CLAY_ViewLayerData;
@@ -162,7 +163,7 @@ static struct {
/* Matcap textures */
struct GPUTexture *matcap_array;
- float matcap_colors[24][3];
+ float matcap_colors[24][4];
/* Ssao */
float winmat[4][4];
@@ -192,6 +193,9 @@ static void clay_view_layer_data_free(void *storage)
{
CLAY_ViewLayerData *sldata = (CLAY_ViewLayerData *)storage;
+ DRW_UBO_FREE_SAFE(sldata->mat_ubo);
+ DRW_UBO_FREE_SAFE(sldata->matcaps_ubo);
+ DRW_UBO_FREE_SAFE(sldata->hair_mat_ubo);
DRW_UBO_FREE_SAFE(sldata->sampling_ubo);
DRW_TEXTURE_FREE_SAFE(sldata->jitter_tx);
}
@@ -399,12 +403,16 @@ static void clay_engine_init(void *vedata)
stl->storage = MEM_callocN(sizeof(CLAY_Storage), "CLAY_Storage");
}
- if (!stl->mat_ubo) {
- stl->mat_ubo = DRW_uniformbuffer_create(sizeof(CLAY_UBO_Storage), NULL);
+ if (!sldata->mat_ubo) {
+ sldata->mat_ubo = DRW_uniformbuffer_create(sizeof(CLAY_UBO_Storage), NULL);
+ }
+
+ if (!sldata->hair_mat_ubo) {
+ sldata->hair_mat_ubo = DRW_uniformbuffer_create(sizeof(CLAY_HAIR_UBO_Storage), NULL);
}
- if (!stl->hair_mat_ubo) {
- stl->hair_mat_ubo = DRW_uniformbuffer_create(sizeof(CLAY_HAIR_UBO_Storage), NULL);
+ if (!sldata->matcaps_ubo) {
+ sldata->matcaps_ubo = DRW_uniformbuffer_create(sizeof(e_data.matcap_colors), e_data.matcap_colors);
}
if (e_data.ubo_mat_idxs[1] == 0) {
@@ -495,9 +503,8 @@ static void clay_engine_init(void *vedata)
}
}
-static DRWShadingGroup *CLAY_shgroup_create(CLAY_Data *vedata, DRWPass *pass, int *material_id, bool use_flat)
+static DRWShadingGroup *CLAY_shgroup_create(CLAY_Data *UNUSED(vedata), DRWPass *pass, int *material_id, bool use_flat)
{
- CLAY_StorageList *stl = vedata->stl;
CLAY_ViewLayerData *sldata = CLAY_view_layer_data_get();
DRWShadingGroup *grp = DRW_shgroup_create(use_flat ? e_data.clay_flat_sh : e_data.clay_sh, pass);
@@ -507,25 +514,26 @@ static DRWShadingGroup *CLAY_shgroup_create(CLAY_Data *vedata, DRWPass *pass, in
DRW_shgroup_uniform_mat4(grp, "WinMatrix", (float *)e_data.winmat);
DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)e_data.viewvecs, 3);
DRW_shgroup_uniform_vec4(grp, "ssao_params", e_data.ssao_params, 1);
- DRW_shgroup_uniform_vec3(grp, "matcaps_color[0]", (float *)e_data.matcap_colors, 24);
DRW_shgroup_uniform_int(grp, "mat_id", material_id, 1);
DRW_shgroup_uniform_texture(grp, "ssao_jitter", sldata->jitter_tx);
DRW_shgroup_uniform_block(grp, "samples_block", sldata->sampling_ubo);
- DRW_shgroup_uniform_block(grp, "material_block", stl->mat_ubo);
+ DRW_shgroup_uniform_block(grp, "material_block", sldata->mat_ubo);
+ DRW_shgroup_uniform_block(grp, "matcaps_block", sldata->matcaps_ubo);
return grp;
}
-static DRWShadingGroup *CLAY_hair_shgroup_create(CLAY_Data *vedata, DRWPass *pass, int *material_id)
+static DRWShadingGroup *CLAY_hair_shgroup_create(CLAY_Data *UNUSED(vedata), DRWPass *pass, int *material_id)
{
- CLAY_StorageList *stl = vedata->stl;
+ CLAY_ViewLayerData *sldata = CLAY_view_layer_data_get();
DRWShadingGroup *grp = DRW_shgroup_create(e_data.hair_sh, pass);
DRW_shgroup_uniform_texture(grp, "matcaps", e_data.matcap_array);
DRW_shgroup_uniform_int(grp, "mat_id", material_id, 1);
- DRW_shgroup_uniform_block(grp, "material_block", stl->mat_ubo);
+ DRW_shgroup_uniform_block(grp, "material_block", sldata->mat_ubo);
+ DRW_shgroup_uniform_block(grp, "matcaps_block", sldata->matcaps_ubo);
return grp;
}
@@ -762,11 +770,7 @@ static void clay_cache_populate_particles(void *vedata, Object *ob)
CLAY_StorageList *stl = ((CLAY_Data *)vedata)->stl;
const DRWContextState *draw_ctx = DRW_context_state_get();
-
- Scene *scene = draw_ctx->scene;
- Object *obedit = scene->obedit;
-
- if (ob != obedit) {
+ if (ob != draw_ctx->object_edit) {
for (ParticleSystem *psys = ob->particlesystem.first; psys; psys = psys->next) {
if (psys_check_enabled(ob, psys, false)) {
ParticleSettings *part = psys->part;
@@ -820,7 +824,7 @@ static void clay_cache_populate(void *vedata, Object *ob)
if (geom) {
IDProperty *ces_mode_ob = BKE_layer_collection_engine_evaluated_get(ob, COLLECTION_MODE_OBJECT, "");
const bool do_cull = BKE_collection_engine_property_value_get_bool(ces_mode_ob, "show_backface_culling");
- const bool is_sculpt_mode = is_active && (ob->mode & OB_MODE_SCULPT) != 0;
+ const bool is_sculpt_mode = is_active && (draw_ctx->object_mode & OB_MODE_SCULPT) != 0;
const bool is_default_mode_shader = is_sculpt_mode;
/* Depth Prepass */
@@ -853,10 +857,11 @@ static void clay_cache_populate(void *vedata, Object *ob)
static void clay_cache_finish(void *vedata)
{
+ CLAY_ViewLayerData *sldata = CLAY_view_layer_data_get();
CLAY_StorageList *stl = ((CLAY_Data *)vedata)->stl;
- DRW_uniformbuffer_update(stl->mat_ubo, &stl->storage->mat_storage);
- DRW_uniformbuffer_update(stl->hair_mat_ubo, &stl->storage->hair_mat_storage);
+ DRW_uniformbuffer_update(sldata->mat_ubo, &stl->storage->mat_storage);
+ DRW_uniformbuffer_update(sldata->hair_mat_ubo, &stl->storage->hair_mat_storage);
}
static void clay_draw_scene(void *vedata)
diff --git a/source/blender/draw/engines/clay/shaders/clay_frag.glsl b/source/blender/draw/engines/clay/shaders/clay_frag.glsl
index 9c8c90bd5b6..619843e2a02 100644
--- a/source/blender/draw/engines/clay/shaders/clay_frag.glsl
+++ b/source/blender/draw/engines/clay/shaders/clay_frag.glsl
@@ -4,7 +4,6 @@ uniform mat4 WinMatrix;
/* Matcap */
uniform sampler2DArray matcaps;
-uniform vec3 matcaps_color[24];
/* Screen Space Occlusion */
/* store the view space vectors for the corners of the view frustum here.
@@ -26,6 +25,10 @@ layout(std140) uniform samples_block {
vec4 ssao_samples[500];
};
+layout(std140) uniform matcaps_block {
+ vec4 matcaps_color[24];
+};
+
layout(std140) uniform material_block {
Material matcaps_param[MAX_MATERIAL];
};
@@ -185,7 +188,7 @@ void main() {
float cavity, edges;
ssao_factors(depth, normal, position, screenco, cavity, edges);
- col *= mix(vec3(1.0), matcaps_color[int(matcap_index)], cavity);
+ col *= mix(vec3(1.0), matcaps_color[int(matcap_index)].rgb, cavity);
#endif
#ifdef USE_HSV
diff --git a/source/blender/draw/engines/eevee/eevee_bloom.c b/source/blender/draw/engines/eevee/eevee_bloom.c
index 63c030a574f..1b015a51f6a 100644
--- a/source/blender/draw/engines/eevee/eevee_bloom.c
+++ b/source/blender/draw/engines/eevee/eevee_bloom.c
@@ -145,14 +145,8 @@ int EEVEE_bloom_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
for (int i = 0; i < effects->bloom_iteration_ct; ++i) {
texsize[0] /= 2; texsize[1] /= 2;
- if (GPU_type_matches(GPU_DEVICE_AMD_VEGA, GPU_OS_UNIX, GPU_DRIVER_OPENSOURCE)) {
- texsize[0] = MAX2(texsize[0], 17);
- texsize[1] = MAX2(texsize[1], 17);
- }
- else {
- texsize[0] = MAX2(texsize[0], 2);
- texsize[1] = MAX2(texsize[1], 2);
- }
+ texsize[0] = MAX2(texsize[0], 2);
+ texsize[1] = MAX2(texsize[1], 2);
effects->downsamp_texel_size[i][0] = 1.0f / (float)texsize[0];
effects->downsamp_texel_size[i][1] = 1.0f / (float)texsize[1];
@@ -168,14 +162,8 @@ int EEVEE_bloom_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
for (int i = 0; i < effects->bloom_iteration_ct - 1; ++i) {
texsize[0] /= 2; texsize[1] /= 2;
- if (GPU_type_matches(GPU_DEVICE_AMD_VEGA, GPU_OS_UNIX, GPU_DRIVER_OPENSOURCE)) {
- texsize[0] = MAX2(texsize[0], 17);
- texsize[1] = MAX2(texsize[1], 17);
- }
- else {
- texsize[0] = MAX2(texsize[0], 2);
- texsize[1] = MAX2(texsize[1], 2);
- }
+ texsize[0] = MAX2(texsize[0], 2);
+ texsize[1] = MAX2(texsize[1], 2);
DRWFboTexture tex_bloom = {&txl->bloom_upsample[i], DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER};
DRW_framebuffer_init(&fbl->bloom_accum_fb[i], &draw_engine_eevee_type,
diff --git a/source/blender/draw/engines/eevee/eevee_data.c b/source/blender/draw/engines/eevee/eevee_data.c
index c6e5f645f10..449668d8590 100644
--- a/source/blender/draw/engines/eevee/eevee_data.c
+++ b/source/blender/draw/engines/eevee/eevee_data.c
@@ -143,8 +143,8 @@ EEVEE_LightProbeEngineData *EEVEE_lightprobe_data_ensure(Object *ob)
ob,
&draw_engine_eevee_type,
sizeof(EEVEE_LightProbeEngineData),
- &eevee_lightprobe_data_init,
- &eevee_lightprobe_data_free);
+ eevee_lightprobe_data_init,
+ eevee_lightprobe_data_free);
}
/* Lamp data. */
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 f5fc79aba4f..dcd45e27337 100644
--- a/source/blender/draw/engines/eevee/eevee_depth_of_field.c
+++ b/source/blender/draw/engines/eevee/eevee_depth_of_field.c
@@ -32,7 +32,7 @@
#include "DNA_anim_types.h"
#include "DNA_camera_types.h"
-#include "DNA_object_force.h"
+#include "DNA_object_force_types.h"
#include "DNA_screen_types.h"
#include "DNA_view3d_types.h"
#include "DNA_world_types.h"
diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c
index c1ac085230e..751b9a0f7d6 100644
--- a/source/blender/draw/engines/eevee/eevee_effects.c
+++ b/source/blender/draw/engines/eevee/eevee_effects.c
@@ -105,9 +105,10 @@ void EEVEE_effects_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, Object
EEVEE_FramebufferList *fbl = vedata->fbl;
EEVEE_TextureList *txl = vedata->txl;
EEVEE_EffectsInfo *effects;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ ViewLayer *view_layer = draw_ctx->view_layer;
const float *viewport_size = DRW_viewport_size_get();
-
/* Shaders */
if (!e_data.downsample_sh) {
eevee_create_shader_downsample();
@@ -129,6 +130,13 @@ void EEVEE_effects_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, Object
effects->enabled_effects |= EEVEE_screen_raytrace_init(sldata, vedata);
effects->enabled_effects |= EEVEE_volumes_init(sldata, vedata);
+ /* Force normal buffer creation. */
+ if (DRW_state_is_image_render() &&
+ (view_layer->passflag & SCE_PASS_NORMAL) != 0)
+ {
+ effects->enabled_effects |= EFFECT_NORMAL_BUFFER;
+ }
+
/**
* Ping Pong buffer
*/
@@ -233,7 +241,8 @@ void EEVEE_effects_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{
static int zero = 0;
psl->color_downsample_cube_ps = DRW_pass_create("Downsample Cube", DRW_STATE_WRITE_COLOR);
- DRWShadingGroup *grp = DRW_shgroup_instance_create(e_data.downsample_cube_sh, psl->color_downsample_cube_ps, quad);
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(e_data.downsample_cube_sh, psl->color_downsample_cube_ps,
+ quad, NULL);
DRW_shgroup_uniform_buffer(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);
diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c
index 8e74f3344dd..4a7258d6525 100644
--- a/source/blender/draw/engines/eevee/eevee_engine.c
+++ b/source/blender/draw/engines/eevee/eevee_engine.c
@@ -177,6 +177,9 @@ static void eevee_draw_background(void *vedata)
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
+ /* Sort transparents before the loop. */
+ DRW_pass_sort_shgroup_z(psl->transparent_pass);
+
/* Number of iteration: needed for all temporal effect (SSR, TAA)
* when using opengl render. */
int loop_ct = DRW_state_is_image_render() ? 4 : 1;
@@ -187,15 +190,18 @@ static void eevee_draw_background(void *vedata)
double r[3];
if (DRW_state_is_image_render() ||
- ((stl->effects->enabled_effects & EFFECT_TAA) != 0))
+ ((stl->effects->enabled_effects & EFFECT_TAA) != 0))
{
BLI_halton_3D(primes, offset, stl->effects->taa_current_sample, r);
EEVEE_update_noise(psl, fbl, r);
+ EEVEE_volumes_set_jitter(sldata, stl->effects->taa_current_sample - 1);
+ EEVEE_materials_init(sldata, stl, fbl);
}
/* Refresh Probes */
DRW_stats_group_start("Probes Refresh");
EEVEE_lightprobes_refresh(sldata, vedata);
+ EEVEE_lightprobes_refresh_planar(sldata, vedata);
DRW_stats_group_end();
/* Update common buffer after probe rendering. */
@@ -220,8 +226,8 @@ static void eevee_draw_background(void *vedata)
}
if (((stl->effects->enabled_effects & EFFECT_TAA) != 0) &&
- (stl->effects->taa_current_sample > 1) &&
- !DRW_state_is_image_render())
+ (stl->effects->taa_current_sample > 1) &&
+ !DRW_state_is_image_render())
{
DRW_viewport_matrix_override_set(stl->effects->overide_persmat, DRW_MAT_PERS);
DRW_viewport_matrix_override_set(stl->effects->overide_persinv, DRW_MAT_PERSINV);
@@ -271,7 +277,6 @@ static void eevee_draw_background(void *vedata)
EEVEE_volumes_resolve(sldata, vedata);
/* Transparent */
- DRW_pass_sort_shgroup_z(psl->transparent_pass);
DRW_draw_pass(psl->transparent_pass);
/* Post Process */
@@ -372,15 +377,15 @@ static void eevee_id_update(void *vedata, ID *id)
}
}
-static void eevee_render_to_image(void *vedata, struct RenderEngine *engine, struct Depsgraph *depsgraph)
+static void eevee_render_to_image(void *vedata, RenderEngine *engine, struct RenderResult *render_result, struct RenderLayer *render_layer)
{
- EEVEE_render_init(vedata, engine, depsgraph);
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ EEVEE_render_init(vedata, engine, draw_ctx->depsgraph);
+
+ DRW_render_object_iter(vedata, engine, draw_ctx->depsgraph, EEVEE_render_cache);
- DRW_render_object_iter(vedata, engine, depsgraph, EEVEE_render_cache);
/* Actually do the rendering. */
- EEVEE_render_draw(vedata, engine, depsgraph);
- /* Write outputs to RenderResult. */
- EEVEE_render_output(vedata, engine, depsgraph);
+ EEVEE_render_draw(vedata, engine, render_result, render_layer);
}
static void eevee_engine_free(void)
@@ -391,6 +396,7 @@ static void eevee_engine_free(void)
EEVEE_lightprobes_free();
EEVEE_lights_free();
EEVEE_materials_free();
+ EEVEE_mist_free();
EEVEE_motion_blur_free();
EEVEE_occlusion_free();
EEVEE_screen_raytrace_free();
@@ -497,7 +503,8 @@ DrawEngineType draw_engine_eevee_type = {
RenderEngineType DRW_engine_viewport_eevee_type = {
NULL, NULL,
EEVEE_ENGINE, N_("Eevee"), RE_INTERNAL | RE_USE_SHADING_NODES,
- NULL, &DRW_render_to_image, NULL, NULL, NULL, NULL, NULL,
+ NULL, &DRW_render_to_image, NULL, NULL, NULL, NULL,
+ &EEVEE_render_update_passes,
&eevee_layer_collection_settings_create,
&eevee_view_layer_settings_create,
&draw_engine_eevee_type,
diff --git a/source/blender/draw/engines/eevee/eevee_lightprobes.c b/source/blender/draw/engines/eevee/eevee_lightprobes.c
index 7403da737dd..b4de6081457 100644
--- a/source/blender/draw/engines/eevee/eevee_lightprobes.c
+++ b/source/blender/draw/engines/eevee/eevee_lightprobes.c
@@ -36,6 +36,7 @@
#include "DNA_view3d_types.h"
#include "BKE_object.h"
+#include "MEM_guardedalloc.h"
#include "GPU_material.h"
#include "GPU_texture.h"
@@ -82,6 +83,9 @@ static struct {
struct GPUTexture *depth_array_placeholder;
struct GPUTexture *cube_face_minmaxz;
+ struct Gwn_VertFormat *format_probe_display_cube;
+ struct Gwn_VertFormat *format_probe_display_planar;
+
int update_world;
} e_data = {NULL}; /* Engine data */
@@ -433,9 +437,7 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
{
psl->probe_glossy_compute = DRW_pass_create("LightProbe Glossy Compute", DRW_STATE_WRITE_COLOR);
- struct Gwn_Batch *geom = DRW_cache_fullscreen_quad_get();
-
- DRWShadingGroup *grp = DRW_shgroup_instance_create(e_data.probe_filter_glossy_sh, psl->probe_glossy_compute, geom);
+ DRWShadingGroup *grp = DRW_shgroup_create(e_data.probe_filter_glossy_sh, psl->probe_glossy_compute);
DRW_shgroup_uniform_float(grp, "intensityFac", &pinfo->intensity_fac, 1);
DRW_shgroup_uniform_float(grp, "sampleCount", &pinfo->samples_ct, 1);
DRW_shgroup_uniform_float(grp, "invSampleCount", &pinfo->invsamples_ct, 1);
@@ -448,8 +450,7 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
DRW_shgroup_uniform_texture(grp, "texHammersley", e_data.hammersley);
// DRW_shgroup_uniform_texture(grp, "texJitter", e_data.jitter);
DRW_shgroup_uniform_texture(grp, "probeHdr", sldata->probe_rt);
-
- DRW_shgroup_set_instance_count(grp, 1);
+ DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
}
{
@@ -505,18 +506,32 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_CULL_BACK;
psl->probe_display = DRW_pass_create("LightProbe Display", state);
- struct Gwn_Batch *geom = DRW_cache_sphere_get();
- DRWShadingGroup *grp = stl->g_data->cube_display_shgrp = DRW_shgroup_instance_create(e_data.probe_cube_display_sh, psl->probe_display, geom);
- DRW_shgroup_attrib_float(grp, "probe_id", 1); /* XXX this works because we are still uploading 4bytes and using the right stride */
- DRW_shgroup_attrib_float(grp, "probe_location", 3);
- DRW_shgroup_attrib_float(grp, "sphere_size", 1);
+ DRW_shgroup_instance_format(e_data.format_probe_display_cube, {
+ {"probe_id", DRW_ATTRIB_INT, 1},
+ {"probe_location", DRW_ATTRIB_FLOAT, 3},
+ {"sphere_size", DRW_ATTRIB_FLOAT, 1},
+ });
+
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(
+ e_data.probe_cube_display_sh,
+ psl->probe_display,
+ DRW_cache_sphere_get(),
+ e_data.format_probe_display_cube);
+ stl->g_data->cube_display_shgrp = grp;
DRW_shgroup_uniform_buffer(grp, "probeCubes", &sldata->probe_pool);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
- geom = DRW_cache_quad_get();
- grp = stl->g_data->planar_display_shgrp = DRW_shgroup_instance_create(e_data.probe_planar_display_sh, psl->probe_display, geom);
- DRW_shgroup_attrib_float(grp, "probe_id", 1); /* XXX this works because we are still uploading 4bytes and using the right stride */
- DRW_shgroup_attrib_float(grp, "probe_mat", 16);
+ DRW_shgroup_instance_format(e_data.format_probe_display_planar, {
+ {"probe_id", DRW_ATTRIB_INT, 1},
+ {"probe_mat", DRW_ATTRIB_FLOAT, 16},
+ });
+
+ grp = DRW_shgroup_instance_create(
+ e_data.probe_planar_display_sh,
+ psl->probe_display,
+ DRW_cache_quad_get(),
+ e_data.format_probe_display_planar);
+ stl->g_data->planar_display_shgrp = grp;
DRW_shgroup_uniform_buffer(grp, "probePlanars", &txl->planar_pool);
}
@@ -524,7 +539,11 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
psl->probe_planar_downsample_ps = DRW_pass_create("LightProbe Planar Downsample", DRW_STATE_WRITE_COLOR);
struct Gwn_Batch *geom = DRW_cache_fullscreen_quad_get();
- DRWShadingGroup *grp = stl->g_data->planar_downsample = DRW_shgroup_instance_create(e_data.probe_planar_downsample_sh, psl->probe_planar_downsample_ps, geom);
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(
+ e_data.probe_planar_downsample_sh,
+ psl->probe_planar_downsample_ps,
+ geom, NULL);
+ stl->g_data->planar_downsample = grp;
DRW_shgroup_uniform_buffer(grp, "source", &txl->planar_pool);
DRW_shgroup_uniform_float(grp, "fireflyFactor", &sldata->common_data.ssr_firefly_fac, 1);
}
@@ -548,7 +567,7 @@ void EEVEE_lightprobes_cache_add(EEVEE_ViewLayerData *sldata, Object *ob)
ped->num_cell = probe->grid_resolution_x * probe->grid_resolution_y * probe->grid_resolution_z;
if ((probe->type == LIGHTPROBE_TYPE_GRID) &&
- ((pinfo->total_irradiance_samples + ped->num_cell) >= MAX_IRRADIANCE_SAMPLES))
+ ((pinfo->total_irradiance_samples + ped->num_cell) >= MAX_IRRADIANCE_SAMPLES))
{
printf("Too much grid samples !!!\n");
return;
@@ -818,16 +837,20 @@ static void EEVEE_lightprobes_updates(EEVEE_ViewLayerData *sldata, EEVEE_PassLis
/* Visibility bias */
egrid->visibility_bias = 0.05f * probe->vis_bias;
egrid->visibility_bleed = probe->vis_bleedbias;
- egrid->visibility_range = max_ff(max_ff(len_v3(egrid->increment_x),
- len_v3(egrid->increment_y)),
- len_v3(egrid->increment_z)) + 1.0f;
+ egrid->visibility_range = (
+ sqrtf(max_fff(len_squared_v3(egrid->increment_x),
+ len_squared_v3(egrid->increment_y),
+ len_squared_v3(egrid->increment_z))) + 1.0f);
/* Debug Display */
if (DRW_state_draw_support() &&
(probe->flag & LIGHTPROBE_FLAG_SHOW_DATA))
{
struct Gwn_Batch *geom = DRW_cache_sphere_get();
- DRWShadingGroup *grp = DRW_shgroup_instance_create(e_data.probe_grid_display_sh, psl->probe_display, geom);
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(
+ e_data.probe_grid_display_sh,
+ psl->probe_display,
+ geom, NULL);
DRW_shgroup_set_instance_count(grp, ped->num_cell);
DRW_shgroup_uniform_int(grp, "offset", &egrid->offset, 1);
DRW_shgroup_uniform_ivec3(grp, "grid_resolution", egrid->resolution, 1);
@@ -1420,7 +1443,7 @@ static void lightprobes_refresh_initialize_grid(EEVEE_ViewLayerData *sldata, EEV
pinfo->grid_initialized = true;
}
-static void lightprobes_refresh_planar(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
+void EEVEE_lightprobes_refresh_planar(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{
EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
EEVEE_TextureList *txl = vedata->txl;
@@ -1428,6 +1451,8 @@ static void lightprobes_refresh_planar(EEVEE_ViewLayerData *sldata, EEVEE_Data *
EEVEE_LightProbesInfo *pinfo = sldata->probes;
if (pinfo->num_planar == 0) {
+ /* Disable SSR if we cannot read previous frame */
+ common_data->ssr_toggle = vedata->stl->g_data->valid_double_buffer;
return;
}
@@ -1464,6 +1489,9 @@ static void lightprobes_refresh_planar(EEVEE_ViewLayerData *sldata, EEVEE_Data *
common_data->prb_lod_planar_max = (float)(max_lod);
DRW_stats_group_end();
}
+
+ /* Disable SSR if we cannot read previous frame */
+ common_data->ssr_toggle = vedata->stl->g_data->valid_double_buffer;
}
static void lightprobes_refresh_cube(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
@@ -1497,6 +1525,8 @@ static void lightprobes_refresh_cube(EEVEE_ViewLayerData *sldata, EEVEE_Data *ve
/* Only do one probe per frame */
return;
}
+
+ pinfo->do_cube_update = false;
}
static void lightprobes_refresh_all_no_world(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
@@ -1645,11 +1675,20 @@ static void lightprobes_refresh_all_no_world(EEVEE_ViewLayerData *sldata, EEVEE_
lightprobes_refresh_cube(sldata, vedata);
}
-void EEVEE_lightprobes_refresh(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
+bool EEVEE_lightprobes_all_probes_ready(EEVEE_ViewLayerData *sldata, EEVEE_Data *UNUSED(vedata))
{
EEVEE_LightProbesInfo *pinfo = sldata->probes;
EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
+ return ((pinfo->do_cube_update == false) &&
+ (pinfo->updated_bounce == pinfo->num_bounce) &&
+ (common_data->prb_num_render_cube == pinfo->num_cube));
+}
+
+void EEVEE_lightprobes_refresh(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
+{
+ EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
+
/* Disable specular lighting when rendering probes to avoid feedback loops (looks bad). */
common_data->spec_toggle = false;
common_data->ssr_toggle = false;
@@ -1665,7 +1704,7 @@ void EEVEE_lightprobes_refresh(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
if (e_data.update_world) {
lightprobes_refresh_world(sldata, vedata);
}
- else if (pinfo->do_cube_update || (pinfo->updated_bounce < pinfo->num_bounce)) {
+ else if (EEVEE_lightprobes_all_probes_ready(sldata, vedata) == false) {
lightprobes_refresh_all_no_world(sldata, vedata);
}
@@ -1675,15 +1714,12 @@ void EEVEE_lightprobes_refresh(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
common_data->sss_toggle = true;
common_data->ao_dist = tmp_ao_dist;
common_data->ao_settings = tmp_ao_settings;
-
- lightprobes_refresh_planar(sldata, vedata);
-
- /* Disable SSR if we cannot read previous frame */
- common_data->ssr_toggle = vedata->stl->g_data->valid_double_buffer;
}
void EEVEE_lightprobes_free(void)
{
+ MEM_SAFE_FREE(e_data.format_probe_display_cube);
+ MEM_SAFE_FREE(e_data.format_probe_display_planar);
DRW_SHADER_FREE_SAFE(e_data.probe_default_sh);
DRW_SHADER_FREE_SAFE(e_data.probe_filter_glossy_sh);
DRW_SHADER_FREE_SAFE(e_data.probe_filter_diffuse_sh);
diff --git a/source/blender/draw/engines/eevee/eevee_lights.c b/source/blender/draw/engines/eevee/eevee_lights.c
index 69b58bf9670..582f7ea747a 100644
--- a/source/blender/draw/engines/eevee/eevee_lights.c
+++ b/source/blender/draw/engines/eevee/eevee_lights.c
@@ -343,7 +343,7 @@ void EEVEE_lights_cache_add(EEVEE_ViewLayerData *sldata, Object *ob)
/* For light update tracking. */
if ((prev_cube_sh_id >= 0) &&
- (prev_cube_sh_id < linfo->shcaster_backbuffer->count))
+ (prev_cube_sh_id < linfo->shcaster_backbuffer->count))
{
linfo->new_shadow_id[prev_cube_sh_id] = linfo->cpu_cube_ct;
}
@@ -380,12 +380,12 @@ void EEVEE_lights_cache_add(EEVEE_ViewLayerData *sldata, Object *ob)
void EEVEE_lights_cache_shcaster_add(
EEVEE_ViewLayerData *sldata, EEVEE_PassList *psl, struct Gwn_Batch *geom, float (*obmat)[4])
{
- DRWShadingGroup *grp = DRW_shgroup_instance_create(e_data.shadow_sh, psl->shadow_cube_pass, geom);
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(e_data.shadow_sh, psl->shadow_cube_pass, geom, NULL);
DRW_shgroup_uniform_block(grp, "shadow_render_block", sldata->shadow_render_ubo);
DRW_shgroup_uniform_mat4(grp, "ShadowModelMatrix", (float *)obmat);
DRW_shgroup_set_instance_count(grp, 6);
- grp = DRW_shgroup_instance_create(e_data.shadow_sh, psl->shadow_cascade_pass, geom);
+ grp = DRW_shgroup_instance_create(e_data.shadow_sh, psl->shadow_cascade_pass, geom, NULL);
DRW_shgroup_uniform_block(grp, "shadow_render_block", sldata->shadow_render_ubo);
DRW_shgroup_uniform_mat4(grp, "ShadowModelMatrix", (float *)obmat);
DRW_shgroup_set_instance_count(grp, MAX_CASCADE_NUM);
@@ -395,7 +395,7 @@ void EEVEE_lights_cache_shcaster_material_add(
EEVEE_ViewLayerData *sldata, EEVEE_PassList *psl, struct GPUMaterial *gpumat,
struct Gwn_Batch *geom, struct Object *ob, float (*obmat)[4], float *alpha_threshold)
{
- DRWShadingGroup *grp = DRW_shgroup_material_instance_create(gpumat, psl->shadow_cube_pass, geom, ob);
+ DRWShadingGroup *grp = DRW_shgroup_material_instance_create(gpumat, psl->shadow_cube_pass, geom, ob, NULL);
if (grp == NULL) return;
@@ -407,7 +407,7 @@ void EEVEE_lights_cache_shcaster_material_add(
DRW_shgroup_set_instance_count(grp, 6);
- grp = DRW_shgroup_material_instance_create(gpumat, psl->shadow_cascade_pass, geom, ob);
+ grp = DRW_shgroup_material_instance_create(gpumat, psl->shadow_cascade_pass, geom, ob, NULL);
DRW_shgroup_uniform_block(grp, "shadow_render_block", sldata->shadow_render_ubo);
DRW_shgroup_uniform_mat4(grp, "ShadowModelMatrix", (float *)obmat);
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c
index 84627e03137..0e444039573 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -471,7 +471,7 @@ static void eevee_init_util_texture(void)
MEM_freeN(texels);
}
-void EEVEE_update_noise(EEVEE_PassList *psl, EEVEE_FramebufferList *fbl, double offsets[3])
+void EEVEE_update_noise(EEVEE_PassList *psl, EEVEE_FramebufferList *fbl, const double offsets[3])
{
e_data.noise_offsets[0] = offsets[0];
e_data.noise_offsets[1] = offsets[1];
@@ -485,6 +485,46 @@ void EEVEE_update_noise(EEVEE_PassList *psl, EEVEE_FramebufferList *fbl, double
DRW_framebuffer_texture_detach(e_data.util_tex);
}
+static void EEVEE_update_viewvecs(float invproj[4][4], float winmat[4][4], float (*r_viewvecs)[4])
+{
+ /* view vectors for the corners of the view frustum.
+ * Can be used to recreate the world space position easily */
+ float view_vecs[4][4] = {
+ {-1.0f, -1.0f, -1.0f, 1.0f},
+ { 1.0f, -1.0f, -1.0f, 1.0f},
+ {-1.0f, 1.0f, -1.0f, 1.0f},
+ {-1.0f, -1.0f, 1.0f, 1.0f}
+ };
+
+ /* convert the view vectors to view space */
+ const bool is_persp = (winmat[3][3] == 0.0f);
+ for (int i = 0; i < 4; i++) {
+ mul_project_m4_v3(invproj, view_vecs[i]);
+ /* normalized trick see:
+ * http://www.derschmale.com/2014/01/26/reconstructing-positions-from-the-depth-buffer */
+ if (is_persp) {
+ /* Divide XY by Z. */
+ mul_v2_fl(view_vecs[i], 1.0f / view_vecs[i][2]);
+ }
+ }
+
+ /**
+ * If ortho : view_vecs[0] is the near-bottom-left corner of the frustum and
+ * view_vecs[1] is the vector going from the near-bottom-left corner to
+ * the far-top-right corner.
+ * If Persp : view_vecs[0].xy and view_vecs[1].xy are respectively the bottom-left corner
+ * when Z = 1, and top-left corner if Z = 1.
+ * view_vecs[0].z the near clip distance and view_vecs[1].z is the (signed)
+ * distance from the near plane to the far clip plane.
+ **/
+ copy_v4_v4(r_viewvecs[0], view_vecs[0]);
+
+ /* we need to store the differences */
+ r_viewvecs[1][0] = view_vecs[1][0] - view_vecs[0][0];
+ r_viewvecs[1][1] = view_vecs[2][1] - view_vecs[0][1];
+ r_viewvecs[1][2] = view_vecs[3][2] - view_vecs[0][2];
+}
+
void EEVEE_materials_init(EEVEE_ViewLayerData *sldata, EEVEE_StorageList *stl, EEVEE_FramebufferList *fbl)
{
if (!e_data.frag_shader_lib) {
@@ -553,60 +593,24 @@ void EEVEE_materials_init(EEVEE_ViewLayerData *sldata, EEVEE_StorageList *stl, E
eevee_init_noise_texture();
}
- /* Alpha hash scale: Non-flickering size if we are not refining the render. */
if (!DRW_state_is_image_render() &&
- (((stl->effects->enabled_effects & EFFECT_TAA) == 0) ||
- (stl->effects->taa_current_sample == 1)))
+ ((stl->effects->enabled_effects & EFFECT_TAA) == 0))
{
e_data.alpha_hash_offset = 0.0f;
}
else {
double r;
- BLI_halton_1D(5, 0.0, stl->effects->taa_current_sample, &r);
+ BLI_halton_1D(5, 0.0, stl->effects->taa_current_sample - 1, &r);
e_data.alpha_hash_offset = (float)r;
}
{
/* Update view_vecs */
float invproj[4][4], winmat[4][4];
- /* view vectors for the corners of the view frustum.
- * Can be used to recreate the world space position easily */
- float view_vecs[3][4] = {
- {-1.0f, -1.0f, -1.0f, 1.0f},
- {1.0f, -1.0f, -1.0f, 1.0f},
- {-1.0f, 1.0f, -1.0f, 1.0f}
- };
-
- /* invert the view matrix */
DRW_viewport_matrix_get(winmat, DRW_MAT_WIN);
- invert_m4_m4(invproj, winmat);
- const bool is_persp = (winmat[3][3] == 0.0f);
-
- /* convert the view vectors to view space */
- for (int i = 0; i < 3; i++) {
- mul_m4_v4(invproj, view_vecs[i]);
- /* normalized trick see:
- * http://www.derschmale.com/2014/01/26/reconstructing-positions-from-the-depth-buffer */
- mul_v3_fl(view_vecs[i], 1.0f / view_vecs[i][3]);
- if (is_persp)
- mul_v3_fl(view_vecs[i], 1.0f / view_vecs[i][2]);
- view_vecs[i][3] = 1.0;
- }
-
- copy_v4_v4(sldata->common_data.view_vecs[0], view_vecs[0]);
- copy_v4_v4(sldata->common_data.view_vecs[1], view_vecs[1]);
-
- /* we need to store the differences */
- sldata->common_data.view_vecs[1][0] -= view_vecs[0][0];
- sldata->common_data.view_vecs[1][1] = view_vecs[2][1] - view_vecs[0][1];
+ DRW_viewport_matrix_get(invproj, DRW_MAT_WININV);
- /* calculate a depth offset as well */
- if (!is_persp) {
- float vec_far[] = {-1.0f, -1.0f, 1.0f, 1.0f};
- mul_m4_v4(invproj, vec_far);
- mul_v3_fl(vec_far, 1.0f / vec_far[3]);
- sldata->common_data.view_vecs[1][2] = vec_far[2] - view_vecs[0][2];
- }
+ EEVEE_update_viewvecs(invproj, winmat, sldata->common_data.view_vecs);
}
{
@@ -1056,9 +1060,16 @@ static void material_opaque(
DRW_shgroup_uniform_texture(*shgrp, "sssTexProfile", sss_tex_profile);
}
- DRW_shgroup_stencil_mask(*shgrp, e_data.sss_count + 1);
- EEVEE_subsurface_add_pass(sldata, vedata, e_data.sss_count + 1, sss_profile);
- e_data.sss_count++;
+ /* Limit of 8 bit stencil buffer. ID 255 is refraction. */
+ if (e_data.sss_count < 254) {
+ DRW_shgroup_stencil_mask(*shgrp, e_data.sss_count + 1);
+ EEVEE_subsurface_add_pass(sldata, vedata, e_data.sss_count + 1, sss_profile);
+ e_data.sss_count++;
+ }
+ else {
+ /* TODO : display message. */
+ printf("Error: Too many different Subsurface shader in the scene.\n");
+ }
}
}
}
@@ -1230,7 +1241,7 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sld
IDProperty *ces_mode_ob = BKE_layer_collection_engine_evaluated_get(ob, COLLECTION_MODE_OBJECT, "");
const bool do_cull = BKE_collection_engine_property_value_get_bool(ces_mode_ob, "show_backface_culling");
const bool is_active = (ob == draw_ctx->obact);
- const bool is_sculpt_mode = is_active && (ob->mode & OB_MODE_SCULPT) != 0;
+ const bool is_sculpt_mode = is_active && (draw_ctx->object_mode & OB_MODE_SCULPT) != 0;
#if 0
const bool is_sculpt_mode_draw = is_sculpt_mode && (draw_ctx->v3d->flag2 & V3D_SHOW_MODE_SHADE_OVERRIDE) == 0;
#else
@@ -1366,7 +1377,7 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sld
}
if (ob->type == OB_MESH) {
- if (ob != draw_ctx->scene->obedit) {
+ if (ob != draw_ctx->object_edit) {
material_hash = stl->g_data->hair_material_hash;
for (ModifierData *md = ob->modifiers.first; md; md = md->next) {
diff --git a/source/blender/draw/engines/eevee/eevee_mist.c b/source/blender/draw/engines/eevee/eevee_mist.c
new file mode 100644
index 00000000000..ba9157a7f91
--- /dev/null
+++ b/source/blender/draw/engines/eevee/eevee_mist.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2016, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Blender Institute
+ *
+ */
+
+/** \file eevee_mist.c
+ * \ingroup draw_engine
+ *
+ * Implementation of Blender Mist pass.
+ * IMPORTANT: This is a "post process" of the Z depth so it will lack any transparent objects.
+ */
+
+#include "DRW_engine.h"
+#include "DRW_render.h"
+
+#include "DNA_world_types.h"
+
+#include "BLI_string_utils.h"
+
+#include "eevee_private.h"
+
+extern char datatoc_common_uniforms_lib_glsl[];
+extern char datatoc_bsdf_common_lib_glsl[];
+extern char datatoc_effect_mist_frag_glsl[];
+
+static struct {
+ struct GPUShader *mist_sh;
+} e_data = {NULL}; /* Engine data */
+
+void EEVEE_mist_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
+{
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ EEVEE_FramebufferList *fbl = vedata->fbl;
+ DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
+ EEVEE_TextureList *txl = vedata->txl;
+ EEVEE_StorageList *stl = vedata->stl;
+ EEVEE_PassList *psl = vedata->psl;
+ EEVEE_PrivateData *g_data = stl->g_data;
+ Scene *scene = draw_ctx->scene;
+
+ const float *viewport_size = DRW_viewport_size_get();
+ float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+
+ if (e_data.mist_sh == NULL) {
+ char *frag_str = BLI_string_joinN(
+ datatoc_common_uniforms_lib_glsl,
+ datatoc_bsdf_common_lib_glsl,
+ datatoc_effect_mist_frag_glsl);
+
+ e_data.mist_sh = DRW_shader_create_fullscreen(frag_str, "#define FIRST_PASS\n");
+
+ MEM_freeN(frag_str);
+ }
+
+ /* Create FrameBuffer. */
+ DRWFboTexture tex_data = {&txl->mist_accum, DRW_TEX_R_32, 0}; /* Should be enough precision for many samples. */
+ DRW_framebuffer_init(&fbl->mist_accum_fb, &draw_engine_eevee_type, (int)viewport_size[0], (int)viewport_size[1],
+ &tex_data, 1);
+
+ /* Clear texture. */
+ DRW_framebuffer_bind(fbl->mist_accum_fb);
+ DRW_framebuffer_clear(true, false, false, clear, 0.0f);
+
+ /* Mist settings. */
+ if (scene && scene->world) {
+ g_data->mist_start = scene->world->miststa;
+ g_data->mist_inv_dist = (scene->world->mistdist > 0.0f) ? 1.0f / scene->world->mistdist : 0.0f;
+
+ switch (scene->world->mistype) {
+ case WO_MIST_QUADRATIC:
+ g_data->mist_falloff = 2.0f;
+ break;
+ case WO_MIST_LINEAR:
+ g_data->mist_falloff = 1.0f;
+ break;
+ case WO_MIST_INVERSE_QUADRATIC:
+ g_data->mist_falloff = 0.5f;
+ break;
+ }
+ }
+ else {
+ float near = -sldata->common_data.view_vecs[0][2];
+ float range = sldata->common_data.view_vecs[1][2];
+ /* Fallback */
+ g_data->mist_start = near;
+ g_data->mist_inv_dist = 1.0f / fabsf(range);
+ g_data->mist_falloff = 1.0f;
+ }
+
+ /* XXX ??!! WHY? If not it does not match cycles. */
+ g_data->mist_falloff *= 0.5f;
+
+ /* Create Pass and shgroup. */
+ psl->mist_accum_ps = DRW_pass_create("Mist Accum", DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE);
+ DRWShadingGroup *grp = DRW_shgroup_create(e_data.mist_sh, psl->mist_accum_ps);
+ DRW_shgroup_uniform_buffer(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);
+}
+
+void EEVEE_mist_output_accumulate(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
+{
+ EEVEE_FramebufferList *fbl = vedata->fbl;
+ EEVEE_PassList *psl = vedata->psl;
+
+ if (fbl->mist_accum_fb != NULL) {
+ DRW_framebuffer_bind(fbl->mist_accum_fb);
+ DRW_draw_pass(psl->mist_accum_ps);
+
+ /* Restore */
+ DRW_framebuffer_bind(fbl->main);
+ }
+}
+
+void EEVEE_mist_free(void)
+{
+ DRW_SHADER_FREE_SAFE(e_data.mist_sh);
+}
diff --git a/source/blender/draw/engines/eevee/eevee_motion_blur.c b/source/blender/draw/engines/eevee/eevee_motion_blur.c
index 037bbe3b6c9..53fff5de50e 100644
--- a/source/blender/draw/engines/eevee/eevee_motion_blur.c
+++ b/source/blender/draw/engines/eevee/eevee_motion_blur.c
@@ -79,6 +79,7 @@ static void eevee_motion_blur_camera_get_matrix_at_time(
scene,
draw_ctx->view_layer,
draw_ctx->engine_type,
+ draw_ctx->object_mode,
DAG_EVAL_VIEWPORT);
eval_ctx.ctime = time;
diff --git a/source/blender/draw/engines/eevee/eevee_occlusion.c b/source/blender/draw/engines/eevee/eevee_occlusion.c
index 9da438e825f..944003d7d1f 100644
--- a/source/blender/draw/engines/eevee/eevee_occlusion.c
+++ b/source/blender/draw/engines/eevee/eevee_occlusion.c
@@ -123,6 +123,48 @@ int EEVEE_occlusion_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
return 0;
}
+void EEVEE_occlusion_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
+{
+ EEVEE_FramebufferList *fbl = vedata->fbl;
+ EEVEE_TextureList *txl = vedata->txl;
+ EEVEE_PassList *psl = vedata->psl;
+ const float *viewport_size = DRW_viewport_size_get();
+
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ ViewLayer *view_layer = draw_ctx->view_layer;
+ IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_EEVEE);
+
+ if (BKE_collection_engine_property_value_get_bool(props, "gtao_enable")) {
+ DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
+ float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+
+ DRWFboTexture tex_data = {&txl->ao_accum, DRW_TEX_R_32, 0};
+ DRW_framebuffer_init(&fbl->ao_accum_fb, &draw_engine_eevee_type, (int)viewport_size[0], (int)viewport_size[1],
+ &tex_data, 1);
+
+ /* Clear texture. */
+ DRW_framebuffer_bind(fbl->ao_accum_fb);
+ DRW_framebuffer_clear(true, false, false, clear, 0.0f);
+
+ /* Accumulation pass */
+ DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE;
+ psl->ao_accum_ps = DRW_pass_create("AO Accum", state);
+ DRWShadingGroup *grp = DRW_shgroup_create(e_data.gtao_debug_sh, psl->ao_accum_ps);
+ DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
+ DRW_shgroup_uniform_buffer(grp, "maxzBuffer", &txl->maxzbuffer);
+ DRW_shgroup_uniform_buffer(grp, "depthBuffer", &dtxl->depth);
+ DRW_shgroup_uniform_buffer(grp, "normalBuffer", &txl->ssr_normal_input);
+ DRW_shgroup_uniform_buffer(grp, "horizonBuffer", &txl->gtao_horizons);
+ DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+ DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
+ }
+ else {
+ /* Cleanup to release memory */
+ DRW_TEXTURE_FREE_SAFE(txl->ao_accum);
+ DRW_FRAMEBUFFER_FREE_SAFE(fbl->ao_accum_fb);
+ }
+}
+
void EEVEE_occlusion_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{
EEVEE_PassList *psl = vedata->psl;
@@ -228,6 +270,26 @@ void EEVEE_occlusion_draw_debug(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data
}
}
+void EEVEE_occlusion_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
+{
+ EEVEE_FramebufferList *fbl = vedata->fbl;
+ EEVEE_PassList *psl = vedata->psl;
+
+ if (fbl->ao_accum_fb != NULL) {
+ DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
+
+ /* Update the min_max/horizon buffers so the refracion materials appear in it. */
+ EEVEE_create_minmax_buffer(vedata, dtxl->depth, -1);
+ EEVEE_occlusion_compute(sldata, vedata, dtxl->depth, -1);
+
+ DRW_framebuffer_bind(fbl->ao_accum_fb);
+ DRW_draw_pass(psl->ao_accum_ps);
+
+ /* Restore */
+ DRW_framebuffer_bind(fbl->main);
+ }
+}
+
void EEVEE_occlusion_free(void)
{
DRW_SHADER_FREE_SAFE(e_data.gtao_sh);
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index 218de6ddd88..85d6dd8b448 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -29,6 +29,8 @@
struct Object;
struct EEVEE_BoundSphere;
struct EEVEE_ShadowCasterBuffer;
+struct RenderLayer;
+struct RenderResult;
extern struct DrawEngineType draw_engine_eevee_type;
@@ -160,6 +162,8 @@ typedef struct EEVEE_PassList {
struct DRWPass *ao_horizon_search;
struct DRWPass *ao_horizon_search_layer;
struct DRWPass *ao_horizon_debug;
+ struct DRWPass *ao_accum_ps;
+ struct DRWPass *mist_accum_ps;
struct DRWPass *motion_blur;
struct DRWPass *bloom_blit;
struct DRWPass *bloom_downsample_first;
@@ -178,6 +182,7 @@ typedef struct EEVEE_PassList {
struct DRWPass *ssr_resolve;
struct DRWPass *sss_blur_ps;
struct DRWPass *sss_resolve_ps;
+ struct DRWPass *sss_accum_ps;
struct DRWPass *color_downsample_ps;
struct DRWPass *color_downsample_cube_ps;
struct DRWPass *taa_resolve;
@@ -220,6 +225,7 @@ typedef struct EEVEE_FramebufferList {
struct GPUFrameBuffer *bloom_accum_fb[MAX_BLOOM_STEP - 1];
struct GPUFrameBuffer *sss_blur_fb;
struct GPUFrameBuffer *sss_clear_fb;
+ struct GPUFrameBuffer *sss_accum_fb;
struct GPUFrameBuffer *dof_down_fb;
struct GPUFrameBuffer *dof_scatter_far_fb;
struct GPUFrameBuffer *dof_scatter_near_fb;
@@ -228,6 +234,8 @@ typedef struct EEVEE_FramebufferList {
struct GPUFrameBuffer *volumetric_integ_fb;
struct GPUFrameBuffer *screen_tracing_fb;
struct GPUFrameBuffer *refract_fb;
+ struct GPUFrameBuffer *mist_accum_fb;
+ struct GPUFrameBuffer *ao_accum_fb;
struct GPUFrameBuffer *update_noise_fb;
@@ -249,6 +257,10 @@ typedef struct EEVEE_TextureList {
struct GPUTexture *bloom_blit; /* R16_G16_B16 */
struct GPUTexture *bloom_downsample[MAX_BLOOM_STEP]; /* R16_G16_B16 */
struct GPUTexture *bloom_upsample[MAX_BLOOM_STEP - 1]; /* R16_G16_B16 */
+ struct GPUTexture *mist_accum;
+ struct GPUTexture *ao_accum;
+ struct GPUTexture *sss_dir_accum;
+ struct GPUTexture *sss_col_accum;
struct GPUTexture *ssr_normal_input;
struct GPUTexture *ssr_specrough_input;
struct GPUTexture *ssr_hit_output;
@@ -736,6 +748,8 @@ typedef struct EEVEE_PrivateData {
float persmat[4][4], persinv[4][4];
float viewmat[4][4], viewinv[4][4];
float winmat[4][4], wininv[4][4];
+ /* Mist Settings */
+ float mist_start, mist_inv_dist, mist_falloff;
} EEVEE_PrivateData; /* Transient data */
/* eevee_data.c */
@@ -765,7 +779,7 @@ struct GPUMaterial *EEVEE_material_mesh_depth_get(struct Scene *scene, Material
struct GPUMaterial *EEVEE_material_hair_get(struct Scene *scene, Material *ma, int shadow_method);
void EEVEE_materials_free(void);
void EEVEE_draw_default_passes(EEVEE_PassList *psl);
-void EEVEE_update_noise(EEVEE_PassList *psl, EEVEE_FramebufferList *fbl, double offsets[3]);
+void EEVEE_update_noise(EEVEE_PassList *psl, EEVEE_FramebufferList *fbl, const double offsets[3]);
/* eevee_lights.c */
void EEVEE_lights_init(EEVEE_ViewLayerData *sldata);
@@ -784,11 +798,13 @@ void EEVEE_draw_shadows(EEVEE_ViewLayerData *sldata, EEVEE_PassList *psl);
void EEVEE_lights_free(void);
/* eevee_lightprobes.c */
+bool EEVEE_lightprobes_all_probes_ready(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_lightprobes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_lightprobes_cache_add(EEVEE_ViewLayerData *sldata, Object *ob);
void EEVEE_lightprobes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_lightprobes_refresh(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
+void EEVEE_lightprobes_refresh_planar(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_lightprobes_free(void);
/* eevee_depth_of_field.c */
@@ -805,6 +821,8 @@ void EEVEE_bloom_free(void);
/* eevee_occlusion.c */
int EEVEE_occlusion_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
+void EEVEE_occlusion_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
+void EEVEE_occlusion_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_occlusion_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_occlusion_compute(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, struct GPUTexture *depth_src, int layer);
void EEVEE_occlusion_draw_debug(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
@@ -820,10 +838,12 @@ void EEVEE_screen_raytrace_free(void);
/* eevee_subsurface.c */
int EEVEE_subsurface_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_subsurface_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
+void EEVEE_subsurface_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_subsurface_add_pass(
EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, unsigned int sss_id, struct GPUUniformBuffer *sss_profile);
void EEVEE_subsurface_data_render(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_subsurface_compute(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
+void EEVEE_subsurface_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_subsurface_free(void);
/* eevee_motion_blur.c */
@@ -832,16 +852,22 @@ void EEVEE_motion_blur_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
void EEVEE_motion_blur_draw(EEVEE_Data *vedata);
void EEVEE_motion_blur_free(void);
+/* eevee_mist.c */
+void EEVEE_mist_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
+void EEVEE_mist_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);;
+void EEVEE_mist_free(void);
+
/* eevee_temporal_sampling.c */
int EEVEE_temporal_sampling_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_temporal_sampling_matrices_calc(
- EEVEE_EffectsInfo *effects, float viewmat[4][4], float persmat[4][4], double ht_point[2]);
+ EEVEE_EffectsInfo *effects, float viewmat[4][4], float persmat[4][4], const double ht_point[2]);
void EEVEE_temporal_sampling_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_temporal_sampling_draw(EEVEE_Data *vedata);
void EEVEE_temporal_sampling_free(void);
/* eevee_volumes.c */
int EEVEE_volumes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
+void EEVEE_volumes_set_jitter(EEVEE_ViewLayerData *sldata, unsigned int current_sample);
void EEVEE_volumes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_volumes_cache_object_add(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, struct Scene *scene, Object *ob);
void EEVEE_volumes_compute(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
@@ -859,11 +885,11 @@ void EEVEE_effects_do_gtao(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_draw_effects(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_effects_free(void);
-/* eevee_ */
+/* eevee_render.c */
void EEVEE_render_init(EEVEE_Data *vedata, struct RenderEngine *engine, struct Depsgraph *depsgraph);
void EEVEE_render_cache(void *vedata, struct Object *ob, struct RenderEngine *engine, struct Depsgraph *depsgraph);
-void EEVEE_render_draw(EEVEE_Data *vedata, struct RenderEngine *engine, struct Depsgraph *depsgraph);
-void EEVEE_render_output(EEVEE_Data *vedata, struct RenderEngine *engine, struct Depsgraph *depsgraph);
+void EEVEE_render_draw(EEVEE_Data *vedata, struct RenderEngine *engine, struct RenderResult *render_result, struct RenderLayer *render_layer);
+void EEVEE_render_update_passes(struct RenderEngine *engine, struct Scene *scene, struct ViewLayer *view_layer);
/* Shadow Matrix */
static const float texcomat[4][4] = { /* From NDC to TexCo */
diff --git a/source/blender/draw/engines/eevee/eevee_render.c b/source/blender/draw/engines/eevee/eevee_render.c
index a020887e420..f2db27f812f 100644
--- a/source/blender/draw/engines/eevee/eevee_render.c
+++ b/source/blender/draw/engines/eevee/eevee_render.c
@@ -30,6 +30,8 @@
#include "DRW_engine.h"
#include "DRW_render.h"
+#include "DNA_node_types.h"
+
#include "BLI_rand.h"
#include "DEG_depsgraph_query.h"
@@ -75,7 +77,7 @@ void EEVEE_render_init(EEVEE_Data *ved, RenderEngine *engine, struct Depsgraph *
stl->g_data = MEM_callocN(sizeof(*stl->g_data), __func__);
}
EEVEE_PrivateData *g_data = stl->g_data;
- g_data->background_alpha = 1.0f; /* TODO option */
+ g_data->background_alpha = DRW_state_draw_background() ? 1.0f : 0.0f;
g_data->valid_double_buffer = 0;
/* Alloc common ubo data. */
@@ -149,8 +151,228 @@ void EEVEE_render_cache(
}
}
-void EEVEE_render_draw(EEVEE_Data *vedata, struct RenderEngine *UNUSED(engine), struct Depsgraph *UNUSED(depsgraph))
+static void eevee_render_result_combined(
+ RenderResult *rr, RenderLayer *rl, const char *viewname,
+ EEVEE_Data *vedata, EEVEE_ViewLayerData *UNUSED(sldata))
+{
+ RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_COMBINED, viewname);
+
+ DRW_framebuffer_bind(vedata->stl->effects->final_fb);
+ DRW_framebuffer_read_data(rr->xof, rr->yof, rr->rectx, rr->recty, 4, 0, rp->rect);
+}
+
+static void eevee_render_result_subsurface(
+ RenderResult *rr, RenderLayer *rl, const char *viewname,
+ EEVEE_Data *vedata, EEVEE_ViewLayerData *UNUSED(sldata))
+{
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ ViewLayer *view_layer = draw_ctx->view_layer;
+
+ if (vedata->fbl->sss_accum_fb == NULL) {
+ /* SSS is not enabled. */
+ return;
+ }
+
+ if ((view_layer->passflag & SCE_PASS_SUBSURFACE_COLOR) != 0) {
+ RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_SUBSURFACE_COLOR, viewname);
+
+ IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_EEVEE);
+ float render_samples = (float)BKE_collection_engine_property_value_get_int(props, "taa_render_samples");
+
+ DRW_framebuffer_bind(vedata->fbl->sss_accum_fb);
+ DRW_framebuffer_read_data(rr->xof, rr->yof, rr->rectx, rr->recty, 3, 1, rp->rect);
+
+ /* This is the accumulated color. Divide by the number of samples. */
+ for (int i = 0; i < rr->rectx * rr->recty * 3; i++) {
+ rp->rect[i] /= render_samples;
+ }
+ }
+
+ if ((view_layer->passflag & SCE_PASS_SUBSURFACE_DIRECT) != 0) {
+ RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_SUBSURFACE_DIRECT, viewname);
+
+ IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_EEVEE);
+ float render_samples = (float)BKE_collection_engine_property_value_get_int(props, "taa_render_samples");
+
+ DRW_framebuffer_bind(vedata->fbl->sss_accum_fb);
+ DRW_framebuffer_read_data(rr->xof, rr->yof, rr->rectx, rr->recty, 3, 0, rp->rect);
+
+ /* This is the accumulated color. Divide by the number of samples. */
+ for (int i = 0; i < rr->rectx * rr->recty * 3; i++) {
+ rp->rect[i] /= render_samples;
+ }
+ }
+
+ if ((view_layer->passflag & SCE_PASS_SUBSURFACE_INDIRECT) != 0) {
+ /* Do nothing as all the lighting is in the direct pass.
+ * TODO : Separate Direct from indirect lighting. */
+ }
+}
+
+static void eevee_render_result_normal(
+ RenderResult *rr, RenderLayer *rl, const char *viewname,
+ EEVEE_Data *vedata, EEVEE_ViewLayerData *UNUSED(sldata))
+{
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ ViewLayer *view_layer = draw_ctx->view_layer;
+ EEVEE_StorageList *stl = vedata->stl;
+ EEVEE_PrivateData *g_data = stl->g_data;
+
+ /* Only read the center texel. */
+ if (stl->effects->taa_current_sample > 1)
+ return;
+
+ if ((view_layer->passflag & SCE_PASS_NORMAL) != 0) {
+ RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_NORMAL, viewname);
+
+ DRW_framebuffer_read_data(rr->xof, rr->yof, rr->rectx, rr->recty, 3, 1, rp->rect);
+
+ /* Convert Eevee encoded normals to Blender normals. */
+ for (int i = 0; i < rr->rectx * rr->recty * 3; i += 3) {
+ if (rp->rect[i] == 0.0f && rp->rect[i + 1] == 0.0f) {
+ /* If normal is not correct then do not produce NANs. */
+ continue;
+ }
+
+ float fenc[2];
+ fenc[0] = rp->rect[i+0] * 4.0f - 2.0f;
+ fenc[1] = rp->rect[i+1] * 4.0f - 2.0f;
+
+ float f = dot_v2v2(fenc, fenc);
+ float g = sqrtf(1.0f - f / 4.0f);
+
+ rp->rect[i + 0] = fenc[0] * g;
+ rp->rect[i + 1] = fenc[1] * g;
+ rp->rect[i + 2] = 1.0f - f / 2.0f;
+
+ mul_mat3_m4_v3(g_data->viewinv, &rp->rect[i]);
+ }
+ }
+}
+
+static void eevee_render_result_z(
+ RenderResult *rr, RenderLayer *rl, const char *viewname,
+ EEVEE_Data *vedata, EEVEE_ViewLayerData *sldata)
+{
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ ViewLayer *view_layer = draw_ctx->view_layer;
+ EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
+ EEVEE_StorageList *stl = vedata->stl;
+ EEVEE_PrivateData *g_data = stl->g_data;
+
+ /* Only read the center texel. */
+ if (stl->effects->taa_current_sample > 1)
+ return;
+
+ if ((view_layer->passflag & SCE_PASS_Z) != 0) {
+ RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_Z, viewname);
+
+ DRW_framebuffer_read_depth(rr->xof, rr->yof, rr->rectx, rr->recty, rp->rect);
+
+ bool is_persp = DRW_viewport_is_persp_get();
+
+ /* Convert ogl depth [0..1] to view Z [near..far] */
+ for (int i = 0; i < rr->rectx * rr->recty; ++i) {
+ if (rp->rect[i] == 1.0f ) {
+ rp->rect[i] = 1e10f; /* Background */
+ }
+ else {
+ if (is_persp) {
+ rp->rect[i] = rp->rect[i] * 2.0f - 1.0f;
+ rp->rect[i] = g_data->winmat[3][2] / (rp->rect[i] + g_data->winmat[2][2]);
+ }
+ else {
+ rp->rect[i] = -common_data->view_vecs[0][2] + rp->rect[i] * -common_data->view_vecs[1][2];
+ }
+ }
+ }
+ }
+}
+
+static void eevee_render_result_mist(
+ RenderResult *rr, RenderLayer *rl, const char *viewname,
+ EEVEE_Data *vedata, EEVEE_ViewLayerData *UNUSED(sldata))
{
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ ViewLayer *view_layer = draw_ctx->view_layer;
+
+ if ((view_layer->passflag & SCE_PASS_MIST) != 0) {
+ RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_MIST, viewname);
+
+ IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_EEVEE);
+ float render_samples = (float)BKE_collection_engine_property_value_get_int(props, "taa_render_samples");
+
+ DRW_framebuffer_bind(vedata->fbl->mist_accum_fb);
+ DRW_framebuffer_read_data(rr->xof, rr->yof, rr->rectx, rr->recty, 1, 0, rp->rect);
+
+ /* This is the accumulated color. Divide by the number of samples. */
+ for (int i = 0; i < rr->rectx * rr->recty; i++) {
+ rp->rect[i] /= render_samples;
+ }
+ }
+}
+
+static void eevee_render_result_occlusion(
+ RenderResult *rr, RenderLayer *rl, const char *viewname,
+ EEVEE_Data *vedata, EEVEE_ViewLayerData *UNUSED(sldata))
+{
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ ViewLayer *view_layer = draw_ctx->view_layer;
+
+ if (vedata->fbl->ao_accum_fb == NULL) {
+ /* AO is not enabled. */
+ return;
+ }
+
+ if ((view_layer->passflag & SCE_PASS_AO) != 0) {
+ RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_AO, viewname);
+
+ IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_EEVEE);
+ float render_samples = (float)BKE_collection_engine_property_value_get_int(props, "taa_render_samples");
+
+ DRW_framebuffer_bind(vedata->fbl->ao_accum_fb);
+ DRW_framebuffer_read_data(rr->xof, rr->yof, rr->rectx, rr->recty, 3, 0, rp->rect);
+
+ /* This is the accumulated color. Divide by the number of samples. */
+ for (int i = 0; i < rr->rectx * rr->recty * 3; i += 3) {
+ rp->rect[i] = rp->rect[i + 1] = rp->rect[i+2] = min_ff(1.0f, rp->rect[i] / render_samples);
+ }
+ }
+}
+
+static void eevee_render_draw_background(EEVEE_Data *vedata)
+{
+ EEVEE_TextureList *txl = vedata->txl;
+ EEVEE_FramebufferList *fbl = vedata->fbl;
+ EEVEE_PassList *psl = vedata->psl;
+
+ /* Prevent background to write to data buffers.
+ * NOTE : This also make sure the textures are bound
+ * to the right double buffer. */
+ if (txl->ssr_normal_input != NULL) {
+ DRW_framebuffer_texture_detach(txl->ssr_normal_input);
+ }
+ if (txl->ssr_specrough_input != NULL) {
+ DRW_framebuffer_texture_detach(txl->ssr_specrough_input);
+ }
+ DRW_framebuffer_bind(fbl->main);
+
+ DRW_draw_pass(psl->background_pass);
+
+ if (txl->ssr_normal_input != NULL) {
+ DRW_framebuffer_texture_attach(fbl->main, txl->ssr_normal_input, 1, 0);
+ }
+ if (txl->ssr_specrough_input != NULL) {
+ DRW_framebuffer_texture_attach(fbl->main, txl->ssr_specrough_input, 2, 0);
+ }
+ DRW_framebuffer_bind(fbl->main);
+}
+
+void EEVEE_render_draw(EEVEE_Data *vedata, RenderEngine *engine, RenderResult *rr, RenderLayer *rl)
+{
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ ViewLayer *view_layer = draw_ctx->view_layer;
+ const char *viewname = RE_GetActiveRenderView(engine->re);
EEVEE_PassList *psl = vedata->psl;
EEVEE_StorageList *stl = vedata->stl;
EEVEE_FramebufferList *fbl = vedata->fbl;
@@ -163,32 +385,60 @@ void EEVEE_render_draw(EEVEE_Data *vedata, struct RenderEngine *UNUSED(engine),
EEVEE_lights_cache_finish(sldata);
EEVEE_lightprobes_cache_finish(sldata, vedata);
- const DRWContextState *draw_ctx = DRW_context_state_get();
- ViewLayer *view_layer = draw_ctx->view_layer;
+ /* Sort transparents before the loop. */
+ DRW_pass_sort_shgroup_z(psl->transparent_pass);
+
+ /* Push instances attribs to the GPU. */
+ DRW_render_instance_buffer_finish();
+
+ if ((view_layer->passflag & (SCE_PASS_SUBSURFACE_COLOR |
+ SCE_PASS_SUBSURFACE_DIRECT |
+ SCE_PASS_SUBSURFACE_INDIRECT)) != 0)
+ {
+ EEVEE_subsurface_output_init(sldata, vedata);
+ }
+
+ if ((view_layer->passflag & SCE_PASS_MIST) != 0) {
+ EEVEE_mist_output_init(sldata, vedata);
+ }
+
+ if ((view_layer->passflag & SCE_PASS_AO) != 0) {
+ EEVEE_occlusion_output_init(sldata, vedata);
+ }
+
IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_EEVEE);
unsigned int render_samples = BKE_collection_engine_property_value_get_int(props, "taa_render_samples");
while (render_samples-- > 0) {
- float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.6f};
+ float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f};
unsigned int primes[3] = {2, 3, 7};
double offset[3] = {0.0, 0.0, 0.0};
double r[3];
+ /* Restore winmat before jittering again. */
+ copy_m4_m4(stl->effects->overide_winmat, g_data->winmat);
+
BLI_halton_3D(primes, offset, stl->effects->taa_current_sample, r);
EEVEE_update_noise(psl, fbl, r);
EEVEE_temporal_sampling_matrices_calc(stl->effects, g_data->viewmat, g_data->persmat, r);
+ EEVEE_volumes_set_jitter(sldata, stl->effects->taa_current_sample - 1);
+ EEVEE_materials_init(sldata, stl, fbl);
- /* Refresh Probes & shadows */
- EEVEE_lightprobes_refresh(sldata, vedata);
+ /* Refresh Probes */
+ while (EEVEE_lightprobes_all_probes_ready(sldata, vedata) == false) {
+ EEVEE_lightprobes_refresh(sldata, vedata);
+ }
+ EEVEE_lightprobes_refresh_planar(sldata, vedata);
DRW_uniformbuffer_update(sldata->common_ubo, &sldata->common_data);
- EEVEE_draw_shadows(sldata, psl);
-
+ /* Set matrices. */
DRW_viewport_matrix_override_set(stl->effects->overide_persmat, DRW_MAT_PERS);
DRW_viewport_matrix_override_set(stl->effects->overide_persinv, DRW_MAT_PERSINV);
DRW_viewport_matrix_override_set(stl->effects->overide_winmat, DRW_MAT_WIN);
DRW_viewport_matrix_override_set(stl->effects->overide_wininv, DRW_MAT_WININV);
DRW_viewport_matrix_override_set(g_data->viewmat, DRW_MAT_VIEW);
DRW_viewport_matrix_override_set(g_data->viewinv, DRW_MAT_VIEWINV);
+ /* Refresh Shadows */
+ EEVEE_draw_shadows(sldata, psl);
DRW_framebuffer_texture_detach(dtxl->depth);
DRW_framebuffer_texture_attach(fbl->main, dtxl->depth, 0, 0);
@@ -202,77 +452,63 @@ void EEVEE_render_draw(EEVEE_Data *vedata, struct RenderEngine *UNUSED(engine),
EEVEE_occlusion_compute(sldata, vedata, dtxl->depth, -1);
EEVEE_volumes_compute(sldata, vedata);
/* Shading pass */
- DRW_draw_pass(psl->background_pass);
+ eevee_render_draw_background(vedata);
+ DRW_framebuffer_bind(fbl->main);
EEVEE_draw_default_passes(psl);
DRW_draw_pass(psl->material_pass);
EEVEE_subsurface_data_render(sldata, vedata);
/* Effects pre-transparency */
EEVEE_subsurface_compute(sldata, vedata);
EEVEE_reflection_compute(sldata, vedata);
- EEVEE_occlusion_draw_debug(sldata, vedata);
- DRW_draw_pass(psl->probe_display);
EEVEE_refraction_compute(sldata, vedata);
/* Opaque refraction */
DRW_draw_pass(psl->refract_depth_pass);
DRW_draw_pass(psl->refract_depth_pass_cull);
DRW_draw_pass(psl->refract_pass);
+ /* Subsurface output */
+ EEVEE_subsurface_output_accumulate(sldata, vedata);
+ /* Occlusion output */
+ EEVEE_occlusion_output_accumulate(sldata, vedata);
+ /* Result NORMAL */
+ eevee_render_result_normal(rr, rl, viewname, vedata, sldata);
/* Volumetrics Resolve Opaque */
EEVEE_volumes_resolve(sldata, vedata);
+ /* Mist output */
+ EEVEE_mist_output_accumulate(sldata, vedata);
/* Transparent */
- DRW_pass_sort_shgroup_z(psl->transparent_pass);
DRW_draw_pass(psl->transparent_pass);
+ /* Result Z */
+ eevee_render_result_z(rr, rl, viewname, vedata, sldata);
/* Post Process */
EEVEE_draw_effects(sldata, vedata);
}
+
+ eevee_render_result_combined(rr, rl, viewname, vedata, sldata);
+ eevee_render_result_subsurface(rr, rl, viewname, vedata, sldata);
+ eevee_render_result_mist(rr, rl, viewname, vedata, sldata);
+ eevee_render_result_occlusion(rr, rl, viewname, vedata, sldata);
}
-void EEVEE_render_output(EEVEE_Data *vedata, RenderEngine *engine, struct Depsgraph *UNUSED(depsgraph))
+void EEVEE_render_update_passes(RenderEngine *engine, Scene *scene, ViewLayer *view_layer)
{
- const DRWContextState *draw_ctx = DRW_context_state_get();
- ViewLayer *view_layer = draw_ctx->view_layer;
- DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
- EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
- EEVEE_FramebufferList *fbl = vedata->fbl;
- EEVEE_StorageList *stl = vedata->stl;
- EEVEE_PrivateData *g_data = stl->g_data;
- EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
+ int type;
- const char *viewname = NULL;
- const float *render_size = DRW_viewport_size_get();
+ RE_engine_register_pass(engine, scene, view_layer, RE_PASSNAME_COMBINED, 4, "RGBA", SOCK_RGBA);
- /* Combined */
- RenderResult *rr = RE_engine_begin_result(engine, 0, 0, (int)render_size[0], (int)render_size[1], NULL, viewname);
- RenderLayer *rl = rr->layers.first;
- RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_COMBINED, viewname);
-
- DRW_framebuffer_bind(stl->effects->final_fb);
- DRW_framebuffer_read_data(0, 0, (int)render_size[0], (int)render_size[1], 4, 0, rp->rect);
-
- if (view_layer->passflag & SCE_PASS_Z) {
- rp = RE_pass_find_by_name(rl, RE_PASSNAME_Z, viewname);
-
- DRW_framebuffer_texture_attach(fbl->main, dtxl->depth, 0, 0);
- DRW_framebuffer_bind(fbl->main);
- DRW_framebuffer_read_depth(0, 0, (int)render_size[0], (int)render_size[1], rp->rect);
-
- bool is_persp = DRW_viewport_is_persp_get();
-
- /* Convert ogl depth [0..1] to view Z [near..far] */
- for (int i = 0; i < (int)render_size[0] * (int)render_size[1]; ++i) {
- if (rp->rect[i] == 1.0f ) {
- rp->rect[i] = 1e10f; /* Background */
- }
- else {
- if (is_persp) {
- rp->rect[i] = rp->rect[i] * 2.0f - 1.0f;
- rp->rect[i] = g_data->winmat[3][2] / (rp->rect[i] + g_data->winmat[2][2]);
- }
- else {
- rp->rect[i] = -common_data->view_vecs[0][2] + rp->rect[i] * -common_data->view_vecs[1][2];
- }
- }
- }
+#define CHECK_PASS(name, channels, chanid) \
+ if (view_layer->passflag & (SCE_PASS_ ## name)) { \
+ if (channels == 4) type = SOCK_RGBA; \
+ else if (channels == 3) type = SOCK_VECTOR; \
+ else type = SOCK_FLOAT; \
+ RE_engine_register_pass(engine, scene, view_layer, RE_PASSNAME_ ## name, channels, chanid, type); \
}
- RE_engine_end_result(engine, rr, false, false, false);
-} \ No newline at end of file
+ CHECK_PASS(Z, 1, "Z");
+ CHECK_PASS(MIST, 1, "Z");
+ CHECK_PASS(NORMAL, 3, "XYZ");
+ CHECK_PASS(AO, 3, "RGB");
+ CHECK_PASS(SUBSURFACE_COLOR, 3, "RGB");
+ CHECK_PASS(SUBSURFACE_DIRECT, 3, "RGB");
+
+#undef CHECK_PASS
+}
diff --git a/source/blender/draw/engines/eevee/eevee_subsurface.c b/source/blender/draw/engines/eevee/eevee_subsurface.c
index 17da4a18b78..c3079d931fb 100644
--- a/source/blender/draw/engines/eevee/eevee_subsurface.c
+++ b/source/blender/draw/engines/eevee/eevee_subsurface.c
@@ -33,7 +33,7 @@
#include "GPU_texture.h"
static struct {
- struct GPUShader *sss_sh[3];
+ struct GPUShader *sss_sh[4];
} e_data = {NULL}; /* Engine data */
extern char datatoc_common_uniforms_lib_glsl[];
@@ -49,6 +49,9 @@ static void eevee_create_shader_subsurface(void)
e_data.sss_sh[1] = DRW_shader_create_fullscreen(frag_str, "#define SECOND_PASS\n");
e_data.sss_sh[2] = DRW_shader_create_fullscreen(frag_str, "#define SECOND_PASS\n"
"#define USE_SEP_ALBEDO\n");
+ e_data.sss_sh[3] = DRW_shader_create_fullscreen(frag_str, "#define SECOND_PASS\n"
+ "#define USE_SEP_ALBEDO\n"
+ "#define RESULT_ACCUM\n");
MEM_freeN(frag_str);
}
@@ -71,6 +74,11 @@ int EEVEE_subsurface_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
effects->sss_separate_albedo = BKE_collection_engine_property_value_get_bool(props, "sss_separate_albedo");
common_data->sss_jitter_threshold = BKE_collection_engine_property_value_get_float(props, "sss_jitter_threshold");
+ /* Force separate albedo for final render */
+ if (DRW_state_is_image_render()) {
+ effects->sss_separate_albedo = true;
+ }
+
/* Shaders */
if (!e_data.sss_sh[0]) {
eevee_create_shader_subsurface();
@@ -90,11 +98,16 @@ int EEVEE_subsurface_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_framebuffer_init(&fbl->sss_clear_fb, &draw_engine_eevee_type, (int)viewport_size[0], (int)viewport_size[1],
&tex_data, 1);
- if (effects->sss_separate_albedo && (txl->sss_albedo == NULL)) {
- txl->sss_albedo = DRW_texture_create_2D((int)viewport_size[0], (int)viewport_size[1],
- DRW_TEX_RGB_11_11_10, 0, NULL);
+ if (effects->sss_separate_albedo) {
+ if (txl->sss_albedo == NULL) {
+ txl->sss_albedo = DRW_texture_create_2D((int)viewport_size[0], (int)viewport_size[1],
+ DRW_TEX_RGB_11_11_10, 0, NULL);
+ }
+ }
+ else {
+ /* Cleanup to release memory */
+ DRW_TEXTURE_FREE_SAFE(txl->sss_albedo);
}
-
return EFFECT_SSS;
}
@@ -109,6 +122,47 @@ int EEVEE_subsurface_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
return 0;
}
+static void set_shgrp_stencil(void *UNUSED(userData), DRWShadingGroup *shgrp)
+{
+ DRW_shgroup_stencil_mask(shgrp, 255);
+}
+
+void EEVEE_subsurface_output_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
+{
+ EEVEE_FramebufferList *fbl = vedata->fbl;
+ EEVEE_TextureList *txl = vedata->txl;
+ const float *viewport_size = DRW_viewport_size_get();
+
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ ViewLayer *view_layer = draw_ctx->view_layer;
+ IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_EEVEE);
+
+ if (BKE_collection_engine_property_value_get_bool(props, "sss_enable")) {
+ float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+
+ DRWFboTexture tex_data[2] = {{&txl->sss_dir_accum, DRW_TEX_RGBA_16, 0},
+ {&txl->sss_col_accum, DRW_TEX_RGBA_16, 0}};
+ DRW_framebuffer_init(&fbl->sss_accum_fb, &draw_engine_eevee_type, (int)viewport_size[0], (int)viewport_size[1],
+ tex_data, 2);
+
+ /* Clear texture. */
+ DRW_framebuffer_bind(fbl->sss_accum_fb);
+ DRW_framebuffer_clear(true, false, false, clear, 0.0f);
+
+ /* Make the opaque refraction pass mask the sss. */
+ DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_CLIP_PLANES |
+ DRW_STATE_WIRE | DRW_STATE_WRITE_STENCIL;
+ DRW_pass_state_set(vedata->psl->refract_pass, state);
+ DRW_pass_foreach_shgroup(vedata->psl->refract_pass, &set_shgrp_stencil, NULL);
+ }
+ else {
+ /* Cleanup to release memory */
+ DRW_TEXTURE_FREE_SAFE(txl->sss_dir_accum);
+ DRW_TEXTURE_FREE_SAFE(txl->sss_col_accum);
+ DRW_FRAMEBUFFER_FREE_SAFE(fbl->sss_accum_fb);
+ }
+}
+
void EEVEE_subsurface_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
{
EEVEE_PassList *psl = vedata->psl;
@@ -121,7 +175,9 @@ void EEVEE_subsurface_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data
*/
psl->sss_blur_ps = DRW_pass_create("Blur Horiz", DRW_STATE_WRITE_COLOR | DRW_STATE_STENCIL_EQUAL);
- psl->sss_resolve_ps = DRW_pass_create("Blur Vert", DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE | DRW_STATE_STENCIL_EQUAL);
+ DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE | DRW_STATE_STENCIL_EQUAL;
+ psl->sss_resolve_ps = DRW_pass_create("Blur Vert", state);
+ psl->sss_accum_ps = DRW_pass_create("Resolve Accum", state);
}
}
@@ -157,6 +213,18 @@ void EEVEE_subsurface_add_pass(
if (effects->sss_separate_albedo) {
DRW_shgroup_uniform_buffer(grp, "sssAlbedo", &txl->sss_albedo);
}
+
+ if (DRW_state_is_image_render()) {
+ grp = DRW_shgroup_create(e_data.sss_sh[3], psl->sss_accum_ps);
+ DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
+ DRW_shgroup_uniform_buffer(grp, "depthBuffer", &dtxl->depth);
+ DRW_shgroup_uniform_buffer(grp, "sssData", &txl->sss_blur);
+ DRW_shgroup_uniform_buffer(grp, "sssAlbedo", &txl->sss_albedo);
+ 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);
+ }
}
void EEVEE_subsurface_data_render(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
@@ -239,13 +307,19 @@ void EEVEE_subsurface_compute(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *v
DRW_framebuffer_texture_detach(dtxl->depth);
- /* First horizontal pass */
+ /* 1. horizontal pass */
DRW_framebuffer_bind(fbl->sss_blur_fb);
DRW_framebuffer_clear(true, false, false, clear, 0.0f);
DRW_draw_pass(psl->sss_blur_ps);
- /* First vertical pass + Resolve */
+ /* 2. vertical pass + Resolve */
DRW_framebuffer_texture_detach(txl->sss_stencil);
+ if ((effects->enabled_effects & EFFECT_NORMAL_BUFFER) != 0) {
+ DRW_framebuffer_texture_detach(txl->ssr_normal_input);
+ }
+ if ((effects->enabled_effects & EFFECT_SSR) != 0) {
+ DRW_framebuffer_texture_detach(txl->ssr_specrough_input);
+ }
DRW_framebuffer_texture_attach(fbl->main, txl->sss_stencil, 0, 0);
DRW_framebuffer_bind(fbl->main);
DRW_draw_pass(psl->sss_resolve_ps);
@@ -254,14 +328,46 @@ void EEVEE_subsurface_compute(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *v
DRW_framebuffer_texture_detach(txl->sss_stencil);
DRW_framebuffer_texture_attach(fbl->sss_blur_fb, txl->sss_stencil, 0, 0);
DRW_framebuffer_texture_attach(fbl->main, dtxl->depth, 0, 0);
+ if ((effects->enabled_effects & EFFECT_NORMAL_BUFFER) != 0) {
+ DRW_framebuffer_texture_attach(fbl->main, txl->ssr_normal_input, 1, 0);
+ }
+ if ((effects->enabled_effects & EFFECT_SSR) != 0) {
+ DRW_framebuffer_texture_attach(fbl->main, txl->ssr_specrough_input, 2, 0);
+ }
DRW_stats_group_end();
}
}
+void EEVEE_subsurface_output_accumulate(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
+{
+ EEVEE_PassList *psl = vedata->psl;
+ EEVEE_FramebufferList *fbl = vedata->fbl;
+ EEVEE_TextureList *txl = vedata->txl;
+ EEVEE_StorageList *stl = vedata->stl;
+ EEVEE_EffectsInfo *effects = stl->effects;
+
+ if (((effects->enabled_effects & EFFECT_SSS) != 0) && (fbl->sss_accum_fb != NULL)) {
+ /* Copy stencil channel, could be avoided (see EEVEE_subsurface_init) */
+ DRW_framebuffer_blit(fbl->main, fbl->sss_blur_fb, false, true);
+
+ /* Only do vertical pass + Resolve */
+ DRW_framebuffer_texture_detach(txl->sss_stencil);
+ DRW_framebuffer_texture_attach(fbl->sss_accum_fb, txl->sss_stencil, 0, 0);
+ DRW_framebuffer_bind(fbl->sss_accum_fb);
+ DRW_draw_pass(psl->sss_accum_ps);
+
+ /* Restore */
+ DRW_framebuffer_texture_detach(txl->sss_stencil);
+ DRW_framebuffer_texture_attach(fbl->sss_blur_fb, txl->sss_stencil, 0, 0);
+ DRW_framebuffer_bind(fbl->main);
+ }
+}
+
void EEVEE_subsurface_free(void)
{
DRW_SHADER_FREE_SAFE(e_data.sss_sh[0]);
DRW_SHADER_FREE_SAFE(e_data.sss_sh[1]);
DRW_SHADER_FREE_SAFE(e_data.sss_sh[2]);
+ DRW_SHADER_FREE_SAFE(e_data.sss_sh[3]);
}
diff --git a/source/blender/draw/engines/eevee/eevee_temporal_sampling.c b/source/blender/draw/engines/eevee/eevee_temporal_sampling.c
index 24b8117b6f5..a417a9bdf56 100644
--- a/source/blender/draw/engines/eevee/eevee_temporal_sampling.c
+++ b/source/blender/draw/engines/eevee/eevee_temporal_sampling.c
@@ -32,9 +32,14 @@
#include "eevee_private.h"
#include "GPU_texture.h"
+#define FILTER_CDF_TABLE_SIZE 512
+
static struct {
/* Temporal Anti Aliasing */
struct GPUShader *taa_resolve_sh;
+
+ /* Pixel filter table: Only blackman-harris for now. */
+ float inverted_cdf[FILTER_CDF_TABLE_SIZE];
} e_data = {NULL}; /* Engine data */
extern char datatoc_effect_temporal_aa_glsl[];
@@ -44,17 +49,107 @@ static void eevee_create_shader_temporal_sampling(void)
e_data.taa_resolve_sh = DRW_shader_create_fullscreen(datatoc_effect_temporal_aa_glsl, NULL);
}
+static float UNUSED_FUNCTION(filter_box)(float UNUSED(x))
+{
+ return 1.0f;
+}
+
+static float filter_blackman_harris(float x)
+{
+ /* Hardcoded 1px footprint [-0.5..0.5]. We resize later. */
+ const float width = 1.0f;
+ x = 2.0f * M_PI * (x / width + 0.5f);
+ return 0.35875f - 0.48829f * cosf(x) + 0.14128f * cosf(2.0f * x) - 0.01168f * cosf(3.0f * x);
+}
+
+/* Compute cumulative distribution function of a discrete function. */
+static void compute_cdf(float (*func)(float x), float cdf[FILTER_CDF_TABLE_SIZE])
+{
+ cdf[0] = 0.0f;
+ /* Actual CDF evaluation. */
+ for (int u = 0; u < FILTER_CDF_TABLE_SIZE - 1; ++u) {
+ float x = (float)(u + 1) / (float)(FILTER_CDF_TABLE_SIZE - 1);
+ cdf[u + 1] = cdf[u] + func(x - 0.5f); /* [-0.5..0.5]. We resize later. */
+ }
+ /* Normalize the CDF. */
+ for (int u = 0; u < FILTER_CDF_TABLE_SIZE - 1; u++) {
+ cdf[u] /= cdf[FILTER_CDF_TABLE_SIZE - 1];
+ }
+ /* Just to make sure. */
+ cdf[FILTER_CDF_TABLE_SIZE - 1] = 1.0f;
+}
+
+static void invert_cdf(const float cdf[FILTER_CDF_TABLE_SIZE], float invert_cdf[FILTER_CDF_TABLE_SIZE])
+{
+ for (int u = 0; u < FILTER_CDF_TABLE_SIZE; u++) {
+ float x = (float)u / (float)(FILTER_CDF_TABLE_SIZE - 1);
+ for (int i = 0; i < FILTER_CDF_TABLE_SIZE; ++i) {
+ if (cdf[i] >= x) {
+ if (i == FILTER_CDF_TABLE_SIZE - 1) {
+ invert_cdf[u] = 1.0f;
+ }
+ else {
+ float t = (x - cdf[i]) / (cdf[i + 1] - cdf[i]);
+ invert_cdf[u] = ((float)i + t) / (float)(FILTER_CDF_TABLE_SIZE - 1);
+ }
+ break;
+ }
+ }
+ }
+}
+
+/* Evaluate a discrete function table with linear interpolation. */
+static float eval_table(float *table, float x)
+{
+ CLAMP(x, 0.0f, 1.0f);
+ x = x * (FILTER_CDF_TABLE_SIZE - 1);
+
+ int index = min_ii((int)(x), FILTER_CDF_TABLE_SIZE - 1);
+ int nindex = min_ii(index + 1, FILTER_CDF_TABLE_SIZE - 1);
+ float t = x - index;
+
+ return (1.0f - t) * table[index] + t * table[nindex];
+}
+
+static void eevee_create_cdf_table_temporal_sampling(void)
+{
+ float *cdf_table = MEM_mallocN(sizeof(float) * FILTER_CDF_TABLE_SIZE, "Eevee Filter CDF table");
+
+ float filter_width = 2.0f; /* Use a 2 pixel footprint by default. */
+
+ {
+ /* Use blackman-harris filter. */
+ filter_width *= 2.0f;
+ compute_cdf(filter_blackman_harris, cdf_table);
+ }
+
+ invert_cdf(cdf_table, e_data.inverted_cdf);
+
+ /* Scale and offset table. */
+ for (int i = 0; i < FILTER_CDF_TABLE_SIZE; ++i) {
+ e_data.inverted_cdf[i] = (e_data.inverted_cdf[i] - 0.5f) * filter_width;
+ }
+
+ MEM_freeN(cdf_table);
+}
+
void EEVEE_temporal_sampling_matrices_calc(
- EEVEE_EffectsInfo *effects, float viewmat[4][4], float persmat[4][4], double ht_point[2])
+ EEVEE_EffectsInfo *effects, float viewmat[4][4], float persmat[4][4], const double ht_point[2])
{
const float *viewport_size = DRW_viewport_size_get();
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ Scene *scene = draw_ctx->scene;
+ RenderData *rd = &scene->r;
+
+ float filter_size = rd->gauss; /* Sigh.. Stupid legacy naming. */
- /* TODO Blackman-Harris filter */
+ float ofs_x = eval_table(e_data.inverted_cdf, (float)(ht_point[0])) * filter_size;
+ float ofs_y = eval_table(e_data.inverted_cdf, (float)(ht_point[1])) * filter_size;
window_translate_m4(
effects->overide_winmat, persmat,
- ((float)(ht_point[0]) * 2.0f - 1.0f) / viewport_size[0],
- ((float)(ht_point[1]) * 2.0f - 1.0f) / viewport_size[1]);
+ ofs_x / viewport_size[0],
+ ofs_y / viewport_size[1]);
mul_m4_m4m4(effects->overide_persmat, effects->overide_winmat, viewmat);
invert_m4_m4(effects->overide_persinv, effects->overide_persmat);
@@ -89,6 +184,7 @@ int EEVEE_temporal_sampling_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data
if (!e_data.taa_resolve_sh) {
eevee_create_shader_temporal_sampling();
+ eevee_create_cdf_table_temporal_sampling();
}
/* Until we support reprojection, we need to make sure
diff --git a/source/blender/draw/engines/eevee/eevee_volumes.c b/source/blender/draw/engines/eevee/eevee_volumes.c
index a960682e8c9..2c5b9072837 100644
--- a/source/blender/draw/engines/eevee/eevee_volumes.c
+++ b/source/blender/draw/engines/eevee/eevee_volumes.c
@@ -30,7 +30,7 @@
#include "BLI_rand.h"
#include "BLI_string_utils.h"
-#include "DNA_object_force.h"
+#include "DNA_object_force_types.h"
#include "DNA_smoke_types.h"
#include "DNA_world_types.h"
@@ -128,6 +128,21 @@ static void eevee_create_shader_volumes(void)
e_data.volumetric_common_lib, NULL);
}
+void EEVEE_volumes_set_jitter(EEVEE_ViewLayerData *sldata, unsigned int current_sample)
+{
+ EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
+
+ double ht_point[3];
+ double ht_offset[3] = {0.0, 0.0};
+ unsigned int ht_primes[3] = {3, 7, 2};
+
+ BLI_halton_3D(ht_primes, ht_offset, current_sample, ht_point);
+
+ common_data->vol_jitter[0] = (float)ht_point[0];
+ common_data->vol_jitter[1] = (float)ht_point[1];
+ common_data->vol_jitter[2] = (float)ht_point[2];
+}
+
int EEVEE_volumes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{
EEVEE_StorageList *stl = vedata->stl;
@@ -223,8 +238,6 @@ int EEVEE_volumes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
}
/* Temporal Super sampling jitter */
- double ht_point[3];
- double ht_offset[3] = {0.0, 0.0};
unsigned int ht_primes[3] = {3, 7, 2};
unsigned int current_sample = 0;
@@ -248,11 +261,8 @@ int EEVEE_volumes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_viewport_request_redraw();
}
}
- BLI_halton_3D(ht_primes, ht_offset, current_sample, ht_point);
- common_data->vol_jitter[0] = (float)ht_point[0];
- common_data->vol_jitter[1] = (float)ht_point[1];
- common_data->vol_jitter[2] = (float)ht_point[2];
+ EEVEE_volumes_set_jitter(sldata, current_sample);
/* Framebuffer setup */
DRWFboTexture tex_vol[4] = {{&txl->volume_prop_scattering, DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER},
@@ -304,7 +314,7 @@ int EEVEE_volumes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
}
else {
const float clip_start = common_data->view_vecs[0][2];
- const float clip_end = common_data->view_vecs[1][2];
+ const float clip_end = clip_start + common_data->view_vecs[1][2];
integration_start = min_ff(integration_end, clip_start);
integration_end = max_ff(-integration_end, clip_end);
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 68299fe7546..f571d8c727b 100644
--- a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
@@ -325,7 +325,7 @@ vec2 get_uvs_from_view(vec3 view)
vec3 get_view_space_from_depth(vec2 uvcoords, float depth)
{
if (ProjectionMatrix[3][3] == 0.0) {
- return (viewVecs[0].xyz + vec3(uvcoords, 0.0) * viewVecs[1].xyz) * get_view_z_from_depth(depth);
+ return vec3(viewVecs[0].xy + uvcoords * viewVecs[1].xy, 1.0) * get_view_z_from_depth(depth);
}
else {
return viewVecs[0].xyz + vec3(uvcoords, depth) * viewVecs[1].xyz;
@@ -418,19 +418,19 @@ float get_btdf_lut(sampler2DArray btdf_lut_tex, float NV, float roughness, float
* Using Method #4: Spheremap Transform */
vec2 normal_encode(vec3 n, vec3 view)
{
- float p = sqrt(n.z * 8.0 + 8.0);
- return n.xy / p + 0.5;
+ float p = sqrt(n.z * 8.0 + 8.0);
+ return n.xy / p + 0.5;
}
vec3 normal_decode(vec2 enc, vec3 view)
{
- vec2 fenc = enc * 4.0 - 2.0;
- float f = dot(fenc, fenc);
- float g = sqrt(1.0 - f / 4.0);
- vec3 n;
- n.xy = fenc*g;
- n.z = 1 - f / 2;
- return n;
+ vec2 fenc = enc * 4.0 - 2.0;
+ float f = dot(fenc, fenc);
+ float g = sqrt(1.0 - f / 4.0);
+ vec3 n;
+ n.xy = fenc*g;
+ n.z = 1 - f / 2;
+ return n;
}
/* ---- RGBM (shared multiplier) encoding ---- */
@@ -654,12 +654,12 @@ Closure closure_add(Closure cl1, Closure cl2)
struct Closure {
vec3 radiance;
float opacity;
-#ifdef USE_SSS
+# ifdef USE_SSS
vec4 sss_data;
-#ifdef USE_SSS_ALBEDO
+# ifdef USE_SSS_ALBEDO
vec3 sss_albedo;
-#endif
-#endif
+# endif
+# endif
vec4 ssr_data;
vec2 ssr_normal;
int ssr_id;
@@ -669,15 +669,15 @@ struct Closure {
#define TRANSPARENT_CLOSURE_FLAG -2
#define REFRACT_CLOSURE_FLAG -3
-#ifdef USE_SSS
-#ifdef USE_SSS_ALBEDO
+# ifdef USE_SSS
+# ifdef USE_SSS_ALBEDO
#define CLOSURE_DEFAULT Closure(vec3(0.0), 1.0, vec4(0.0), vec3(0.0), vec4(0.0), vec2(0.0), -1)
-#else
+# else
#define CLOSURE_DEFAULT Closure(vec3(0.0), 1.0, vec4(0.0), vec4(0.0), vec2(0.0), -1)
-#endif
-#else
+# endif
+# else
#define CLOSURE_DEFAULT Closure(vec3(0.0), 1.0, vec4(0.0), vec2(0.0), -1)
-#endif
+# endif
uniform int outputSsrId;
@@ -685,45 +685,51 @@ Closure closure_mix(Closure cl1, Closure cl2, float fac)
{
Closure cl;
- if (cl1.ssr_id == outputSsrId) {
- cl.ssr_data = mix(cl1.ssr_data.xyzw, vec4(vec3(0.0), cl1.ssr_data.w), fac); /* do not blend roughness */
- cl.ssr_normal = cl1.ssr_normal;
- cl.ssr_id = cl1.ssr_id;
- }
- else {
- cl.ssr_data = mix(vec4(vec3(0.0), cl2.ssr_data.w), cl2.ssr_data.xyzw, fac); /* do not blend roughness */
- cl.ssr_normal = cl2.ssr_normal;
- cl.ssr_id = cl2.ssr_id;
- }
if (cl1.ssr_id == TRANSPARENT_CLOSURE_FLAG) {
cl1.radiance = cl2.radiance;
-#ifdef USE_SSS
+ cl1.ssr_normal = cl2.ssr_normal;
+ cl1.ssr_data = cl2.ssr_data;
+ cl1.ssr_id = cl2.ssr_id;
+# ifdef USE_SSS
cl1.sss_data = cl2.sss_data;
-#ifdef USE_SSS_ALBEDO
+# ifdef USE_SSS_ALBEDO
cl1.sss_albedo = cl2.sss_albedo;
-#endif
-#endif
+# endif
+# endif
}
if (cl2.ssr_id == TRANSPARENT_CLOSURE_FLAG) {
cl2.radiance = cl1.radiance;
-#ifdef USE_SSS
+ cl2.ssr_normal = cl1.ssr_normal;
+ cl2.ssr_data = cl1.ssr_data;
+ cl2.ssr_id = cl1.ssr_id;
+# ifdef USE_SSS
cl2.sss_data = cl1.sss_data;
-#ifdef USE_SSS_ALBEDO
+# ifdef USE_SSS_ALBEDO
cl2.sss_albedo = cl1.sss_albedo;
-#endif
-#endif
+# endif
+# endif
+ }
+ if (cl1.ssr_id == outputSsrId) {
+ cl.ssr_data = mix(cl1.ssr_data.xyzw, vec4(vec3(0.0), cl1.ssr_data.w), fac); /* do not blend roughness */
+ cl.ssr_normal = cl1.ssr_normal;
+ cl.ssr_id = cl1.ssr_id;
+ }
+ else {
+ cl.ssr_data = mix(vec4(vec3(0.0), cl2.ssr_data.w), cl2.ssr_data.xyzw, fac); /* do not blend roughness */
+ cl.ssr_normal = cl2.ssr_normal;
+ cl.ssr_id = cl2.ssr_id;
}
cl.radiance = mix(cl1.radiance, cl2.radiance, fac);
cl.opacity = mix(cl1.opacity, cl2.opacity, fac);
-#ifdef USE_SSS
+# 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;
-#ifdef USE_SSS_ALBEDO
+# 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;
-#endif
-#endif
+# endif
+# endif
return cl;
}
@@ -731,80 +737,80 @@ Closure closure_mix(Closure cl1, Closure cl2, float fac)
Closure closure_add(Closure cl1, Closure cl2)
{
Closure cl = (cl1.ssr_id == outputSsrId) ? cl1 : cl2;
-#ifdef USE_SSS
+# ifdef USE_SSS
cl.sss_data = (cl1.sss_data.a > 0.0) ? cl1.sss_data : cl2.sss_data;
-#ifdef USE_SSS_ALBEDO
+# 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;
-#endif
-#endif
+# endif
+# endif
cl.radiance = cl1.radiance + cl2.radiance;
cl.opacity = saturate(cl1.opacity + cl2.opacity);
return cl;
}
-#if defined(MESH_SHADER) && !defined(USE_ALPHA_HASH) && !defined(USE_ALPHA_CLIP) && !defined(SHADOW_SHADER) && !defined(USE_MULTIPLY)
+# if defined(MESH_SHADER) && !defined(USE_ALPHA_HASH) && !defined(USE_ALPHA_CLIP) && !defined(SHADOW_SHADER) && !defined(USE_MULTIPLY)
layout(location = 0) out vec4 fragColor;
-#ifdef USE_SSS
-#ifdef USE_SSS_ALBEDO
+# ifdef USE_SSS
+# ifdef USE_SSS_ALBEDO
layout(location = 1) out vec4 sssData;
layout(location = 2) out vec4 sssAlbedo;
layout(location = 3) out vec4 ssrNormals;
layout(location = 4) out vec4 ssrData;
-#else
+# else
layout(location = 1) out vec4 sssData;
layout(location = 2) out vec4 ssrNormals;
layout(location = 3) out vec4 ssrData;
-#endif /* USE_SSS_ALBEDO */
-#else
+# endif /* USE_SSS_ALBEDO */
+# else
layout(location = 1) out vec4 ssrNormals;
layout(location = 2) out vec4 ssrData;
-#endif /* USE_SSS */
+# endif /* USE_SSS */
Closure nodetree_exec(void); /* Prototype */
-#if defined(USE_ALPHA_BLEND_VOLUMETRICS)
+# if defined(USE_ALPHA_BLEND_VOLUMETRICS)
/* Prototype because this file is included before volumetric_lib.glsl */
vec4 volumetric_resolve(vec4 scene_color, vec2 frag_uvs, float frag_depth);
-#endif
+# endif
#define NODETREE_EXEC
void main()
{
Closure cl = nodetree_exec();
-#ifndef USE_ALPHA_BLEND
+# ifndef USE_ALPHA_BLEND
/* Prevent alpha hash material writing into alpha channel. */
cl.opacity = 1.0;
-#endif
+# endif
-#if defined(USE_ALPHA_BLEND_VOLUMETRICS)
+# if defined(USE_ALPHA_BLEND_VOLUMETRICS)
/* XXX fragile, better use real viewport resolution */
vec2 uvs = gl_FragCoord.xy / vec2(2 * textureSize(maxzBuffer, 0).xy);
fragColor = volumetric_resolve(vec4(cl.radiance, cl.opacity), uvs, gl_FragCoord.z);
-#else
+# else
fragColor = vec4(cl.radiance, cl.opacity);
-#endif
+# endif
ssrNormals = cl.ssr_normal.xyyy;
ssrData = cl.ssr_data;
-#ifdef USE_SSS
+# ifdef USE_SSS
sssData = cl.sss_data;
-#ifdef USE_SSS_ALBEDO
+# ifdef USE_SSS_ALBEDO
sssAlbedo = cl.sss_albedo.rgbb;
-#endif
-#endif
+# endif
+# endif
/* For Probe capture */
-#ifdef USE_SSS
-#ifdef USE_SSS_ALBEDO
+# ifdef USE_SSS
+# ifdef USE_SSS_ALBEDO
fragColor.rgb += cl.sss_data.rgb * cl.sss_albedo.rgb * float(!sssToggle);
-#else
+# else
fragColor.rgb += cl.sss_data.rgb * float(!sssToggle);
-#endif
-#endif
+# endif
+# endif
}
-#endif /* MESH_SHADER && !SHADOW_SHADER */
+# endif /* MESH_SHADER && !SHADOW_SHADER */
#endif /* VOLUMETRICS */
diff --git a/source/blender/draw/engines/eevee/shaders/effect_gtao_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_gtao_frag.glsl
index 32edf709d88..b7bcf5c8a8b 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_gtao_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_gtao_frag.glsl
@@ -28,7 +28,8 @@ void main()
gtao_deferred(normal, viewPosition, noise, depth, visibility, bent_normal);
- FragColor = vec4(visibility);
+ /* Handle Background case. Prevent artifact due to uncleared Horizon Render Target. */
+ FragColor = vec4((depth == 1.0) ? 0.0 : visibility);
}
#else
diff --git a/source/blender/draw/engines/eevee/shaders/effect_minmaxz_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_minmaxz_frag.glsl
index 65d3970a82a..05fef73b159 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_minmaxz_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_minmaxz_frag.glsl
@@ -23,7 +23,9 @@ uniform sampler2D depthBuffer;
#define minmax(a, b) max(a, b)
#endif
-#ifdef GPU_INTEL
+/* On some AMD card / driver conbination, it is needed otherwise,
+ * the shader does not write anything. */
+#if defined(GPU_INTEL) || defined(GPU_ATI)
out vec4 fragColor;
#endif
@@ -65,10 +67,9 @@ void main()
}
#endif
-#ifdef GPU_INTEL
+#if defined(GPU_INTEL) || defined(GPU_ATI)
/* Use color format instead of 24bit depth texture */
fragColor = vec4(val);
-#else
- gl_FragDepth = val;
#endif
+ gl_FragDepth = val;
} \ No newline at end of file
diff --git a/source/blender/draw/engines/eevee/shaders/effect_mist_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_mist_frag.glsl
new file mode 100644
index 00000000000..fe38b2e9aac
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/effect_mist_frag.glsl
@@ -0,0 +1,31 @@
+/* Convert depth to Mist factor */
+uniform vec3 mistSettings;
+
+#define mistStart mistSettings.x
+#define mistInvDistance mistSettings.y
+#define mistFalloff mistSettings.z
+
+out vec4 fragColor;
+
+void main()
+{
+ vec2 texel_size = 1.0 / vec2(textureSize(depthBuffer, 0)).xy;
+ vec2 uvs = gl_FragCoord.xy * texel_size;
+
+ float depth = textureLod(depthBuffer, uvs, 0.0).r;
+ vec3 co = get_view_space_from_depth(uvs, depth);
+
+ float zcor = (ProjectionMatrix[3][3] == 0.0) ? length(co) : -co.z;
+
+ /* bring depth into 0..1 range */
+ float mist = saturate((zcor - mistStart) * mistInvDistance);
+
+ /* falloff */
+ mist = pow(mist, mistFalloff);
+
+ fragColor = vec4(mist);
+
+ // if (mist > 0.999) fragColor = vec4(1.0);
+ // else if (mist > 0.0001) fragColor = vec4(0.5);
+ // else fragColor = vec4(0.0);
+}
diff --git a/source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl
index 184eac54c26..d9e12bcc4bd 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl
@@ -18,7 +18,10 @@ uniform sampler2DArray utilTex;
#define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0)
#endif /* UTIL_TEX */
-out vec4 FragColor;
+layout(location = 0) out vec4 FragColor;
+#ifdef RESULT_ACCUM
+layout(location = 1) out vec4 sssColor;
+#endif
uniform mat4 ProjectionMatrix;
@@ -84,10 +87,15 @@ void main(void)
#ifdef FIRST_PASS
FragColor = vec4(accum, sss_data.a);
#else /* SECOND_PASS */
- #ifdef USE_SEP_ALBEDO
+# ifdef USE_SEP_ALBEDO
+# ifdef RESULT_ACCUM
+ FragColor = vec4(accum, 1.0);
+ sssColor = texture(sssAlbedo, uvs);
+# else
FragColor = vec4(accum * texture(sssAlbedo, uvs).rgb, 1.0);
- #else
+# endif
+# else
FragColor = vec4(accum, 1.0);
- #endif
+# endif
#endif
}
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index 528495b8710..f62b224b094 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -140,7 +140,7 @@ typedef struct DrawEngineType {
void (*view_update)(void *vedata);
void (*id_update)(void *vedata, struct ID *id);
- void (*render_to_image)(void *vedata, struct RenderEngine *engine, struct Depsgraph *graph);
+ void (*render_to_image)(void *vedata, struct RenderEngine *engine, struct RenderResult *result, struct RenderLayer *layer);
} DrawEngineType;
#ifndef __DRW_ENGINE_H__
@@ -305,13 +305,33 @@ typedef enum {
#define DRW_STATE_DEFAULT (DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS)
+typedef enum {
+ DRW_ATTRIB_INT,
+ DRW_ATTRIB_FLOAT,
+} DRWAttribType;
+
+typedef struct DRWInstanceAttribFormat {
+ char name[32];
+ DRWAttribType type;
+ int components;
+} DRWInstanceAttribFormat;
+
+struct Gwn_VertFormat *DRW_shgroup_instance_format_array(const DRWInstanceAttribFormat attribs[], int arraysize);
+#define DRW_shgroup_instance_format(format, ...) do { \
+ if (format == NULL) { \
+ DRWInstanceAttribFormat drw_format[] = __VA_ARGS__;\
+ format = DRW_shgroup_instance_format_array(drw_format, (sizeof(drw_format) / sizeof(DRWInstanceAttribFormat))); \
+ } \
+} while (0)
DRWShadingGroup *DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass);
DRWShadingGroup *DRW_shgroup_material_create(struct GPUMaterial *material, DRWPass *pass);
DRWShadingGroup *DRW_shgroup_material_instance_create(
- struct GPUMaterial *material, DRWPass *pass, struct Gwn_Batch *geom, struct Object *ob);
+ struct GPUMaterial *material, DRWPass *pass, struct Gwn_Batch *geom, struct Object *ob,
+ struct Gwn_VertFormat *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 Gwn_Batch *geom);
+DRWShadingGroup *DRW_shgroup_instance_create(
+ struct GPUShader *shader, DRWPass *pass, struct Gwn_Batch *geom, struct Gwn_VertFormat *format);
DRWShadingGroup *DRW_shgroup_point_batch_create(struct GPUShader *shader, DRWPass *pass);
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);
@@ -335,12 +355,12 @@ void DRW_shgroup_call_dynamic_add_array(DRWShadingGroup *shgroup, const void *at
DRW_shgroup_call_dynamic_add_array(shgroup, array, (sizeof(array) / sizeof(*array))); \
} while (0)
/* Use this to set a high number of instances. */
-void DRW_shgroup_set_instance_count(DRWShadingGroup *shgroup, int count);
+void DRW_shgroup_set_instance_count(DRWShadingGroup *shgroup, unsigned int count);
+unsigned int 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, unsigned int mask);
-void DRW_shgroup_attrib_float(DRWShadingGroup *shgroup, const char *name, int size);
void DRW_shgroup_uniform_texture(DRWShadingGroup *shgroup, const char *name, const struct GPUTexture *tex);
void DRW_shgroup_uniform_block(DRWShadingGroup *shgroup, const char *name, const struct GPUUniformBuffer *ubo);
@@ -393,6 +413,7 @@ void DRW_render_to_image(struct RenderEngine *re, struct Depsgraph *depsgraph);
void DRW_render_object_iter(
void *vedata, struct RenderEngine *engine, struct Depsgraph *graph,
void (*callback)(void *vedata, struct Object *ob, struct RenderEngine *engine, struct Depsgraph *graph));
+void DRW_render_instance_buffer_finish(void);
/* ViewLayers */
void *DRW_view_layer_engine_data_get(DrawEngineType *engine_type);
@@ -445,6 +466,7 @@ bool DRW_state_is_select(void);
bool DRW_state_is_depth(void);
bool DRW_state_is_image_render(void);
bool DRW_state_is_scene_render(void);
+bool DRW_state_is_opengl_render(void);
bool DRW_state_show_text(void);
bool DRW_state_draw_support(void);
bool DRW_state_draw_background(void);
@@ -455,6 +477,7 @@ struct DRWTextStore *DRW_state_text_cache_get(void);
/* Avoid too many lookups while drawing */
typedef struct DRWContextState {
+
struct ARegion *ar; /* 'CTX_wm_region(C)' */
struct RegionView3D *rv3d; /* 'CTX_wm_region_view3d(C)' */
struct View3D *v3d; /* 'CTX_wm_view3d(C)' */
@@ -462,16 +485,25 @@ typedef struct DRWContextState {
struct Scene *scene; /* 'CTX_data_scene(C)' */
struct ViewLayer *view_layer; /* 'CTX_data_view_layer(C)' */
- /* Use 'scene->obedit' for edit-mode */
+ /* Use 'object_edit' for edit-mode */
struct Object *obact; /* 'OBACT' */
struct RenderEngineType *engine_type;
struct Depsgraph *depsgraph;
+ eObjectMode object_mode;
+
/* Last resort (some functions take this as an arg so we can't easily avoid).
* May be NULL when used for selection or depth buffer. */
const struct bContext *evil_C;
+
+ /* ---- */
+
+ /* Cache: initialized by 'drw_context_state_init'. */
+ struct Object *object_pose;
+ struct Object *object_edit;
+
} DRWContextState;
const DRWContextState *DRW_context_state_get(void);
diff --git a/source/blender/draw/intern/draw_armature.c b/source/blender/draw/intern/draw_armature.c
index 09fe3d68651..c14fe70e0c3 100644
--- a/source/blender/draw/intern/draw_armature.c
+++ b/source/blender/draw/intern/draw_armature.c
@@ -1308,7 +1308,9 @@ static void draw_armature_pose(Object *ob, const float const_color[4])
// if (!(base->flag & OB_FROMDUPLI)) // TODO
{
- if (ob->mode & OB_MODE_POSE) {
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+
+ if ((draw_ctx->object_mode & OB_MODE_POSE) || (ob == draw_ctx->object_pose)) {
arm->flag |= ARM_POSEMODE;
}
diff --git a/source/blender/draw/intern/draw_common.c b/source/blender/draw/intern/draw_common.c
index 0eb97a54ba5..62166092638 100644
--- a/source/blender/draw/intern/draw_common.c
+++ b/source/blender/draw/intern/draw_common.c
@@ -35,7 +35,6 @@
#include "draw_common.h"
-
#if 0
#define UI_COLOR_RGB_FROM_U8(r, g, b, v4) \
ARRAY_SET_ITEMS(v4, (float)r / 255.0f, (float)g / 255.0f, (float)b / 255.0f, 1.0)
@@ -157,6 +156,29 @@ void DRW_globals_update(void)
/* ********************************* SHGROUP ************************************* */
+static struct {
+ struct Gwn_VertFormat *instance_screenspace;
+ struct Gwn_VertFormat *instance_color;
+ struct Gwn_VertFormat *instance_screen_aligned;
+ struct Gwn_VertFormat *instance_scaled;
+ struct Gwn_VertFormat *instance_sized;
+ struct Gwn_VertFormat *instance;
+ struct Gwn_VertFormat *instance_camera;
+ struct Gwn_VertFormat *instance_distance_lines;
+ struct Gwn_VertFormat *instance_spot;
+ struct Gwn_VertFormat *instance_bone_envelope_wire;
+ struct Gwn_VertFormat *instance_bone_envelope_solid;
+ struct Gwn_VertFormat *instance_mball_handles;
+} g_formats = {NULL};
+
+void DRW_globals_free(void)
+{
+ struct Gwn_VertFormat **format = &g_formats.instance_screenspace;
+ for (int i = 0; i < sizeof(g_formats) / sizeof(void *); ++i, ++format) {
+ MEM_SAFE_FREE(*format);
+ }
+}
+
DRWShadingGroup *shgroup_dynlines_uniform_color(DRWPass *pass, float color[4])
{
GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
@@ -204,9 +226,12 @@ DRWShadingGroup *shgroup_instance_screenspace(DRWPass *pass, struct Gwn_Batch *g
{
GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_SCREENSPACE_VARIYING_COLOR);
- DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom);
- DRW_shgroup_attrib_float(grp, "world_pos", 3);
- DRW_shgroup_attrib_float(grp, "color", 3);
+ DRW_shgroup_instance_format(g_formats.instance_screenspace, {
+ {"world_pos", DRW_ATTRIB_FLOAT, 3},
+ {"color" , DRW_ATTRIB_FLOAT, 3}
+ });
+
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom, g_formats.instance_screenspace);
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);
@@ -220,9 +245,12 @@ DRWShadingGroup *shgroup_instance_solid(DRWPass *pass, struct Gwn_Batch *geom)
static float light[3] = {0.0f, 0.0f, 1.0f};
GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_OBJECTSPACE_SIMPLE_LIGHTING_VARIYING_COLOR);
- DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom);
- DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16);
- DRW_shgroup_attrib_float(grp, "color", 4);
+ DRW_shgroup_instance_format(g_formats.instance_color, {
+ {"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16},
+ {"color" , DRW_ATTRIB_FLOAT, 4}
+ });
+
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom, g_formats.instance_color);
DRW_shgroup_uniform_vec3(grp, "light", light, 1);
return grp;
@@ -232,9 +260,12 @@ DRWShadingGroup *shgroup_instance_wire(DRWPass *pass, struct Gwn_Batch *geom)
{
GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_OBJECTSPACE_VARIYING_COLOR);
- DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom);
- DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16);
- DRW_shgroup_attrib_float(grp, "color", 4);
+ DRW_shgroup_instance_format(g_formats.instance_color, {
+ {"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16},
+ {"color" , DRW_ATTRIB_FLOAT, 4}
+ });
+
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom, g_formats.instance_color);
return grp;
}
@@ -243,10 +274,13 @@ DRWShadingGroup *shgroup_instance_screen_aligned(DRWPass *pass, struct Gwn_Batch
{
GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED);
- DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom);
- DRW_shgroup_attrib_float(grp, "color", 3);
- DRW_shgroup_attrib_float(grp, "size", 1);
- DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16);
+ DRW_shgroup_instance_format(g_formats.instance_screen_aligned, {
+ {"color" , DRW_ATTRIB_FLOAT, 3},
+ {"size" , DRW_ATTRIB_FLOAT, 1},
+ {"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16}
+ });
+
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom, g_formats.instance_screen_aligned);
DRW_shgroup_uniform_vec3(grp, "screen_vecs[0]", DRW_viewport_screenvecs_get(), 2);
return grp;
@@ -256,10 +290,13 @@ DRWShadingGroup *shgroup_instance_axis_names(DRWPass *pass, struct Gwn_Batch *ge
{
GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED_AXIS);
- DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom);
- DRW_shgroup_attrib_float(grp, "color", 3);
- DRW_shgroup_attrib_float(grp, "size", 1);
- DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16);
+ DRW_shgroup_instance_format(g_formats.instance_screen_aligned, {
+ {"color" , DRW_ATTRIB_FLOAT, 3},
+ {"size" , DRW_ATTRIB_FLOAT, 1},
+ {"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16}
+ });
+
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom, g_formats.instance_screen_aligned);
DRW_shgroup_uniform_vec3(grp, "screen_vecs[0]", DRW_viewport_screenvecs_get(), 2);
return grp;
@@ -269,10 +306,13 @@ DRWShadingGroup *shgroup_instance_scaled(DRWPass *pass, struct Gwn_Batch *geom)
{
GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SCALE);
- DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom);
- DRW_shgroup_attrib_float(grp, "color", 3);
- DRW_shgroup_attrib_float(grp, "size", 3);
- DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16);
+ DRW_shgroup_instance_format(g_formats.instance_scaled, {
+ {"color" , DRW_ATTRIB_FLOAT, 3},
+ {"size" , DRW_ATTRIB_FLOAT, 3},
+ {"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16}
+ });
+
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom, g_formats.instance_scaled);
return grp;
}
@@ -281,10 +321,13 @@ DRWShadingGroup *shgroup_instance(DRWPass *pass, struct Gwn_Batch *geom)
{
GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE);
- DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom);
- DRW_shgroup_attrib_float(grp, "color", 3);
- DRW_shgroup_attrib_float(grp, "size", 1);
- DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16);
+ DRW_shgroup_instance_format(g_formats.instance_sized, {
+ {"color" , DRW_ATTRIB_FLOAT, 3},
+ {"size" , DRW_ATTRIB_FLOAT, 1},
+ {"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16}
+ });
+
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom, g_formats.instance_sized);
return grp;
}
@@ -293,12 +336,15 @@ DRWShadingGroup *shgroup_camera_instance(DRWPass *pass, struct Gwn_Batch *geom)
{
GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_CAMERA);
- DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom);
- DRW_shgroup_attrib_float(grp, "color", 3);
- DRW_shgroup_attrib_float(grp, "corners", 8);
- DRW_shgroup_attrib_float(grp, "depth", 1);
- DRW_shgroup_attrib_float(grp, "tria", 4);
- DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16);
+ DRW_shgroup_instance_format(g_formats.instance_camera, {
+ {"color" , DRW_ATTRIB_FLOAT, 3},
+ {"corners" , DRW_ATTRIB_FLOAT, 8},
+ {"depth" , DRW_ATTRIB_FLOAT, 1},
+ {"tria" , DRW_ATTRIB_FLOAT, 4},
+ {"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16}
+ });
+
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom, g_formats.instance_camera);
return grp;
}
@@ -308,11 +354,14 @@ DRWShadingGroup *shgroup_distance_lines_instance(DRWPass *pass, struct Gwn_Batch
GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_DISTANCE_LINES);
static float point_size = 4.0f;
- DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom);
- DRW_shgroup_attrib_float(grp, "color", 3);
- DRW_shgroup_attrib_float(grp, "start", 1);
- DRW_shgroup_attrib_float(grp, "end", 1);
- DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16);
+ DRW_shgroup_instance_format(g_formats.instance_distance_lines, {
+ {"color" , DRW_ATTRIB_FLOAT, 3},
+ {"start" , DRW_ATTRIB_FLOAT, 1},
+ {"end" , DRW_ATTRIB_FLOAT, 1},
+ {"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16}
+ });
+
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom, g_formats.instance_distance_lines);
DRW_shgroup_uniform_float(grp, "size", &point_size, 1);
return grp;
@@ -324,9 +373,12 @@ DRWShadingGroup *shgroup_spot_instance(DRWPass *pass, struct Gwn_Batch *geom)
static const int True = true;
static const int False = false;
- DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom);
- DRW_shgroup_attrib_float(grp, "color", 3);
- DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16);
+ DRW_shgroup_instance_format(g_formats.instance_spot, {
+ {"color" , DRW_ATTRIB_FLOAT, 3},
+ {"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16}
+ });
+
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom, g_formats.instance_spot);
DRW_shgroup_uniform_bool(grp, "drawFront", &False, 1);
DRW_shgroup_uniform_bool(grp, "drawBack", &False, 1);
DRW_shgroup_uniform_bool(grp, "drawSilhouette", &True, 1);
@@ -338,12 +390,15 @@ DRWShadingGroup *shgroup_instance_bone_envelope_wire(DRWPass *pass, struct Gwn_B
{
GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_INSTANCE_BONE_ENVELOPE_WIRE);
- DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom);
- DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16);
- DRW_shgroup_attrib_float(grp, "color", 4);
- DRW_shgroup_attrib_float(grp, "radius_head", 1);
- DRW_shgroup_attrib_float(grp, "radius_tail", 1);
- DRW_shgroup_attrib_float(grp, "distance", 1);
+ DRW_shgroup_instance_format(g_formats.instance_bone_envelope_wire, {
+ {"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16},
+ {"color" , DRW_ATTRIB_FLOAT, 4},
+ {"radius_head" , DRW_ATTRIB_FLOAT, 1},
+ {"radius_tail" , DRW_ATTRIB_FLOAT, 1},
+ {"distance" , DRW_ATTRIB_FLOAT, 1}
+ });
+
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom, g_formats.instance_bone_envelope_wire);
return grp;
}
@@ -353,24 +408,30 @@ DRWShadingGroup *shgroup_instance_bone_envelope_solid(DRWPass *pass, struct Gwn_
static float light[3] = {0.0f, 0.0f, 1.0f};
GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_INSTANCE_BONE_ENVELOPE_SOLID);
- DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom);
- DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16);
- DRW_shgroup_attrib_float(grp, "color", 4);
- DRW_shgroup_attrib_float(grp, "radius_head", 1);
- DRW_shgroup_attrib_float(grp, "radius_tail", 1);
+ DRW_shgroup_instance_format(g_formats.instance_bone_envelope_solid, {
+ {"InstanceModelMatrix" , DRW_ATTRIB_FLOAT, 16},
+ {"color" , DRW_ATTRIB_FLOAT, 4},
+ {"radius_head" , DRW_ATTRIB_FLOAT, 1},
+ {"radius_tail" , DRW_ATTRIB_FLOAT, 1}
+ });
+
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom, g_formats.instance_bone_envelope_solid);
DRW_shgroup_uniform_vec3(grp, "light", light, 1);
return grp;
}
-DRWShadingGroup *shgroup_instance_mball_helpers(DRWPass *pass, struct Gwn_Batch *geom)
+DRWShadingGroup *shgroup_instance_mball_handles(DRWPass *pass, struct Gwn_Batch *geom)
{
- GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_INSTANCE_MBALL_HELPERS);
+ GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_INSTANCE_MBALL_HANDLES);
+
+ DRW_shgroup_instance_format(g_formats.instance_mball_handles, {
+ {"ScaleTranslationMatrix" , DRW_ATTRIB_FLOAT, 16},
+ {"radius" , DRW_ATTRIB_FLOAT, 1},
+ {"color" , DRW_ATTRIB_FLOAT, 3}
+ });
- DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom);
- DRW_shgroup_attrib_float(grp, "ScaleTranslationMatrix", 12);
- DRW_shgroup_attrib_float(grp, "radius", 1);
- DRW_shgroup_attrib_float(grp, "color", 3);
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom, g_formats.instance_mball_handles);
DRW_shgroup_uniform_vec3(grp, "screen_vecs[0]", DRW_viewport_screenvecs_get(), 2);
return grp;
@@ -386,7 +447,8 @@ DRWShadingGroup *shgroup_instance_mball_helpers(DRWPass *pass, struct Gwn_Batch
*/
int DRW_object_wire_theme_get(Object *ob, ViewLayer *view_layer, float **r_color)
{
- const bool is_edit = (ob->mode & OB_MODE_EDIT) != 0;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ const bool is_edit = (draw_ctx->object_mode & OB_MODE_EDIT) != 0;
const bool active = (view_layer->basact && view_layer->basact->object == ob);
/* confusing logic here, there are 2 methods of setting the color
* 'colortab[colindex]' and 'theme_id', colindex overrides theme_id.
diff --git a/source/blender/draw/intern/draw_common.h b/source/blender/draw/intern/draw_common.h
index cfd88effd15..ec646693207 100644
--- a/source/blender/draw/intern/draw_common.h
+++ b/source/blender/draw/intern/draw_common.h
@@ -100,6 +100,7 @@ typedef struct GlobalsUboStorage {
/* Keep in sync with globalsBlock in shaders */
void DRW_globals_update(void);
+void DRW_globals_free(void);
struct DRWShadingGroup *shgroup_dynlines_uniform_color(struct DRWPass *pass, float color[4]);
struct DRWShadingGroup *shgroup_dynpoints_uniform_color(struct DRWPass *pass, float color[4], float *size);
@@ -118,9 +119,10 @@ struct DRWShadingGroup *shgroup_distance_lines_instance(struct DRWPass *pass, st
struct DRWShadingGroup *shgroup_spot_instance(struct DRWPass *pass, struct Gwn_Batch *geom);
struct DRWShadingGroup *shgroup_instance_bone_envelope_wire(struct DRWPass *pass, struct Gwn_Batch *geom);
struct DRWShadingGroup *shgroup_instance_bone_envelope_solid(struct DRWPass *pass, struct Gwn_Batch *geom);
-struct DRWShadingGroup *shgroup_instance_mball_helpers(struct DRWPass *pass, struct Gwn_Batch *geom);
+struct DRWShadingGroup *shgroup_instance_mball_handles(struct DRWPass *pass, struct Gwn_Batch *geom);
-int DRW_object_wire_theme_get(struct Object *ob, struct ViewLayer *view_layer, float **r_color);
+int DRW_object_wire_theme_get(
+ struct Object *ob, struct ViewLayer *view_layer, float **r_color);
float *DRW_color_background_blend_get(int theme_id);
/* draw_armature.c */
diff --git a/source/blender/draw/intern/draw_instance_data.c b/source/blender/draw/intern/draw_instance_data.c
index e7ce4374d1c..c2aae8e33ae 100644
--- a/source/blender/draw/intern/draw_instance_data.c
+++ b/source/blender/draw/intern/draw_instance_data.c
@@ -34,11 +34,20 @@
#include "draw_instance_data.h"
#include "DRW_engine.h"
+#include "DRW_render.h" /* For DRW_shgroup_get_instance_count() */
#include "MEM_guardedalloc.h"
#include "BLI_utildefines.h"
-#define MAX_INSTANCE_DATA_SIZE 32 /* Can be adjusted for more */
+#define BUFFER_CHUNK_SIZE 32
+#define BUFFER_VERTS_CHUNK 32
+
+typedef struct DRWInstanceBuffer {
+ struct DRWShadingGroup *shgroup; /* Link back to the owning shGroup. Also tells if it's used */
+ Gwn_VertFormat *format; /* Identifier. */
+ Gwn_VertBuf *vert; /* Gwn_VertBuf contained in the Gwn_Batch. */
+ Gwn_Batch *batch; /* Gwn_Batch containing the Gwn_VertBuf. */
+} DRWInstanceBuffer;
struct DRWInstanceData {
struct DRWInstanceData *next;
@@ -56,10 +65,118 @@ struct DRWInstanceDataList {
* This is done to minimize the reattribution misses. */
DRWInstanceData *idata_head[MAX_INSTANCE_DATA_SIZE];
DRWInstanceData *idata_tail[MAX_INSTANCE_DATA_SIZE];
+
+ struct {
+ size_t cursor; /* Offset to the next instance data. */
+ size_t alloc_size; /* Number of DRWInstanceBuffer alloc'd in ibufs. */
+ DRWInstanceBuffer *ibufs;
+ } ibuffers;
};
/* -------------------------------------------------------------------- */
+/** \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]).
+ **/
+
+void DRW_instance_buffer_request(
+ DRWInstanceDataList *idatalist, Gwn_VertFormat *format, struct DRWShadingGroup *shgroup,
+ Gwn_Batch **r_batch, Gwn_VertBuf **r_vert, Gwn_PrimType type)
+{
+ BLI_assert(format);
+
+ DRWInstanceBuffer *ibuf = idatalist->ibuffers.ibufs;
+ int first_non_alloced = -1;
+
+ /* Search for an unused batch. */
+ for (int i = 0; i < idatalist->ibuffers.alloc_size; i++, ibuf++) {
+ if (ibuf->shgroup == NULL) {
+ if (ibuf->format == format) {
+ ibuf->shgroup = shgroup;
+ *r_batch = ibuf->batch;
+ *r_vert = ibuf->vert;
+ return;
+ }
+ else if (ibuf->format == NULL && first_non_alloced == -1) {
+ first_non_alloced = i;
+ }
+ }
+ }
+
+ if (first_non_alloced == -1) {
+ /* There is no batch left. Allocate more. */
+ first_non_alloced = idatalist->ibuffers.alloc_size;
+ idatalist->ibuffers.alloc_size += BUFFER_CHUNK_SIZE;
+ idatalist->ibuffers.ibufs = MEM_reallocN(idatalist->ibuffers.ibufs,
+ idatalist->ibuffers.alloc_size * sizeof(DRWInstanceBuffer));
+ /* Clear new part of the memory. */
+ memset(idatalist->ibuffers.ibufs + first_non_alloced, 0, sizeof(DRWInstanceBuffer) * BUFFER_CHUNK_SIZE);
+ }
+
+ /* Create the batch. */
+ ibuf = idatalist->ibuffers.ibufs + first_non_alloced;
+ ibuf->vert = *r_vert = GWN_vertbuf_create_dynamic_with_format(format);
+ ibuf->batch = *r_batch = GWN_batch_create_ex(type, ibuf->vert, NULL, GWN_BATCH_OWNS_VBO);
+ ibuf->format = format;
+ ibuf->shgroup = shgroup;
+
+ GWN_vertbuf_data_alloc(*r_vert, BUFFER_VERTS_CHUNK);
+}
+
+void DRW_instance_buffer_finish(DRWInstanceDataList *idatalist)
+{
+ DRWInstanceBuffer *ibuf = idatalist->ibuffers.ibufs;
+ size_t minimum_alloc_size = 1; /* Avoid 0 size realloc. */
+
+ /* Resize down buffers in use and send data to GPU & free unused buffers. */
+ for (int i = 0; i < idatalist->ibuffers.alloc_size; i++, ibuf++) {
+ if (ibuf->shgroup != NULL) {
+ minimum_alloc_size = i + 1;
+ unsigned int vert_ct = DRW_shgroup_get_instance_count(ibuf->shgroup);
+ /* Do not realloc to 0 size buffer */
+ vert_ct += (vert_ct == 0) ? 1 : 0;
+ /* Resize buffer to reclame space. */
+ if (vert_ct + BUFFER_VERTS_CHUNK <= ibuf->vert->vertex_ct) {
+ unsigned int size = vert_ct + BUFFER_VERTS_CHUNK - 1;
+ size = size - size % BUFFER_VERTS_CHUNK;
+ GWN_vertbuf_data_resize(ibuf->vert, size);
+ }
+ /* Send data. */
+ GWN_vertbuf_use(ibuf->vert);
+ /* Set as non used for the next round. */
+ ibuf->shgroup = NULL;
+ }
+ else {
+ GWN_BATCH_DISCARD_SAFE(ibuf->batch);
+ /* Tag as non alloced. */
+ ibuf->format = NULL;
+ }
+ }
+
+ /* Resize down the handle buffer (ibuffers). */
+ /* Rounding up to nearest chunk size. */
+ minimum_alloc_size += BUFFER_CHUNK_SIZE - 1;
+ minimum_alloc_size -= minimum_alloc_size % BUFFER_CHUNK_SIZE;
+ /* Resize down if necessary. */
+ if (minimum_alloc_size < idatalist->ibuffers.alloc_size) {
+ idatalist->ibuffers.alloc_size = minimum_alloc_size;
+ idatalist->ibuffers.ibufs = MEM_reallocN(idatalist->ibuffers.ibufs,
+ minimum_alloc_size * sizeof(DRWInstanceBuffer));
+ }
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+
/** \name Instance Data (DRWInstanceData)
* \{ */
@@ -145,11 +262,16 @@ DRWInstanceData *DRW_instance_data_request(
DRWInstanceDataList *DRW_instance_data_list_create(void)
{
- return MEM_callocN(sizeof(DRWInstanceDataList), "DRWInstanceDataList");
+ DRWInstanceDataList *idatalist = MEM_callocN(sizeof(DRWInstanceDataList), "DRWInstanceDataList");
+ idatalist->ibuffers.ibufs = MEM_callocN(sizeof(DRWInstanceBuffer) * BUFFER_CHUNK_SIZE, "DRWInstanceBuffers");
+ idatalist->ibuffers.alloc_size = BUFFER_CHUNK_SIZE;
+
+ return idatalist;
}
void DRW_instance_data_list_free(DRWInstanceDataList *idatalist)
{
+ DRWInstanceBuffer *ibuf = idatalist->ibuffers.ibufs;
DRWInstanceData *idata, *next_idata;
for (int i = 0; i < MAX_INSTANCE_DATA_SIZE; ++i) {
@@ -161,6 +283,11 @@ void DRW_instance_data_list_free(DRWInstanceDataList *idatalist)
idatalist->idata_head[i] = NULL;
idatalist->idata_tail[i] = NULL;
}
+
+ for (int i = 0; i < idatalist->ibuffers.alloc_size; i++, ibuf++) {
+ GWN_BATCH_DISCARD_SAFE(ibuf->batch);
+ }
+ MEM_freeN(idatalist->ibuffers.ibufs);
}
void DRW_instance_data_list_reset(DRWInstanceDataList *idatalist)
diff --git a/source/blender/draw/intern/draw_instance_data.h b/source/blender/draw/intern/draw_instance_data.h
index 637c0e3cc24..a7a66c9baff 100644
--- a/source/blender/draw/intern/draw_instance_data.h
+++ b/source/blender/draw/intern/draw_instance_data.h
@@ -26,14 +26,30 @@
#ifndef __DRAW_INSTANCE_DATA_H__
#define __DRAW_INSTANCE_DATA_H__
+#include "BLI_compiler_attrs.h"
+#include "BLI_sys_types.h"
+
+#include "GPU_batch.h"
+
+#define MAX_INSTANCE_DATA_SIZE 42 /* Can be adjusted for more */
+
typedef struct DRWInstanceData DRWInstanceData;
typedef struct DRWInstanceDataList DRWInstanceDataList;
+struct DRWShadingGroup;
+
void *DRW_instance_data_next(DRWInstanceData *idata);
void *DRW_instance_data_get(DRWInstanceData *idata);
DRWInstanceData *DRW_instance_data_request(
DRWInstanceDataList *idatalist, unsigned int attrib_size, unsigned int instance_group);
+void DRW_instance_buffer_request(
+ DRWInstanceDataList *idatalist, Gwn_VertFormat *format, struct DRWShadingGroup *shgroup,
+ Gwn_Batch **r_batch, Gwn_VertBuf **r_vert, Gwn_PrimType type);
+
+/* Upload all instance data to the GPU as soon as possible. */
+void DRW_instance_buffer_finish(DRWInstanceDataList *idatalist);
+
void DRW_instance_data_list_reset(DRWInstanceDataList *idatalist);
void DRW_instance_data_list_free_unused(DRWInstanceDataList *idatalist);
void DRW_instance_data_list_resize(DRWInstanceDataList *idatalist);
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index 55195b88c05..a3a59efc799 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -75,6 +75,7 @@
#include "IMB_colormanagement.h"
#include "RE_engine.h"
+#include "RE_pipeline.h"
#include "UI_interface.h"
#include "UI_resources.h"
@@ -171,26 +172,30 @@ typedef enum {
DRW_UNIFORM_BLOCK
} DRWUniformType;
-typedef enum {
- DRW_ATTRIB_INT,
- DRW_ATTRIB_FLOAT,
-} DRWAttribType;
+#define MAX_UNIFORM_DATA_SIZE 16
struct DRWUniform {
struct DRWUniform *next;
- DRWUniformType type;
- int location;
- int length;
- int arraysize;
const void *value;
+ int location;
+ char type; /* DRWUniformType */
+ char length; /* cannot be more than 16 */
+ char arraysize; /* cannot be more than 16 too */
};
struct DRWInterface {
DRWUniform *uniforms; /* DRWUniform, single-linked list */
- int attribs_count;
- int attribs_stride;
- int attribs_size[16];
- int attribs_loc[16];
+ /* Dynamic batch */
+#ifdef USE_GPU_SELECT
+ struct DRWInstanceData *inst_selectid;
+ /* Override for single object instances. */
+ int override_selectid;
+#endif
+ Gwn_VertBuf *instance_vbo;
+ unsigned int instance_count;
+#ifndef NDEBUG
+ char attribs_count;
+#endif
/* matrices locations */
int model;
int modelinverse;
@@ -209,17 +214,6 @@ struct DRWInterface {
int orcotexfac;
int eye;
int clipplanes;
- /* Dynamic batch */
- Gwn_Batch *instance_batch; /* contains instances attributes */
- GLuint instance_vbo; /* same as instance_batch but generated from DRWCalls */
- struct DRWInstanceData *inst_data;
-#ifdef USE_GPU_SELECT
- struct DRWInstanceData *inst_selectid;
- /* Override for single object instances. */
- int override_selectid;
-#endif
- int instance_count;
- Gwn_VertFormat vbo_format;
};
struct DRWPass {
@@ -276,6 +270,7 @@ struct DRWShadingGroup {
ID *instance_data; /* Object->data to instance */
Gwn_Batch *instance_geom; /* Geometry to instance */
+ Gwn_Batch *instancing_geom;/* Instances attributes */
Gwn_Batch *batch_geom; /* Result of call batching */
#ifdef USE_GPU_SELECT
@@ -291,6 +286,7 @@ enum {
DRW_SHG_LINE_BATCH,
DRW_SHG_TRIANGLE_BATCH,
DRW_SHG_INSTANCE,
+ DRW_SHG_INSTANCE_EXTERNAL,
};
/* Used by DRWCall.type */
@@ -312,6 +308,7 @@ static struct DRWGlobalState {
DRWCallGenerate *last_callgenerate;
DRWShadingGroup *last_shgroup;
DRWInstanceDataList *idatalist;
+ DRWInstanceData *common_instance_data[MAX_INSTANCE_DATA_SIZE];
/* Rendering state */
GPUShader *shader;
@@ -349,6 +346,8 @@ static struct DRWGlobalState {
ListBase enabled_engines; /* RenderEngineType */
+ bool buffer_finish_called; /* Avoid bad usage of DRW_render_instance_buffer_finish */
+
/* Profiling */
double cache_time;
} DST = {NULL};
@@ -635,7 +634,7 @@ void DRW_shader_free(GPUShader *shader)
/** \name Interface (DRW_interface)
* \{ */
-static void drw_interface_create(DRWInterface *interface, GPUShader *shader)
+static void drw_interface_init(DRWInterface *interface, GPUShader *shader)
{
interface->model = GPU_shader_get_builtin_uniform(shader, GWN_UNIFORM_MODEL);
interface->modelinverse = GPU_shader_get_builtin_uniform(shader, GWN_UNIFORM_MODEL_INV);
@@ -655,20 +654,56 @@ static void drw_interface_create(DRWInterface *interface, GPUShader *shader)
interface->clipplanes = GPU_shader_get_builtin_uniform(shader, GWN_UNIFORM_CLIPPLANES);
interface->eye = GPU_shader_get_builtin_uniform(shader, GWN_UNIFORM_EYE);
interface->instance_count = 0;
+#ifndef NDEBUG
interface->attribs_count = 0;
- interface->attribs_stride = 0;
- interface->instance_vbo = 0;
- interface->instance_batch = NULL;
- interface->inst_data = NULL;
+#endif
interface->uniforms = NULL;
#ifdef USE_GPU_SELECT
interface->inst_selectid = NULL;
interface->override_selectid = -1;
#endif
-
- memset(&interface->vbo_format, 0, sizeof(Gwn_VertFormat));
}
+static void drw_interface_instance_init(
+ DRWShadingGroup *shgroup, GPUShader *shader, Gwn_VertFormat *format)
+{
+ DRWInterface *interface = &shgroup->interface;
+ drw_interface_init(interface, shader);
+
+#ifndef NDEBUG
+ interface->attribs_count = (format != NULL) ? format->attrib_ct : 0;
+#endif
+
+ Gwn_PrimType type;
+ Gwn_Batch **r_batch = NULL;
+ switch (shgroup->type) {
+ case DRW_SHG_INSTANCE:
+ r_batch = &shgroup->instancing_geom;
+ type = GWN_PRIM_POINTS;
+ break;
+ case DRW_SHG_POINT_BATCH:
+ r_batch = &shgroup->batch_geom;
+ type = GWN_PRIM_POINTS;
+ break;
+ case DRW_SHG_LINE_BATCH:
+ r_batch = &shgroup->batch_geom;
+ type = GWN_PRIM_LINES;
+ break;
+ case DRW_SHG_TRIANGLE_BATCH:
+ r_batch = &shgroup->batch_geom;
+ type = GWN_PRIM_TRIS;
+ break;
+ default:
+ BLI_assert(0);
+ }
+
+ if (format != NULL) {
+ DRW_instance_buffer_request(DST.idatalist, format, shgroup, r_batch, &interface->instance_vbo, type);
+ }
+ else {
+ *r_batch = NULL;
+ }
+}
static void drw_interface_uniform(DRWShadingGroup *shgroup, const char *name,
DRWUniformType type, const void *value, int length, int arraysize)
@@ -691,7 +726,8 @@ static void drw_interface_uniform(DRWShadingGroup *shgroup, const char *name,
DRWUniform *uni = BLI_mempool_alloc(DST.vmempool->uniforms);
- BLI_assert(arraysize > 0);
+ BLI_assert(arraysize > 0 && arraysize <= 16);
+ BLI_assert(arraysize * length <= MAX_UNIFORM_DATA_SIZE);
uni->location = location;
uni->type = type;
@@ -704,36 +740,17 @@ static void drw_interface_uniform(DRWShadingGroup *shgroup, const char *name,
shgroup->interface.uniforms = uni;
}
-static void drw_interface_attrib(DRWShadingGroup *shgroup, const char *name, DRWAttribType UNUSED(type), int size, bool dummy)
+Gwn_VertFormat *DRW_shgroup_instance_format_array(const DRWInstanceAttribFormat attribs[], int arraysize)
{
- unsigned int attrib_id = shgroup->interface.attribs_count;
- GLuint program = GPU_shader_get_program(shgroup->shader);
+ Gwn_VertFormat *format = MEM_callocN(sizeof(Gwn_VertFormat), "Gwn_VertFormat");
- shgroup->interface.attribs_loc[attrib_id] = glGetAttribLocation(program, name);
- shgroup->interface.attribs_size[attrib_id] = size;
- shgroup->interface.attribs_stride += size;
- shgroup->interface.attribs_count += 1;
-
- if (shgroup->type != DRW_SHG_INSTANCE) {
- BLI_assert(size <= 4); /* Matrices are not supported by Gawain. */
- GWN_vertformat_attr_add(&shgroup->interface.vbo_format, name, GWN_COMP_F32, size, GWN_FETCH_FLOAT);
+ for (int i = 0; i < arraysize; ++i) {
+ GWN_vertformat_attr_add(format, attribs[i].name,
+ (attribs[i].type == DRW_ATTRIB_INT) ? GWN_COMP_I32 : GWN_COMP_F32,
+ attribs[i].components,
+ (attribs[i].type == DRW_ATTRIB_INT) ? GWN_FETCH_INT : GWN_FETCH_FLOAT);
}
-
- BLI_assert(shgroup->interface.attribs_count < MAX_ATTRIB_COUNT);
-
-/* Adding attribute even if not found for now (to keep memory alignment).
- * Should ideally take vertex format automatically from batch eventually */
-#if 0
- if (attrib->location == -1 && !dummy) {
- if (G.debug & G_DEBUG)
- fprintf(stderr, "Attribute '%s' not found!\n", name);
- BLI_assert(0);
- MEM_freeN(attrib);
- return;
- }
-#else
- UNUSED_VARS(dummy);
-#endif
+ return format;
}
/** \} */
@@ -744,7 +761,7 @@ static void drw_interface_attrib(DRWShadingGroup *shgroup, const char *name, DRW
/** \name Shading Group (DRW_shgroup)
* \{ */
-DRWShadingGroup *DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass)
+static DRWShadingGroup *drw_shgroup_create_ex(struct GPUShader *shader, DRWPass *pass)
{
DRWShadingGroup *shgroup = BLI_mempool_alloc(DST.vmempool->shgroups);
@@ -757,15 +774,13 @@ DRWShadingGroup *DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass)
}
pass->shgroups_last = shgroup;
shgroup->next = NULL;
-
- drw_interface_create(&shgroup->interface, shader);
-
shgroup->type = DRW_SHG_NORMAL;
shgroup->shader = shader;
shgroup->state_extra = 0;
shgroup->state_extra_disable = ~0x0;
shgroup->stencil_mask = 0;
shgroup->batch_geom = NULL;
+ shgroup->instancing_geom = NULL;
shgroup->instance_geom = NULL;
shgroup->instance_data = NULL;
@@ -779,22 +794,22 @@ DRWShadingGroup *DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass)
return shgroup;
}
-DRWShadingGroup *DRW_shgroup_material_create(struct GPUMaterial *material, DRWPass *pass)
+static DRWShadingGroup *drw_shgroup_material_create_ex(GPUPass *gpupass, DRWPass *pass)
{
- double time = 0.0; /* TODO make time variable */
-
- /* TODO : Ideally we should not convert. But since the whole codegen
- * is relying on GPUPass we keep it as is for now. */
- GPUPass *gpupass = GPU_material_get_pass(material);
-
if (!gpupass) {
/* Shader compilation error */
return NULL;
}
- struct GPUShader *shader = GPU_pass_shader(gpupass);
+ DRWShadingGroup *grp = drw_shgroup_create_ex(GPU_pass_shader(gpupass), pass);
+ return grp;
+}
- DRWShadingGroup *grp = DRW_shgroup_create(shader, pass);
+static DRWShadingGroup *drw_shgroup_material_inputs(
+ DRWShadingGroup *grp, struct GPUMaterial *material, GPUPass *gpupass)
+{
+ /* TODO : Ideally we should not convert. But since the whole codegen
+ * is relying on GPUPass we keep it as is for now. */
/* Converting dynamic GPUInput to DRWUniform */
ListBase *inputs = &gpupass->inputs;
@@ -802,6 +817,7 @@ DRWShadingGroup *DRW_shgroup_material_create(struct GPUMaterial *material, DRWPa
for (GPUInput *input = inputs->first; input; input = input->next) {
/* Textures */
if (input->ima) {
+ double time = 0.0; /* TODO make time variable */
GPUTexture *tex = GPU_texture_from_blender(
input->ima, input->iuser, input->textarget, input->image_isdata, time, 1);
@@ -842,15 +858,32 @@ DRWShadingGroup *DRW_shgroup_material_create(struct GPUMaterial *material, DRWPa
return grp;
}
+DRWShadingGroup *DRW_shgroup_material_create(
+ struct GPUMaterial *material, DRWPass *pass)
+{
+ GPUPass *gpupass = GPU_material_get_pass(material);
+ DRWShadingGroup *shgroup = drw_shgroup_material_create_ex(gpupass, pass);
+
+ if (shgroup) {
+ drw_interface_init(&shgroup->interface, GPU_pass_shader(gpupass));
+ drw_shgroup_material_inputs(shgroup, material, gpupass);
+ }
+
+ return shgroup;
+}
+
DRWShadingGroup *DRW_shgroup_material_instance_create(
- struct GPUMaterial *material, DRWPass *pass, Gwn_Batch *geom, Object *ob)
+ struct GPUMaterial *material, DRWPass *pass, Gwn_Batch *geom, Object *ob, Gwn_VertFormat *format)
{
- DRWShadingGroup *shgroup = DRW_shgroup_material_create(material, pass);
+ 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;
shgroup->instance_data = ob->data;
+ drw_interface_instance_init(shgroup, GPU_pass_shader(gpupass), format);
+ drw_shgroup_material_inputs(shgroup, material, gpupass);
}
return shgroup;
@@ -859,43 +892,64 @@ DRWShadingGroup *DRW_shgroup_material_instance_create(
DRWShadingGroup *DRW_shgroup_material_empty_tri_batch_create(
struct GPUMaterial *material, DRWPass *pass, int size)
{
- DRWShadingGroup *shgroup = DRW_shgroup_material_create(material, pass);
+#ifdef USE_GPU_SELECT
+ BLI_assert((G.f & G_PICKSEL) == 0);
+#endif
+ GPUPass *gpupass = GPU_material_get_pass(material);
+ DRWShadingGroup *shgroup = drw_shgroup_material_create_ex(gpupass, pass);
if (shgroup) {
shgroup->type = DRW_SHG_TRIANGLE_BATCH;
shgroup->interface.instance_count = size * 3;
- drw_interface_attrib(shgroup, "dummy", DRW_ATTRIB_FLOAT, 1, true);
+ /* Calling drw_interface_init will cause it to GWN_batch_draw_procedural. */
+ drw_interface_init(&shgroup->interface, GPU_pass_shader(gpupass));
+ drw_shgroup_material_inputs(shgroup, material, gpupass);
}
return shgroup;
}
-DRWShadingGroup *DRW_shgroup_instance_create(struct GPUShader *shader, DRWPass *pass, Gwn_Batch *geom)
+DRWShadingGroup *DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass)
{
- DRWShadingGroup *shgroup = DRW_shgroup_create(shader, pass);
+ DRWShadingGroup *shgroup = drw_shgroup_create_ex(shader, pass);
+ drw_interface_init(&shgroup->interface, shader);
+ return shgroup;
+}
+DRWShadingGroup *DRW_shgroup_instance_create(
+ struct GPUShader *shader, DRWPass *pass, Gwn_Batch *geom, Gwn_VertFormat *format)
+{
+ DRWShadingGroup *shgroup = drw_shgroup_create_ex(shader, pass);
shgroup->type = DRW_SHG_INSTANCE;
shgroup->instance_geom = geom;
+ drw_interface_instance_init(shgroup, shader, format);
+
return shgroup;
}
+static Gwn_VertFormat *g_pos_format = NULL;
+
DRWShadingGroup *DRW_shgroup_point_batch_create(struct GPUShader *shader, DRWPass *pass)
{
- DRWShadingGroup *shgroup = DRW_shgroup_create(shader, pass);
+ DRW_shgroup_instance_format(g_pos_format, {{"pos", DRW_ATTRIB_FLOAT, 3}});
+ DRWShadingGroup *shgroup = drw_shgroup_create_ex(shader, pass);
shgroup->type = DRW_SHG_POINT_BATCH;
- DRW_shgroup_attrib_float(shgroup, "pos", 3);
+
+ drw_interface_instance_init(shgroup, shader, g_pos_format);
return shgroup;
}
DRWShadingGroup *DRW_shgroup_line_batch_create(struct GPUShader *shader, DRWPass *pass)
{
- DRWShadingGroup *shgroup = DRW_shgroup_create(shader, pass);
+ DRW_shgroup_instance_format(g_pos_format, {{"pos", DRW_ATTRIB_FLOAT, 3}});
+ DRWShadingGroup *shgroup = drw_shgroup_create_ex(shader, pass);
shgroup->type = DRW_SHG_LINE_BATCH;
- DRW_shgroup_attrib_float(shgroup, "pos", 3);
+
+ drw_interface_instance_init(shgroup, shader, g_pos_format);
return shgroup;
}
@@ -905,24 +959,23 @@ DRWShadingGroup *DRW_shgroup_line_batch_create(struct GPUShader *shader, DRWPass
* and dont need any VBO attrib */
DRWShadingGroup *DRW_shgroup_empty_tri_batch_create(struct GPUShader *shader, DRWPass *pass, int size)
{
- DRWShadingGroup *shgroup = DRW_shgroup_create(shader, pass);
+#ifdef USE_GPU_SELECT
+ BLI_assert((G.f & G_PICKSEL) == 0);
+#endif
+ DRWShadingGroup *shgroup = drw_shgroup_create_ex(shader, pass);
+
+ /* Calling drw_interface_init will cause it to GWN_batch_draw_procedural. */
+ drw_interface_init(&shgroup->interface, shader);
shgroup->type = DRW_SHG_TRIANGLE_BATCH;
shgroup->interface.instance_count = size * 3;
- drw_interface_attrib(shgroup, "dummy", DRW_ATTRIB_FLOAT, 1, true);
return shgroup;
}
-void DRW_shgroup_free(struct DRWShadingGroup *shgroup)
+void DRW_shgroup_free(struct DRWShadingGroup *UNUSED(shgroup))
{
- if (shgroup->interface.instance_vbo &&
- (shgroup->interface.instance_batch == 0))
- {
- glDeleteBuffers(1, &shgroup->interface.instance_vbo);
- }
-
- GWN_BATCH_DISCARD_SAFE(shgroup->batch_geom);
+ return;
}
#define CALL_PREPEND(shgroup, call) { \
@@ -937,12 +990,14 @@ void DRW_shgroup_free(struct DRWShadingGroup *shgroup)
call->head.prev = NULL; \
} ((void)0)
+/* Specify an external batch instead of adding each attrib one by one. */
void DRW_shgroup_instance_batch(DRWShadingGroup *shgroup, struct Gwn_Batch *instances)
{
BLI_assert(shgroup->type == DRW_SHG_INSTANCE);
- BLI_assert(shgroup->interface.instance_batch == NULL);
+ BLI_assert(shgroup->instancing_geom == NULL);
- shgroup->interface.instance_batch = instances;
+ shgroup->type = DRW_SHG_INSTANCE_EXTERNAL;
+ shgroup->instancing_geom = instances;
#ifdef USE_GPU_SELECT
DRWCall *call = BLI_mempool_alloc(DST.vmempool->calls);
@@ -1056,24 +1111,18 @@ void DRW_shgroup_call_dynamic_add_array(DRWShadingGroup *shgroup, const void *at
BLI_assert(attr_len == interface->attribs_count);
UNUSED_VARS_NDEBUG(attr_len);
- if (interface->attribs_stride > 0) {
- if (interface->inst_data == NULL) {
- interface->inst_data = DRW_instance_data_request(DST.idatalist, interface->attribs_stride, 16);
- }
-
- float *data = DRW_instance_data_next(interface->inst_data);
-
- for (int i = 0; i < interface->attribs_count; ++i) {
- memcpy(data, attr[i], sizeof(float) * interface->attribs_size[i]);
- data = data + interface->attribs_size[i];
+ for (int i = 0; i < attr_len; ++i) {
+ if (interface->instance_count == interface->instance_vbo->vertex_ct) {
+ GWN_vertbuf_data_resize(interface->instance_vbo, interface->instance_count + 32);
}
+ GWN_vertbuf_attr_set(interface->instance_vbo, i, interface->instance_count, attr[i]);
}
interface->instance_count += 1;
}
/* Used for instancing with no attributes */
-void DRW_shgroup_set_instance_count(DRWShadingGroup *shgroup, int count)
+void DRW_shgroup_set_instance_count(DRWShadingGroup *shgroup, unsigned int count)
{
DRWInterface *interface = &shgroup->interface;
@@ -1089,6 +1138,13 @@ void DRW_shgroup_set_instance_count(DRWShadingGroup *shgroup, int count)
interface->instance_count = count;
}
+unsigned int DRW_shgroup_get_instance_count(const DRWShadingGroup *shgroup)
+{
+ BLI_assert(shgroup->type != DRW_SHG_NORMAL && shgroup->type != DRW_SHG_INSTANCE_EXTERNAL);
+
+ return shgroup->interface.instance_count;
+}
+
/**
* State is added to #Pass.state while drawing.
* Use to temporarily enable draw options.
@@ -1105,14 +1161,10 @@ void DRW_shgroup_state_disable(DRWShadingGroup *shgroup, DRWState state)
void DRW_shgroup_stencil_mask(DRWShadingGroup *shgroup, unsigned int mask)
{
+ BLI_assert(mask <= 255);
shgroup->stencil_mask = mask;
}
-void DRW_shgroup_attrib_float(DRWShadingGroup *shgroup, const char *name, int size)
-{
- drw_interface_attrib(shgroup, name, DRW_ATTRIB_FLOAT, size, false);
-}
-
void DRW_shgroup_uniform_texture(DRWShadingGroup *shgroup, const char *name, const GPUTexture *tex)
{
drw_interface_uniform(shgroup, name, DRW_UNIFORM_TEXTURE, tex, 0, 1);
@@ -1188,88 +1240,6 @@ void DRW_shgroup_uniform_mat4(DRWShadingGroup *shgroup, const char *name, const
drw_interface_uniform(shgroup, name, DRW_UNIFORM_MAT4, value, 16, 1);
}
-/* Creates a VBO containing OGL primitives for all DRWCallDynamic */
-static void shgroup_dynamic_batch(DRWShadingGroup *shgroup)
-{
- DRWInterface *interface = &shgroup->interface;
- int nbr = interface->instance_count;
-
- Gwn_PrimType type = (shgroup->type == DRW_SHG_POINT_BATCH) ? GWN_PRIM_POINTS :
- (shgroup->type == DRW_SHG_TRIANGLE_BATCH) ? GWN_PRIM_TRIS : GWN_PRIM_LINES;
-
- if (nbr == 0)
- return;
-
- /* Upload Data */
- Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&interface->vbo_format);
- if (interface->inst_data) {
- GWN_vertbuf_data_set(vbo, nbr, DRW_instance_data_get(interface->inst_data), false);
- } else {
- /* Use unitialized memory. This is for dummy vertex buffers. */
- /* XXX TODO do not alloc at all. */
- GWN_vertbuf_data_alloc(vbo, nbr);
- }
-
- /* TODO make the batch dynamic instead of freeing it every times */
- if (shgroup->batch_geom)
- GWN_batch_discard(shgroup->batch_geom);
-
- shgroup->batch_geom = GWN_batch_create_ex(type, vbo, NULL, GWN_BATCH_OWNS_VBO);
-}
-
-static void shgroup_dynamic_instance(DRWShadingGroup *shgroup)
-{
- DRWInterface *interface = &shgroup->interface;
- int buffer_size = 0;
- void *data = NULL;
-
- if (interface->instance_batch != NULL) {
- return;
- }
-
- /* TODO We still need this because gawain does not support Matrix attribs. */
- if (interface->instance_count == 0) {
- if (interface->instance_vbo) {
- glDeleteBuffers(1, &interface->instance_vbo);
- interface->instance_vbo = 0;
- }
- return;
- }
-
- /* Gather Data */
- buffer_size = sizeof(float) * interface->attribs_stride * interface->instance_count;
-
- /* TODO poke mike to add this to gawain */
- if (interface->instance_vbo) {
- glDeleteBuffers(1, &interface->instance_vbo);
- interface->instance_vbo = 0;
- }
-
- if (interface->inst_data) {
- data = DRW_instance_data_get(interface->inst_data);
- }
-
- glGenBuffers(1, &interface->instance_vbo);
- glBindBuffer(GL_ARRAY_BUFFER, interface->instance_vbo);
- glBufferData(GL_ARRAY_BUFFER, buffer_size, data, GL_STATIC_DRAW);
-}
-
-static void shgroup_dynamic_batch_from_calls(DRWShadingGroup *shgroup)
-{
- if ((shgroup->interface.instance_vbo || shgroup->batch_geom) &&
- (G.debug_value == 667))
- {
- return;
- }
-
- if (shgroup->type == DRW_SHG_INSTANCE) {
- shgroup_dynamic_instance(shgroup);
- }
- else {
- shgroup_dynamic_batch(shgroup);
- }
-}
-
/** \} */
@@ -1685,6 +1655,11 @@ static void draw_geometry_prepare(
float mvp[4][4], mv[4][4], mi[4][4], mvi[4][4], pi[4][4], n[3][3], wn[3][3];
float orcofacs[2][3] = {{0.0f, 0.0f, 0.0f}, {1.0f, 1.0f, 1.0f}};
float eye[3] = { 0.0f, 0.0f, 1.0f }; /* looking into the screen */
+ float viewcamtexcofac[4] = { 1.0f, 1.0f, 0.0f, 0.0f };
+
+ if (rv3d != NULL) {
+ copy_v4_v4(viewcamtexcofac, rv3d->viewcamtexcofac);
+ }
bool do_pi = (interface->projectioninverse != -1);
bool do_mvp = (interface->modelviewprojection != -1);
@@ -1777,7 +1752,7 @@ static void draw_geometry_prepare(
GPU_shader_uniform_vector(shgroup->shader, interface->modelviewinverse, 16, 1, (float *)mvi);
GPU_shader_uniform_vector(shgroup->shader, interface->normal, 9, 1, (float *)n);
GPU_shader_uniform_vector(shgroup->shader, interface->worldnormal, 9, 1, (float *)wn);
- GPU_shader_uniform_vector(shgroup->shader, interface->camtexfac, 4, 1, (float *)rv3d->viewcamtexcofac);
+ GPU_shader_uniform_vector(shgroup->shader, interface->camtexfac, 4, 1, (float *)viewcamtexcofac);
GPU_shader_uniform_vector(shgroup->shader, interface->orcotexfac, 3, 2, (float *)orcofacs);
GPU_shader_uniform_vector(shgroup->shader, interface->eye, 3, 1, (float *)eye);
GPU_shader_uniform_vector(shgroup->shader, interface->clipplanes, 4, DST.num_clip_planes, (float *)DST.clip_planes_eq);
@@ -1786,17 +1761,19 @@ static void draw_geometry_prepare(
static void draw_geometry_execute_ex(
DRWShadingGroup *shgroup, Gwn_Batch *geom, unsigned int start, unsigned int count)
{
- DRWInterface *interface = &shgroup->interface;
+ /* Special case: empty drawcall, placement is done via shader, don't bind anything. */
+ if (geom == NULL) {
+ BLI_assert(shgroup->type == DRW_SHG_TRIANGLE_BATCH); /* Add other type if needed. */
+ /* Shader is already bound. */
+ Gwn_Batch *batch = DRW_cache_fullscreen_quad_get();
+ GWN_batch_draw_procedural(batch, GWN_PRIM_TRIS, count);
+ return;
+ }
+
/* step 2 : bind vertex array & draw */
GWN_batch_program_set(geom, GPU_shader_get_program(shgroup->shader), GPU_shader_get_interface(shgroup->shader));
- if (interface->instance_batch) {
- /* Used for Particles. Cannot do partial drawing. */
- GWN_batch_draw_stupid_instanced_with_batch(geom, interface->instance_batch);
- }
- else if (interface->instance_vbo) {
- GWN_batch_draw_stupid_instanced(
- geom, interface->instance_vbo, start, count, interface->attribs_count,
- interface->attribs_stride, interface->attribs_size, interface->attribs_loc);
+ if (ELEM(shgroup->type, DRW_SHG_INSTANCE, DRW_SHG_INSTANCE_EXTERNAL)) {
+ GWN_batch_draw_stupid_instanced(geom, shgroup->instancing_geom, start, count);
}
else {
GWN_batch_draw_stupid(geom, start, count);
@@ -1863,6 +1840,7 @@ static void bind_texture(GPUTexture *tex)
GPU_texture_bind(tex, RST.bind_tex_inc);
RST.bound_texs[RST.bind_tex_inc] = tex;
RST.bound_tex_slots[RST.bind_tex_inc] = true;
+ // printf("Binds Texture %d %p\n", RST.bind_tex_inc, tex);
return;
}
}
@@ -1914,12 +1892,6 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
DST.shader = shgroup->shader;
}
- const bool is_normal = ELEM(shgroup->type, DRW_SHG_NORMAL);
-
- if (!is_normal) {
- shgroup_dynamic_batch_from_calls(shgroup);
- }
-
release_texture_slots();
release_ubo_slots();
@@ -2017,30 +1989,32 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
#endif
/* Rendering Calls */
- if (!is_normal) {
+ if (!ELEM(shgroup->type, DRW_SHG_NORMAL)) {
/* Replacing multiple calls with only one */
float obmat[4][4];
unit_m4(obmat);
- if (shgroup->type == DRW_SHG_INSTANCE &&
- (interface->instance_count > 0 || interface->instance_batch != NULL))
- {
- if (interface->instance_batch != NULL) {
- GPU_SELECT_LOAD_IF_PICKSEL((DRWCall *)shgroup->calls_first);
- draw_geometry(shgroup, shgroup->instance_geom, obmat, shgroup->instance_data, 0, 0);
+ if (ELEM(shgroup->type, DRW_SHG_INSTANCE, DRW_SHG_INSTANCE_EXTERNAL)) {
+ if (shgroup->type == DRW_SHG_INSTANCE_EXTERNAL) {
+ if (shgroup->instancing_geom != NULL) {
+ GPU_SELECT_LOAD_IF_PICKSEL((DRWCall *)shgroup->calls_first);
+ draw_geometry(shgroup, shgroup->instance_geom, obmat, shgroup->instance_data, 0, 0);
+ }
}
else {
- unsigned int count, start;
- GPU_SELECT_LOAD_IF_PICKSEL_LIST(shgroup, start, count)
- {
- draw_geometry(shgroup, shgroup->instance_geom, obmat, shgroup->instance_data, start, count);
+ if (shgroup->interface.instance_count > 0) {
+ unsigned int count, start;
+ GPU_SELECT_LOAD_IF_PICKSEL_LIST(shgroup, start, count)
+ {
+ draw_geometry(shgroup, shgroup->instance_geom, obmat, shgroup->instance_data, start, count);
+ }
+ GPU_SELECT_LOAD_IF_PICKSEL_LIST_END(start, count)
}
- GPU_SELECT_LOAD_IF_PICKSEL_LIST_END(start, count)
}
}
else {
/* Some dynamic batch can have no geom (no call to aggregate) */
- if (shgroup->batch_geom) {
+ if (shgroup->interface.instance_count > 0) {
unsigned int count, start;
GPU_SELECT_LOAD_IF_PICKSEL_LIST(shgroup, start, count)
{
@@ -2087,6 +2061,8 @@ static void drw_draw_pass_ex(DRWPass *pass, DRWShadingGroup *start_group, DRWSha
/* Start fresh */
DST.shader = NULL;
+ BLI_assert(DST.buffer_finish_called && "DRW_render_instance_buffer_finish had not been called before drawing");
+
drw_state_set(pass->state);
DRW_stats_query_start(pass->name);
@@ -2152,7 +2128,7 @@ void DRW_state_reset_ex(DRWState state)
void DRW_state_reset(void)
{
/* Reset blending function */
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
DRW_state_reset_ex(DRW_STATE_DEFAULT);
}
@@ -2199,13 +2175,10 @@ struct DRWTextStore *DRW_text_cache_ensure(void)
bool DRW_object_is_renderable(Object *ob)
{
- Scene *scene = DST.draw_ctx.scene;
- Object *obedit = scene->obedit;
-
BLI_assert(BKE_object_is_visible(ob, OB_VISIBILITY_CHECK_UNKNOWN_RENDER_MODE));
if (ob->type == OB_MESH) {
- if (ob == obedit) {
+ if (ob == DST.draw_ctx.object_edit) {
IDProperty *props = BKE_layer_collection_engine_evaluated_get(ob, COLLECTION_MODE_EDIT, "");
bool do_show_occlude_wire = BKE_collection_engine_property_value_get_bool(props, "show_occlude_wire");
if (do_show_occlude_wire) {
@@ -2250,8 +2223,8 @@ bool DRW_object_is_flat_normal(const Object *ob)
int DRW_object_is_mode_shade(const Object *ob)
{
BLI_assert(ob == DST.draw_ctx.obact);
- if ((ob->mode & OB_MODE_EDIT) == 0) {
- if (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) {
+ if ((DST.draw_ctx.object_mode & OB_MODE_EDIT) == 0) {
+ if (DST.draw_ctx.object_mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) {
if ((DST.draw_ctx.v3d->flag2 & V3D_SHOW_MODE_SHADE_OVERRIDE) == 0) {
return true;
}
@@ -2579,17 +2552,41 @@ static void drw_viewport_cache_resize(void)
GPU_viewport_cache_release(DST.viewport);
if (DST.vmempool != NULL) {
- BLI_mempool_clear_ex(DST.vmempool->calls, BLI_mempool_count(DST.vmempool->calls));
- BLI_mempool_clear_ex(DST.vmempool->calls_generate, BLI_mempool_count(DST.vmempool->calls_generate));
- BLI_mempool_clear_ex(DST.vmempool->shgroups, BLI_mempool_count(DST.vmempool->shgroups));
- BLI_mempool_clear_ex(DST.vmempool->uniforms, BLI_mempool_count(DST.vmempool->uniforms));
- BLI_mempool_clear_ex(DST.vmempool->passes, BLI_mempool_count(DST.vmempool->passes));
+ BLI_mempool_clear_ex(DST.vmempool->calls, BLI_mempool_len(DST.vmempool->calls));
+ BLI_mempool_clear_ex(DST.vmempool->calls_generate, BLI_mempool_len(DST.vmempool->calls_generate));
+ 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));
}
DRW_instance_data_list_free_unused(DST.idatalist);
DRW_instance_data_list_resize(DST.idatalist);
}
+
+/* Not a viewport variable, we could split this out. */
+static void drw_context_state_init(void)
+{
+ /* Edit object. */
+ if (DST.draw_ctx.object_mode & OB_MODE_EDIT) {
+ DST.draw_ctx.object_edit = DST.draw_ctx.obact;
+ }
+ else {
+ DST.draw_ctx.object_edit = NULL;
+ }
+
+ /* Pose object. */
+ if (DST.draw_ctx.object_mode & OB_MODE_POSE) {
+ DST.draw_ctx.object_pose = DST.draw_ctx.obact;
+ }
+ else if (DST.draw_ctx.object_mode & OB_MODE_WEIGHT_PAINT) {
+ DST.draw_ctx.object_pose = BKE_object_pose_armature_get(DST.draw_ctx.obact);
+ }
+ else {
+ DST.draw_ctx.object_pose = NULL;
+ }
+}
+
/* It also stores viewport variable to an immutable place: DST
* This is because a cache uniform only store reference
* to its value. And we don't want to invalidate the cache
@@ -2597,7 +2594,6 @@ static void drw_viewport_cache_resize(void)
static void drw_viewport_var_init(void)
{
RegionView3D *rv3d = DST.draw_ctx.rv3d;
-
/* Refresh DST.size */
if (DST.viewport) {
int size[2];
@@ -2653,8 +2649,8 @@ static void drw_viewport_var_init(void)
DST.backface = GL_CW;
glFrontFace(DST.frontface);
- if (DST.draw_ctx.scene->obedit) {
- ED_view3d_init_mats_rv3d(DST.draw_ctx.scene->obedit, rv3d);
+ if (DST.draw_ctx.object_edit) {
+ ED_view3d_init_mats_rv3d(DST.draw_ctx.object_edit, rv3d);
}
/* Alloc array of texture reference. */
@@ -2666,6 +2662,7 @@ static void drw_viewport_var_init(void)
}
memset(viewport_matrix_override.override, 0x0, sizeof(viewport_matrix_override.override));
+ memset(DST.common_instance_data, 0x0, sizeof(DST.common_instance_data));
}
void DRW_viewport_matrix_get(float mat[4][4], DRWViewportMatrixType type)
@@ -2812,7 +2809,22 @@ ObjectEngineData *DRW_object_engine_data_ensure(
return oed;
}
/* Allocate new data. */
- oed = MEM_callocN(size, "ObjectEngineData");
+ if ((ob->base_flag & BASE_FROMDUPLI) != 0) {
+ /* NOTE: data is not persistent in this case. It is reset each redraw. */
+ BLI_assert(free_cb == NULL); /* No callback allowed. */
+ /* Round to sizeof(float) for DRW_instance_data_request(). */
+ const size_t t = sizeof(float) - 1;
+ size = (size + t) & ~t;
+ size_t fsize = size / sizeof(float);
+ if (DST.common_instance_data[fsize] == NULL) {
+ DST.common_instance_data[fsize] = DRW_instance_data_request(DST.idatalist, fsize, 16);
+ }
+ oed = (ObjectEngineData *)DRW_instance_data_next(DST.common_instance_data[fsize]);
+ memset(oed, 0, size);
+ }
+ else {
+ oed = MEM_callocN(size, "ObjectEngineData");
+ }
oed->engine_type = engine_type;
oed->free = free_cb;
/* Perform user-side initialization, if needed. */
@@ -3145,10 +3157,10 @@ static void drw_engines_enable_external(void)
use_drw_engine(DRW_engine_viewport_external_type.draw_engine);
}
-static void drw_engines_enable(const Scene *scene, ViewLayer *view_layer, RenderEngineType *engine_type)
+static void drw_engines_enable(ViewLayer *view_layer, RenderEngineType *engine_type)
{
Object *obact = OBACT(view_layer);
- const int mode = CTX_data_mode_enum_ex(scene->obedit, obact);
+ const int mode = CTX_data_mode_enum_ex(DST.draw_ctx.object_edit, obact, DST.draw_ctx.object_mode);
drw_engines_enable_from_engine(engine_type);
@@ -3322,11 +3334,11 @@ void DRW_notify_view_update(const DRWUpdateContext *update_ctx)
DST.viewport = rv3d->viewport;
DST.draw_ctx = (DRWContextState){
- ar, rv3d, v3d, scene, view_layer, OBACT(view_layer), engine_type, depsgraph,
+ ar, rv3d, v3d, scene, view_layer, OBACT(view_layer), engine_type, depsgraph, OB_MODE_OBJECT,
NULL,
};
- drw_engines_enable(scene, view_layer, engine_type);
+ drw_engines_enable(view_layer, engine_type);
for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
DrawEngineType *draw_engine = link->data;
@@ -3369,9 +3381,9 @@ void DRW_notify_id_update(const DRWUpdateContext *update_ctx, ID *id)
memset(&DST, 0x0, sizeof(DST));
DST.viewport = rv3d->viewport;
DST.draw_ctx = (DRWContextState){
- ar, rv3d, v3d, scene, view_layer, OBACT(view_layer), engine_type, depsgraph, NULL,
+ ar, rv3d, v3d, scene, view_layer, OBACT(view_layer), engine_type, depsgraph, OB_MODE_OBJECT, NULL,
};
- drw_engines_enable(scene, view_layer, engine_type);
+ drw_engines_enable(view_layer, engine_type);
for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
DrawEngineType *draw_engine = link->data;
ViewportEngineData *data = DRW_viewport_engine_data_ensure(draw_engine);
@@ -3395,14 +3407,15 @@ void DRW_notify_id_update(const DRWUpdateContext *update_ctx, ID *id)
* for each relevant engine / mode engine. */
void DRW_draw_view(const bContext *C)
{
- struct Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
RenderEngineType *engine_type = CTX_data_engine_type(C);
ARegion *ar = CTX_wm_region(C);
View3D *v3d = CTX_wm_view3d(C);
/* Reset before using it. */
memset(&DST, 0x0, sizeof(DST));
- DRW_draw_render_loop_ex(depsgraph, engine_type, ar, v3d, C);
+ DRW_draw_render_loop_ex(eval_ctx.depsgraph, engine_type, ar, v3d, eval_ctx.object_mode, C);
}
/**
@@ -3412,7 +3425,7 @@ void DRW_draw_view(const bContext *C)
void DRW_draw_render_loop_ex(
struct Depsgraph *depsgraph,
RenderEngineType *engine_type,
- ARegion *ar, View3D *v3d,
+ ARegion *ar, View3D *v3d, const eObjectMode object_mode,
const bContext *evil_C)
{
Scene *scene = DEG_get_evaluated_scene(depsgraph);
@@ -3428,16 +3441,16 @@ void DRW_draw_render_loop_ex(
GPU_viewport_engines_data_validate(DST.viewport, DRW_engines_get_hash());
DST.draw_ctx = (DRWContextState){
- ar, rv3d, v3d, scene, view_layer, OBACT(view_layer), engine_type, depsgraph,
+ ar, rv3d, v3d, scene, view_layer, OBACT(view_layer), engine_type, depsgraph, object_mode,
/* reuse if caller sets */
DST.draw_ctx.evil_C,
};
-
+ drw_context_state_init();
drw_viewport_var_init();
/* Get list of enabled engines */
- drw_engines_enable(scene, view_layer, engine_type);
+ drw_engines_enable(view_layer, engine_type);
/* Update ubos */
DRW_globals_update();
@@ -3457,6 +3470,8 @@ void DRW_draw_render_loop_ex(
DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END
drw_engines_cache_finish();
+
+ DRW_render_instance_buffer_finish();
PROFILE_END_ACCUM(DST.cache_time, stime);
}
@@ -3537,7 +3552,7 @@ void DRW_draw_render_loop_ex(
void DRW_draw_render_loop(
struct Depsgraph *depsgraph,
- ARegion *ar, View3D *v3d)
+ ARegion *ar, View3D *v3d, const eObjectMode object_mode)
{
/* Reset before using it. */
memset(&DST, 0x0, sizeof(DST));
@@ -3545,13 +3560,14 @@ void DRW_draw_render_loop(
Scene *scene = DEG_get_evaluated_scene(depsgraph);
RenderEngineType *engine_type = RE_engines_find(scene->view_render.engine_id);
- DRW_draw_render_loop_ex(depsgraph, engine_type, ar, v3d, NULL);
+ DRW_draw_render_loop_ex(depsgraph, engine_type, ar, v3d, object_mode, NULL);
}
/* @viewport CAN be NULL, in this case we create one. */
void DRW_draw_render_loop_offscreen(
struct Depsgraph *depsgraph, RenderEngineType *engine_type,
- ARegion *ar, View3D *v3d, const bool draw_background, GPUOffScreen *ofs,
+ ARegion *ar, View3D *v3d, const eObjectMode object_mode,
+ const bool draw_background, GPUOffScreen *ofs,
GPUViewport *viewport)
{
RegionView3D *rv3d = ar->regiondata;
@@ -3572,7 +3588,7 @@ void DRW_draw_render_loop_offscreen(
memset(&DST, 0x0, sizeof(DST));
DST.options.is_image_render = true;
DST.options.draw_background = draw_background;
- DRW_draw_render_loop_ex(depsgraph, engine_type, ar, v3d, NULL);
+ DRW_draw_render_loop_ex(depsgraph, engine_type, ar, v3d, object_mode, NULL);
/* restore */
{
@@ -3590,21 +3606,25 @@ void DRW_draw_render_loop_offscreen(
GPU_offscreen_bind(ofs, false);
}
-void DRW_render_to_image(RenderEngine *re, struct Depsgraph *depsgraph)
+void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph)
{
Scene *scene = DEG_get_evaluated_scene(depsgraph);
- ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
- RenderEngineType *engine_type = re->type;
+ RenderEngineType *engine_type = engine->type;
DrawEngineType *draw_engine_type = engine_type->draw_engine;
RenderData *r = &scene->r;
+ Render *render = engine->re;
+ const EvaluationContext *eval_ctx = RE_GetEvalCtx(render);
/* Reset before using it. */
memset(&DST, 0x0, sizeof(DST));
DST.options.is_image_render = true;
+ DST.options.is_scene_render = true;
+ DST.options.draw_background = scene->r.alphamode == R_ADDSKY;
DST.draw_ctx = (DRWContextState){
- NULL, NULL, NULL, scene, view_layer, OBACT(view_layer), engine_type, depsgraph, NULL
+ NULL, NULL, NULL, scene, NULL, NULL, engine_type, depsgraph, eval_ctx->object_mode, NULL,
};
+ drw_context_state_init();
DST.viewport = GPU_viewport_create();
const int size[2] = {(r->size * r->xsch) / 100, (r->size * r->ysch) / 100};
@@ -3619,7 +3639,36 @@ void DRW_render_to_image(RenderEngine *re, struct Depsgraph *depsgraph)
glDisable(GL_SCISSOR_TEST);
glViewport(0, 0, size[0], size[1]);
- engine_type->draw_engine->render_to_image(data, re, depsgraph);
+ /* Main rendering loop. */
+
+ /* Init render result. */
+ const float *render_size = DRW_viewport_size_get();
+ RenderResult *render_result = RE_engine_begin_result(engine, 0, 0, (int)render_size[0], (int)render_size[1], NULL, NULL);
+
+ for (RenderView *render_view = render_result->views.first;
+ render_view != NULL;
+ render_view = render_view->next)
+ {
+ RE_SetActiveRenderView(render, render_view->name);
+ for (RenderLayer *render_layer = render_result->layers.first;
+ render_layer != NULL;
+ render_layer = render_layer->next)
+ {
+ ViewLayer *view_layer = BLI_findstring(&scene->view_layers, render_layer->name, offsetof(ViewLayer, name));
+ DST.draw_ctx.view_layer = view_layer;
+
+ /* TODO(dfelinto/sergey) we should not get depsgraph from scene.
+ * For rendering depsgraph is to be owned by Render. */
+ DST.draw_ctx.depsgraph = BKE_scene_get_depsgraph(scene, view_layer, true);
+
+ engine_type->draw_engine->render_to_image(data, engine, render_result, render_layer);
+ DST.buffer_finish_called = false;
+ /* Force cache to reset. */
+ drw_viewport_cache_resize();
+ }
+ }
+
+ RE_engine_end_result(engine, render_result, false, false, false);
/* TODO grease pencil */
@@ -3654,17 +3703,26 @@ void DRW_render_object_iter(
DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END
}
+/* Must run after all instance datas have been added. */
+void DRW_render_instance_buffer_finish(void)
+{
+ BLI_assert(!DST.buffer_finish_called && "DRW_render_instance_buffer_finish called twice!");
+ DST.buffer_finish_called = true;
+ DRW_instance_buffer_finish(DST.idatalist);
+}
+
/**
* object mode select-loop, see: ED_view3d_draw_select_loop (legacy drawing).
*/
void DRW_draw_select_loop(
struct Depsgraph *depsgraph,
- ARegion *ar, View3D *v3d,
+ ARegion *ar, View3D *v3d, const eObjectMode object_mode,
bool UNUSED(use_obedit_skip), bool UNUSED(use_nearest), const rcti *rect)
{
Scene *scene = DEG_get_evaluated_scene(depsgraph);
RenderEngineType *engine_type = RE_engines_find(scene->view_render.engine_id);
ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
+ Object *obact = OBACT(view_layer);
#ifndef USE_GPU_SELECT
UNUSED_VARS(vc, scene, view_layer, v3d, ar, rect);
#else
@@ -3679,14 +3737,12 @@ void DRW_draw_select_loop(
bool use_obedit = false;
int obedit_mode = 0;
- if (scene->obedit && scene->obedit->type == OB_MBALL) {
- use_obedit = true;
- obedit_mode = CTX_MODE_EDIT_METABALL;
- }
- else if ((scene->obedit && scene->obedit->type == OB_ARMATURE)) {
- /* if not drawing sketch, draw bones */
- // if (!BDR_drawSketchNames(vc))
- {
+ if (object_mode & OB_MODE_EDIT) {
+ if (obact->type == OB_MBALL) {
+ use_obedit = true;
+ obedit_mode = CTX_MODE_EDIT_METABALL;
+ }
+ else if (obact->type == OB_ARMATURE) {
use_obedit = true;
obedit_mode = CTX_MODE_EDIT_ARMATURE;
}
@@ -3715,9 +3771,10 @@ void DRW_draw_select_loop(
/* Instead of 'DRW_context_state_init(C, &DST.draw_ctx)', assign from args */
DST.draw_ctx = (DRWContextState){
- ar, rv3d, v3d, scene, view_layer, OBACT(view_layer), engine_type, depsgraph, (bContext *)NULL,
+ ar, rv3d, v3d, scene, view_layer, obact, engine_type, depsgraph, object_mode,
+ (bContext *)NULL,
};
-
+ drw_context_state_init();
drw_viewport_var_init();
/* Update ubos */
@@ -3733,7 +3790,7 @@ void DRW_draw_select_loop(
drw_engines_cache_init();
if (use_obedit) {
- drw_engines_cache_populate(scene->obedit);
+ drw_engines_cache_populate(obact);
}
else {
DEG_OBJECT_ITER(depsgraph, ob, DRW_iterator_mode_get(),
@@ -3750,6 +3807,8 @@ void DRW_draw_select_loop(
}
drw_engines_cache_finish();
+
+ DRW_render_instance_buffer_finish();
}
/* Start Drawing */
@@ -3780,7 +3839,7 @@ void DRW_draw_select_loop(
*/
void DRW_draw_depth_loop(
Depsgraph *depsgraph,
- ARegion *ar, View3D *v3d)
+ ARegion *ar, View3D *v3d, const eObjectMode object_mode)
{
Scene *scene = DEG_get_evaluated_scene(depsgraph);
RenderEngineType *engine_type = RE_engines_find(scene->view_render.engine_id);
@@ -3814,9 +3873,10 @@ void DRW_draw_depth_loop(
/* Instead of 'DRW_context_state_init(C, &DST.draw_ctx)', assign from args */
DST.draw_ctx = (DRWContextState){
- ar, rv3d, v3d, scene, view_layer, OBACT(view_layer), engine_type, depsgraph, (bContext *)NULL,
+ ar, rv3d, v3d, scene, view_layer, OBACT(view_layer), engine_type, depsgraph, object_mode,
+ (bContext *)NULL,
};
-
+ drw_context_state_init();
drw_viewport_var_init();
/* Update ubos */
@@ -3838,6 +3898,8 @@ void DRW_draw_depth_loop(
DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END
drw_engines_cache_finish();
+
+ DRW_render_instance_buffer_finish();
}
/* Start Drawing */
@@ -3917,6 +3979,14 @@ bool DRW_state_is_scene_render(void)
}
/**
+* Whether we are rendering simple opengl render
+*/
+bool DRW_state_is_opengl_render(void)
+{
+ return DST.options.is_image_render && !DST.options.is_scene_render;
+}
+
+/**
* Gives you the iterator mode to use for depsgraph.
*/
eDepsObjectIteratorMode DRW_iterator_mode_get(void)
@@ -4052,6 +4122,7 @@ void DRW_engines_free(void)
{
DRW_shape_cache_free();
DRW_stats_free();
+ DRW_globals_free();
DrawEngineType *next;
for (DrawEngineType *type = DRW_engines.first; type; type = next) {
@@ -4069,6 +4140,8 @@ void DRW_engines_free(void)
if (globals_ramp)
GPU_texture_free(globals_ramp);
+ MEM_SAFE_FREE(g_pos_format);
+
MEM_SAFE_FREE(RST.bound_texs);
MEM_SAFE_FREE(RST.bound_tex_slots);
diff --git a/source/blender/draw/intern/draw_view.c b/source/blender/draw/intern/draw_view.c
index 391c29e511f..d9ffbde38e7 100644
--- a/source/blender/draw/intern/draw_view.c
+++ b/source/blender/draw/intern/draw_view.c
@@ -611,21 +611,21 @@ void DRW_draw_background(void)
/* **************************** 3D Cursor ******************************** */
-static bool is_cursor_visible(Scene *scene, ViewLayer *view_layer)
+static bool is_cursor_visible(const DRWContextState *draw_ctx, Scene *scene, ViewLayer *view_layer)
{
Object *ob = OBACT(view_layer);
/* don't draw cursor in paint modes, but with a few exceptions */
- if (ob && ob->mode & OB_MODE_ALL_PAINT) {
+ if (ob && draw_ctx->object_mode & OB_MODE_ALL_PAINT) {
/* exception: object is in weight paint and has deforming armature in pose mode */
- if (ob->mode & OB_MODE_WEIGHT_PAINT) {
+ if (draw_ctx->object_mode & OB_MODE_WEIGHT_PAINT) {
if (BKE_object_pose_armature_get(ob) != NULL) {
return true;
}
}
/* exception: object in texture paint mode, clone brush, use_clone_layer disabled */
- else if (ob->mode & OB_MODE_TEXTURE_PAINT) {
- const Paint *p = BKE_paint_get_active(scene, view_layer);
+ else if (draw_ctx->object_mode & OB_MODE_TEXTURE_PAINT) {
+ const Paint *p = BKE_paint_get_active(scene, view_layer, draw_ctx->object_mode);
if (p && p->brush && p->brush->imagepaint_tool == PAINT_TOOL_CLONE) {
if ((scene->toolsettings->imapaint.flag & IMAGEPAINT_PROJECT_LAYER_CLONE) == 0) {
@@ -654,7 +654,7 @@ void DRW_draw_cursor(void)
glDisable(GL_DEPTH_TEST);
glLineWidth(1.0f);
- if (is_cursor_visible(scene, view_layer)) {
+ if (is_cursor_visible(draw_ctx, scene, view_layer)) {
float *co = ED_view3d_cursor3d_get(scene, v3d);
unsigned char crosshair_color[3];
diff --git a/source/blender/draw/modes/edit_curve_mode.c b/source/blender/draw/modes/edit_curve_mode.c
index 54a1bd79572..73a4fb1e9e6 100644
--- a/source/blender/draw/modes/edit_curve_mode.c
+++ b/source/blender/draw/modes/edit_curve_mode.c
@@ -229,12 +229,11 @@ static void EDIT_CURVE_cache_populate(void *vedata, Object *ob)
EDIT_CURVE_StorageList *stl = ((EDIT_CURVE_Data *)vedata)->stl;
const DRWContextState *draw_ctx = DRW_context_state_get();
const Scene *scene = draw_ctx->scene;
- const Object *obedit = scene->obedit;
UNUSED_VARS(psl, stl);
if (ob->type == OB_CURVE) {
- if (ob == obedit) {
+ if (ob == draw_ctx->object_edit) {
Curve *cu = ob->data;
/* Get geometry cache */
struct Gwn_Batch *geom;
diff --git a/source/blender/draw/modes/edit_lattice_mode.c b/source/blender/draw/modes/edit_lattice_mode.c
index e676677ff97..0268f4eb453 100644
--- a/source/blender/draw/modes/edit_lattice_mode.c
+++ b/source/blender/draw/modes/edit_lattice_mode.c
@@ -188,13 +188,11 @@ static void EDIT_LATTICE_cache_populate(void *vedata, Object *ob)
EDIT_LATTICE_PassList *psl = ((EDIT_LATTICE_Data *)vedata)->psl;
EDIT_LATTICE_StorageList *stl = ((EDIT_LATTICE_Data *)vedata)->stl;
const DRWContextState *draw_ctx = DRW_context_state_get();
- Scene *scene = draw_ctx->scene;
- Object *obedit = scene->obedit;
UNUSED_VARS(psl);
if (ob->type == OB_LATTICE) {
- if (ob == obedit) {
+ if (ob == draw_ctx->object_edit) {
/* Get geometry cache */
struct Gwn_Batch *geom;
diff --git a/source/blender/draw/modes/edit_mesh_mode.c b/source/blender/draw/modes/edit_mesh_mode.c
index 29ba658f79d..cc1373dc29f 100644
--- a/source/blender/draw/modes/edit_mesh_mode.c
+++ b/source/blender/draw/modes/edit_mesh_mode.c
@@ -443,11 +443,10 @@ static void EDIT_MESH_cache_populate(void *vedata, Object *ob)
const DRWContextState *draw_ctx = DRW_context_state_get();
View3D *v3d = draw_ctx->v3d;
Scene *scene = draw_ctx->scene;
- Object *obedit = scene->obedit;
struct Gwn_Batch *geom;
if (ob->type == OB_MESH) {
- if (ob == obedit) {
+ if (ob == draw_ctx->object_edit) {
const Mesh *me = ob->data;
IDProperty *ces_mode_ed = BKE_layer_collection_engine_evaluated_get(ob, COLLECTION_MODE_EDIT, "");
bool do_occlude_wire = BKE_collection_engine_property_value_get_bool(ces_mode_ed, "show_occlude_wire");
diff --git a/source/blender/draw/modes/edit_metaball_mode.c b/source/blender/draw/modes/edit_metaball_mode.c
index 78ceaf8b6f1..bcabeef5bc3 100644
--- a/source/blender/draw/modes/edit_metaball_mode.c
+++ b/source/blender/draw/modes/edit_metaball_mode.c
@@ -119,11 +119,11 @@ 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_helpers(psl->pass, DRW_cache_screenspace_circle_get());
+ stl->g_data->group = shgroup_instance_mball_handles(psl->pass, DRW_cache_screenspace_circle_get());
}
}
-static void EDIT_METABALL_cache_populate_radius_visualization(
+static void EDIT_METABALL_cache_populate_radius(
DRWShadingGroup *group, MetaElem *ml, const float scale_xform[3][4],
const float *radius, const int selection_id)
{
@@ -142,7 +142,7 @@ static void EDIT_METABALL_cache_populate_radius_visualization(
DRW_shgroup_call_dynamic_add(group, scale_xform, radius, color);
}
-static void EDIT_METABALL_cache_populate_stiffness_visualization(
+static void EDIT_METABALL_cache_populate_stiffness(
DRWShadingGroup *group, MetaElem *ml, const float scale_xform[3][4],
const float *radius, const int selection_id)
{
@@ -169,11 +169,9 @@ static void EDIT_METABALL_cache_populate(void *vedata, Object *ob)
if (ob->type == OB_MBALL) {
const DRWContextState *draw_ctx = DRW_context_state_get();
- Scene *scene = draw_ctx->scene;
- Object *obedit = scene->obedit;
DRWShadingGroup *group = stl->g_data->group;
- if (ob == obedit) {
+ if (ob == draw_ctx->object_edit) {
MetaBall *mb = ob->data;
const bool is_select = DRW_state_is_select();
@@ -181,13 +179,13 @@ static void EDIT_METABALL_cache_populate(void *vedata, Object *ob)
int selection_id = 0;
for (MetaElem *ml = mb->editelems->first; ml != NULL; ml = ml->next) {
- BKE_mball_element_calc_display_m3x4(ml->draw_scale_xform, ob->obmat, &ml->x);
+ BKE_mball_element_calc_scale_xform(ml->draw_scale_xform, ob->obmat, &ml->x);
ml->draw_stiffness_radius = ml->rad * atanf(ml->s) / (float)M_PI_2;
- EDIT_METABALL_cache_populate_radius_visualization(
+ EDIT_METABALL_cache_populate_radius(
group, ml, ml->draw_scale_xform, &ml->rad, is_select ? ++selection_id : -1);
- EDIT_METABALL_cache_populate_stiffness_visualization(
+ EDIT_METABALL_cache_populate_stiffness(
group, ml, ml->draw_scale_xform, &ml->draw_stiffness_radius, is_select ? ++selection_id : -1);
}
}
diff --git a/source/blender/draw/modes/edit_text_mode.c b/source/blender/draw/modes/edit_text_mode.c
index 60f28d89f4b..43c4a356279 100644
--- a/source/blender/draw/modes/edit_text_mode.c
+++ b/source/blender/draw/modes/edit_text_mode.c
@@ -190,13 +190,11 @@ static void EDIT_TEXT_cache_populate(void *vedata, Object *ob)
EDIT_TEXT_PassList *psl = ((EDIT_TEXT_Data *)vedata)->psl;
EDIT_TEXT_StorageList *stl = ((EDIT_TEXT_Data *)vedata)->stl;
const DRWContextState *draw_ctx = DRW_context_state_get();
- Scene *scene = draw_ctx->scene;
- Object *obedit = scene->obedit;
UNUSED_VARS(psl, stl);
if (ob->type == OB_FONT) {
- if (ob == obedit) {
+ if (ob == draw_ctx->object_edit) {
const Curve *cu = ob->data;
/* Get geometry cache */
struct Gwn_Batch *geom;
diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c
index f27f41c3d2a..4a7a5d25b11 100644
--- a/source/blender/draw/modes/object_mode.c
+++ b/source/blender/draw/modes/object_mode.c
@@ -32,7 +32,7 @@
#include "DNA_curve_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meta_types.h"
-#include "DNA_object_force.h"
+#include "DNA_object_force_types.h"
#include "DNA_lightprobe_types.h"
#include "DNA_particle_types.h"
#include "DNA_view3d_types.h"
@@ -55,6 +55,8 @@
#include "GPU_shader.h"
#include "GPU_texture.h"
+#include "MEM_guardedalloc.h"
+
#include "UI_resources.h"
#include "draw_mode_engines.h"
@@ -154,7 +156,7 @@ typedef struct OBJECT_PrivateData {
DRWShadingGroup *probe_grid;
/* MetaBalls */
- DRWShadingGroup *mball_circle;
+ DRWShadingGroup *mball_handle;
/* Lamps */
DRWShadingGroup *lamp_center;
@@ -215,6 +217,10 @@ typedef struct OBJECT_PrivateData {
} OBJECT_PrivateData; /* Transient data */
static struct {
+ /* Instance Data format */
+ struct Gwn_VertFormat *empty_image_format;
+ struct Gwn_VertFormat *empty_image_wire_format;
+
/* fullscreen shaders */
GPUShader *outline_resolve_sh;
GPUShader *outline_resolve_aa_sh;
@@ -531,6 +537,8 @@ static void OBJECT_engine_init(void *vedata)
static void OBJECT_engine_free(void)
{
+ MEM_SAFE_FREE(e_data.empty_image_format);
+ MEM_SAFE_FREE(e_data.empty_image_wire_format);
DRW_SHADER_FREE_SAFE(e_data.outline_resolve_sh);
DRW_SHADER_FREE_SAFE(e_data.outline_resolve_aa_sh);
DRW_SHADER_FREE_SAFE(e_data.outline_detect_sh);
@@ -663,14 +671,16 @@ static void DRW_shgroup_empty_image(
image_calc_aspect(ob->data, ob->iuser, empty_image_data->image_aspect);
if (tex) {
+ DRW_shgroup_instance_format(e_data.empty_image_format, {
+ {"objectColor" , DRW_ATTRIB_FLOAT, 4},
+ {"size" , DRW_ATTRIB_FLOAT, 1},
+ {"offset" , DRW_ATTRIB_FLOAT, 2},
+ {"InstanceModelMatrix" , DRW_ATTRIB_FLOAT, 16},
+ });
+
struct Gwn_Batch *geom = DRW_cache_image_plane_get();
DRWShadingGroup *grp = DRW_shgroup_instance_create(
- e_data.object_empty_image_sh, psl->non_meshes, geom);
- DRW_shgroup_attrib_float(grp, "objectColor", 4);
- DRW_shgroup_attrib_float(grp, "size", 1);
- DRW_shgroup_attrib_float(grp, "offset", 2);
- DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16);
-
+ e_data.object_empty_image_sh, psl->non_meshes, geom, e_data.empty_image_format);
DRW_shgroup_uniform_texture(grp, "image", tex);
DRW_shgroup_uniform_vec2(grp, "aspect", empty_image_data->image_aspect, 1);
@@ -681,14 +691,16 @@ static void DRW_shgroup_empty_image(
}
{
+ DRW_shgroup_instance_format(e_data.empty_image_wire_format, {
+ {"objectColor" , DRW_ATTRIB_FLOAT, 4},
+ {"size" , DRW_ATTRIB_FLOAT, 1},
+ {"offset" , DRW_ATTRIB_FLOAT, 2},
+ {"InstanceModelMatrix" , DRW_ATTRIB_FLOAT, 16}
+ });
+
struct Gwn_Batch *geom = DRW_cache_image_plane_wire_get();
DRWShadingGroup *grp = DRW_shgroup_instance_create(
- e_data.object_empty_image_wire_sh, psl->non_meshes, geom);
- DRW_shgroup_attrib_float(grp, "color", 3);
- DRW_shgroup_attrib_float(grp, "size", 1);
- DRW_shgroup_attrib_float(grp, "offset", 2);
- DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16);
-
+ e_data.object_empty_image_wire_sh, psl->non_meshes, geom, e_data.empty_image_wire_format);
DRW_shgroup_uniform_vec2(grp, "aspect", empty_image_data->image_aspect, 1);
empty_image_data->shgrp_wire = grp;
@@ -968,10 +980,10 @@ static void OBJECT_cache_init(void *vedata)
}
{
- /* Metaballs Helpers */
+ /* Metaballs Handles */
struct Gwn_Batch *geom;
geom = DRW_cache_screenspace_circle_get();
- stl->g_data->mball_circle = shgroup_instance_mball_helpers(psl->non_meshes, geom);
+ stl->g_data->mball_handle = shgroup_instance_mball_handles(psl->non_meshes, geom);
}
{
@@ -1103,7 +1115,7 @@ static void OBJECT_cache_init(void *vedata)
}
}
-static void DRW_shgroup_mball_helpers(OBJECT_StorageList *stl, Object *ob, ViewLayer *view_layer)
+static void DRW_shgroup_mball_handles(OBJECT_StorageList *stl, Object *ob, ViewLayer *view_layer)
{
MetaBall *mb = ob->data;
@@ -1112,8 +1124,8 @@ static void DRW_shgroup_mball_helpers(OBJECT_StorageList *stl, Object *ob, ViewL
for (MetaElem *ml = mb->elems.first; ml != NULL; ml = ml->next) {
/* draw radius */
- BKE_mball_element_calc_display_m3x4(ml->draw_scale_xform, ob->obmat, &ml->x);
- DRW_shgroup_call_dynamic_add(stl->g_data->mball_circle, ml->draw_scale_xform, &ml->rad, color);
+ BKE_mball_element_calc_scale_xform(ml->draw_scale_xform, ob->obmat, &ml->x);
+ DRW_shgroup_call_dynamic_add(stl->g_data->mball_handle, ml->draw_scale_xform, &ml->rad, color);
}
}
@@ -1471,6 +1483,8 @@ static void DRW_shgroup_speaker(OBJECT_StorageList *stl, Object *ob, ViewLayer *
}
typedef struct OBJECT_LightProbeEngineData {
+ ObjectEngineData engine_data;
+
float prb_mats[6][4][4];
float probe_cube_mat[4][4];
float draw_size;
@@ -1531,7 +1545,8 @@ static void DRW_shgroup_lightprobe(OBJECT_StorageList *stl, OBJECT_PassList *psl
mul_m4_v3(ob->obmat, prb_data->increment_z);
sub_v3_v3(prb_data->increment_z, prb_data->corner);
- DRWShadingGroup *grp = DRW_shgroup_instance_create(e_data.lightprobe_grid_sh, psl->lightprobes, DRW_cache_sphere_get());
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(e_data.lightprobe_grid_sh, psl->lightprobes,
+ DRW_cache_sphere_get(), NULL);
DRW_shgroup_set_instance_count(grp, prb->grid_resolution_x * prb->grid_resolution_y * prb->grid_resolution_z);
DRW_shgroup_uniform_vec4(grp, "color", color, 1);
DRW_shgroup_uniform_vec3(grp, "corner", prb_data->corner, 1);
@@ -1751,21 +1766,21 @@ static void OBJECT_cache_populate_particles(Object *ob,
break;
case PART_DRAW_CROSS:
shgrp = DRW_shgroup_instance_create(
- e_data.part_prim_sh, psl->particle, DRW_cache_particles_get_prim(PART_DRAW_CROSS));
+ e_data.part_prim_sh, psl->particle, DRW_cache_particles_get_prim(PART_DRAW_CROSS), NULL);
DRW_shgroup_uniform_texture(shgrp, "ramp", globals_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);
break;
case PART_DRAW_CIRC:
shgrp = DRW_shgroup_instance_create(
- e_data.part_prim_sh, psl->particle, DRW_cache_particles_get_prim(PART_DRAW_CIRC));
+ e_data.part_prim_sh, psl->particle, DRW_cache_particles_get_prim(PART_DRAW_CIRC), NULL);
DRW_shgroup_uniform_texture(shgrp, "ramp", globals_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);
break;
case PART_DRAW_AXIS:
shgrp = DRW_shgroup_instance_create(
- e_data.part_axis_sh, psl->particle, DRW_cache_particles_get_prim(PART_DRAW_AXIS));
+ e_data.part_axis_sh, psl->particle, DRW_cache_particles_get_prim(PART_DRAW_AXIS), NULL);
DRW_shgroup_uniform_int(shgrp, "screen_space", &screen_space[0], 1);
break;
default:
@@ -1788,7 +1803,6 @@ static void OBJECT_cache_populate(void *vedata, Object *ob)
OBJECT_PassList *psl = ((OBJECT_Data *)vedata)->psl;
OBJECT_StorageList *stl = ((OBJECT_Data *)vedata)->stl;
const DRWContextState *draw_ctx = DRW_context_state_get();
- Scene *scene = draw_ctx->scene;
ViewLayer *view_layer = draw_ctx->view_layer;
View3D *v3d = draw_ctx->v3d;
int theme_id = TH_UNDEFINED;
@@ -1808,8 +1822,7 @@ static void OBJECT_cache_populate(void *vedata, Object *ob)
bool do_outlines = ((ob->base_flag & BASE_SELECTED) != 0);
if (do_outlines) {
- Object *obedit = scene->obedit;
- if (ob != obedit && !((ob == draw_ctx->obact) && (ob->mode & OB_MODE_ALL_PAINT))) {
+ if ((ob != draw_ctx->object_edit) && !((ob == draw_ctx->obact) && (draw_ctx->object_mode & OB_MODE_ALL_PAINT))) {
struct Gwn_Batch *geom = DRW_cache_object_surface_get(ob);
if (geom) {
theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL);
@@ -1826,8 +1839,7 @@ static void OBJECT_cache_populate(void *vedata, Object *ob)
{
Mesh *me = ob->data;
if (me->totpoly == 0) {
- Object *obedit = scene->obedit;
- if (ob != obedit) {
+ if (ob != draw_ctx->object_edit) {
struct Gwn_Batch *geom = DRW_cache_mesh_edges_get(ob);
if (geom) {
if (theme_id == TH_UNDEFINED) {
@@ -1845,8 +1857,7 @@ static void OBJECT_cache_populate(void *vedata, Object *ob)
break;
case OB_LATTICE:
{
- Object *obedit = scene->obedit;
- if (ob != obedit) {
+ if (ob != draw_ctx->object_edit) {
struct Gwn_Batch *geom = DRW_cache_lattice_wire_get(ob, false);
if (theme_id == TH_UNDEFINED) {
theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL);
@@ -1860,8 +1871,7 @@ static void OBJECT_cache_populate(void *vedata, Object *ob)
case OB_CURVE:
{
- Object *obedit = scene->obedit;
- if (ob != obedit) {
+ if (ob != draw_ctx->object_edit) {
struct Gwn_Batch *geom = DRW_cache_curve_edge_wire_get(ob);
if (theme_id == TH_UNDEFINED) {
theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL);
@@ -1873,9 +1883,8 @@ static void OBJECT_cache_populate(void *vedata, Object *ob)
}
case OB_MBALL:
{
- Object *obedit = scene->obedit;
- if (ob != obedit) {
- DRW_shgroup_mball_helpers(stl, ob, view_layer);
+ if (ob != draw_ctx->object_edit) {
+ DRW_shgroup_mball_handles(stl, ob, view_layer);
}
break;
}
diff --git a/source/blender/draw/modes/particle_mode.c b/source/blender/draw/modes/particle_mode.c
index 0d0758971d5..f92505a8778 100644
--- a/source/blender/draw/modes/particle_mode.c
+++ b/source/blender/draw/modes/particle_mode.c
@@ -200,7 +200,7 @@ static void PARTICLE_draw_scene(void *vedata)
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
- UNUSED_VARS(fbl, dfbl, dtxl);
+ UNUSED_VARS(fbl, dfbl, dtxl, psl);
/* Show / hide entire passes, swap framebuffers ... whatever you fancy */
/*
@@ -212,7 +212,7 @@ static void PARTICLE_draw_scene(void *vedata)
*/
/* ... or just render passes on default framebuffer. */
- DRW_draw_pass(psl->pass);
+ //DRW_draw_pass(psl->pass);
/* If you changed framebuffer, double check you rebind
* the default one with its textures attached before finishing */
diff --git a/source/blender/draw/modes/pose_mode.c b/source/blender/draw/modes/pose_mode.c
index 560773f2d05..749c3e71368 100644
--- a/source/blender/draw/modes/pose_mode.c
+++ b/source/blender/draw/modes/pose_mode.c
@@ -136,14 +136,16 @@ static void POSE_cache_populate(void *vedata, Object *ob)
*/
bool DRW_pose_mode_armature(Object *ob, Object *active_ob)
{
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+
/* Pode armature is handled by pose mode engine. */
- if ((ob == active_ob) && ((ob->mode & OB_MODE_POSE) != 0)) {
+ if ((ob == active_ob) && ((draw_ctx->object_mode & OB_MODE_POSE) != 0)) {
return true;
}
/* Armature parent is also handled by pose mode engine. */
- if ((active_ob != NULL) && ((active_ob->mode & OB_MODE_WEIGHT_PAINT) != 0)) {
- if (active_ob->parent == ob) {
+ if ((active_ob != NULL) && ((draw_ctx->object_mode & OB_MODE_WEIGHT_PAINT) != 0)) {
+ if (ob == draw_ctx->object_pose) {
return true;
}
}
diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c
index 9fb30dc8066..87fe002e536 100644
--- a/source/blender/editors/animation/anim_channels_defines.c
+++ b/source/blender/editors/animation/anim_channels_defines.c
@@ -3827,7 +3827,7 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float
selected = 0;
/* set blending again, as may not be set in previous step */
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
/* step 1) draw backdrop ........................................... */
diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c
index 0db465e583b..d137e5f1c74 100644
--- a/source/blender/editors/animation/anim_channels_edit.c
+++ b/source/blender/editors/animation/anim_channels_edit.c
@@ -225,6 +225,33 @@ void ANIM_set_active_channel(bAnimContext *ac, void *data, eAnimCont_Types datat
ANIM_animdata_freelist(&anim_data);
}
+static void select_pchan_for_action_group(bAnimContext *ac, bActionGroup *agrp, bAnimListElem *ale)
+{
+ /* Armatures-Specific Feature:
+ * See mouse_anim_channels() -> ANIMTYPE_GROUP case for more details (T38737)
+ */
+ if ((ac->ads->filterflag & ADS_FILTER_ONLYSEL) == 0) {
+ if ((ale->id) && (GS(ale->id->name) == ID_OB)) {
+ Object *ob = (Object *)ale->id;
+ if (ob->type == OB_ARMATURE) {
+ /* Assume for now that any group with corresponding name is what we want
+ * (i.e. for an armature whose location is animated, things would break
+ * if the user were to add a bone named "Location").
+ *
+ * TODO: check the first F-Curve or so to be sure...
+ */
+ bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, agrp->name);
+ if (agrp->flag & AGRP_SELECTED) {
+ ED_pose_bone_select(ob, pchan, true);
+ }
+ else {
+ ED_pose_bone_select(ob, pchan, false);
+ }
+ }
+ }
+ }
+}
+
/* Deselect all animation channels
* - data: pointer to datatype, as contained in bAnimContext
* - datatype: the type of data that 'data' represents (eAnimCont_Types)
@@ -345,8 +372,8 @@ void ANIM_deselect_anim_channels(bAnimContext *ac, void *data, eAnimCont_Types d
case ANIMTYPE_GROUP:
{
bActionGroup *agrp = (bActionGroup *)ale->data;
-
ACHANNEL_SET_FLAG(agrp, sel, AGRP_SELECTED);
+ select_pchan_for_action_group(ac, agrp, ale);
agrp->flag &= ~AGRP_ACTIVE;
break;
}
@@ -2398,33 +2425,7 @@ static void borderselect_anim_channels(bAnimContext *ac, rcti *rect, short selec
case ANIMTYPE_GROUP:
{
bActionGroup *agrp = (bActionGroup *)ale->data;
-
- /* Armatures-Specific Feature:
- * See mouse_anim_channels() -> ANIMTYPE_GROUP case for more details (T38737)
- */
- if ((ac->ads->filterflag & ADS_FILTER_ONLYSEL) == 0) {
- if ((ale->id) && (GS(ale->id->name) == ID_OB)) {
- Object *ob = (Object *)ale->id;
-
- if (ob->type == OB_ARMATURE) {
- /* Assume for now that any group with corresponding name is what we want
- * (i.e. for an armature whose location is animated, things would break
- * if the user were to add a bone named "Location").
- *
- * TODO: check the first F-Curve or so to be sure...
- */
- bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, agrp->name);
-
- if (agrp->flag & AGRP_SELECTED) {
- ED_pose_bone_select(ob, pchan, true);
- }
- else {
- ED_pose_bone_select(ob, pchan, false);
- }
- }
- }
- }
-
+ select_pchan_for_action_group(ac, agrp, ale);
/* always clear active flag after doing this */
agrp->flag &= ~AGRP_ACTIVE;
break;
@@ -2682,8 +2683,10 @@ static int mouse_anim_channels(bContext *C, bAnimContext *ac, int channel_index,
}
case ANIMTYPE_OBJECT:
{
+#if 0
bDopeSheet *ads = (bDopeSheet *)ac->data;
Scene *sce = (Scene *)ads->source;
+#endif
ViewLayer *view_layer = ac->view_layer;
Base *base = (Base *)ale->data;
Object *ob = base->object;
@@ -2722,7 +2725,7 @@ static int mouse_anim_channels(bContext *C, bAnimContext *ac, int channel_index,
adt->flag |= ADT_UI_ACTIVE;
/* ensure we exit editmode on whatever object was active before to avoid getting stuck there - T48747 */
- if (ob != sce->obedit)
+ if (ob != CTX_data_edit_object(C))
ED_object_editmode_exit(C, EM_FREEDATA | EM_FREEUNDO | EM_WAITCURSOR | EM_DO_UNDO);
notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
diff --git a/source/blender/editors/animation/anim_draw.c b/source/blender/editors/animation/anim_draw.c
index 08851cebf51..9a07eaf896c 100644
--- a/source/blender/editors/animation/anim_draw.c
+++ b/source/blender/editors/animation/anim_draw.c
@@ -160,7 +160,7 @@ void ANIM_draw_previewrange(const bContext *C, View2D *v2d, int end_frame_width)
/* only draw this if preview range is set */
if (PRVRANGEON) {
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
Gwn_VertFormat *format = immVertexFormat();
diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c
index 107a46999f0..e43735c51fb 100644
--- a/source/blender/editors/animation/anim_markers.c
+++ b/source/blender/editors/animation/anim_markers.c
@@ -345,7 +345,7 @@ static void draw_marker(
int icon_id;
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
/* vertical line - dotted */
#ifdef DURIAN_CAMERA_SWITCH
@@ -462,7 +462,7 @@ void ED_markers_draw(const bContext *C, int flag)
immUniformColor4ubv(shade);
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
immRectf(pos, v2d->cur.xmin, 0, v2d->cur.xmax, UI_MARKER_MARGIN_Y);
@@ -1113,14 +1113,15 @@ static void select_timeline_marker_frame(ListBase *markers, int frame, bool exte
}
}
- BLI_LISTBASE_CIRCULAR_FORWARD_BEGIN (markers, marker, marker_first) {
+ LISTBASE_CIRCULAR_FORWARD_BEGIN(markers, marker, marker_first)
+ {
/* this way a not-extend select will always give 1 selected marker */
if (marker->frame == frame) {
marker->flag ^= SELECT;
break;
}
}
- BLI_LISTBASE_CIRCULAR_FORWARD_END (markers, marker, marker_first);
+ LISTBASE_CIRCULAR_FORWARD_END(markers, marker, marker_first);
}
static int ed_marker_select(bContext *C, const wmEvent *event, bool extend, bool camera)
diff --git a/source/blender/editors/animation/keyframes_edit.c b/source/blender/editors/animation/keyframes_edit.c
index 9d25fc9e1a3..0ef6aa4bd4a 100644
--- a/source/blender/editors/animation/keyframes_edit.c
+++ b/source/blender/editors/animation/keyframes_edit.c
@@ -36,7 +36,7 @@
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
-#include "BLI_lasso.h"
+#include "BLI_lasso_2d.h"
#include "BLI_math.h"
#include "DNA_anim_types.h"
diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c
index 24f6a2dab2c..6df0a1cd302 100644
--- a/source/blender/editors/animation/keyframing.c
+++ b/source/blender/editors/animation/keyframing.c
@@ -1579,6 +1579,9 @@ void ANIM_OT_keyframe_delete(wmOperatorType *ot)
static int clear_anim_v3d_exec(bContext *C, wmOperator *UNUSED(op))
{
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
+
bool changed = false;
CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
@@ -1595,7 +1598,7 @@ static int clear_anim_v3d_exec(bContext *C, wmOperator *UNUSED(op))
fcn = fcu->next;
/* in pose mode, only delete the F-Curve if it belongs to a selected bone */
- if (ob->mode & OB_MODE_POSE) {
+ if (eval_ctx.object_mode & OB_MODE_POSE) {
if ((fcu->rna_path) && strstr(fcu->rna_path, "pose.bones[")) {
bPoseChannel *pchan;
char *bone_name;
@@ -1658,8 +1661,10 @@ void ANIM_OT_keyframe_clear_v3d(wmOperatorType *ot)
static int delete_key_v3d_exec(bContext *C, wmOperator *op)
{
- Scene *scene = CTX_data_scene(C);
- float cfra = (float)CFRA;
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
+
+ const float cfra = eval_ctx.ctime;
CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
{
@@ -1687,7 +1692,7 @@ static int delete_key_v3d_exec(bContext *C, wmOperator *op)
/* special exception for bones, as this makes this operator more convenient to use
* NOTE: This is only done in pose mode. In object mode, we're dealign with the entire object.
*/
- if ((ob->mode & OB_MODE_POSE) && strstr(fcu->rna_path, "pose.bones[\"")) {
+ if ((eval_ctx.object_mode & OB_MODE_POSE) && strstr(fcu->rna_path, "pose.bones[\"")) {
bPoseChannel *pchan;
char *bone_name;
diff --git a/source/blender/editors/armature/armature_edit.c b/source/blender/editors/armature/armature_edit.c
index a2fbfe645f7..6c8779202e9 100644
--- a/source/blender/editors/armature/armature_edit.c
+++ b/source/blender/editors/armature/armature_edit.c
@@ -50,6 +50,7 @@
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_report.h"
+#include "BKE_object.h"
#include "RNA_access.h"
#include "RNA_define.h"
@@ -138,17 +139,16 @@ void ED_armature_transform(struct bArmature *arm, float mat[4][4], const bool do
/* exported for use in editors/object/ */
/* 0 == do center, 1 == center new, 2 == center cursor */
-void ED_armature_origin_set(Scene *scene, Object *ob, float cursor[3], int centermode, int around)
+void ED_armature_origin_set(Object *ob, float cursor[3], int centermode, int around)
{
- Object *obedit = scene->obedit; // XXX get from context
+ const bool is_editmode = BKE_object_is_in_editmode(ob);
EditBone *ebone;
bArmature *arm = ob->data;
float cent[3];
/* Put the armature into editmode */
- if (ob != obedit) {
+ if (is_editmode == false) {
ED_armature_to_edit(arm);
- obedit = NULL; /* we cant use this so behave as if there is no obedit */
}
/* Find the centerpoint */
@@ -188,13 +188,13 @@ void ED_armature_origin_set(Scene *scene, Object *ob, float cursor[3], int cente
}
/* Turn the list into an armature */
- if (obedit == NULL) {
+ if (is_editmode == false) {
ED_armature_from_edit(arm);
ED_armature_edit_free(arm);
}
/* Adjust object location for new centerpoint */
- if (centermode && obedit == NULL) {
+ if (centermode && (is_editmode == false)) {
mul_mat3_m4_v3(ob->obmat, cent); /* omit translation part */
add_v3_v3(ob->loc, cent);
}
diff --git a/source/blender/editors/armature/armature_intern.h b/source/blender/editors/armature/armature_intern.h
index 192bb8eea61..0ba720a17d0 100644
--- a/source/blender/editors/armature/armature_intern.h
+++ b/source/blender/editors/armature/armature_intern.h
@@ -250,7 +250,7 @@ void armature_tag_unselect(struct bArmature *arm);
void *get_nearest_bone(struct bContext *C, const int xy[2], bool findunsel);
void *get_bone_from_selectbuffer(
- struct Scene *scene, struct Base *base, const unsigned int *buffer, short hits,
+ struct Base *base, struct Object *obedit, const unsigned int *buffer, short hits,
bool findunsel, bool do_nearest);
int bone_looper(struct Object *ob, struct Bone *bone, void *data,
diff --git a/source/blender/editors/armature/armature_relations.c b/source/blender/editors/armature/armature_relations.c
index de2611f7092..8fc7aeaf029 100644
--- a/source/blender/editors/armature/armature_relations.c
+++ b/source/blender/editors/armature/armature_relations.c
@@ -281,7 +281,6 @@ int join_armature_exec(bContext *C, wmOperator *op)
/* get pose of active object and move it out of posemode */
pose = ob->pose;
- ob->mode &= ~OB_MODE_POSE;
CTX_DATA_BEGIN(C, Base *, base, selected_editable_bases)
{
@@ -302,8 +301,6 @@ int join_armature_exec(bContext *C, wmOperator *op)
/* Get Pose of current armature */
opose = base->object->pose;
- base->object->mode &= ~OB_MODE_POSE;
- //BASACT->flag &= ~OB_MODE_POSE;
/* Find the difference matrix */
invert_m4_m4(oimat, ob->obmat);
@@ -608,8 +605,6 @@ static int separate_armature_exec(bContext *C, wmOperator *op)
/* 1) store starting settings and exit editmode */
oldob = obedit;
oldbase = view_layer->basact;
- oldob->mode &= ~OB_MODE_POSE;
- //oldbase->flag &= ~OB_POSEMODE;
ED_armature_from_edit(obedit->data);
ED_armature_edit_free(obedit->data);
diff --git a/source/blender/editors/armature/armature_select.c b/source/blender/editors/armature/armature_select.c
index b87942fed84..f178ad640b6 100644
--- a/source/blender/editors/armature/armature_select.c
+++ b/source/blender/editors/armature/armature_select.c
@@ -77,10 +77,9 @@ Bone *get_indexed_bone(Object *ob, int index)
/* See if there are any selected bones in this buffer */
/* only bones from base are checked on */
void *get_bone_from_selectbuffer(
- Scene *scene, Base *base, const unsigned int *buffer, short hits,
+ Base *base, Object *obedit, const unsigned int *buffer, short hits,
bool findunsel, bool do_nearest)
{
- Object *obedit = scene->obedit; // XXX get from context
Bone *bone;
EditBone *ebone;
void *firstunSel = NULL, *firstSel = NULL, *data;
@@ -183,9 +182,9 @@ void *get_nearest_bone(bContext *C, const int xy[2], bool findunsel)
hits = view3d_opengl_select(&eval_ctx, &vc, buffer, MAXPICKBUF, &rect, VIEW3D_SELECT_PICK_NEAREST);
- if (hits > 0)
- return get_bone_from_selectbuffer(vc.scene, vc.view_layer->basact, buffer, hits, findunsel, true);
-
+ if (hits > 0) {
+ return get_bone_from_selectbuffer(vc.view_layer->basact, vc.obedit, buffer, hits, findunsel, true);
+ }
return NULL;
}
diff --git a/source/blender/editors/armature/armature_skinning.c b/source/blender/editors/armature/armature_skinning.c
index 72b4837c1b8..8900da900c0 100644
--- a/source/blender/editors/armature/armature_skinning.c
+++ b/source/blender/editors/armature/armature_skinning.c
@@ -66,7 +66,7 @@
/* ********************************** Bone Skinning *********************************************** */
-static int bone_skinnable_cb(Object *ob, Bone *bone, void *datap)
+static int bone_skinnable_cb(Object *UNUSED(ob), Bone *bone, void *datap)
{
/* Bones that are deforming
* are regarded to be "skinnable" and are eligible for
@@ -92,9 +92,9 @@ static int bone_skinnable_cb(Object *ob, Bone *bone, void *datap)
*/
Bone ***hbone;
int a, segments;
- struct { Object *armob; void *list; int heat; } *data = datap;
+ struct { Object *armob; void *list; int heat; bool is_weight_paint; } *data = datap;
- if (!(ob->mode & OB_MODE_WEIGHT_PAINT) || !(bone->flag & BONE_HIDDEN_P)) {
+ if (!(data->is_weight_paint) || !(bone->flag & BONE_HIDDEN_P)) {
if (!(bone->flag & BONE_NO_DEFORM)) {
if (data->heat && data->armob->pose && BKE_pose_channel_find_name(data->armob->pose, bone->name))
segments = bone->segments;
@@ -157,18 +157,17 @@ static int dgroup_skinnable_cb(Object *ob, Bone *bone, void *datap)
*/
bDeformGroup ***hgroup, *defgroup = NULL;
int a, segments;
- struct { Object *armob; void *list; int heat; } *data = datap;
- int wpmode = (ob->mode & OB_MODE_WEIGHT_PAINT);
+ struct { Object *armob; void *list; int heat; bool is_weight_paint; } *data = datap;
bArmature *arm = data->armob->data;
- if (!wpmode || !(bone->flag & BONE_HIDDEN_P)) {
+ if (!data->is_weight_paint || !(bone->flag & BONE_HIDDEN_P)) {
if (!(bone->flag & BONE_NO_DEFORM)) {
if (data->heat && data->armob->pose && BKE_pose_channel_find_name(data->armob->pose, bone->name))
segments = bone->segments;
else
segments = 1;
- if (!wpmode || ((arm->layer & bone->layer) && (bone->flag & BONE_SELECTED))) {
+ if (!data->is_weight_paint || ((arm->layer & bone->layer) && (bone->flag & BONE_SELECTED))) {
if (!(defgroup = defgroup_find_name(ob, bone->name))) {
defgroup = BKE_object_defgroup_add_name(ob, bone->name);
}
@@ -192,9 +191,11 @@ static int dgroup_skinnable_cb(Object *ob, Bone *bone, void *datap)
return 0;
}
-static void envelope_bone_weighting(Object *ob, Mesh *mesh, float (*verts)[3], int numbones, Bone **bonelist,
- bDeformGroup **dgrouplist, bDeformGroup **dgroupflip,
- float (*root)[3], float (*tip)[3], const int *selected, float scale)
+static void envelope_bone_weighting(
+ const EvaluationContext *eval_ctx,
+ Object *ob, Mesh *mesh, float (*verts)[3], int numbones, Bone **bonelist,
+ bDeformGroup **dgrouplist, bDeformGroup **dgroupflip,
+ float (*root)[3], float (*tip)[3], const int *selected, float scale)
{
/* Create vertex group weights from envelopes */
@@ -205,7 +206,7 @@ static void envelope_bone_weighting(Object *ob, Mesh *mesh, float (*verts)[3], i
bool use_topology = (mesh->editflag & ME_EDIT_MIRROR_TOPO) != 0;
bool use_mask = false;
- if ((ob->mode & OB_MODE_WEIGHT_PAINT) &&
+ if ((eval_ctx->object_mode & OB_MODE_WEIGHT_PAINT) &&
(mesh->editflag & (ME_EDIT_PAINT_FACE_SEL | ME_EDIT_PAINT_VERT_SEL)))
{
use_mask = true;
@@ -276,12 +277,12 @@ static void add_verts_to_dgroups(
float (*root)[3], (*tip)[3], (*verts)[3];
int *selected;
int numbones, vertsfilled = 0, i, j, segments = 0;
- int wpmode = (ob->mode & OB_MODE_WEIGHT_PAINT);
- struct { Object *armob; void *list; int heat; } looper_data;
+ struct { Object *armob; void *list; int heat; bool is_weight_paint; } looper_data;
looper_data.armob = par;
looper_data.heat = heat;
looper_data.list = NULL;
+ looper_data.is_weight_paint = (eval_ctx->object_mode & OB_MODE_WEIGHT_PAINT);
/* count the number of skinnable bones */
numbones = bone_looper(ob, arm->bonebase.first, &looper_data, bone_skinnable_cb);
@@ -354,7 +355,7 @@ static void add_verts_to_dgroups(
mul_m4_v3(par->obmat, tip[j]);
/* set selected */
- if (wpmode) {
+ if (eval_ctx->object_mode & OB_MODE_WEIGHT_PAINT) {
if ((arm->layer & bone->layer) && (bone->flag & BONE_SELECTED))
selected[j] = 1;
}
@@ -374,7 +375,7 @@ static void add_verts_to_dgroups(
mesh = (Mesh *)ob->data;
verts = MEM_callocN(mesh->totvert * sizeof(*verts), "closestboneverts");
- if (wpmode) {
+ if (eval_ctx->object_mode & OB_MODE_WEIGHT_PAINT) {
/* if in weight paint mode, use final verts from derivedmesh */
DerivedMesh *dm = mesh_get_derived_final(eval_ctx, scene, ob, CD_MASK_BAREMESH);
@@ -404,15 +405,17 @@ static void add_verts_to_dgroups(
if (heat) {
const char *error = NULL;
- heat_bone_weighting(ob, mesh, verts, numbones, dgrouplist, dgroupflip,
- root, tip, selected, &error);
+ heat_bone_weighting(
+ eval_ctx, ob, mesh, verts, numbones, dgrouplist, dgroupflip,
+ root, tip, selected, &error);
if (error) {
BKE_report(reports, RPT_WARNING, error);
}
}
else {
- envelope_bone_weighting(ob, mesh, verts, numbones, bonelist, dgrouplist,
- dgroupflip, root, tip, selected, mat4_to_scale(par->obmat));
+ envelope_bone_weighting(
+ eval_ctx, ob, mesh, verts, numbones, bonelist, dgrouplist,
+ dgroupflip, root, tip, selected, mat4_to_scale(par->obmat));
}
/* only generated in some cases but can call anyway */
diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c
index f4bebfd85e0..c91f92bc70b 100644
--- a/source/blender/editors/armature/editarmature_sketch.c
+++ b/source/blender/editors/armature/editarmature_sketch.c
@@ -178,7 +178,7 @@ const char *BIF_listTemplates(const bContext *UNUSED(C))
GHashIterator ghi;
const char *menu_header = IFACE_("Template %t|None %x0|");
char *p;
- const size_t template_size = (BLI_ghash_size(TEMPLATES_HASH) * 32 + 30);
+ const size_t template_size = (BLI_ghash_len(TEMPLATES_HASH) * 32 + 30);
if (TEMPLATES_MENU != NULL) {
MEM_freeN(TEMPLATES_MENU);
@@ -2031,7 +2031,7 @@ static void sk_drawSketch(Scene *scene, View3D *UNUSED(v3d), SK_Sketch *sketch,
gpuPushMatrix();
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
switch (sketch->next_point.mode) {
case PT_SNAP:
diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c
index 9500fd59b8b..d53350ab3cb 100644
--- a/source/blender/editors/armature/meshlaplacian.c
+++ b/source/blender/editors/armature/meshlaplacian.c
@@ -46,6 +46,8 @@
#include "ED_mesh.h"
#include "ED_armature.h"
+#include "DEG_depsgraph.h"
+
#include "eigen_capi.h"
#include "meshlaplacian.h"
@@ -600,9 +602,11 @@ static float heat_limit_weight(float weight)
return weight;
}
-void heat_bone_weighting(Object *ob, Mesh *me, float (*verts)[3], int numsource,
- bDeformGroup **dgrouplist, bDeformGroup **dgroupflip,
- float (*root)[3], float (*tip)[3], int *selected, const char **err_str)
+void heat_bone_weighting(
+ const EvaluationContext *eval_ctx,
+ Object *ob, Mesh *me, float (*verts)[3], int numsource,
+ bDeformGroup **dgrouplist, bDeformGroup **dgroupflip,
+ float (*root)[3], float (*tip)[3], int *selected, const char **err_str)
{
LaplacianSystem *sys;
MLoopTri *mlooptri;
@@ -623,7 +627,7 @@ void heat_bone_weighting(Object *ob, Mesh *me, float (*verts)[3], int numsource,
tottri = poly_to_tri_count(me->totpoly, me->totloop);
/* count triangles and create mask */
- if (ob->mode & OB_MODE_WEIGHT_PAINT &&
+ if (eval_ctx->object_mode & OB_MODE_WEIGHT_PAINT &&
(use_face_sel || use_vert_sel))
{
mask = MEM_callocN(sizeof(int) * me->totvert, "heat_bone_weighting mask");
diff --git a/source/blender/editors/armature/meshlaplacian.h b/source/blender/editors/armature/meshlaplacian.h
index bba8c739abf..c790c2fbee7 100644
--- a/source/blender/editors/armature/meshlaplacian.h
+++ b/source/blender/editors/armature/meshlaplacian.h
@@ -52,10 +52,12 @@ float laplacian_system_get_solution(LaplacianSystem *sys, int v);
/* Heat Weighting */
-void heat_bone_weighting(struct Object *ob, struct Mesh *me, float (*verts)[3],
- int numbones, struct bDeformGroup **dgrouplist,
- struct bDeformGroup **dgroupflip, float (*root)[3], float (*tip)[3],
- int *selected, const char **error);
+void heat_bone_weighting(
+ const struct EvaluationContext *eval_ctx,
+ struct Object *ob, struct Mesh *me, float (*verts)[3],
+ int numbones, struct bDeformGroup **dgrouplist,
+ struct bDeformGroup **dgroupflip, float (*root)[3], float (*tip)[3],
+ int *selected, const char **error);
#ifdef RIGID_DEFORM
/* As-Rigid-As-Possible Deformation */
diff --git a/source/blender/editors/armature/pose_edit.c b/source/blender/editors/armature/pose_edit.c
index 74e29b2e8da..119a27cd4a7 100644
--- a/source/blender/editors/armature/pose_edit.c
+++ b/source/blender/editors/armature/pose_edit.c
@@ -94,13 +94,16 @@ void ED_armature_enter_posemode(bContext *C, Base *base)
switch (ob->type) {
case OB_ARMATURE:
- ob->restore_mode = ob->mode;
- ob->mode |= OB_MODE_POSE;
+ {
+ WorkSpace *workspace = CTX_wm_workspace(C);
+ workspace->object_mode_restore = workspace->object_mode;
+ workspace->object_mode |= OB_MODE_POSE;
/* Inform all CoW versions that we changed the mode. */
DEG_id_tag_update_ex(CTX_data_main(C), &ob->id, DEG_TAG_COPY_ON_WRITE);
WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_POSE, NULL);
break;
+ }
default:
return;
}
@@ -112,10 +115,11 @@ void ED_armature_enter_posemode(bContext *C, Base *base)
void ED_armature_exit_posemode(bContext *C, Base *base)
{
if (base) {
+ WorkSpace *workspace = CTX_wm_workspace(C);
Object *ob = base->object;
- ob->restore_mode = ob->mode;
- ob->mode &= ~OB_MODE_POSE;
+ workspace->object_mode_restore = workspace->object_mode;
+ workspace->object_mode &= ~OB_MODE_POSE;
/* Inform all CoW versions that we changed the mode. */
DEG_id_tag_update_ex(CTX_data_main(C), &ob->id, DEG_TAG_COPY_ON_WRITE);
diff --git a/source/blender/editors/armature/pose_select.c b/source/blender/editors/armature/pose_select.c
index 9bc678cd9e6..16f5bb59641 100644
--- a/source/blender/editors/armature/pose_select.c
+++ b/source/blender/editors/armature/pose_select.c
@@ -134,7 +134,8 @@ void ED_pose_bone_select(Object *ob, bPoseChannel *pchan, bool select)
/* called from editview.c, for mode-less pose selection */
/* assumes scene obact and basact is still on old situation */
bool ED_do_pose_selectbuffer(
- Scene *scene, ViewLayer *view_layer, Base *base, const unsigned int *buffer, short hits,
+ const EvaluationContext *eval_ctx,
+ ViewLayer *view_layer, Base *base, const unsigned int *buffer, short hits,
bool extend, bool deselect, bool toggle, bool do_nearest)
{
Object *ob = base->object;
@@ -142,11 +143,13 @@ bool ED_do_pose_selectbuffer(
if (!ob || !ob->pose) return 0;
- nearBone = get_bone_from_selectbuffer(scene, base, buffer, hits, 1, do_nearest);
+ Object *ob_act = OBACT(view_layer);
+ Object *obedit = OBEDIT_FROM_EVAL_CTX(eval_ctx);
+
+ nearBone = get_bone_from_selectbuffer(base, obedit, buffer, hits, 1, do_nearest);
/* if the bone cannot be affected, don't do anything */
if ((nearBone) && !(nearBone->flag & BONE_UNSELECTABLE)) {
- Object *ob_act = OBACT(view_layer);
bArmature *arm = ob->data;
/* since we do unified select, we don't shift+select a bone if the
@@ -154,7 +157,7 @@ bool ED_do_pose_selectbuffer(
* note, special exception for armature mode so we can do multi-select
* we could check for multi-select explicitly but think its fine to
* always give predictable behavior in weight paint mode - campbell */
- if ((ob_act == NULL) || ((ob_act != ob) && (ob_act->mode & OB_MODE_WEIGHT_PAINT) == 0)) {
+ if ((ob_act == NULL) || ((ob_act != ob) && (eval_ctx->object_mode & OB_MODE_WEIGHT_PAINT) == 0)) {
/* when we are entering into posemode via toggle-select,
* from another active object - always select the bone. */
if (!extend && !deselect && toggle) {
@@ -195,7 +198,7 @@ bool ED_do_pose_selectbuffer(
if (ob_act) {
/* in weightpaint we select the associated vertex group too */
- if (ob_act->mode & OB_MODE_WEIGHT_PAINT) {
+ if (eval_ctx->object_mode & OB_MODE_WEIGHT_PAINT) {
if (nearBone == arm->act_bone) {
ED_vgroup_select_by_name(ob_act, nearBone->name);
DEG_id_tag_update(&ob_act->id, OB_RECALC_DATA);
@@ -873,6 +876,7 @@ void POSE_OT_select_grouped(wmOperatorType *ot)
*/
static int pose_select_mirror_exec(bContext *C, wmOperator *op)
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Object *ob_act = CTX_data_active_object(C);
Object *ob = BKE_object_pose_armature_get(ob_act);
bArmature *arm;
@@ -880,10 +884,6 @@ static int pose_select_mirror_exec(bContext *C, wmOperator *op)
const bool active_only = RNA_boolean_get(op->ptr, "only_active");
const bool extend = RNA_boolean_get(op->ptr, "extend");
- if ((ob && (ob->mode & OB_MODE_POSE)) == 0) {
- return OPERATOR_CANCELLED;
- }
-
arm = ob->data;
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
@@ -920,7 +920,7 @@ static int pose_select_mirror_exec(bContext *C, wmOperator *op)
arm->act_bone = pchan_mirror_act->bone;
/* in weightpaint we select the associated vertex group too */
- if (ob_act->mode & OB_MODE_WEIGHT_PAINT) {
+ if (workspace->object_mode & OB_MODE_WEIGHT_PAINT) {
ED_vgroup_select_by_name(ob_act, pchan_mirror_act->name);
DEG_id_tag_update(&ob_act->id, OB_RECALC_DATA);
}
diff --git a/source/blender/editors/armature/reeb.c b/source/blender/editors/armature/reeb.c
index 0eb44085bae..fda7012e955 100644
--- a/source/blender/editors/armature/reeb.c
+++ b/source/blender/editors/armature/reeb.c
@@ -546,7 +546,7 @@ void verifyFaces(ReebGraph *rg)
int total = 0;
ReebArc *arc = NULL;
for (arc = rg->arcs.first; arc; arc = arc->next) {
- total += BLI_ghash_size(arc->faces);
+ total += BLI_ghash_len(arc->faces);
}
#endif
@@ -1656,7 +1656,7 @@ int filterSmartReebGraph(ReebGraph *UNUSED(rg), float UNUSED(threshold))
{
GHashIterator ghi;
int merging = 0;
- int total = BLI_ghash_size(arc->faces);
+ int total = BLI_ghash_len(arc->faces);
float avg_angle = 0;
float avg_vec[3] = {0, 0, 0};
@@ -1932,7 +1932,7 @@ void REEB_exportGraph(ReebGraph *rg, int count)
add_v3_v3v3(p, arc->tail->p, arc->head->p);
mul_v3_fl(p, 0.5f);
- fprintf(f, "angle %0.3f %0.3f %0.3f %0.3f %i\n", p[0], p[1], p[2], arc->angle, BLI_ghash_size(arc->faces));
+ fprintf(f, "angle %0.3f %0.3f %0.3f %0.3f %i\n", p[0], p[1], p[2], arc->angle, BLI_ghash_len(arc->faces));
exportNode(f, "v2", arc->tail);
}
@@ -2678,7 +2678,7 @@ static void shortestPathsFromVert(EditMesh *em, EditVert *starting_vert, EdgeInd
eed->f1 = 0;
}
- while (BLI_heap_size(edge_heap) > 0) {
+ while (BLI_heap_len(edge_heap) > 0) {
float current_weight;
current_eve->f1 = 1; /* mark vertex as selected */
@@ -2695,7 +2695,7 @@ static void shortestPathsFromVert(EditMesh *em, EditVert *starting_vert, EdgeInd
/* Find next shortest edge with unselected verts */
do {
current_weight = BLI_heap_node_value(BLI_heap_top(edge_heap));
- select_eed = BLI_heap_popmin(edge_heap);
+ select_eed = BLI_heap_pop_min(edge_heap);
} while (select_eed != NULL && select_eed->v1->f1 != 0 && select_eed->v2->f1);
if (select_eed != NULL) {
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index 4b578ba389e..94b090bff05 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -530,7 +530,7 @@ static GHash *dupli_keyIndexHash(GHash *keyindex)
GHash *gh;
GHashIterator gh_iter;
- gh = BLI_ghash_ptr_new_ex("dupli_keyIndex gh", BLI_ghash_size(keyindex));
+ gh = BLI_ghash_ptr_new_ex("dupli_keyIndex gh", BLI_ghash_len(keyindex));
GHASH_ITER (gh_iter, keyindex) {
void *cv = BLI_ghashIterator_getKey(&gh_iter);
@@ -5027,7 +5027,7 @@ static int add_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event)
snap_context,
SCE_SELECT_FACE,
&(const struct SnapObjectParams){
- .snap_select = (vc.scene->obedit != NULL) ? SNAP_NOT_ACTIVE : SNAP_ALL,
+ .snap_select = (vc.obedit != NULL) ? SNAP_NOT_ACTIVE : SNAP_ALL,
.use_object_edit_cage = false,
},
mval, NULL, true,
diff --git a/source/blender/editors/curve/editcurve_paint.c b/source/blender/editors/curve/editcurve_paint.c
index 062b9c94a1b..169afb140fb 100644
--- a/source/blender/editors/curve/editcurve_paint.c
+++ b/source/blender/editors/curve/editcurve_paint.c
@@ -365,7 +365,7 @@ static void curve_draw_stroke_3d(const struct bContext *UNUSED(C), ARegion *UNUS
wmOperator *op = arg;
struct CurveDrawData *cdd = op->customdata;
- const int stroke_len = BLI_mempool_count(cdd->stroke_elem_pool);
+ const int stroke_len = BLI_mempool_len(cdd->stroke_elem_pool);
if (stroke_len == 0) {
return;
@@ -706,7 +706,7 @@ static void curve_draw_exec_precalc(wmOperator *op)
if (!RNA_property_is_set(op->ptr, prop)) {
bool use_cyclic = false;
- if (BLI_mempool_count(cdd->stroke_elem_pool) > 2) {
+ if (BLI_mempool_len(cdd->stroke_elem_pool) > 2) {
BLI_mempool_iter iter;
const struct StrokeElem *selem, *selem_first, *selem_last;
@@ -732,7 +732,7 @@ static void curve_draw_exec_precalc(wmOperator *op)
(cps->radius_taper_end != 0.0f))
{
/* note, we could try to de-duplicate the length calculations above */
- const int stroke_len = BLI_mempool_count(cdd->stroke_elem_pool);
+ const int stroke_len = BLI_mempool_len(cdd->stroke_elem_pool);
BLI_mempool_iter iter;
struct StrokeElem *selem, *selem_prev;
@@ -788,18 +788,18 @@ static int curve_draw_exec(bContext *C, wmOperator *op)
struct CurveDrawData *cdd = op->customdata;
const CurvePaintSettings *cps = &cdd->vc.scene->toolsettings->curve_paint_settings;
- Object *obedit = cdd->vc.scene->obedit;
+ Object *obedit = cdd->vc.obedit;
Curve *cu = obedit->data;
ListBase *nurblist = object_editcurve_get(obedit);
- int stroke_len = BLI_mempool_count(cdd->stroke_elem_pool);
+ int stroke_len = BLI_mempool_len(cdd->stroke_elem_pool);
const bool is_3d = (cu->flag & CU_3D) != 0;
invert_m4_m4(obedit->imat, obedit->obmat);
- if (BLI_mempool_count(cdd->stroke_elem_pool) == 0) {
+ if (BLI_mempool_len(cdd->stroke_elem_pool) == 0) {
curve_draw_stroke_from_operator(op);
- stroke_len = BLI_mempool_count(cdd->stroke_elem_pool);
+ stroke_len = BLI_mempool_len(cdd->stroke_elem_pool);
}
ED_curve_deselect_all(cu->editnurb);
diff --git a/source/blender/editors/curve/editcurve_select.c b/source/blender/editors/curve/editcurve_select.c
index 02b8970731c..4a4b13d0d1b 100644
--- a/source/blender/editors/curve/editcurve_select.c
+++ b/source/blender/editors/curve/editcurve_select.c
@@ -1607,7 +1607,7 @@ static void curve_select_shortest_path_surf(Nurb *nu, int vert_src, int vert_dst
int axis, sign;
int u, v;
- vert_curr = *((int *)BLI_heap_popmin(heap));
+ vert_curr = *((int *)BLI_heap_pop_min(heap));
if (vert_curr == vert_dst) {
break;
}
diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c
index 4a95027528b..942aa861cec 100644
--- a/source/blender/editors/gpencil/drawgpencil.c
+++ b/source/blender/editors/gpencil/drawgpencil.c
@@ -41,7 +41,7 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
-#include "BLI_polyfill2d.h"
+#include "BLI_polyfill_2d.h"
#include "BLF_api.h"
#include "BLT_translation.h"
@@ -1479,7 +1479,7 @@ static void gp_draw_status_text(const bGPdata *gpd, ARegion *ar)
/* grease pencil icon... */
// XXX: is this too intrusive?
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
xco -= U.widget_unit;
diff --git a/source/blender/editors/gpencil/gpencil_convert.c b/source/blender/editors/gpencil/gpencil_convert.c
index 76fa3b3f9ea..e2b22d063bd 100644
--- a/source/blender/editors/gpencil/gpencil_convert.c
+++ b/source/blender/editors/gpencil/gpencil_convert.c
@@ -55,6 +55,7 @@
#include "DNA_space_types.h"
#include "DNA_view3d_types.h"
#include "DNA_gpencil_types.h"
+#include "DNA_workspace_types.h"
#include "BKE_collection.h"
#include "BKE_context.h"
@@ -1293,6 +1294,7 @@ static int gp_convert_poll(bContext *C)
bGPDframe *gpf = NULL;
ScrArea *sa = CTX_wm_area(C);
Scene *scene = CTX_data_scene(C);
+ const WorkSpace *workspace = CTX_wm_workspace(C);
/* only if the current view is 3D View, if there's valid data (i.e. at least one stroke!),
* and if we are not in edit mode!
@@ -1301,7 +1303,7 @@ static int gp_convert_poll(bContext *C)
(gpl = BKE_gpencil_layer_getactive(gpd)) &&
(gpf = BKE_gpencil_layer_getframe(gpl, CFRA, 0)) &&
(gpf->strokes.first) &&
- (scene->obedit == NULL));
+ ((workspace->object_mode & OB_MODE_EDIT) == 0));
}
static int gp_convert_layer_exec(bContext *C, wmOperator *op)
diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c
index 472b88cb18b..c25e4d3ea73 100644
--- a/source/blender/editors/gpencil/gpencil_paint.c
+++ b/source/blender/editors/gpencil/gpencil_paint.c
@@ -1862,7 +1862,7 @@ static void gpencil_draw_eraser(bContext *UNUSED(C), int x, int y, void *p_ptr)
glEnable(GL_LINE_SMOOTH);
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
immUniformColor4ub(255, 100, 100, 20);
imm_draw_circle_fill_2d(shdr_pos, x, y, p->radius, 40);
diff --git a/source/blender/editors/gpencil/gpencil_select.c b/source/blender/editors/gpencil/gpencil_select.c
index 07abab8af2e..dc3483163bf 100644
--- a/source/blender/editors/gpencil/gpencil_select.c
+++ b/source/blender/editors/gpencil/gpencil_select.c
@@ -37,7 +37,7 @@
#include "BLI_blenlib.h"
#include "BLI_ghash.h"
-#include "BLI_lasso.h"
+#include "BLI_lasso_2d.h"
#include "BLI_utildefines.h"
#include "BLI_math_vector.h"
diff --git a/source/blender/editors/include/BIF_glutil.h b/source/blender/editors/include/BIF_glutil.h
index 3184ebee4d9..863d817d19a 100644
--- a/source/blender/editors/include/BIF_glutil.h
+++ b/source/blender/editors/include/BIF_glutil.h
@@ -107,38 +107,6 @@ void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state,
float x, float y, int img_w, int img_h, int format, int type, int zoomfilter, void *rect, float scaleX, float scaleY,
float clip_min_x, float clip_min_y, float clip_max_x, float clip_max_y,
float xzoom, float yzoom, float color[4]);
-/* 2D Drawing Assistance */
-
-/** Define a 2D area (viewport, scissor, matrices) for OpenGL rendering.
- *
- * glaDefine2DArea and glaBegin2DDraw set up an OpenGL state appropriate
- * for drawing using both vertex (Vertex, etc) and raster (RasterPos, Rect)
- * commands. All coordinates should be at integer positions. There is little
- * to no reason to use glVertex2f etc. functions during 2D rendering, and
- * thus no reason to +-0.5 the coordinates or perform other silly
- * tricks.
- *
- * \param screen_rect The screen rectangle to be defined for 2D drawing.
- */
-void glaDefine2DArea(struct rcti *screen_rect);
-
-/* TODO(merwin): put the following 2D code to use, or build new 2D code inspired & informd by it */
-
-#if 0 /* UNUSED */
-
-typedef struct gla2DDrawInfo gla2DDrawInfo;
-
-gla2DDrawInfo *glaBegin2DDraw(struct rcti *screen_rect, struct rctf *world_rect);
-void gla2DDrawTranslatePt(gla2DDrawInfo *di, float wo_x, float wo_y, int *r_sc_x, int *r_sc_y);
-void gla2DDrawTranslatePtv(gla2DDrawInfo *di, float world[2], int r_screen[2]);
-
-void glaEnd2DDraw(gla2DDrawInfo *di);
-
-/** Adjust the transformation mapping of a 2d area */
-void gla2DGetMap(gla2DDrawInfo *di, struct rctf *rect);
-void gla2DSetMap(gla2DDrawInfo *di, struct rctf *rect);
-
-#endif /* UNUSED */
void set_inverted_drawing(int enable);
void setlinestyle(int nr);
diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h
index 4595bcfa86d..18eb442766b 100644
--- a/source/blender/editors/include/ED_armature.h
+++ b/source/blender/editors/include/ED_armature.h
@@ -143,7 +143,8 @@ void ED_armature_deselect_all(struct Object *obedit);
void ED_armature_deselect_all_visible(struct Object *obedit);
bool ED_do_pose_selectbuffer(
- struct Scene *scene, struct ViewLayer *view_layer, struct Base *base, const unsigned int *buffer, short hits,
+ const struct EvaluationContext *eval_ctx,
+ struct ViewLayer *view_layer, struct Base *base, const unsigned int *buffer, short hits,
bool extend, bool deselect, bool toggle, bool do_nearest);
bool ED_armature_select_pick(struct bContext *C, const int mval[2], bool extend, bool deselect, bool toggle);
int join_armature_exec(struct bContext *C, struct wmOperator *op);
@@ -168,7 +169,7 @@ void ED_armature_ebone_from_mat3(EditBone *ebone, float mat[3][3]);
void ED_armature_ebone_from_mat4(EditBone *ebone, float mat[4][4]);
void transform_armature_mirror_update(struct Object *obedit);
-void ED_armature_origin_set(struct Scene *scene, struct Object *ob, float cursor[3], int centermode, int around);
+void ED_armature_origin_set(struct Object *ob, float cursor[3], int centermode, int around);
void ED_armature_transform_bones(struct bArmature *arm, float mat[4][4], const bool do_props);
void ED_armature_apply_transform(struct Object *ob, float mat[4][4], const bool do_props);
diff --git a/source/blender/editors/include/ED_image.h b/source/blender/editors/include/ED_image.h
index 95ba6095517..9802f8c3c03 100644
--- a/source/blender/editors/include/ED_image.h
+++ b/source/blender/editors/include/ED_image.h
@@ -40,6 +40,7 @@ struct wmWindowManager;
struct ARegion;
struct Scene;
struct ViewLayer;
+struct WorkSpace;
/* image_edit.c, exported for transform */
struct Image *ED_space_image(struct SpaceImage *sima);
@@ -75,7 +76,10 @@ bool ED_space_image_show_uvedit(struct SpaceImage *sima, struct Object *obedit);
bool ED_space_image_paint_curve(const struct bContext *C);
-bool ED_space_image_check_show_maskedit(struct ViewLayer *view_layer, struct SpaceImage *sima);
+bool ED_space_image_check_show_maskedit(
+ struct SpaceImage *sima,
+ const struct WorkSpace *workspace,
+ struct ViewLayer *view_layer);
int ED_space_image_maskedit_poll(struct bContext *C);
int ED_space_image_maskedit_mask_poll(struct bContext *C);
diff --git a/source/blender/editors/include/ED_info.h b/source/blender/editors/include/ED_info.h
index 072b1a135a3..3d873906ecf 100644
--- a/source/blender/editors/include/ED_info.h
+++ b/source/blender/editors/include/ED_info.h
@@ -27,8 +27,11 @@
#ifndef __ED_INFO_H__
#define __ED_INFO_H__
+struct EvaluationContext;
+
/* info_stats.c */
void ED_info_stats_clear(struct ViewLayer *view_layer);
-const char *ED_info_stats_string(struct Scene *scene, struct ViewLayer *view_layer);
+const char *ED_info_stats_string(
+ struct Scene *scene, struct WorkSpace *workspace, struct ViewLayer *view_layer);
#endif /* __ED_INFO_H__ */
diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h
index 78497b29313..0293f7cd204 100644
--- a/source/blender/editors/include/ED_mesh.h
+++ b/source/blender/editors/include/ED_mesh.h
@@ -219,12 +219,14 @@ typedef struct MirrTopoStore_t {
intptr_t *index_lookup;
int prev_vert_tot;
int prev_edge_tot;
- int prev_ob_mode;
+ bool prev_is_editmode;
} MirrTopoStore_t;
-bool ED_mesh_mirrtopo_recalc_check(struct Mesh *me, struct DerivedMesh *dm, const int ob_mode, MirrTopoStore_t *mesh_topo_store);
-void ED_mesh_mirrtopo_init(struct Mesh *me, struct DerivedMesh *dm, const int ob_mode, MirrTopoStore_t *mesh_topo_store,
- const bool skip_em_vert_array_init);
+bool ED_mesh_mirrtopo_recalc_check(
+ struct Mesh *me, struct DerivedMesh *dm, MirrTopoStore_t *mesh_topo_store);
+void ED_mesh_mirrtopo_init(
+ struct Mesh *me, struct DerivedMesh *dm, MirrTopoStore_t *mesh_topo_store,
+ const bool skip_em_vert_array_init);
void ED_mesh_mirrtopo_free(MirrTopoStore_t *mesh_topo_store);
diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h
index 8d2ff327c51..5df46dd26b8 100644
--- a/source/blender/editors/include/ED_object.h
+++ b/source/blender/editors/include/ED_object.h
@@ -55,6 +55,11 @@ struct wmOperatorType;
struct PointerRNA;
struct PropertyRNA;
struct EnumPropertyItem;
+struct EvaluationContext;
+struct WorkSpace;
+struct wmWindowManager;
+
+#include "DNA_object_enums.h"
/* object_edit.c */
struct Object *ED_object_context(struct bContext *C); /* context.object */
@@ -113,8 +118,8 @@ struct Base *ED_object_add_duplicate(struct Main *bmain, struct Scene *scene, st
void ED_object_parent(struct Object *ob, struct Object *parent, const int type, const char *substr);
-bool ED_object_mode_compat_set(struct bContext *C, struct Object *ob, int mode, struct ReportList *reports);
-void ED_object_toggle_modes(struct bContext *C, int mode);
+bool ED_object_mode_compat_set(struct bContext *C, struct WorkSpace *workspace, eObjectMode mode, struct ReportList *reports);
+void ED_object_toggle_modes(struct bContext *C, eObjectMode mode);
/* bitflags for enter/exit editmode */
#define EM_FREEDATA 1
@@ -122,12 +127,34 @@ void ED_object_toggle_modes(struct bContext *C, int mode);
#define EM_WAITCURSOR 4
#define EM_DO_UNDO 8
#define EM_IGNORE_LAYER 16
+void ED_object_editmode_exit_ex(
+ struct bContext *C, struct WorkSpace *workspace, struct Scene *scene, struct Object *obedit, int flag);
void ED_object_editmode_exit(struct bContext *C, int flag);
void ED_object_editmode_enter(struct bContext *C, int flag);
bool ED_object_editmode_load(struct Object *obedit);
bool ED_object_editmode_calc_active_center(struct Object *obedit, const bool select_only, float r_center[3]);
+
+void ED_object_vpaintmode_enter_ex(
+ const struct EvaluationContext *eval_ctx, struct wmWindowManager *wm,
+ struct WorkSpace *workspace, struct Scene *scene, struct Object *ob);
+void ED_object_vpaintmode_enter(struct bContext *C);
+void ED_object_wpaintmode_enter_ex(
+ const struct EvaluationContext *eval_ctx, struct wmWindowManager *wm,
+ struct WorkSpace *workspace, struct Scene *scene, struct Object *ob);
+void ED_object_wpaintmode_enter(struct bContext *C);
+
+void ED_object_vpaintmode_exit_ex(struct WorkSpace *workspace, struct Object *ob);
+void ED_object_vpaintmode_exit(struct bContext *C);
+void ED_object_wpaintmode_exit_ex(struct WorkSpace *workspace, struct Object *ob);
+void ED_object_wpaintmode_exit(struct bContext *C);
+
+void ED_object_sculptmode_exit_ex(
+ const struct EvaluationContext *eval_ctx,
+ struct WorkSpace *workspace, struct Scene *scene, struct Object *ob);
+void ED_object_sculptmode_exit(struct bContext *C);
+
void ED_object_location_from_view(struct bContext *C, float loc[3]);
void ED_object_rotation_from_view(struct bContext *C, float rot[3], const char align_axis);
void ED_object_base_init_transform(struct bContext *C, struct Base *base, const float loc[3], const float rot[3]);
@@ -160,9 +187,9 @@ void ED_objects_clear_paths(struct bContext *C, bool only_selected);
void ED_objects_recalculate_paths(struct bContext *C, struct Scene *scene);
/* constraints */
-struct ListBase *get_active_constraints(struct Object *ob);
+struct ListBase *get_active_constraints(const struct EvaluationContext *eval_ctx, struct Object *ob);
struct ListBase *get_constraint_lb(struct Object *ob, struct bConstraint *con, struct bPoseChannel **r_pchan);
-struct bConstraint *get_active_constraint(struct Object *ob);
+struct bConstraint *get_active_constraint(const struct EvaluationContext *eval_ctx, struct Object *ob);
void object_test_constraints(struct Object *ob);
@@ -187,24 +214,30 @@ enum {
MODIFIER_APPLY_SHAPE
};
-struct ModifierData *ED_object_modifier_add(struct ReportList *reports, struct Main *bmain, struct Scene *scene,
- struct Object *ob, const char *name, int type);
+struct ModifierData *ED_object_modifier_add(
+ struct ReportList *reports, struct Main *bmain, struct Scene *scene,
+ struct Object *ob, eObjectMode object_mode, const char *name, int type);
bool ED_object_modifier_remove(struct ReportList *reports, struct Main *bmain,
struct Object *ob, struct ModifierData *md);
void ED_object_modifier_clear(struct Main *bmain, struct Object *ob);
int ED_object_modifier_move_down(struct ReportList *reports, struct Object *ob, struct ModifierData *md);
int ED_object_modifier_move_up(struct ReportList *reports, struct Object *ob, struct ModifierData *md);
-int ED_object_modifier_convert(struct ReportList *reports, struct Main *bmain, struct Scene *scene,
- struct ViewLayer *view_layer, struct Object *ob, struct ModifierData *md);
+int ED_object_modifier_convert(
+ struct ReportList *reports, struct Main *bmain, struct Scene *scene,
+ struct ViewLayer *view_layer, struct Object *ob, eObjectMode object_mode, struct ModifierData *md);
int ED_object_modifier_apply(struct ReportList *reports, const struct bContext *C, struct Scene *scene,
struct Object *ob, struct ModifierData *md, int mode);
int ED_object_modifier_copy(struct ReportList *reports, struct Object *ob, struct ModifierData *md);
-bool ED_object_iter_other(struct Main *bmain, struct Object *orig_ob, const bool include_orig,
- bool (*callback)(struct Object *ob, void *callback_data),
- void *callback_data);
+bool ED_object_iter_other(
+ const struct EvaluationContext *eval_ctx, struct Main *bmain,
+ struct Object *orig_ob, const bool include_orig,
+ bool (*callback)(const struct EvaluationContext *eval_ctx, struct Object *ob, void *callback_data),
+ void *callback_data);
-bool ED_object_multires_update_totlevels_cb(struct Object *ob, void *totlevel_v);
+bool ED_object_multires_update_totlevels_cb(
+ const struct EvaluationContext *eval_ctx,
+ struct Object *ob, void *totlevel_v);
/* object_select.c */
void ED_object_select_linked_by_id(struct bContext *C, struct ID *id);
@@ -216,7 +249,9 @@ const struct EnumPropertyItem *ED_object_vgroup_selection_itemf_helper(
bool *r_free,
const unsigned int selection_mask);
-void ED_object_check_force_modifiers(struct Main *bmain, struct Scene *scene, struct Object *object);
+void ED_object_check_force_modifiers(
+ struct Main *bmain, struct Scene *scene,
+ struct Object *object, eObjectMode object_mode);
/* object_facemap_ops.c */
void ED_object_facemap_face_add(struct Object *ob, struct bFaceMap *fmap, int facenum);
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index 32e6ddf6f54..6513a55ec2b 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -66,7 +66,6 @@ void ED_region_do_listen(
void ED_region_do_draw(struct bContext *C, struct ARegion *ar);
void ED_region_exit(struct bContext *C, struct ARegion *ar);
void ED_region_pixelspace(struct ARegion *ar);
-void ED_region_set(const struct bContext *C, struct ARegion *ar);
void ED_region_update_rect(struct bContext *C, struct ARegion *ar);
void ED_region_init(struct bContext *C, struct ARegion *ar);
void ED_region_tag_redraw(struct ARegion *ar);
@@ -152,7 +151,7 @@ void ED_screen_update_after_scene_change(
const struct bScreen *screen,
struct Scene *scene_new,
struct ViewLayer *view_layer);
-void ED_screen_set_subwinactive(struct bContext *C, const struct wmEvent *event);
+void ED_screen_set_active_region(struct bContext *C, const struct wmEvent *event);
void ED_screen_exit(struct bContext *C, struct wmWindow *window, struct bScreen *screen);
void ED_screen_animation_timer(struct bContext *C, int redraws, int refresh, int sync, int enable);
void ED_screen_animation_timer_update(struct bScreen *screen, int redraws, int refresh);
@@ -164,6 +163,8 @@ struct ScrArea *ED_screen_state_toggle(struct bContext *C, struct wmWindow *win,
void ED_screens_header_tools_menu_create(struct bContext *C, struct uiLayout *layout, void *arg);
bool ED_screen_stereo3d_required(const struct bScreen *screen, const struct Scene *scene);
Scene *ED_screen_scene_find(const struct bScreen *screen, const struct wmWindowManager *wm);
+Scene *ED_screen_scene_find_with_window(const struct bScreen *screen, const struct wmWindowManager *wm, struct wmWindow **r_window);
+struct wmWindow *ED_screen_window_find(const struct bScreen *screen, const struct wmWindowManager *wm);
void ED_screen_preview_render(const struct bScreen *screen, int size_x, int size_y, unsigned int *r_rect) ATTR_NONNULL();
/* workspaces */
@@ -176,7 +177,7 @@ struct WorkSpace *ED_workspace_add(
bool ED_workspace_change(
struct WorkSpace *workspace_new,
struct bContext *C,
- struct wmWindowManager *wm, struct wmWindow *win) ATTR_NONNULL();
+ struct wmWindow *win) ATTR_NONNULL();
struct WorkSpace *ED_workspace_duplicate(
struct WorkSpace *workspace_old,
struct Main *bmain, struct wmWindow *win);
diff --git a/source/blender/editors/include/ED_uvedit.h b/source/blender/editors/include/ED_uvedit.h
index 96b4004b6a6..e25c34ddb78 100644
--- a/source/blender/editors/include/ED_uvedit.h
+++ b/source/blender/editors/include/ED_uvedit.h
@@ -62,7 +62,7 @@ void ED_object_assign_active_image(struct Main *bmain, struct Object *ob, int ma
bool ED_uvedit_test(struct Object *obedit);
/* visibility and selection */
-bool uvedit_face_visible_test(struct Scene *scene, struct Image *ima, struct BMFace *efa);
+bool uvedit_face_visible_test(struct Scene *scene, struct Object *obedit, struct Image *ima, struct BMFace *efa);
bool uvedit_face_select_test(struct Scene *scene, struct BMFace *efa,
const int cd_loop_uv_offset);
bool uvedit_edge_select_test(struct Scene *scene, struct BMLoop *l,
@@ -112,7 +112,10 @@ void ED_unwrap_lscm(struct Scene *scene, struct Object *obedit, const short sel)
/* uvedit_draw.c */
void ED_image_draw_cursor(struct ARegion *ar, const float cursor[2]);
-void ED_uvedit_draw_main(struct SpaceImage *sima, struct ARegion *ar, struct Scene *scene, struct ViewLayer *view_layer, struct Object *obedit, struct Object *obact, struct Depsgraph *depsgraph);
+void ED_uvedit_draw_main(
+ struct SpaceImage *sima, const struct EvaluationContext *eval_ctx,
+ struct ARegion *ar, struct Scene *scene, struct ViewLayer *view_layer,
+ struct Object *obedit, struct Object *obact, struct Depsgraph *depsgraph);
/* uvedit_buttons.c */
void ED_uvedit_buttons_register(struct ARegionType *art);
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index 7eee053061e..e3eb4c7ac97 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -476,7 +476,7 @@ void ED_view3d_operator_properties_viewmat_get(struct wmOperator *op, int *winx,
/* render */
void ED_view3d_stop_render_preview(struct wmWindowManager *wm, struct ARegion *ar);
-void ED_view3d_shade_update(struct Main *bmain, struct Scene *scene, struct View3D *v3d, struct ScrArea *sa);
+void ED_view3d_shade_update(struct Main *bmain, struct View3D *v3d, struct ScrArea *sa);
#define V3D_IS_ZBUF(v3d) \
(((v3d)->flag & V3D_ZBUF_SELECT) && ((v3d)->drawtype > OB_WIRE))
diff --git a/source/blender/editors/interface/CMakeLists.txt b/source/blender/editors/interface/CMakeLists.txt
index 94f377fb35e..c023816b52c 100644
--- a/source/blender/editors/interface/CMakeLists.txt
+++ b/source/blender/editors/interface/CMakeLists.txt
@@ -70,7 +70,9 @@ set(SRC
view2d.c
view2d_ops.c
+ interface_eyedropper_intern.h
interface_intern.h
+ interface_regions_intern.h
)
if(WITH_INTERNATIONAL)
@@ -81,6 +83,10 @@ if(WITH_HEADLESS)
add_definitions(-DWITH_HEADLESS)
endif()
+if(WITH_CYCLES)
+ add_definitions(-DWITH_CYCLES)
+endif()
+
if(WITH_PYTHON)
add_definitions(-DWITH_PYTHON)
endif()
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index a5ef2943387..bfaa986d1ca 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -69,7 +69,6 @@
#include "WM_api.h"
#include "WM_types.h"
-#include "wm_subwindow.h"
#include "WM_message.h"
#include "RNA_access.h"
@@ -1393,7 +1392,6 @@ void UI_block_draw(const bContext *C, uiBlock *block)
ARegion *ar;
uiBut *but;
rcti rect;
- int multisample_enabled;
/* get menu region or area region */
ar = CTX_wm_menu(C);
@@ -1403,13 +1401,8 @@ void UI_block_draw(const bContext *C, uiBlock *block)
if (!block->endblock)
UI_block_end(C, block);
- /* disable AA, makes widgets too blurry */
- multisample_enabled = glIsEnabled(GL_MULTISAMPLE);
- if (multisample_enabled)
- glDisable(GL_MULTISAMPLE);
-
/* we set this only once */
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
/* scale fonts */
ui_fontscale(&style.paneltitle.points, block->aspect);
@@ -1451,9 +1444,6 @@ void UI_block_draw(const bContext *C, uiBlock *block)
gpuPopProjectionMatrix();
gpuPopMatrix();
- if (multisample_enabled)
- glEnable(GL_MULTISAMPLE);
-
ui_draw_links(block);
}
@@ -2895,7 +2885,6 @@ uiBlock *UI_block_begin(const bContext *C, ARegion *region, const char *name, sh
uiBlock *block;
wmWindow *window;
Scene *scn;
- int getsizex, getsizey;
window = CTX_wm_window(C);
scn = CTX_data_scene(C);
@@ -2926,22 +2915,22 @@ uiBlock *UI_block_begin(const bContext *C, ARegion *region, const char *name, sh
UI_block_region_set(block, region);
/* window matrix and aspect */
- if (region && region->swinid) {
- wm_subwindow_matrix_get(window, region->swinid, block->winmat);
- wm_subwindow_size_get(window, region->swinid, &getsizex, &getsizey);
+ if (region && region->visible) {
+ gpuGetProjectionMatrix(block->winmat);
- block->aspect = 2.0f / fabsf(getsizex * block->winmat[0][0]);
+ block->aspect = 2.0f / fabsf(region->winx * block->winmat[0][0]);
}
else {
- const bScreen *screen = WM_window_get_active_screen(window);
-
/* no subwindow created yet, for menus for example, so we
* use the main window instead, since buttons are created
* there anyway */
- wm_subwindow_matrix_get(window, screen->mainwin, block->winmat);
- wm_subwindow_size_get(window, screen->mainwin, &getsizex, &getsizey);
+ int width = WM_window_pixels_x(window);
+ int height = WM_window_pixels_y(window);
+ rcti winrct = {0, width -1, 0, height - 1};
+
+ wmGetProjectionMatrix(block->winmat, &winrct);
- block->aspect = 2.0f / fabsf(getsizex * block->winmat[0][0]);
+ block->aspect = 2.0f / fabsf(width * block->winmat[0][0]);
block->auto_open = true;
block->flag |= UI_BLOCK_LOOP; /* tag as menu */
}
diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c
index 3ecb72353bc..5e5da60593c 100644
--- a/source/blender/editors/interface/interface_draw.c
+++ b/source/blender/editors/interface/interface_draw.c
@@ -615,7 +615,7 @@ static void draw_scope_end(const rctf *rect, GLint *scissor)
/* restore scissortest */
glScissor(scissor[0], scissor[1], scissor[2], scissor[3]);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
/* outline */
UI_draw_roundbox_corner_set(UI_CNR_ALL);
@@ -635,7 +635,7 @@ static void histogram_draw_one(
return;
glEnable(GL_LINE_SMOOTH);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_ONE, GL_ONE);
immUniformColor4fv(color);
@@ -665,7 +665,7 @@ static void histogram_draw_one(
/* curve outline */
immUniformColor4f(0.0f, 0.0f, 0.0f, 0.25f);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
immBegin(GWN_PRIM_LINE_STRIP, res);
for (int i = 0; i < res; i++) {
float x2 = x + i * (w / (float)res);
@@ -696,7 +696,7 @@ void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol)
float h = BLI_rctf_size_y(&rect) * hist->ymax;
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
float color[4];
UI_GetThemeColor4fv(TH_PREVIEW_BACK, color);
@@ -705,7 +705,7 @@ void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol)
/* need scissor test, histogram can draw outside of boundary */
GLint scissor[4];
- glGetIntegerv(GL_VIEWPORT, scissor);
+ glGetIntegerv(GL_SCISSOR_BOX, scissor);
glScissor(ar->winrct.xmin + (rect.xmin - 1),
ar->winrct.ymin + (rect.ymin - 1),
(rect.xmax + 1) - (rect.xmin - 1),
@@ -817,7 +817,7 @@ void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol),
}
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
float color[4];
UI_GetThemeColor4fv(TH_PREVIEW_BACK, color);
@@ -825,7 +825,7 @@ void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol),
UI_draw_roundbox_4fv(true, rect.xmin - 1, rect.ymin - 1, rect.xmax + 1, rect.ymax + 1, 3.0f, color);
/* need scissor test, waveform can draw outside of boundary */
- glGetIntegerv(GL_VIEWPORT, scissor);
+ glGetIntegerv(GL_SCISSOR_BOX, scissor);
glScissor(ar->winrct.xmin + (rect.xmin - 1),
ar->winrct.ymin + (rect.ymin - 1),
(rect.xmax + 1) - (rect.xmin - 1),
@@ -841,7 +841,7 @@ void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol),
}
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
Gwn_VertFormat *format = immVertexFormat();
unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
@@ -1085,7 +1085,7 @@ void ui_draw_but_VECTORSCOPE(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wco
float alpha = scopes->vecscope_alpha * scopes->vecscope_alpha * scopes->vecscope_alpha;
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
float color[4];
UI_GetThemeColor4fv(TH_PREVIEW_BACK, color);
@@ -1094,7 +1094,7 @@ void ui_draw_but_VECTORSCOPE(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wco
/* need scissor test, hvectorscope can draw outside of boundary */
GLint scissor[4];
- glGetIntegerv(GL_VIEWPORT, scissor);
+ glGetIntegerv(GL_SCISSOR_BOX, scissor);
glScissor(ar->winrct.xmin + (rect.xmin - 1),
ar->winrct.ymin + (rect.ymin - 1),
(rect.xmax + 1) - (rect.xmin - 1),
@@ -1520,7 +1520,7 @@ void ui_draw_but_CURVE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, const rcti
/* need scissor test, curve can draw outside of boundary */
GLint scissor[4];
- glGetIntegerv(GL_VIEWPORT, scissor);
+ glGetIntegerv(GL_SCISSOR_BOX, scissor);
rcti scissor_new = {
.xmin = ar->winrct.xmin + rect->xmin,
.ymin = ar->winrct.ymin + rect->ymin,
@@ -1564,7 +1564,7 @@ void ui_draw_but_CURVE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, const rcti
if (but->a1 == UI_GRAD_H) {
/* grid, hsv uses different grid */
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
immUniformColor4ub(0, 0, 0, 48);
ui_draw_but_curve_grid(pos, rect, zoomx, zoomy, offsx, offsy, 0.1666666f);
glDisable(GL_BLEND);
@@ -1738,11 +1738,11 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc
int height = BLI_rctf_size_y(&rect);
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
/* need scissor test, preview image can draw outside of boundary */
GLint scissor[4];
- glGetIntegerv(GL_VIEWPORT, scissor);
+ glGetIntegerv(GL_SCISSOR_BOX, scissor);
glScissor(ar->winrct.xmin + (rect.xmin - 1),
ar->winrct.ymin + (rect.ymin - 1),
(rect.xmax + 1) - (rect.xmin - 1),
@@ -1874,7 +1874,7 @@ void ui_draw_but_NODESOCKET(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol
GLint scissor[4];
/* need scissor test, can draw outside of boundary */
- glGetIntegerv(GL_VIEWPORT, scissor);
+ glGetIntegerv(GL_SCISSOR_BOX, scissor);
rcti scissor_new = {
.xmin = ar->winrct.xmin + recti->xmin,
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 9ccb47938d2..9e1697bc39a 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -46,6 +46,7 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
+#include "DNA_workspace_types.h"
#include "BLI_math.h"
#include "BLI_listbase.h"
@@ -73,6 +74,8 @@
#include "BKE_unit.h"
#include "BKE_paint.h"
+#include "DEG_depsgraph.h"
+
#include "ED_screen.h"
#include "ED_util.h"
#include "ED_keyframing.h"
@@ -185,6 +188,7 @@ typedef struct uiSelectContextStore {
uiSelectContextElem *elems;
int elems_len;
bool do_free;
+ bool is_enabled;
/* When set, simply copy values (don't apply difference).
* Rules are:
* - dragging numbers uses delta.
@@ -200,9 +204,7 @@ static void ui_selectcontext_apply(
bContext *C, uiBut *but, struct uiSelectContextStore *selctx_data,
const double value, const double value_orig);
-#if 0
#define IS_ALLSELECT_EVENT(event) ((event)->alt != 0)
-#endif
/** just show a tinted color so users know its activated */
#define UI_BUT_IS_SELECT_CONTEXT UI_BUT_NODE_ACTIVE
@@ -1194,11 +1196,14 @@ static void ui_multibut_states_apply(bContext *C, uiHandleButtonData *data, uiBl
ui_but_execute_begin(C, ar, but, &active_back);
#ifdef USE_ALLSELECT
- if (mbut_state->select_others.elems_len == 0) {
- ui_selectcontext_begin(C, but, &mbut_state->select_others);
- }
- if (mbut_state->select_others.elems_len == 0) {
- mbut_state->select_others.elems_len = -1;
+ if (data->select_others.is_enabled) {
+ /* init once! */
+ if (mbut_state->select_others.elems_len == 0) {
+ ui_selectcontext_begin(C, but, &mbut_state->select_others);
+ }
+ if (mbut_state->select_others.elems_len == 0) {
+ mbut_state->select_others.elems_len = -1;
+ }
}
/* needed so we apply the right deltas */
@@ -2081,7 +2086,12 @@ static void ui_apply_but(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
else
# endif
if (data->select_others.elems_len == 0) {
- ui_selectcontext_begin(C, but, &data->select_others);
+ wmWindow *win = CTX_wm_window(C);
+ /* may have been enabled before activating */
+ if (data->select_others.is_enabled || IS_ALLSELECT_EVENT(win->eventstate)) {
+ ui_selectcontext_begin(C, but, &data->select_others);
+ data->select_others.is_enabled = true;
+ }
}
if (data->select_others.elems_len == 0) {
/* dont check again */
@@ -3086,7 +3096,11 @@ static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data)
#ifdef USE_ALLSELECT
if (is_num_but) {
- data->select_others.is_copy = true;
+ if (IS_ALLSELECT_EVENT(win->eventstate)) {
+ data->select_others.is_enabled = true;
+ data->select_others.is_copy = true;
+
+ }
}
#endif
@@ -3691,6 +3705,15 @@ static void ui_block_open_begin(bContext *C, uiBut *but, uiHandleButtonData *dat
data->menu->popup = but->block->handle->popup;
}
+#ifdef USE_ALLSELECT
+ {
+ wmWindow *win = CTX_wm_window(C);
+ if (IS_ALLSELECT_EVENT(win->eventstate)) {
+ data->select_others.is_enabled = true;
+ }
+ }
+#endif
+
/* this makes adjacent blocks auto open from now on */
//if (but->block->auto_open == 0) but->block->auto_open = 1;
}
@@ -5252,9 +5275,10 @@ static int ui_do_but_COLOR(
if ((int)(but->a1) == UI_PALETTE_COLOR) {
if (!event->ctrl) {
float color[3];
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
- Paint *paint = BKE_paint_get_active(scene, view_layer);
+ Paint *paint = BKE_paint_get_active(scene, view_layer, workspace->object_mode);
Brush *brush = BKE_paint_brush(paint);
if (brush->flag & BRUSH_USE_GRADIENT) {
@@ -6170,6 +6194,7 @@ static int ui_do_but_CURVE(
{
int mx, my, a;
bool changed = false;
+
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
@@ -6286,6 +6311,7 @@ static int ui_do_but_CURVE(
}
else if (event->type == LEFTMOUSE && event->val != KM_PRESS) {
if (data->dragsel != -1) {
+ const WorkSpace *workspace = CTX_wm_workspace(C);
CurveMapping *cumap = (CurveMapping *)but->poin;
CurveMap *cuma = cumap->cm + cumap->cur;
CurveMapPoint *cmp = cuma->curve;
@@ -6300,7 +6326,7 @@ static int ui_do_but_CURVE(
}
else {
curvemapping_changed(cumap, true); /* remove doubles */
- BKE_paint_invalidate_cursor_overlay(scene, view_layer, cumap);
+ BKE_paint_invalidate_cursor_overlay(scene, view_layer, cumap, workspace->object_mode);
}
}
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index d048324d35e..0a36fbafc39 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -46,6 +46,7 @@
#include "DNA_object_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
+#include "DNA_workspace_types.h"
#include "RNA_access.h"
#include "RNA_enum_types.h"
@@ -61,6 +62,8 @@
#include "BIF_glutil.h"
+#include "DEG_depsgraph.h"
+
#include "ED_datafiles.h"
#include "ED_keyframes_draw.h"
#include "ED_render.h"
@@ -1112,7 +1115,7 @@ static void icon_draw_size(
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_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, alpha, rgb);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
}
else if (di->type == ICON_TYPE_BUFFER) {
/* it is a builtin icon */
@@ -1122,9 +1125,9 @@ static void icon_draw_size(
#endif
if (!iimg->rect) return; /* something has gone wrong! */
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
icon_draw_rect(x, y, w, h, aspect, iimg->w, iimg->h, iimg->rect, alpha, rgb, is_preview);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
}
else if (di->type == ICON_TYPE_PREVIEW) {
PreviewImage *pi = (icon->type != 0) ? BKE_previewimg_id_ensure((ID *)icon->obj) : icon->obj;
@@ -1137,7 +1140,7 @@ static void icon_draw_size(
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
icon_draw_rect(x, y, w, h, aspect, pi->w[size], pi->h[size], pi->rect[size], alpha, rgb, is_preview);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
}
}
}
@@ -1193,6 +1196,7 @@ static int ui_id_brush_get_icon(const bContext *C, ID *id)
ui_id_icon_render(C, id, true);
}
else {
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Object *ob = CTX_data_active_object(C);
SpaceImage *sima;
const EnumPropertyItem *items = NULL;
@@ -1203,11 +1207,11 @@ static int ui_id_brush_get_icon(const bContext *C, ID *id)
* checking various context stuff here */
if (CTX_wm_view3d(C) && ob) {
- if (ob->mode & OB_MODE_SCULPT)
+ if (workspace->object_mode & OB_MODE_SCULPT)
mode = OB_MODE_SCULPT;
- else if (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT))
+ else if (workspace->object_mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT))
mode = OB_MODE_VERTEX_PAINT;
- else if (ob->mode & OB_MODE_TEXTURE_PAINT)
+ else if (workspace->object_mode & OB_MODE_TEXTURE_PAINT)
mode = OB_MODE_TEXTURE_PAINT;
}
else if ((sima = CTX_wm_space_image(C)) &&
diff --git a/source/blender/editors/interface/interface_region_popup.c b/source/blender/editors/interface/interface_region_popup.c
index 24990c593ac..c3d6d635c17 100644
--- a/source/blender/editors/interface/interface_region_popup.c
+++ b/source/blender/editors/interface/interface_region_popup.c
@@ -48,7 +48,6 @@
#include "WM_api.h"
#include "WM_types.h"
-#include "wm_subwindow.h"
#include "UI_interface.h"
@@ -589,9 +588,7 @@ uiBlock *ui_popup_block_refresh(
ED_region_init(C, ar);
/* get winmat now that we actually have the subwindow */
- wmSubWindowSet(window, ar->swinid);
-
- wm_subwindow_matrix_get(window, ar->swinid, block->winmat);
+ wmGetProjectionMatrix(block->winmat, &ar->winrct);
/* notify change and redraw */
ED_region_tag_redraw(ar);
diff --git a/source/blender/editors/interface/interface_region_tooltip.c b/source/blender/editors/interface/interface_region_tooltip.c
index 07fbefa42e1..449e783b03e 100644
--- a/source/blender/editors/interface/interface_region_tooltip.c
+++ b/source/blender/editors/interface/interface_region_tooltip.c
@@ -175,12 +175,7 @@ static void ui_tooltip_region_draw_cb(const bContext *UNUSED(C), ARegion *ar)
float background_color[3];
float tone_bg;
- int i, multisample_enabled;
-
- /* disable AA, makes widgets too blurry */
- multisample_enabled = glIsEnabled(GL_MULTISAMPLE);
- if (multisample_enabled)
- glDisable(GL_MULTISAMPLE);
+ int i;
wmOrtho2_region_pixelspace(ar);
@@ -285,9 +280,6 @@ static void ui_tooltip_region_draw_cb(const bContext *UNUSED(C), ARegion *ar)
BLF_disable(data->fstyle.uifont_id, BLF_WORD_WRAP);
BLF_disable(blf_mono_font, BLF_WORD_WRAP);
-
- if (multisample_enabled)
- glEnable(GL_MULTISAMPLE);
}
static void ui_tooltip_region_free_cb(ARegion *ar)
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index ce2d3bebb97..af7065a81ba 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -36,7 +36,7 @@
#include "DNA_node_types.h"
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
-#include "DNA_object_force.h"
+#include "DNA_object_force_types.h"
#include "DNA_brush_types.h"
#include "DNA_texture_types.h"
@@ -638,6 +638,9 @@ static void template_ID(
bContext *C, uiLayout *layout, TemplateID *template_ui, StructRNA *type, int flag,
const char *newop, const char *openop, const char *unlinkop)
{
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
+
uiBut *but;
uiBlock *block;
PointerRNA idptr;
@@ -722,7 +725,7 @@ static void template_ID(
(idfrom && idfrom->lib) ||
(!editable) ||
/* object in editmode - don't change data */
- (idfrom && GS(idfrom->name) == ID_OB && (((Object *)idfrom)->mode & OB_MODE_EDIT)))
+ (idfrom && GS(idfrom->name) == ID_OB && (eval_ctx.object_mode & OB_MODE_EDIT)))
{
UI_but_flag_enable(but, UI_BUT_DISABLED);
}
@@ -1306,7 +1309,8 @@ static int modifier_is_simulation(ModifierData *md)
}
static uiLayout *draw_modifier(
- uiLayout *layout, Scene *scene, Object *ob,
+ uiLayout *layout,
+ const EvaluationContext *eval_ctx, Scene *scene, Object *ob,
ModifierData *md, int index, int cageIndex, int lastCageIndex)
{
const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
@@ -1443,7 +1447,7 @@ static uiLayout *draw_modifier(
if (md->type == eModifierType_ParticleSystem) {
ParticleSystem *psys = ((ParticleSystemModifierData *)md)->psys;
- if (!(ob->mode & OB_MODE_PARTICLE_EDIT)) {
+ if (!(eval_ctx->object_mode & OB_MODE_PARTICLE_EDIT)) {
if (ELEM(psys->part->ren_as, PART_DRAW_GR, PART_DRAW_OB))
uiItemO(row, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Convert"), ICON_NONE,
"OBJECT_OT_duplicates_make_real");
@@ -1492,6 +1496,8 @@ static uiLayout *draw_modifier(
uiLayout *uiTemplateModifier(uiLayout *layout, bContext *C, PointerRNA *ptr)
{
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
Scene *scene = CTX_data_scene(C);
Object *ob;
ModifierData *md, *vmd;
@@ -1522,7 +1528,7 @@ uiLayout *uiTemplateModifier(uiLayout *layout, bContext *C, PointerRNA *ptr)
for (i = 0; vmd; i++, vmd = vmd->next) {
if (md == vmd)
- return draw_modifier(layout, scene, ob, md, i, cageIndex, lastCageIndex);
+ return draw_modifier(layout, &eval_ctx, scene, ob, md, i, cageIndex, lastCageIndex);
else if (vmd->mode & eModifierMode_Virtual)
i--;
}
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index a9c3f973569..2c509a949b5 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -729,7 +729,7 @@ static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol)
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor4ubv((unsigned char *)wcol->inner);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
for (a = 0; a < wtb->totvert; a++) {
x_mid += wtb->inner_v[a][0];
diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c
index ac5fb3e40cb..74332be0996 100644
--- a/source/blender/editors/interface/resources.c
+++ b/source/blender/editors/interface/resources.c
@@ -45,6 +45,7 @@
#include "BLI_utildefines.h"
#include "BLI_math.h"
+#include "BKE_addon.h"
#include "BKE_appdir.h"
#include "BKE_colorband.h"
#include "BKE_DerivedMesh.h"
@@ -2318,13 +2319,9 @@ void init_userdef_do_versions(void)
if (btheme->tipo.handle_sel_auto_clamped[3] == 0)
rgba_char_args_set(btheme->tipo.handle_sel_auto_clamped, 0xf0, 0xaf, 0x90, 255);
}
-
+
/* enable (Cycles) addon by default */
- if (!BLI_findstring(&U.addons, "cycles", offsetof(bAddon, module))) {
- bAddon *baddon = MEM_callocN(sizeof(bAddon), "bAddon");
- BLI_strncpy(baddon->module, "cycles", sizeof(baddon->module));
- BLI_addtail(&U.addons, baddon);
- }
+ BKE_addon_ensure(&U.addons, "cycles");
}
if (!USER_VERSION_ATLEAST(260, 5)) {
@@ -2992,6 +2989,15 @@ void init_userdef_do_versions(void)
// we default to the first audio device
U.audiodevice = 0;
+ /* Not versioning, just avoid errors. */
+#ifndef WITH_CYCLES
+ bAddon *addon = BLI_findstring(&U.addons, "cycles", offsetof(bAddon, module));
+ if (addon) {
+ BLI_remlink(&U.addons, addon);
+ BKE_addon_free(addon);
+ }
+#endif
+
/* funny name, but it is GE stuff, moves userdef stuff to engine */
// XXX space_set_commmandline_options();
/* this timer uses U */
diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c
index a94ef0d1d5b..d31f2dec145 100644
--- a/source/blender/editors/interface/view2d.c
+++ b/source/blender/editors/interface/view2d.c
@@ -1027,6 +1027,13 @@ bool UI_view2d_tab_set(View2D *v2d, int tab)
void UI_view2d_zoom_cache_reset(void)
{
+ /* TODO(sergey): This way we avoid threading conflict with VSE rendering
+ * text strip. But ideally we want to make glyph cache to be fully safe
+ * for threading.
+ */
+ if (G.is_rendering) {
+ return;
+ }
/* While scaling we can accumulate fonts at many sizes (~20 or so).
* Not an issue with embedded font, but can use over 500Mb with i18n ones! See [#38244]. */
diff --git a/source/blender/editors/manipulator_library/manipulator_types/cage2d_manipulator.c b/source/blender/editors/manipulator_library/manipulator_types/cage2d_manipulator.c
index 0299a33d0fe..23c6030f091 100644
--- a/source/blender/editors/manipulator_library/manipulator_types/cage2d_manipulator.c
+++ b/source/blender/editors/manipulator_library/manipulator_types/cage2d_manipulator.c
@@ -37,7 +37,7 @@
#include "MEM_guardedalloc.h"
#include "BLI_math.h"
-#include "BLI_dial.h"
+#include "BLI_dial_2d.h"
#include "BLI_rect.h"
#include "BKE_context.h"
diff --git a/source/blender/editors/manipulator_library/manipulator_types/cage3d_manipulator.c b/source/blender/editors/manipulator_library/manipulator_types/cage3d_manipulator.c
index d58cdb4b187..67fb2419931 100644
--- a/source/blender/editors/manipulator_library/manipulator_types/cage3d_manipulator.c
+++ b/source/blender/editors/manipulator_library/manipulator_types/cage3d_manipulator.c
@@ -37,7 +37,7 @@
#include "MEM_guardedalloc.h"
#include "BLI_math.h"
-#include "BLI_dial.h"
+#include "BLI_dial_2d.h"
#include "BLI_rect.h"
#include "BKE_context.h"
diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c
index c60b673ec69..689a96a3dec 100644
--- a/source/blender/editors/mask/mask_draw.c
+++ b/source/blender/editors/mask/mask_draw.c
@@ -555,7 +555,7 @@ static void draw_masklays(const bContext *C, Mask *mask, const char draw_flag, c
const int width, const int height)
{
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
GPU_enable_program_point_size();
MaskLayer *masklay;
diff --git a/source/blender/editors/mask/mask_select.c b/source/blender/editors/mask/mask_select.c
index 9f2f6de8a09..7ffd82e262c 100644
--- a/source/blender/editors/mask/mask_select.c
+++ b/source/blender/editors/mask/mask_select.c
@@ -33,7 +33,7 @@
#include "BLI_utildefines.h"
#include "BLI_rect.h"
-#include "BLI_lasso.h"
+#include "BLI_lasso_2d.h"
#include "BLI_math.h"
#include "BKE_context.h"
diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c
index 992d0fada5e..113173c1c03 100644
--- a/source/blender/editors/mesh/editface.c
+++ b/source/blender/editors/mesh/editface.c
@@ -635,8 +635,9 @@ static int mirrtopo_vert_sort(const void *v1, const void *v2)
return 0;
}
-bool ED_mesh_mirrtopo_recalc_check(Mesh *me, DerivedMesh *dm, const int ob_mode, MirrTopoStore_t *mesh_topo_store)
+bool ED_mesh_mirrtopo_recalc_check(Mesh *me, DerivedMesh *dm, MirrTopoStore_t *mesh_topo_store)
{
+ const bool is_editmode = (me->edit_btmesh != NULL);
int totvert;
int totedge;
@@ -654,7 +655,7 @@ bool ED_mesh_mirrtopo_recalc_check(Mesh *me, DerivedMesh *dm, const int ob_mode,
}
if ((mesh_topo_store->index_lookup == NULL) ||
- (mesh_topo_store->prev_ob_mode != ob_mode) ||
+ (mesh_topo_store->prev_is_editmode != is_editmode) ||
(totvert != mesh_topo_store->prev_vert_tot) ||
(totedge != mesh_topo_store->prev_edge_tot))
{
@@ -666,9 +667,11 @@ bool ED_mesh_mirrtopo_recalc_check(Mesh *me, DerivedMesh *dm, const int ob_mode,
}
-void ED_mesh_mirrtopo_init(Mesh *me, DerivedMesh *dm, const int ob_mode, MirrTopoStore_t *mesh_topo_store,
- const bool skip_em_vert_array_init)
+void ED_mesh_mirrtopo_init(
+ Mesh *me, DerivedMesh *dm, MirrTopoStore_t *mesh_topo_store,
+ const bool skip_em_vert_array_init)
{
+ const bool is_editmode = (me->edit_btmesh != NULL);
MEdge *medge = NULL, *med;
BMEditMesh *em = dm ? NULL : me->edit_btmesh;
@@ -691,7 +694,7 @@ void ED_mesh_mirrtopo_init(Mesh *me, DerivedMesh *dm, const int ob_mode, MirrTop
/* reallocate if needed */
ED_mesh_mirrtopo_free(mesh_topo_store);
- mesh_topo_store->prev_ob_mode = ob_mode;
+ mesh_topo_store->prev_is_editmode = is_editmode;
if (em) {
BM_mesh_elem_index_ensure(em->bm, BM_VERT);
diff --git a/source/blender/editors/mesh/editmesh_intersect.c b/source/blender/editors/mesh/editmesh_intersect.c
index 3498c6246d7..d681d904e74 100644
--- a/source/blender/editors/mesh/editmesh_intersect.c
+++ b/source/blender/editors/mesh/editmesh_intersect.c
@@ -400,7 +400,7 @@ static void bm_face_split_by_edges(
bm, f, edge_net_temp_buf->data, edge_net_temp_buf->count,
&face_arr, &face_arr_len);
- BLI_buffer_empty(edge_net_temp_buf);
+ BLI_buffer_clear(edge_net_temp_buf);
if (face_arr_len) {
int i;
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index 5d5e54edf56..d9bbec7082d 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -1116,7 +1116,7 @@ static void knifetool_draw(const bContext *C, ARegion *UNUSED(ar), void *arg)
int i;
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
/* draw any snapped verts first */
immUniformColor4ubv(kcd->colors.point_a);
@@ -1158,7 +1158,7 @@ static void knifetool_draw(const bContext *C, ARegion *UNUSED(ar), void *arg)
immUniformColor3ubv(kcd->colors.line);
glLineWidth(1.0);
- immBeginAtMost(GWN_PRIM_LINES, BLI_mempool_count(kcd->kedges) * 2);
+ immBeginAtMost(GWN_PRIM_LINES, BLI_mempool_len(kcd->kedges) * 2);
BLI_mempool_iternew(kcd->kedges, &iter);
for (kfe = BLI_mempool_iterstep(&iter); kfe; kfe = BLI_mempool_iterstep(&iter)) {
@@ -1179,7 +1179,7 @@ static void knifetool_draw(const bContext *C, ARegion *UNUSED(ar), void *arg)
immUniformColor3ubv(kcd->colors.point);
glPointSize(5.0);
- immBeginAtMost(GWN_PRIM_POINTS, BLI_mempool_count(kcd->kverts));
+ immBeginAtMost(GWN_PRIM_POINTS, BLI_mempool_len(kcd->kverts));
BLI_mempool_iternew(kcd->kverts, &iter);
for (kfv = BLI_mempool_iterstep(&iter); kfv; kfv = BLI_mempool_iterstep(&iter)) {
@@ -2300,7 +2300,7 @@ static void knife_make_face_cuts(KnifeTool_OpData *kcd, BMFace *f, ListBase *kfe
/* point to knife edges we've created edges in, edge_array aligned */
KnifeEdge **kfe_array = BLI_array_alloca(kfe_array, edge_array_len);
- BLI_assert(BLI_gset_size(kcd->edgenet.edge_visit) == 0);
+ BLI_assert(BLI_gset_len(kcd->edgenet.edge_visit) == 0);
i = 0;
for (ref = kfedges->first; ref; ref = ref->next) {
diff --git a/source/blender/editors/mesh/editmesh_path.c b/source/blender/editors/mesh/editmesh_path.c
index b71dd029bf2..795c7b6aa53 100644
--- a/source/blender/editors/mesh/editmesh_path.c
+++ b/source/blender/editors/mesh/editmesh_path.c
@@ -121,10 +121,9 @@ static void verttag_set_cb(BMVert *v, bool val, void *user_data_v)
}
static void mouse_mesh_shortest_path_vert(
- Scene *scene, const struct PathSelectParams *op_params,
+ Scene *UNUSED(scene), Object *obedit, const struct PathSelectParams *op_params,
BMVert *v_act, BMVert *v_dst)
{
- Object *obedit = scene->obedit;
BMEditMesh *em = BKE_editmesh_from_object(obedit);
BMesh *bm = em->bm;
@@ -280,11 +279,11 @@ static void edgetag_set_cb(BMEdge *e, bool val, void *user_data_v)
}
}
-static void edgetag_ensure_cd_flag(Scene *scene, Mesh *me)
+static void edgetag_ensure_cd_flag(Mesh *me, const char edge_mode)
{
BMesh *bm = me->edit_btmesh->bm;
- switch (scene->toolsettings->edge_mode) {
+ switch (edge_mode) {
case EDGE_MODE_TAG_CREASE:
BM_mesh_cd_flag_ensure(bm, me, ME_CDFLAG_EDGE_CREASE);
break;
@@ -307,10 +306,9 @@ static void edgetag_ensure_cd_flag(Scene *scene, Mesh *me)
/* since you want to create paths with multiple selects, it doesn't have extend option */
static void mouse_mesh_shortest_path_edge(
- Scene *scene, const struct PathSelectParams *op_params,
+ Scene *scene, Object *obedit, const struct PathSelectParams *op_params,
BMEdge *e_act, BMEdge *e_dst)
{
- Object *obedit = scene->obedit;
BMEditMesh *em = BKE_editmesh_from_object(obedit);
BMesh *bm = em->bm;
@@ -319,7 +317,7 @@ static void mouse_mesh_shortest_path_edge(
Mesh *me = obedit->data;
bool is_path_ordered = false;
- edgetag_ensure_cd_flag(scene, obedit->data);
+ edgetag_ensure_cd_flag(obedit->data, op_params->edge_mode);
if (e_act && (e_act != e_dst)) {
if (op_params->use_fill) {
@@ -377,7 +375,7 @@ static void mouse_mesh_shortest_path_edge(
}
else {
const bool is_act = !edgetag_test_cb(e_dst, &user_data);
- edgetag_ensure_cd_flag(scene, obedit->data);
+ edgetag_ensure_cd_flag(obedit->data, op_params->edge_mode);
edgetag_set_cb(e_dst, is_act, &user_data); /* switch the edge option */
}
@@ -452,10 +450,9 @@ static void facetag_set_cb(BMFace *f, bool val, void *user_data_v)
}
static void mouse_mesh_shortest_path_face(
- Scene *scene, const struct PathSelectParams *op_params,
+ Scene *UNUSED(scene), Object *obedit, const struct PathSelectParams *op_params,
BMFace *f_act, BMFace *f_dst)
{
- Object *obedit = scene->obedit;
BMEditMesh *em = BKE_editmesh_from_object(obedit);
BMesh *bm = em->bm;
@@ -547,7 +544,7 @@ static void mouse_mesh_shortest_path_face(
/* Main Operator for vert/edge/face tag */
static bool edbm_shortest_path_pick_ex(
- Scene *scene, const struct PathSelectParams *op_params,
+ Scene *scene, Object *obedit, const struct PathSelectParams *op_params,
BMElem *ele_src, BMElem *ele_dst)
{
@@ -555,15 +552,15 @@ static bool edbm_shortest_path_pick_ex(
/* pass */
}
else if (ele_src->head.htype == BM_VERT) {
- mouse_mesh_shortest_path_vert(scene, op_params, (BMVert *)ele_src, (BMVert *)ele_dst);
+ mouse_mesh_shortest_path_vert(scene, obedit, op_params, (BMVert *)ele_src, (BMVert *)ele_dst);
return true;
}
else if (ele_src->head.htype == BM_EDGE) {
- mouse_mesh_shortest_path_edge(scene, op_params, (BMEdge *)ele_src, (BMEdge *)ele_dst);
+ mouse_mesh_shortest_path_edge(scene, obedit, op_params, (BMEdge *)ele_src, (BMEdge *)ele_dst);
return true;
}
else if (ele_src->head.htype == BM_FACE) {
- mouse_mesh_shortest_path_face(scene, op_params, (BMFace *)ele_src, (BMFace *)ele_dst);
+ mouse_mesh_shortest_path_face(scene, obedit, op_params, (BMFace *)ele_src, (BMFace *)ele_dst);
return true;
}
@@ -644,7 +641,7 @@ static int edbm_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmE
op_params.track_active = track_active;
op_params.edge_mode = vc.scene->toolsettings->edge_mode;
- if (!edbm_shortest_path_pick_ex(vc.scene, &op_params, ele_src, ele_dst)) {
+ if (!edbm_shortest_path_pick_ex(vc.scene, vc.obedit, &op_params, ele_src, ele_dst)) {
return OPERATOR_PASS_THROUGH;
}
@@ -681,7 +678,7 @@ static int edbm_shortest_path_pick_exec(bContext *C, wmOperator *op)
op_params.track_active = true;
op_params.edge_mode = scene->toolsettings->edge_mode;
- if (!edbm_shortest_path_pick_ex(scene, &op_params, ele_src, ele_dst)) {
+ if (!edbm_shortest_path_pick_ex(scene, obedit, &op_params, ele_src, ele_dst)) {
return OPERATOR_CANCELLED;
}
@@ -720,8 +717,8 @@ void MESH_OT_shortest_path_pick(wmOperatorType *ot)
static int edbm_shortest_path_select_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
- Object *ob = CTX_data_edit_object(C);
- BMEditMesh *em = BKE_editmesh_from_object(ob);
+ Object *obedit = CTX_data_edit_object(C);
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
BMesh *bm = em->bm;
BMIter iter;
BMEditSelection *ese_src, *ese_dst;
@@ -773,7 +770,7 @@ static int edbm_shortest_path_select_exec(bContext *C, wmOperator *op)
struct PathSelectParams op_params;
path_select_params_from_op(op, &op_params);
- edbm_shortest_path_pick_ex(scene, &op_params, ele_src, ele_dst);
+ edbm_shortest_path_pick_ex(scene, obedit, &op_params, ele_src, ele_dst);
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c
index 3e0afd3095e..7b88b091672 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.c
@@ -280,7 +280,7 @@ bool EDBM_backbuf_border_mask_init(const struct EvaluationContext *eval_ctx, Vie
/* method in use for face selecting too */
if (vc->obedit == NULL) {
- if (!BKE_paint_select_elem_test(vc->obact)) {
+ if (!BKE_paint_select_elem_test(vc->obact, eval_ctx->object_mode)) {
return false;
}
}
@@ -332,7 +332,7 @@ bool EDBM_backbuf_circle_init(
/* method in use for face selecting too */
if (vc->obedit == NULL) {
- if (!BKE_paint_select_elem_test(vc->obact)) {
+ if (!BKE_paint_select_elem_test(vc->obact, eval_ctx->object_mode)) {
return false;
}
}
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index 75a13a916e6..b2371ef1ad3 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -3374,7 +3374,11 @@ static int edbm_separate_exec(bContext *C, wmOperator *op)
}
if (retval_iter) {
- BM_mesh_bm_to_me(bm_old, me, (&(struct BMeshToMeshParams){0}));
+ BM_mesh_bm_to_me(
+ bm_old, me,
+ (&(struct BMeshToMeshParams){
+ .calc_object_remap = true,
+ }));
DEG_id_tag_update(&me->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, me);
diff --git a/source/blender/editors/mesh/editmesh_undo.c b/source/blender/editors/mesh/editmesh_undo.c
index 534ca22178e..11667ed5710 100644
--- a/source/blender/editors/mesh/editmesh_undo.c
+++ b/source/blender/editors/mesh/editmesh_undo.c
@@ -496,6 +496,8 @@ static void *editbtMesh_to_undoMesh(void *emv, void *obdata)
BM_mesh_bm_to_me(
em->bm, &um->me, (&(struct BMeshToMeshParams){
+ /* Undo code should not be manipulating 'G.main->object' hooks/vertex-parent. */
+ .calc_object_remap = false,
.cd_mask_extra = CD_MASK_SHAPE_KEYINDEX,
}));
diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c
index a52f12ec055..7b727e75b55 100644
--- a/source/blender/editors/mesh/editmesh_utils.c
+++ b/source/blender/editors/mesh/editmesh_utils.c
@@ -381,7 +381,10 @@ void EDBM_mesh_load(Object *ob)
bm->shapenr = 1;
}
- BM_mesh_bm_to_me(bm, me, (&(struct BMeshToMeshParams){0}));
+ BM_mesh_bm_to_me(
+ bm, me, (&(struct BMeshToMeshParams){
+ .calc_object_remap = true,
+ }));
#ifdef USE_TESSFACE_DEFAULT
BKE_mesh_tessface_calc(me);
@@ -1013,7 +1016,7 @@ void EDBM_verts_mirror_cache_begin_ex(BMEditMesh *em, const int axis, const bool
BM_mesh_elem_index_ensure(bm, BM_VERT);
if (use_topology) {
- ED_mesh_mirrtopo_init(me, NULL, -1, &mesh_topo_store, true);
+ ED_mesh_mirrtopo_init(me, NULL, &mesh_topo_store, true);
}
else {
tree = BLI_kdtree_new(bm->totvert);
diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c
index 218b97d3ede..bd3d2f652c0 100644
--- a/source/blender/editors/mesh/mesh_data.c
+++ b/source/blender/editors/mesh/mesh_data.c
@@ -506,13 +506,14 @@ static int layers_poll(bContext *C)
static int mesh_uv_texture_add_exec(bContext *C, wmOperator *UNUSED(op))
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Object *ob = ED_object_context(C);
Mesh *me = ob->data;
if (ED_mesh_uv_texture_add(me, NULL, true) == -1)
return OPERATOR_CANCELLED;
- if (ob->mode & OB_MODE_TEXTURE_PAINT) {
+ if (workspace->object_mode & OB_MODE_TEXTURE_PAINT) {
Scene *scene = CTX_data_scene(C);
BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL);
@@ -622,13 +623,14 @@ void MESH_OT_drop_named_image(wmOperatorType *ot)
static int mesh_uv_texture_remove_exec(bContext *C, wmOperator *UNUSED(op))
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Object *ob = ED_object_context(C);
Mesh *me = ob->data;
if (!ED_mesh_uv_texture_remove_active(me))
return OPERATOR_CANCELLED;
- if (ob->mode & OB_MODE_TEXTURE_PAINT) {
+ if (workspace->object_mode & OB_MODE_TEXTURE_PAINT) {
Scene *scene = CTX_data_scene(C);
BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL);
@@ -742,13 +744,14 @@ static int mesh_customdata_mask_clear_poll(bContext *C)
{
Object *ob = ED_object_context(C);
if (ob && ob->type == OB_MESH) {
- Mesh *me = ob->data;
+ const WorkSpace *workspace = CTX_wm_workspace(C);
/* special case - can't run this if we're in sculpt mode */
- if (ob->mode & OB_MODE_SCULPT) {
+ if (workspace->object_mode & OB_MODE_SCULPT) {
return false;
}
+ Mesh *me = ob->data;
if (!ID_IS_LINKED(me)) {
CustomData *data = GET_CD_DATA(me, vdata);
if (CustomData_has_layer(data, CD_PAINT_MASK)) {
diff --git a/source/blender/editors/mesh/mesh_navmesh.c b/source/blender/editors/mesh/mesh_navmesh.c
index bd2ad21d51c..aaa06951ec6 100644
--- a/source/blender/editors/mesh/mesh_navmesh.c
+++ b/source/blender/editors/mesh/mesh_navmesh.c
@@ -662,8 +662,10 @@ void MESH_OT_navmesh_face_add(struct wmOperatorType *ot)
static int navmesh_obmode_data_poll(bContext *C)
{
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
Object *ob = ED_object_active_context(C);
- if (ob && (ob->mode == OB_MODE_OBJECT) && (ob->type == OB_MESH)) {
+ if (ob && (eval_ctx.object_mode == OB_MODE_OBJECT) && (ob->type == OB_MESH)) {
Mesh *me = ob->data;
return CustomData_has_layer(&me->pdata, CD_RECAST);
}
@@ -672,8 +674,10 @@ static int navmesh_obmode_data_poll(bContext *C)
static int navmesh_obmode_poll(bContext *C)
{
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
Object *ob = ED_object_active_context(C);
- if (ob && (ob->mode == OB_MODE_OBJECT) && (ob->type == OB_MESH)) {
+ if (ob && (eval_ctx.object_mode == OB_MODE_OBJECT) && (ob->type == OB_MESH)) {
return true;
}
return false;
diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c
index dd1fbc36d8a..64b6f5b8010 100644
--- a/source/blender/editors/mesh/meshtools.c
+++ b/source/blender/editors/mesh/meshtools.c
@@ -42,6 +42,7 @@
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_view3d_types.h"
+#include "DNA_workspace_types.h"
#include "BLI_math.h"
#include "BLI_blenlib.h"
@@ -222,9 +223,10 @@ static void join_mesh_single(
multiresModifier_prepare_join(&eval_ctx, scene, ob_src, ob_dst);
if ((mmd = get_multires_modifier(scene, ob_src, true))) {
- ED_object_iter_other(bmain, ob_src, true,
- ED_object_multires_update_totlevels_cb,
- &mmd->totlvl);
+ ED_object_iter_other(
+ &eval_ctx, bmain, ob_src, true,
+ ED_object_multires_update_totlevels_cb,
+ &mmd->totlvl);
}
}
@@ -274,6 +276,7 @@ static void join_mesh_single(
int join_mesh_exec(bContext *C, wmOperator *op)
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
Object *ob = CTX_data_active_object(C);
@@ -293,7 +296,7 @@ int join_mesh_exec(bContext *C, wmOperator *op)
bDeformGroup *dg, *odg;
CustomData vdata, edata, fdata, ldata, pdata;
- if (scene->obedit) {
+ if (workspace->object_mode & OB_MODE_EDIT) {
BKE_report(op->reports, RPT_WARNING, "Cannot join while in edit mode");
return OPERATOR_CANCELLED;
}
@@ -777,15 +780,16 @@ static MirrTopoStore_t mesh_topo_store = {NULL, -1. - 1, -1};
/* mode is 's' start, or 'e' end, or 'u' use */
/* if end, ob can be NULL */
/* note, is supposed return -1 on error, which callers are currently checking for, but is not used so far */
-int ED_mesh_mirror_topo_table(Object *ob, DerivedMesh *dm, char mode)
+int ED_mesh_mirror_topo_table(
+ Object *ob, DerivedMesh *dm, char mode)
{
if (mode == 'u') { /* use table */
- if (ED_mesh_mirrtopo_recalc_check(ob->data, dm, ob->mode, &mesh_topo_store)) {
+ if (ED_mesh_mirrtopo_recalc_check(ob->data, dm, &mesh_topo_store)) {
ED_mesh_mirror_topo_table(ob, dm, 's');
}
}
else if (mode == 's') { /* start table */
- ED_mesh_mirrtopo_init(ob->data, dm, ob->mode, &mesh_topo_store, false);
+ ED_mesh_mirrtopo_init(ob->data, dm, &mesh_topo_store, false);
}
else if (mode == 'e') { /* end table */
ED_mesh_mirrtopo_free(&mesh_topo_store);
@@ -1339,17 +1343,17 @@ bool ED_mesh_pick_vert(bContext *C, Object *ob, const int mval[2], unsigned int
MDeformVert *ED_mesh_active_dvert_get_em(Object *ob, BMVert **r_eve)
{
- if (ob->mode & OB_MODE_EDIT && ob->type == OB_MESH && ob->defbase.first) {
+ if (ob->type == OB_MESH && ob->defbase.first) {
Mesh *me = ob->data;
- BMesh *bm = me->edit_btmesh->bm;
- const int cd_dvert_offset = CustomData_get_offset(&bm->vdata, CD_MDEFORMVERT);
-
- if (cd_dvert_offset != -1) {
- BMVert *eve = BM_mesh_active_vert_get(bm);
-
- if (eve) {
- if (r_eve) *r_eve = eve;
- return BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset);
+ if (me->edit_btmesh != NULL) {
+ BMesh *bm = me->edit_btmesh->bm;
+ const int cd_dvert_offset = CustomData_get_offset(&bm->vdata, CD_MDEFORMVERT);
+ if (cd_dvert_offset != -1) {
+ BMVert *eve = BM_mesh_active_vert_get(bm);
+ if (eve) {
+ if (r_eve) *r_eve = eve;
+ return BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset);
+ }
}
}
}
@@ -1374,7 +1378,8 @@ MDeformVert *ED_mesh_active_dvert_get_ob(Object *ob, int *r_index)
MDeformVert *ED_mesh_active_dvert_get_only(Object *ob)
{
if (ob->type == OB_MESH) {
- if (ob->mode & OB_MODE_EDIT) {
+ Mesh *me = ob->data;
+ if (me->edit_btmesh != NULL) {
return ED_mesh_active_dvert_get_em(ob, NULL);
}
else {
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index 5c96c13ebed..c4bad6f76c9 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -42,8 +42,8 @@
#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meta_types.h"
-#include "DNA_object_fluidsim.h"
-#include "DNA_object_force.h"
+#include "DNA_object_fluidsim_types.h"
+#include "DNA_object_force_types.h"
#include "DNA_object_types.h"
#include "DNA_lightprobe_types.h"
#include "DNA_scene_types.h"
@@ -1673,7 +1673,7 @@ static int convert_poll(bContext *C)
Base *base_act = CTX_data_active_base(C);
Object *obact = base_act ? base_act->object : NULL;
- return (!ID_IS_LINKED(scene) && obact && scene->obedit != obact &&
+ return (!ID_IS_LINKED(scene) && obact && (BKE_object_is_in_editmode(obact) == false) &&
(base_act->flag & BASE_SELECTED) && !ID_IS_LINKED(obact));
}
@@ -2081,7 +2081,9 @@ void OBJECT_OT_convert(wmOperatorType *ot)
/* used below, assumes id.new is correct */
/* leaves selection of base/object unaltered */
/* Does set ID->newid pointers. */
-static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, ViewLayer *view_layer, Object *ob, int dupflag)
+static Base *object_add_duplicate_internal(
+ Main *bmain, Scene *scene,
+ ViewLayer *view_layer, Object *ob, int dupflag)
{
#define ID_NEW_REMAP_US(a) if ( (a)->id.newid) { (a) = (void *)(a)->id.newid; (a)->id.us++; }
#define ID_NEW_REMAP_US2(a) if (((ID *)a)->newid) { (a) = ((ID *)a)->newid; ((ID *)a)->us++; }
@@ -2092,10 +2094,14 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, ViewLayer
ID *id;
int a, didit;
- if (ob->mode & OB_MODE_POSE) {
+ /* ignore pose mode now, Caller can inspect mode. */
+#if 0
+ if (eval_ctx->object_mode & OB_MODE_POSE) {
; /* nothing? */
}
- else {
+ else
+#endif
+ {
obn = ID_NEW_SET(ob, BKE_object_copy(bmain, ob));
DEG_id_tag_update(&obn->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
@@ -2523,10 +2529,10 @@ static int join_poll(bContext *C)
static int join_exec(bContext *C, wmOperator *op)
{
- Scene *scene = CTX_data_scene(C);
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Object *ob = CTX_data_active_object(C);
- if (scene->obedit) {
+ if (workspace->object_mode & OB_MODE_EDIT) {
BKE_report(op->reports, RPT_ERROR, "This data does not support joining in edit mode");
return OPERATOR_CANCELLED;
}
@@ -2577,10 +2583,10 @@ static int join_shapes_poll(bContext *C)
static int join_shapes_exec(bContext *C, wmOperator *op)
{
- Scene *scene = CTX_data_scene(C);
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Object *ob = CTX_data_active_object(C);
- if (scene->obedit) {
+ if (workspace->object_mode & OB_MODE_EDIT) {
BKE_report(op->reports, RPT_ERROR, "This data does not support joining in edit mode");
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c
index 3efb6253f6f..a13df441c5f 100644
--- a/source/blender/editors/object/object_bake.c
+++ b/source/blender/editors/object/object_bake.c
@@ -206,7 +206,8 @@ static bool multiresbake_check(bContext *C, wmOperator *op)
return ok;
}
-static DerivedMesh *multiresbake_create_loresdm(Scene *scene, Object *ob, int *lvl)
+static DerivedMesh *multiresbake_create_loresdm(
+ Scene *scene, Object *ob, eObjectMode object_mode, int *lvl)
{
DerivedMesh *dm;
MultiresModifierData *mmd = get_multires_modifier(scene, ob, 0);
@@ -226,13 +227,15 @@ static DerivedMesh *multiresbake_create_loresdm(Scene *scene, Object *ob, int *l
tmp_mmd.lvl = *lvl;
tmp_mmd.sculptlvl = *lvl;
- dm = multires_make_derived_from_derived(cddm, &tmp_mmd, ob, 0);
+ dm = multires_make_derived_from_derived(cddm, &tmp_mmd, ob, 0, object_mode);
cddm->release(cddm);
return dm;
}
-static DerivedMesh *multiresbake_create_hiresdm(Scene *scene, Object *ob, int *lvl, bool *simple)
+static DerivedMesh *multiresbake_create_hiresdm(
+ Scene *scene, Object *ob, eObjectMode object_mode,
+ int *lvl, bool *simple)
{
Mesh *me = (Mesh *)ob->data;
MultiresModifierData *mmd = get_multires_modifier(scene, ob, 0);
@@ -253,7 +256,7 @@ static DerivedMesh *multiresbake_create_hiresdm(Scene *scene, Object *ob, int *l
tmp_mmd.lvl = mmd->totlvl;
tmp_mmd.sculptlvl = mmd->totlvl;
- dm = multires_make_derived_from_derived(cddm, &tmp_mmd, ob, 0);
+ dm = multires_make_derived_from_derived(cddm, &tmp_mmd, ob, 0, object_mode);
cddm->release(cddm);
return dm;
@@ -317,6 +320,7 @@ static void clear_images_poly(Image **ob_image_array, int ob_image_array_len, Cl
static int multiresbake_image_exec_locked(bContext *C, wmOperator *op)
{
Object *ob;
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Scene *scene = CTX_data_scene(C);
int objects_baked = 0;
@@ -371,8 +375,8 @@ static int multiresbake_image_exec_locked(bContext *C, wmOperator *op)
bkr.ob_image.array = BKE_object_material_edit_image_get_array(ob);
bkr.ob_image.len = ob->totcol;
- bkr.hires_dm = multiresbake_create_hiresdm(scene, ob, &bkr.tot_lvl, &bkr.simple);
- bkr.lores_dm = multiresbake_create_loresdm(scene, ob, &bkr.lvl);
+ bkr.hires_dm = multiresbake_create_hiresdm(scene, ob, workspace->object_mode, &bkr.tot_lvl, &bkr.simple);
+ bkr.lores_dm = multiresbake_create_loresdm(scene, ob, workspace->object_mode, &bkr.lvl);
RE_multires_bake_images(&bkr);
@@ -396,6 +400,7 @@ static int multiresbake_image_exec_locked(bContext *C, wmOperator *op)
/* Multiresbake adopted for job-system executing */
static void init_multiresbake_job(bContext *C, MultiresBakeJob *bkj)
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Scene *scene = CTX_data_scene(C);
Object *ob;
@@ -427,8 +432,8 @@ static void init_multiresbake_job(bContext *C, MultiresBakeJob *bkj)
data->ob_image.len = ob->totcol;
/* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */
- data->hires_dm = multiresbake_create_hiresdm(scene, ob, &data->tot_lvl, &data->simple);
- data->lores_dm = multiresbake_create_loresdm(scene, ob, &lvl);
+ data->hires_dm = multiresbake_create_hiresdm(scene, ob, workspace->object_mode, &data->tot_lvl, &data->simple);
+ data->lores_dm = multiresbake_create_loresdm(scene, ob, workspace->object_mode, &lvl);
data->lvl = lvl;
BLI_addtail(&bkj->data, data);
@@ -861,9 +866,9 @@ static int bake_image_exec(bContext *C, wmOperator *op)
RE_Database_Baking(bkr.re, bmain, scene, scene->lay, scene->r.bake_mode, (scene->r.bake_flag & R_BAKE_TO_ACTIVE) ? OBACT(view_layer) : NULL);
/* baking itself is threaded, cannot use test_break in threads */
- BLI_init_threads(&threads, do_bake_render, 1);
+ BLI_threadpool_init(&threads, do_bake_render, 1);
bkr.ready = 0;
- BLI_insert_thread(&threads, &bkr);
+ BLI_threadpool_insert(&threads, &bkr);
while (bkr.ready == 0) {
PIL_sleep_ms(50);
@@ -874,7 +879,7 @@ static int bake_image_exec(bContext *C, wmOperator *op)
if (!G.background)
BKE_blender_test_break();
}
- BLI_end_threads(&threads);
+ BLI_threadpool_end(&threads);
if (bkr.result == BAKE_RESULT_NO_OBJECTS)
BKE_report(op->reports, RPT_ERROR, "No valid images found to bake to");
diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c
index 0174a307c16..c8bcc9224e9 100644
--- a/source/blender/editors/object/object_bake_api.c
+++ b/source/blender/editors/object/object_bake_api.c
@@ -623,8 +623,7 @@ static size_t initialize_internal_images(BakeImages *bake_images, ReportList *re
/* create new mesh with edit mode changes and modifiers applied */
static Mesh *bake_mesh_new_from_object(EvaluationContext *eval_ctx, Main *bmain, Scene *scene, Object *ob)
{
- if (ob->mode & OB_MODE_EDIT)
- ED_object_editmode_load(ob);
+ ED_object_editmode_load(ob);
Mesh *me = BKE_mesh_new_from_object(eval_ctx, bmain, scene, ob, 1, 2, 0, 0);
if (me->flag & ME_AUTOSMOOTH) {
@@ -852,7 +851,7 @@ static int bake(
/* triangulating so BVH returns the primitive_id that will be used for rendering */
highpoly[i].tri_mod = ED_object_modifier_add(
- reports, bmain, scene, highpoly[i].ob,
+ reports, bmain, scene, highpoly[i].ob, OB_MODE_OBJECT,
"TmpTriangulate", eModifierType_Triangulate);
tmd = (TriangulateModifierData *)highpoly[i].tri_mod;
tmd->quad_method = MOD_TRIANGULATE_QUAD_FIXED;
diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c
index 05a5f652382..1b462e92ca4 100644
--- a/source/blender/editors/object/object_constraint.c
+++ b/source/blender/editors/object/object_constraint.c
@@ -87,12 +87,12 @@
/* -------------- Get Active Constraint Data ---------------------- */
/* if object in posemode, active bone constraints, else object constraints */
-ListBase *get_active_constraints(Object *ob)
+ListBase *get_active_constraints(const EvaluationContext *eval_ctx, Object *ob)
{
if (ob == NULL)
return NULL;
- if (ob->mode & OB_MODE_POSE) {
+ if (eval_ctx->object_mode & OB_MODE_POSE) {
bPoseChannel *pchan;
pchan = BKE_pose_channel_active(ob);
@@ -142,9 +142,9 @@ ListBase *get_constraint_lb(Object *ob, bConstraint *con, bPoseChannel **r_pchan
}
/* single constraint */
-bConstraint *get_active_constraint(Object *ob)
+bConstraint *get_active_constraint(const EvaluationContext *eval_ctx, Object *ob)
{
- return BKE_constraints_active_get(get_active_constraints(ob));
+ return BKE_constraints_active_get(get_active_constraints(eval_ctx, ob));
}
/* -------------- Constraint Management (Add New, Remove, Rename) -------------------- */
@@ -639,7 +639,8 @@ static int edit_constraint_invoke_properties(bContext *C, wmOperator *op)
return 0;
}
-static bConstraint *edit_constraint_property_get(wmOperator *op, Object *ob, int type)
+static bConstraint *edit_constraint_property_get(
+ const EvaluationContext *eval_ctx, wmOperator *op, Object *ob, int type)
{
char constraint_name[MAX_NAME];
int owner = RNA_enum_get(op->ptr, "owner");
@@ -664,7 +665,7 @@ static bConstraint *edit_constraint_property_get(wmOperator *op, Object *ob, int
else {
//if (G.debug & G_DEBUG)
//printf("edit_constraint_property_get: defaulting to getting list in the standard way\n");
- list = get_active_constraints(ob);
+ list = get_active_constraints(eval_ctx, ob);
}
con = BKE_constraints_find_name(list, constraint_name);
@@ -684,8 +685,10 @@ static bConstraint *edit_constraint_property_get(wmOperator *op, Object *ob, int
static int stretchto_reset_exec(bContext *C, wmOperator *op)
{
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
Object *ob = ED_object_active_context(C);
- bConstraint *con = edit_constraint_property_get(op, ob, CONSTRAINT_TYPE_STRETCHTO);
+ bConstraint *con = edit_constraint_property_get(&eval_ctx, op, ob, CONSTRAINT_TYPE_STRETCHTO);
bStretchToConstraint *data = (con) ? (bStretchToConstraint *)con->data : NULL;
/* despite 3 layers of checks, we may still not be able to find a constraint */
@@ -730,8 +733,10 @@ void CONSTRAINT_OT_stretchto_reset(wmOperatorType *ot)
static int limitdistance_reset_exec(bContext *C, wmOperator *op)
{
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
Object *ob = ED_object_active_context(C);
- bConstraint *con = edit_constraint_property_get(op, ob, CONSTRAINT_TYPE_DISTLIMIT);
+ bConstraint *con = edit_constraint_property_get(&eval_ctx, op, ob, CONSTRAINT_TYPE_DISTLIMIT);
bDistLimitConstraint *data = (con) ? (bDistLimitConstraint *)con->data : NULL;
/* despite 3 layers of checks, we may still not be able to find a constraint */
@@ -866,9 +871,11 @@ static void child_get_inverse_matrix(const bContext *C, Scene *scene, Object *ob
/* ChildOf Constraint - set inverse callback */
static int childof_set_inverse_exec(bContext *C, wmOperator *op)
{
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
Scene *scene = CTX_data_scene(C);
Object *ob = ED_object_active_context(C);
- bConstraint *con = edit_constraint_property_get(op, ob, CONSTRAINT_TYPE_CHILDOF);
+ bConstraint *con = edit_constraint_property_get(&eval_ctx, op, ob, CONSTRAINT_TYPE_CHILDOF);
bChildOfConstraint *data = (con) ? (bChildOfConstraint *)con->data : NULL;
const int owner = RNA_enum_get(op->ptr, "owner");
@@ -917,7 +924,9 @@ void CONSTRAINT_OT_childof_set_inverse(wmOperatorType *ot)
static int childof_clear_inverse_exec(bContext *C, wmOperator *op)
{
Object *ob = ED_object_active_context(C);
- bConstraint *con = edit_constraint_property_get(op, ob, CONSTRAINT_TYPE_CHILDOF);
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
+ bConstraint *con = edit_constraint_property_get(&eval_ctx, op, ob, CONSTRAINT_TYPE_CHILDOF);
bChildOfConstraint *data = (con) ? (bChildOfConstraint *)con->data : NULL;
if (data == NULL) {
@@ -964,8 +973,10 @@ void CONSTRAINT_OT_childof_clear_inverse(wmOperatorType *ot)
static int followpath_path_animate_exec(bContext *C, wmOperator *op)
{
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
Object *ob = ED_object_active_context(C);
- bConstraint *con = edit_constraint_property_get(op, ob, CONSTRAINT_TYPE_FOLLOWPATH);
+ bConstraint *con = edit_constraint_property_get(&eval_ctx, op, ob, CONSTRAINT_TYPE_FOLLOWPATH);
bFollowPathConstraint *data = (con) ? (bFollowPathConstraint *)con->data : NULL;
bAction *act = NULL;
@@ -1088,9 +1099,11 @@ void CONSTRAINT_OT_followpath_path_animate(wmOperatorType *ot)
static int objectsolver_set_inverse_exec(bContext *C, wmOperator *op)
{
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
Scene *scene = CTX_data_scene(C);
Object *ob = ED_object_active_context(C);
- bConstraint *con = edit_constraint_property_get(op, ob, CONSTRAINT_TYPE_OBJECTSOLVER);
+ bConstraint *con = edit_constraint_property_get(&eval_ctx, op, ob, CONSTRAINT_TYPE_OBJECTSOLVER);
bObjectSolverConstraint *data = (con) ? (bObjectSolverConstraint *)con->data : NULL;
const int owner = RNA_enum_get(op->ptr, "owner");
@@ -1137,8 +1150,10 @@ void CONSTRAINT_OT_objectsolver_set_inverse(wmOperatorType *ot)
static int objectsolver_clear_inverse_exec(bContext *C, wmOperator *op)
{
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
Object *ob = ED_object_active_context(C);
- bConstraint *con = edit_constraint_property_get(op, ob, CONSTRAINT_TYPE_OBJECTSOLVER);
+ bConstraint *con = edit_constraint_property_get(&eval_ctx, op, ob, CONSTRAINT_TYPE_OBJECTSOLVER);
bObjectSolverConstraint *data = (con) ? (bObjectSolverConstraint *)con->data : NULL;
if (data == NULL) {
@@ -1306,8 +1321,10 @@ void CONSTRAINT_OT_delete(wmOperatorType *ot)
static int constraint_move_down_exec(bContext *C, wmOperator *op)
{
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
Object *ob = ED_object_active_context(C);
- bConstraint *con = edit_constraint_property_get(op, ob, 0);
+ bConstraint *con = edit_constraint_property_get(&eval_ctx, op, ob, 0);
if (con && con->next) {
ListBase *conlist = get_constraint_lb(ob, con, NULL);
@@ -1355,8 +1372,10 @@ void CONSTRAINT_OT_move_down(wmOperatorType *ot)
static int constraint_move_up_exec(bContext *C, wmOperator *op)
{
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
Object *ob = ED_object_active_context(C);
- bConstraint *con = edit_constraint_property_get(op, ob, 0);
+ bConstraint *con = edit_constraint_property_get(&eval_ctx, op, ob, 0);
if (con && con->prev) {
ListBase *conlist = get_constraint_lb(ob, con, NULL);
@@ -1575,6 +1594,8 @@ void OBJECT_OT_constraints_copy(wmOperatorType *ot)
/* get the Object and/or PoseChannel to use as target */
static bool get_new_constraint_target(bContext *C, int con_type, Object **tar_ob, bPoseChannel **tar_pchan, bool add)
{
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
Object *obact = ED_object_active_context(C);
bPoseChannel *pchanact = BKE_pose_channel_active(obact);
bool only_curve = false, only_mesh = false, only_ob = false;
@@ -1653,7 +1674,7 @@ static bool get_new_constraint_target(bContext *C, int con_type, Object **tar_ob
/* for armatures in pose mode, look inside the armature for the active bone
* so that we set up cross-armature constraints with less effort
*/
- if ((ob->type == OB_ARMATURE) && (ob->mode & OB_MODE_POSE) &&
+ if ((ob->type == OB_ARMATURE) && (eval_ctx.mode & OB_MODE_POSE) &&
(!only_curve && !only_mesh))
{
/* just use the active bone, and assume that it is visible + usable */
@@ -1871,6 +1892,8 @@ static int object_constraint_add_exec(bContext *C, wmOperator *op)
/* dummy operator callback */
static int pose_constraint_add_exec(bContext *C, wmOperator *op)
{
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
Object *ob = BKE_object_pose_armature_get(ED_object_active_context(C));
int type = RNA_enum_get(op->ptr, "type");
short with_targets = 0;
@@ -1886,7 +1909,7 @@ static int pose_constraint_add_exec(bContext *C, wmOperator *op)
if (strstr(op->idname, "with_targets"))
with_targets = 1;
- return constraint_add_exec(C, op, ob, get_active_constraints(ob), type, with_targets);
+ return constraint_add_exec(C, op, ob, get_active_constraints(&eval_ctx, ob), type, with_targets);
}
/* ------------------ */
@@ -2027,11 +2050,13 @@ static int pose_ik_add_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED
/* call constraint_add_exec() to add the IK constraint */
static int pose_ik_add_exec(bContext *C, wmOperator *op)
{
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
Object *ob = CTX_data_active_object(C);
const bool with_targets = RNA_boolean_get(op->ptr, "with_targets");
/* add the constraint - all necessary checks should have been done by the invoke() callback already... */
- return constraint_add_exec(C, op, ob, get_active_constraints(ob), CONSTRAINT_TYPE_KINEMATIC, with_targets);
+ return constraint_add_exec(C, op, ob, get_active_constraints(&eval_ctx, ob), CONSTRAINT_TYPE_KINEMATIC, with_targets);
}
void POSE_OT_ik_add(wmOperatorType *ot)
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index 5697c48d381..c6f9ced51a3 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -54,10 +54,11 @@
#include "DNA_property_types.h"
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
-#include "DNA_object_force.h"
+#include "DNA_object_force_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_vfont_types.h"
#include "DNA_mesh_types.h"
+#include "DNA_lattice_types.h"
#include "DNA_workspace_types.h"
#include "IMB_imbuf_types.h"
@@ -83,6 +84,7 @@
#include "BKE_modifier.h"
#include "BKE_editmesh.h"
#include "BKE_report.h"
+#include "BKE_object.h"
#include "BKE_workspace.h"
#include "DEG_depsgraph.h"
@@ -171,6 +173,9 @@ static bool ED_object_editmode_load_ex(Main *bmain, Object *obedit, const bool f
if (obedit->type == OB_MESH) {
Mesh *me = obedit->data;
+ if (me->edit_btmesh == NULL) {
+ return false;
+ }
if (me->edit_btmesh->bm->totvert > MESH_MAX_VERTS) {
error("Too many vertices");
@@ -184,15 +189,21 @@ static bool ED_object_editmode_load_ex(Main *bmain, Object *obedit, const bool f
MEM_freeN(me->edit_btmesh);
me->edit_btmesh = NULL;
}
- if (obedit->restore_mode & OB_MODE_WEIGHT_PAINT) {
+ /* will be recalculated as needed. */
+ {
ED_mesh_mirror_spatial_table(NULL, NULL, NULL, NULL, 'e');
ED_mesh_mirror_topo_table(NULL, NULL, 'e');
}
}
else if (obedit->type == OB_ARMATURE) {
+ const bArmature *arm = obedit->data;
+ if (arm->edbo == NULL) {
+ return false;
+ }
ED_armature_from_edit(obedit->data);
- if (freedata)
+ if (freedata) {
ED_armature_edit_free(obedit->data);
+ }
/* TODO(sergey): Pose channels might have been changed, so need
* to inform dependency graph about this. But is it really the
* best place to do this?
@@ -200,27 +211,46 @@ static bool ED_object_editmode_load_ex(Main *bmain, Object *obedit, const bool f
DEG_relations_tag_update(bmain);
}
else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) {
+ const Curve *cu = obedit->data;
+ if (cu->editnurb == NULL) {
+ return false;
+ }
ED_curve_editnurb_load(obedit);
- if (freedata) ED_curve_editnurb_free(obedit);
+ if (freedata) {
+ ED_curve_editnurb_free(obedit);
+ }
}
else if (obedit->type == OB_FONT) {
+ const Curve *cu = obedit->data;
+ if (cu->editfont == NULL) {
+ return false;
+ }
ED_curve_editfont_load(obedit);
- if (freedata) ED_curve_editfont_free(obedit);
+ if (freedata) {
+ ED_curve_editfont_free(obedit);
+ }
}
else if (obedit->type == OB_LATTICE) {
+ const Lattice *lt = obedit->data;
+ if (lt->editlatt == NULL) {
+ return false;
+ }
ED_lattice_editlatt_load(obedit);
- if (freedata) ED_lattice_editlatt_free(obedit);
+ if (freedata) {
+ ED_lattice_editlatt_free(obedit);
+ }
}
else if (obedit->type == OB_MBALL) {
+ const MetaBall *mb = obedit->data;
+ if (mb->editelems == NULL) {
+ return false;
+ }
ED_mball_editmball_load(obedit);
- if (freedata) ED_mball_editmball_free(obedit);
+ if (freedata) {
+ ED_mball_editmball_free(obedit);
+ }
}
- /* Tag update so no access to freed data referenced from
- * derived cache will happen.
- */
- DEG_id_tag_update((ID *)obedit->data, 0);
-
return true;
}
@@ -230,23 +260,23 @@ bool ED_object_editmode_load(Object *obedit)
return ED_object_editmode_load_ex(G.main, obedit, false);
}
-void ED_object_editmode_exit(bContext *C, int flag)
+/**
+ * \param C: Can be NULL, only if #EM_DO_UNDO isn't set.
+ * \param flag:
+ * - Only in exceptional cases should #EM_DO_UNDO NOT be in the flag.
+ * - If #EM_FREEDATA isn't in the flag, use ED_object_editmode_load directly.
+ */
+void ED_object_editmode_exit_ex(bContext *C, WorkSpace *workspace, Scene *scene, Object *obedit, int flag)
{
- /* Note! only in exceptional cases should 'EM_DO_UNDO' NOT be in the flag */
- /* Note! if 'EM_FREEDATA' isn't in the flag, use ED_object_editmode_load directly */
- Scene *scene = CTX_data_scene(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Object *obedit = CTX_data_edit_object(C);
+ BLI_assert(C || !(flag & EM_DO_UNDO));
const bool freedata = (flag & EM_FREEDATA) != 0;
if (flag & EM_WAITCURSOR) waitcursor(1);
- if (ED_object_editmode_load_ex(CTX_data_main(C), obedit, freedata) == false) {
+ if (ED_object_editmode_load_ex(G.main, obedit, freedata) == false) {
/* in rare cases (background mode) its possible active object
* is flagged for editmode, without 'obedit' being set [#35489] */
- if (UNLIKELY(view_layer->basact && (view_layer->basact->object->mode & OB_MODE_EDIT))) {
- view_layer->basact->object->mode &= ~OB_MODE_EDIT;
- }
+ workspace->object_mode &= ~OB_MODE_EDIT;
if (flag & EM_WAITCURSOR) waitcursor(0);
return;
}
@@ -256,9 +286,6 @@ void ED_object_editmode_exit(bContext *C, int flag)
ListBase pidlist;
PTCacheID *pid;
- /* for example; displist make is different in editmode */
- scene->obedit = NULL; // XXX for context
-
/* flag object caches as outdated */
BKE_ptcache_ids_from_object(&pidlist, obedit, scene, 0);
for (pid = pidlist.first; pid; pid = pid->next) {
@@ -275,9 +302,14 @@ void ED_object_editmode_exit(bContext *C, int flag)
if (flag & EM_DO_UNDO)
ED_undo_push(C, "Editmode");
- WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_OBJECT, scene);
+ if (C != NULL) {
+ WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_OBJECT, scene);
+ }
+ else {
+ WM_main_add_notifier(NC_SCENE | ND_MODE | NS_MODE_OBJECT, scene);
+ }
- obedit->mode &= ~OB_MODE_EDIT;
+ workspace->object_mode &= ~OB_MODE_EDIT;
}
if (flag & EM_WAITCURSOR) waitcursor(0);
@@ -286,9 +318,17 @@ void ED_object_editmode_exit(bContext *C, int flag)
DEG_id_tag_update(&scene->id, 0);
}
+void ED_object_editmode_exit(bContext *C, int flag)
+{
+ WorkSpace *workspace = CTX_wm_workspace(C);
+ Scene *scene = CTX_data_scene(C);
+ Object *obedit = CTX_data_edit_object(C);
+ ED_object_editmode_exit_ex(C, workspace, scene, obedit, flag);
+}
void ED_object_editmode_enter(bContext *C, int flag)
{
+ WorkSpace *workspace = CTX_wm_workspace(C);
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *ob;
@@ -318,20 +358,18 @@ void ED_object_editmode_enter(bContext *C, int flag)
if (flag & EM_WAITCURSOR) waitcursor(1);
- ob->restore_mode = ob->mode;
+ workspace->object_mode_restore = workspace->object_mode;
/* note, when switching scenes the object can have editmode data but
* not be scene->obedit: bug 22954, this avoids calling self eternally */
- if ((ob->restore_mode & OB_MODE_EDIT) == 0)
- ED_object_toggle_modes(C, ob->mode);
+ if ((workspace->object_mode_restore & OB_MODE_EDIT) == 0)
+ ED_object_toggle_modes(C, workspace->object_mode);
- ob->mode = OB_MODE_EDIT;
+ workspace->object_mode = OB_MODE_EDIT;
if (ob->type == OB_MESH) {
BMEditMesh *em;
ok = 1;
- scene->obedit = ob; /* context sees this */
-
const bool use_key_index = mesh_needs_keyindex(ob->data);
EDBM_mesh_make(scene->toolsettings, ob, use_key_index);
@@ -361,7 +399,6 @@ void ED_object_editmode_enter(bContext *C, int flag)
return;
}
ok = 1;
- scene->obedit = ob;
ED_armature_to_edit(arm);
/* to ensure all goes in restposition and without striding */
DEG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); /* XXX: should this be OB_RECALC_DATA? */
@@ -369,21 +406,18 @@ void ED_object_editmode_enter(bContext *C, int flag)
WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_EDITMODE_ARMATURE, scene);
}
else if (ob->type == OB_FONT) {
- scene->obedit = ob; /* XXX for context */
ok = 1;
ED_curve_editfont_make(ob);
WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_EDITMODE_TEXT, scene);
}
else if (ob->type == OB_MBALL) {
- scene->obedit = ob; /* XXX for context */
ok = 1;
ED_mball_editmball_make(ob);
WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_EDITMODE_MBALL, scene);
}
else if (ob->type == OB_LATTICE) {
- scene->obedit = ob; /* XXX for context */
ok = 1;
ED_lattice_editlatt_make(ob);
@@ -391,7 +425,6 @@ void ED_object_editmode_enter(bContext *C, int flag)
}
else if (ob->type == OB_SURF || ob->type == OB_CURVE) {
ok = 1;
- scene->obedit = ob; /* XXX for context */
ED_curve_editnurb_make(ob);
WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_EDITMODE_CURVE, scene);
@@ -403,8 +436,7 @@ void ED_object_editmode_enter(bContext *C, int flag)
DEG_id_tag_update(&scene->id, 0);
}
else {
- scene->obedit = NULL; /* XXX for context */
- ob->mode &= ~OB_MODE_EDIT;
+ workspace->object_mode &= ~OB_MODE_EDIT;
WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_OBJECT, scene);
}
@@ -414,13 +446,13 @@ void ED_object_editmode_enter(bContext *C, int flag)
static int editmode_toggle_exec(bContext *C, wmOperator *op)
{
+ WorkSpace *workspace = CTX_wm_workspace(C);
const int mode_flag = OB_MODE_EDIT;
const bool is_mode_set = (CTX_data_edit_object(C) != NULL);
Scene *scene = CTX_data_scene(C);
if (!is_mode_set) {
- Object *ob = CTX_data_active_object(C);
- if (!ED_object_mode_compat_set(C, ob, mode_flag, op->reports)) {
+ if (!ED_object_mode_compat_set(C, workspace, mode_flag, op->reports)) {
return OPERATOR_CANCELLED;
}
}
@@ -443,9 +475,12 @@ static int editmode_toggle_poll(bContext *C)
if (ELEM(NULL, ob, ob->data) || ID_IS_LINKED(ob->data))
return 0;
+ const WorkSpace *workspace = CTX_wm_workspace(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_VIEW) && !(workspace->object_mode & OB_MODE_EDIT)) {
return 0;
+ }
return OB_TYPE_SUPPORT_EDITMODE(ob->type);
}
@@ -470,13 +505,14 @@ void OBJECT_OT_editmode_toggle(wmOperatorType *ot)
static int posemode_exec(bContext *C, wmOperator *op)
{
+ WorkSpace *workspace = CTX_wm_workspace(C);
Base *base = CTX_data_active_base(C);
Object *ob = base->object;
const int mode_flag = OB_MODE_POSE;
- const bool is_mode_set = (ob->mode & mode_flag) != 0;
-
+ const bool is_mode_set = (workspace->object_mode & mode_flag) != 0;
+
if (!is_mode_set) {
- if (!ED_object_mode_compat_set(C, ob, mode_flag, op->reports)) {
+ if (!ED_object_mode_compat_set(C, workspace, mode_flag, op->reports)) {
return OPERATOR_CANCELLED;
}
}
@@ -671,7 +707,7 @@ static void copy_attr(Main *bmain, Scene *scene, ViewLayer *view_layer, short ev
if (!(ob = OBACT(view_layer))) return;
- if (scene->obedit) { // XXX get from context
+ if (BKE_object_is_in_editmode(ob)) {
/* obedit_copymenu(); */
return;
}
@@ -910,7 +946,7 @@ static void copy_attr(Main *bmain, Scene *scene, ViewLayer *view_layer, short ev
DEG_relations_tag_update(bmain);
}
-static void UNUSED_FUNCTION(copy_attr_menu) (Main *bmain, Scene *scene, ViewLayer *view_layer)
+static void UNUSED_FUNCTION(copy_attr_menu) (Main *bmain, Scene *scene, ViewLayer *view_layer, Object *obedit)
{
Object *ob;
short event;
@@ -918,7 +954,7 @@ static void UNUSED_FUNCTION(copy_attr_menu) (Main *bmain, Scene *scene, ViewLaye
if (!(ob = OBACT(view_layer))) return;
- if (scene->obedit) { /* XXX get from context */
+ if (obedit) {
/* if (ob->type == OB_MESH) */
/* XXX mesh_copy_menu(); */
return;
@@ -969,7 +1005,7 @@ static void UNUSED_FUNCTION(copy_attr_menu) (Main *bmain, Scene *scene, ViewLaye
/* ******************* force field toggle operator ***************** */
-void ED_object_check_force_modifiers(Main *bmain, Scene *scene, Object *object)
+void ED_object_check_force_modifiers(Main *bmain, Scene *scene, Object *object, eObjectMode object_mode)
{
PartDeflect *pd = object->pd;
ModifierData *md = modifiers_findByType(object, eModifierType_Surface);
@@ -978,7 +1014,7 @@ void ED_object_check_force_modifiers(Main *bmain, Scene *scene, Object *object)
if (!md) {
if (pd && (pd->shape == PFIELD_SHAPE_SURFACE) && !ELEM(pd->forcefield, 0, PFIELD_GUIDE, PFIELD_TEXTURE)) {
if (ELEM(object->type, OB_MESH, OB_SURF, OB_FONT, OB_CURVE)) {
- ED_object_modifier_add(NULL, bmain, scene, object, NULL, eModifierType_Surface);
+ ED_object_modifier_add(NULL, bmain, scene, object, object_mode, NULL, eModifierType_Surface);
}
}
}
@@ -999,8 +1035,9 @@ static int forcefield_toggle_exec(bContext *C, wmOperator *UNUSED(op))
ob->pd->forcefield = PFIELD_FORCE;
else
ob->pd->forcefield = 0;
-
- ED_object_check_force_modifiers(CTX_data_main(C), CTX_data_scene(C), ob);
+
+ const WorkSpace *workspace = CTX_wm_workspace(C);
+ ED_object_check_force_modifiers(CTX_data_main(C), CTX_data_scene(C), ob, workspace->object_mode);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
@@ -1334,7 +1371,7 @@ void OBJECT_OT_shade_smooth(wmOperatorType *ot)
/* ********************** */
-static void UNUSED_FUNCTION(image_aspect) (Scene *scene, ViewLayer *view_layer)
+static void UNUSED_FUNCTION(image_aspect) (Scene *scene, ViewLayer *view_layer, Object *obedit)
{
/* all selected objects with an image map: scale in image aspect */
Base *base;
@@ -1344,7 +1381,7 @@ static void UNUSED_FUNCTION(image_aspect) (Scene *scene, ViewLayer *view_layer)
float x, y, space;
int a, b, done;
- if (scene->obedit) return; // XXX get from context
+ if (obedit) return;
if (ID_IS_LINKED(scene)) return;
for (base = FIRSTBASE(view_layer); base; base = base->next) {
@@ -1446,7 +1483,7 @@ static const EnumPropertyItem *object_mode_set_itemsf(
return item;
}
-static const char *object_mode_op_string(int mode)
+static const char *object_mode_op_string(eObjectMode mode)
{
if (mode & OB_MODE_EDIT)
return "OBJECT_OT_editmode_toggle";
@@ -1512,18 +1549,14 @@ static bool object_mode_compat_test(Object *ob, eObjectMode mode)
*
* This is so each mode's exec function can call
*/
-bool ED_object_mode_compat_set(bContext *C, Object *ob, int mode, ReportList *reports)
+bool ED_object_mode_compat_set(bContext *C, WorkSpace *workspace, eObjectMode mode, ReportList *reports)
{
bool ok;
- if (!ELEM(ob->mode, mode, OB_MODE_OBJECT)) {
- const char *opstring = object_mode_op_string(ob->mode);
+ if (!ELEM(workspace->object_mode, mode, OB_MODE_OBJECT)) {
+ const char *opstring = object_mode_op_string(workspace->object_mode);
WM_operator_name_call(C, opstring, WM_OP_EXEC_REGION_WIN, NULL);
-#ifdef USE_WORKSPACE_MODE
- BKE_workspace_object_mode_set(CTX_wm_workspace(C), CTX_data_scene(C), ob->mode);
-#endif
-
- ok = ELEM(ob->mode, mode, OB_MODE_OBJECT);
+ ok = ELEM(workspace->object_mode, mode, OB_MODE_OBJECT);
if (!ok) {
wmOperatorType *ot = WM_operatortype_find(opstring, false);
BKE_reportf(reports, RPT_ERROR, "Unable to execute '%s', error changing modes", ot->name);
@@ -1551,10 +1584,11 @@ static int object_mode_set_poll(bContext *C)
static int object_mode_set_exec(bContext *C, wmOperator *op)
{
+ WorkSpace *workspace = CTX_wm_workspace(C);
Object *ob = CTX_data_active_object(C);
bGPdata *gpd = CTX_data_gpencil_data(C);
eObjectMode mode = RNA_enum_get(op->ptr, "mode");
- eObjectMode restore_mode = (ob) ? ob->mode : OB_MODE_OBJECT;
+ eObjectMode restore_mode = workspace->object_mode;
const bool toggle = RNA_boolean_get(op->ptr, "toggle");
if (gpd) {
@@ -1578,28 +1612,31 @@ static int object_mode_set_exec(bContext *C, wmOperator *op)
if (!ob || !object_mode_compat_test(ob, mode))
return OPERATOR_PASS_THROUGH;
- if (ob->mode != mode) {
+ if (workspace->object_mode != mode) {
/* we should be able to remove this call, each operator calls */
- ED_object_mode_compat_set(C, ob, mode, op->reports);
+ ED_object_mode_compat_set(C, workspace, mode, op->reports);
}
/* Exit current mode if it's not the mode we're setting */
- if (mode != OB_MODE_OBJECT && (ob->mode != mode || toggle)) {
+ if (mode != OB_MODE_OBJECT && (workspace->object_mode != mode || toggle)) {
/* Enter new mode */
ED_object_toggle_modes(C, mode);
}
if (toggle) {
/* Special case for Object mode! */
- if (mode == OB_MODE_OBJECT && restore_mode == OB_MODE_OBJECT && ob->restore_mode != OB_MODE_OBJECT) {
- ED_object_toggle_modes(C, ob->restore_mode);
+ if ((mode == OB_MODE_OBJECT) &&
+ (restore_mode == OB_MODE_OBJECT) &&
+ (workspace->object_mode_restore != OB_MODE_OBJECT))
+ {
+ ED_object_toggle_modes(C, workspace->object_mode_restore);
}
- else if (ob->mode == mode) {
+ else if (workspace->object_mode == mode) {
/* For toggling, store old mode so we know what to go back to */
- ob->restore_mode = restore_mode;
+ workspace->object_mode_restore = restore_mode;
}
- else if (ob->restore_mode != OB_MODE_OBJECT && ob->restore_mode != mode) {
- ED_object_toggle_modes(C, ob->restore_mode);
+ else if (!ELEM(workspace->object_mode_restore, mode, OB_MODE_OBJECT)) {
+ ED_object_toggle_modes(C, workspace->object_mode_restore);
}
}
@@ -1631,24 +1668,13 @@ void OBJECT_OT_mode_set(wmOperatorType *ot)
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
-
-void ED_object_toggle_modes(bContext *C, int mode)
+void ED_object_toggle_modes(bContext *C, eObjectMode mode)
{
if (mode != OB_MODE_OBJECT) {
const char *opstring = object_mode_op_string(mode);
if (opstring) {
-#ifdef USE_WORKSPACE_MODE
- WorkSpace *workspace = CTX_wm_workspace(C);
-#endif
WM_operator_name_call(C, opstring, WM_OP_EXEC_REGION_WIN, NULL);
-
-#ifdef USE_WORKSPACE_MODE
- Object *ob = CTX_data_active_object(C);
- if (ob) {
- BKE_workspace_object_mode_set(workspace, CTX_data_scene(C), ob->mode);
- }
-#endif
}
}
}
diff --git a/source/blender/editors/object/object_facemap_ops.c b/source/blender/editors/object/object_facemap_ops.c
index 857446ac6b0..c865b45889a 100644
--- a/source/blender/editors/object/object_facemap_ops.c
+++ b/source/blender/editors/object/object_facemap_ops.c
@@ -35,6 +35,7 @@
#include "DNA_object_types.h"
#include "DNA_mesh_types.h"
+#include "DNA_workspace_types.h"
#include "BKE_context.h"
#include "BKE_customdata.h"
@@ -173,7 +174,13 @@ static int face_map_supported_edit_mode_poll(bContext *C)
{
Object *ob = ED_object_context(C);
ID *data = (ob) ? ob->data : NULL;
- return (ob && !ob->id.lib && ob->type == OB_MESH && data && !data->lib && ob->mode == OB_MODE_EDIT);
+ if (ob && !ob->id.lib && ob->type == OB_MESH && data && !data->lib) {
+ const WorkSpace *workspace = CTX_wm_workspace(C);
+ if (workspace->object_mode == OB_MODE_EDIT) {
+ return true;
+ }
+ }
+ return false;
}
static int face_map_add_exec(bContext *C, wmOperator *UNUSED(op))
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index ca58a60806c..9d1792e9f16 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -40,7 +40,7 @@
#include "DNA_key_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
-#include "DNA_object_force.h"
+#include "DNA_object_force_types.h"
#include "DNA_scene_types.h"
#include "BLI_bitmap.h"
@@ -95,7 +95,10 @@ static void modifier_skin_customdata_delete(struct Object *ob);
/******************************** API ****************************/
-ModifierData *ED_object_modifier_add(ReportList *reports, Main *bmain, Scene *scene, Object *ob, const char *name, int type)
+ModifierData *ED_object_modifier_add(
+ ReportList *reports,
+ Main *bmain, Scene *scene,
+ Object *ob, eObjectMode object_mode, const char *name, int type)
{
ModifierData *md = NULL, *new_md = NULL;
const ModifierTypeInfo *mti = modifierType_getInfo(type);
@@ -162,7 +165,7 @@ ModifierData *ED_object_modifier_add(ReportList *reports, Main *bmain, Scene *sc
/* set totlvl from existing MDISPS layer if object already had it */
multiresModifier_set_levels_from_disps((MultiresModifierData *)new_md, ob);
- if (ob->mode & OB_MODE_SCULPT) {
+ if (object_mode & OB_MODE_SCULPT) {
/* ensure that grid paint mask layer is created */
BKE_sculpt_mask_layers_ensure(ob, (MultiresModifierData *)new_md);
}
@@ -202,9 +205,11 @@ static bool object_has_modifier(const Object *ob, const ModifierData *exclude,
* If the callback ever returns true, iteration will stop and the
* function value will be true. Otherwise the function returns false.
*/
-bool ED_object_iter_other(Main *bmain, Object *orig_ob, const bool include_orig,
- bool (*callback)(Object *ob, void *callback_data),
- void *callback_data)
+bool ED_object_iter_other(
+ const EvaluationContext *eval_ctx,
+ Main *bmain, Object *orig_ob, const bool include_orig,
+ bool (*callback)(const EvaluationContext *eval_ctx, Object *ob, void *callback_data),
+ void *callback_data)
{
ID *ob_data_id = orig_ob->data;
int users = ob_data_id->us;
@@ -223,7 +228,7 @@ bool ED_object_iter_other(Main *bmain, Object *orig_ob, const bool include_orig,
if (((ob != orig_ob) || include_orig) &&
(ob->data == orig_ob->data))
{
- if (callback(ob, callback_data))
+ if (callback(eval_ctx, ob, callback_data))
return true;
totfound++;
@@ -231,13 +236,15 @@ bool ED_object_iter_other(Main *bmain, Object *orig_ob, const bool include_orig,
}
}
else if (include_orig) {
- return callback(orig_ob, callback_data);
+ return callback(eval_ctx, orig_ob, callback_data);
}
return false;
}
-static bool object_has_modifier_cb(Object *ob, void *data)
+static bool object_has_modifier_cb(
+ const EvaluationContext *UNUSED(eval_ctx),
+ Object *ob, void *data)
{
ModifierType type = *((ModifierType *)data);
@@ -247,14 +254,16 @@ static bool object_has_modifier_cb(Object *ob, void *data)
/* Use with ED_object_iter_other(). Sets the total number of levels
* for any multires modifiers on the object to the int pointed to by
* callback_data. */
-bool ED_object_multires_update_totlevels_cb(Object *ob, void *totlevel_v)
+bool ED_object_multires_update_totlevels_cb(
+ const struct EvaluationContext *eval_ctx,
+ Object *ob, void *totlevel_v)
{
ModifierData *md;
int totlevel = *((char *)totlevel_v);
for (md = ob->modifiers.first; md; md = md->next) {
if (md->type == eModifierType_Multires) {
- multires_set_tot_level(ob, (MultiresModifierData *)md, totlevel);
+ multires_set_tot_level((MultiresModifierData *)md, totlevel, eval_ctx->object_mode);
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
}
}
@@ -267,7 +276,7 @@ static bool object_modifier_safe_to_delete(Main *bmain, Object *ob,
ModifierType type)
{
return (!object_has_modifier(ob, exclude, type) &&
- !ED_object_iter_other(bmain, ob, false,
+ !ED_object_iter_other(NULL, bmain, ob, false,
object_has_modifier_cb, &type));
}
@@ -316,11 +325,13 @@ static bool object_modifier_remove(Main *bmain, Object *ob, ModifierData *md,
modifier_skin_customdata_delete(ob);
}
+#if 0 /* not needed now modes are in workspace */
if (ELEM(md->type, eModifierType_Softbody, eModifierType_Cloth) &&
BLI_listbase_is_empty(&ob->particlesystem))
{
ob->mode &= ~OB_MODE_PARTICLE_EDIT;
}
+#endif
DEG_relations_tag_update(bmain);
@@ -413,7 +424,9 @@ int ED_object_modifier_move_down(ReportList *reports, Object *ob, ModifierData *
return 1;
}
-int ED_object_modifier_convert(ReportList *UNUSED(reports), Main *bmain, Scene *scene, ViewLayer *view_layer, Object *ob, ModifierData *md)
+int ED_object_modifier_convert(
+ ReportList *UNUSED(reports), Main *bmain, Scene *scene,
+ ViewLayer *view_layer, Object *UNUSED(ob), eObjectMode object_mode, ModifierData *md)
{
Object *obn;
ParticleSystem *psys;
@@ -427,7 +440,7 @@ int ED_object_modifier_convert(ReportList *UNUSED(reports), Main *bmain, Scene *
int totpart = 0, totchild = 0;
if (md->type != eModifierType_ParticleSystem) return 0;
- if (ob && ob->mode & OB_MODE_PARTICLE_EDIT) return 0;
+ if (object_mode & OB_MODE_PARTICLE_EDIT) return 0;
psys = ((ParticleSystemModifierData *)md)->psys;
part = psys->part;
@@ -677,9 +690,10 @@ static int modifier_apply_obdata(ReportList *reports, const bContext *C, Scene *
int ED_object_modifier_apply(ReportList *reports, const bContext *C, Scene *scene, Object *ob, ModifierData *md, int mode)
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
int prev_mode;
- if (scene->obedit) {
+ if (BKE_object_is_in_editmode(ob)) {
BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied in edit mode");
return 0;
}
@@ -687,7 +701,7 @@ int ED_object_modifier_apply(ReportList *reports, const bContext *C, Scene *scen
BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied to multi-user data");
return 0;
}
- else if ((ob->mode & OB_MODE_SCULPT) &&
+ else if ((workspace->object_mode & OB_MODE_SCULPT) &&
(find_multires_modifier_before(scene, md)) &&
(modifier_isSameTopology(md) == false))
{
@@ -739,12 +753,13 @@ int ED_object_modifier_copy(ReportList *UNUSED(reports), Object *ob, ModifierDat
static int modifier_add_exec(bContext *C, wmOperator *op)
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
Object *ob = ED_object_active_context(C);
int type = RNA_enum_get(op->ptr, "type");
- if (!ED_object_modifier_add(op->reports, bmain, scene, ob, NULL, type))
+ if (!ED_object_modifier_add(op->reports, bmain, scene, ob, workspace->object_mode, NULL, type))
return OPERATOR_CANCELLED;
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
@@ -881,11 +896,12 @@ ModifierData *edit_modifier_property_get(wmOperator *op, Object *ob, int type)
static int modifier_remove_exec(bContext *C, wmOperator *op)
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Main *bmain = CTX_data_main(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *ob = ED_object_active_context(C);
ModifierData *md = edit_modifier_property_get(op, ob, 0);
- int mode_orig = ob->mode;
+ int mode_orig = workspace->object_mode;
if (!md || !ED_object_modifier_remove(op->reports, bmain, ob, md))
return OPERATOR_CANCELLED;
@@ -893,11 +909,13 @@ static int modifier_remove_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
/* if cloth/softbody was removed, particle mode could be cleared */
- if (mode_orig & OB_MODE_PARTICLE_EDIT)
- if ((ob->mode & OB_MODE_PARTICLE_EDIT) == 0)
- if (view_layer->basact && view_layer->basact->object == ob)
+ if (mode_orig & OB_MODE_PARTICLE_EDIT) {
+ if ((workspace->object_mode & OB_MODE_PARTICLE_EDIT) == 0) {
+ if (view_layer->basact && view_layer->basact->object == ob) {
WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_OBJECT, NULL);
-
+ }
+ }
+ }
return OPERATOR_FINISHED;
}
@@ -1056,14 +1074,16 @@ void OBJECT_OT_modifier_apply(wmOperatorType *ot)
static int modifier_convert_exec(bContext *C, wmOperator *op)
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *ob = ED_object_active_context(C);
ModifierData *md = edit_modifier_property_get(op, ob, 0);
-
- if (!md || !ED_object_modifier_convert(op->reports, bmain, scene, view_layer, ob, md))
+
+ if (!md || !ED_object_modifier_convert(op->reports, bmain, scene, view_layer, ob, workspace->object_mode, md)) {
return OPERATOR_CANCELLED;
+ }
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
@@ -1147,10 +1167,13 @@ static int multires_higher_levels_delete_exec(bContext *C, wmOperator *op)
if (!mmd)
return OPERATOR_CANCELLED;
-
- multiresModifier_del_levels(mmd, ob, 1);
- ED_object_iter_other(CTX_data_main(C), ob, true,
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
+
+ multiresModifier_del_levels(mmd, ob, 1, eval_ctx.object_mode);
+
+ ED_object_iter_other(&eval_ctx, CTX_data_main(C), ob, true,
ED_object_multires_update_totlevels_cb,
&mmd->totlvl);
@@ -1191,17 +1214,20 @@ static int multires_subdivide_exec(bContext *C, wmOperator *op)
if (!mmd)
return OPERATOR_CANCELLED;
-
- multiresModifier_subdivide(mmd, ob, 0, mmd->simple);
- ED_object_iter_other(CTX_data_main(C), ob, true,
- ED_object_multires_update_totlevels_cb,
- &mmd->totlvl);
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
+ multiresModifier_subdivide(mmd, ob, 0, mmd->simple, eval_ctx.object_mode);
+
+ ED_object_iter_other(
+ &eval_ctx, CTX_data_main(C), ob, true,
+ ED_object_multires_update_totlevels_cb,
+ &mmd->totlvl);
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
- if (ob->mode & OB_MODE_SCULPT) {
+ if (eval_ctx.mode & OB_MODE_SCULPT) {
/* ensure that grid paint mask layer is created */
BKE_sculpt_mask_layers_ensure(ob, mmd);
}
@@ -1415,8 +1441,9 @@ static int multires_base_apply_exec(bContext *C, wmOperator *op)
if (!mmd)
return OPERATOR_CANCELLED;
-
- multiresModifier_base_apply(mmd, ob);
+
+ const WorkSpace *workspace = CTX_wm_workspace(C);
+ multiresModifier_base_apply(mmd, ob, workspace->object_mode);
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index 9c321f5cb79..ba3541b428a 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -47,6 +47,8 @@
#include "ED_screen.h"
#include "ED_object.h"
+#include "DEG_depsgraph.h"
+
#include "object_intern.h"
@@ -290,8 +292,9 @@ void ED_operatormacros_object(void)
static int object_mode_poll(bContext *C)
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Object *ob = CTX_data_active_object(C);
- return (!ob || ob->mode == OB_MODE_OBJECT);
+ return (!ob || workspace->object_mode == OB_MODE_OBJECT);
}
void ED_keymap_object(wmKeyConfig *keyconf)
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index d73e3aabaf0..9e6a5778490 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -717,7 +717,8 @@ bool ED_object_parent_set(ReportList *reports, const bContext *C, Scene *scene,
switch (partype) {
case PAR_CURVE: /* curve deform */
if (modifiers_isDeformedByCurve(ob) != par) {
- md = ED_object_modifier_add(reports, bmain, scene, ob, NULL, eModifierType_Curve);
+ md = ED_object_modifier_add(
+ reports, bmain, scene, ob, eval_ctx.object_mode, NULL, eModifierType_Curve);
if (md) {
((CurveModifierData *)md)->object = par;
}
@@ -728,7 +729,8 @@ bool ED_object_parent_set(ReportList *reports, const bContext *C, Scene *scene,
break;
case PAR_LATTICE: /* lattice deform */
if (modifiers_isDeformedByLattice(ob) != par) {
- md = ED_object_modifier_add(reports, bmain, scene, ob, NULL, eModifierType_Lattice);
+ md = ED_object_modifier_add(
+ reports, bmain, scene, ob, eval_ctx.object_mode, NULL, eModifierType_Lattice);
if (md) {
((LatticeModifierData *)md)->object = par;
}
@@ -736,7 +738,8 @@ bool ED_object_parent_set(ReportList *reports, const bContext *C, Scene *scene,
break;
default: /* armature deform */
if (modifiers_isDeformedByArmature(ob) != par) {
- md = ED_object_modifier_add(reports, bmain, scene, ob, NULL, eModifierType_Armature);
+ md = ED_object_modifier_add(
+ reports, bmain, scene, ob, eval_ctx.object_mode, NULL, eModifierType_Armature);
if (md) {
((ArmatureModifierData *)md)->object = par;
}
@@ -1425,6 +1428,7 @@ static bool allow_make_links_data(const int type, Object *ob_src, Object *ob_dst
static int make_links_data_exec(bContext *C, wmOperator *op)
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Main *bmain = CTX_data_main(C);
const int type = RNA_enum_get(op->ptr, "type");
Object *ob_src;
@@ -1509,7 +1513,7 @@ static int make_links_data_exec(bContext *C, wmOperator *op)
}
break;
case MAKE_LINKS_MODIFIERS:
- BKE_object_link_modifiers(ob_dst, ob_src);
+ BKE_object_link_modifiers(ob_dst, ob_src, workspace->object_mode);
DEG_id_tag_update(&ob_dst->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
break;
case MAKE_LINKS_FONTS:
@@ -2411,7 +2415,6 @@ static int make_override_static_exec(bContext *C, wmOperator *op)
bool success = false;
if (!ID_IS_LINKED(obact) && obact->dup_group != NULL && ID_IS_LINKED(obact->dup_group)) {
-#if 0 /* Not working yet! */
Base *base = BLI_findlink(&obact->dup_group->view_layer->object_bases, RNA_enum_get(op->ptr, "object"));
Object *obgroup = obact;
obact = base->object;
@@ -2424,7 +2427,7 @@ static int make_override_static_exec(bContext *C, wmOperator *op)
FOREACH_GROUP_OBJECT(obgroup->dup_group, ob)
{
- make_override_tag_object(obact, ob);
+ make_override_static_tag_object(obact, ob);
}
FOREACH_GROUP_OBJECT_END;
@@ -2435,7 +2438,7 @@ static int make_override_static_exec(bContext *C, wmOperator *op)
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *new_obact = (Object *)obact->id.newid;
if (new_obact != NULL && (base = BKE_view_layer_base_find(view_layer, new_obact)) == NULL) {
- BKE_collection_object_add_from(scene, obact, new_obact);
+ BKE_collection_object_add_from(scene, obgroup, new_obact);
base = BKE_view_layer_base_find(view_layer, new_obact);
BKE_view_layer_base_select(view_layer, base);
}
@@ -2453,9 +2456,6 @@ static int make_override_static_exec(bContext *C, wmOperator *op)
/* Cleanup. */
BKE_main_id_clear_newpoins(bmain);
BKE_main_id_tag_listbase(&bmain->object, LIB_TAG_DOIT, false);
-#else
- UNUSED_VARS(op);
-#endif
}
/* Else, poll func ensures us that ID_IS_LINKED(obact) is true. */
else if (obact->type == OB_ARMATURE) {
@@ -2512,8 +2512,8 @@ void OBJECT_OT_make_override_static(wmOperatorType *ot)
/* properties */
PropertyRNA *prop;
- prop = RNA_def_enum(ot->srna, "object", DummyRNA_DEFAULT_items, 0, "Proxy Object",
- "Name of lib-linked/grouped object to make a proxy for");
+ prop = RNA_def_enum(ot->srna, "object", DummyRNA_DEFAULT_items, 0, "Override Object",
+ "Name of lib-linked/group object to make an override from");
RNA_def_enum_funcs(prop, proxy_group_object_itemf);
RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
ot->prop = prop;
diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c
index b20fe9a004c..8a62438dc80 100644
--- a/source/blender/editors/object/object_select.c
+++ b/source/blender/editors/object/object_select.c
@@ -56,7 +56,9 @@
#include "BKE_layer.h"
#include "BKE_main.h"
#include "BKE_material.h"
+#include "BKE_object.h"
#include "BKE_particle.h"
+#include "BKE_paint.h"
#include "BKE_property.h"
#include "BKE_report.h"
#include "BKE_scene.h"
@@ -64,6 +66,8 @@
#include "BKE_library.h"
#include "BKE_deform.h"
+#include "DEG_depsgraph.h"
+
#include "WM_api.h"
#include "WM_types.h"
@@ -119,12 +123,82 @@ void ED_object_base_select(Base *base, eObjectSelect_Mode mode)
void ED_object_base_activate(bContext *C, Base *base)
{
ViewLayer *view_layer = CTX_data_view_layer(C);
+
+ WorkSpace *workspace = CTX_wm_workspace(C);
+
+ bool reset = true;
+ if (base) {
+ Object *ob_prev = OBACT(view_layer);
+ Object *ob_curr = base->object;
+ if (ob_prev != NULL) {
+ if (ob_prev->type == ob_curr->type) {
+ reset = false;
+ }
+ }
+ }
+
+ eObjectMode object_mode = workspace->object_mode;
+
+ {
+ Scene *scene = CTX_data_scene(C);
+ /* We don't know the previous active object in update.
+ *
+ * Not correct because it's possible other work-spaces use these.
+ * although that's a corner case. */
+ if (workspace->object_mode & OB_MODE_EDIT) {
+ FOREACH_OBJECT(view_layer, ob) {
+ if (ob != base->object) {
+ if (BKE_object_is_in_editmode(ob)) {
+ ED_object_editmode_exit_ex(NULL, workspace, scene, ob, EM_FREEDATA);
+ }
+ }
+ }
+ FOREACH_OBJECT_END;
+ }
+ else if (workspace->object_mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_SCULPT)) {
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
+ FOREACH_OBJECT(view_layer, ob) {
+ if (ob != base->object) {
+ if (ob->sculpt) {
+ switch (ob->sculpt->mode_type) {
+ case OB_MODE_VERTEX_PAINT:
+ {
+ ED_object_vpaintmode_exit_ex(workspace, ob);
+ break;
+ }
+ case OB_MODE_WEIGHT_PAINT:
+ {
+ ED_object_wpaintmode_exit_ex(workspace, ob);
+ break;
+ }
+ case OB_MODE_SCULPT:
+ {
+ ED_object_sculptmode_exit_ex(&eval_ctx, workspace, scene, ob);
+ break;
+ }
+ }
+ }
+ }
+ }
+ FOREACH_OBJECT_END;
+ }
+ }
+
+ workspace->object_mode = OB_MODE_OBJECT;
+
view_layer->basact = base;
+ if (reset == false) {
+ wmOperatorType *ot = WM_operatortype_find("OBJECT_OT_mode_set", false);
+ PointerRNA ptr;
+ WM_operator_properties_create_ptr(&ptr, ot);
+ RNA_enum_set(&ptr, "mode", object_mode);
+ WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &ptr);
+ WM_operator_properties_free(&ptr);
+ }
+
if (base) {
-#ifdef USE_WORKSPACE_MODE
- BKE_workspace_object_mode_set(CTX_wm_workspace(C), CTX_data_scene(C), base->object->mode);
-#endif
WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, view_layer);
}
else {
@@ -138,13 +212,14 @@ static int objects_selectable_poll(bContext *C)
{
/* we don't check for linked scenes here, selection is
* still allowed then for inspection of scene */
- Object *obact = CTX_data_active_object(C);
-
- if (CTX_data_edit_object(C))
+ if (CTX_data_edit_object(C)) {
return 0;
- if (obact && obact->mode)
+ }
+
+ const WorkSpace *workspace = CTX_wm_workspace(C);
+ if (workspace->object_mode != OB_MODE_OBJECT) {
return 0;
-
+ }
return 1;
}
diff --git a/source/blender/editors/object/object_shapekey.c b/source/blender/editors/object/object_shapekey.c
index 1f80cb5f0bc..bd3bd8fd0a5 100644
--- a/source/blender/editors/object/object_shapekey.c
+++ b/source/blender/editors/object/object_shapekey.c
@@ -49,6 +49,7 @@
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
+#include "DNA_workspace_types.h"
#include "BKE_context.h"
#include "BKE_key.h"
@@ -225,18 +226,20 @@ static bool object_shape_key_mirror(bContext *C, Object *ob,
static int shape_key_mode_poll(bContext *C)
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Object *ob = ED_object_context(C);
ID *data = (ob) ? ob->data : NULL;
- return (ob && !ID_IS_LINKED(ob) && data && !ID_IS_LINKED(data) && ob->mode != OB_MODE_EDIT);
+ return (ob && !ID_IS_LINKED(ob) && data && !ID_IS_LINKED(data) && (workspace->object_mode != OB_MODE_EDIT));
}
static int shape_key_mode_exists_poll(bContext *C)
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Object *ob = ED_object_context(C);
ID *data = (ob) ? ob->data : NULL;
/* same as shape_key_mode_poll */
- return (ob && !ID_IS_LINKED(ob) && data && !ID_IS_LINKED(data) && ob->mode != OB_MODE_EDIT) &&
+ return (ob && !ID_IS_LINKED(ob) && data && !ID_IS_LINKED(data) && (workspace->object_mode != OB_MODE_EDIT)) &&
/* check a keyblock exists */
(BKE_keyblock_from_object(ob) != NULL);
}
@@ -244,12 +247,13 @@ static int shape_key_mode_exists_poll(bContext *C)
static int shape_key_move_poll(bContext *C)
{
/* Same as shape_key_mode_exists_poll above, but ensure we have at least two shapes! */
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Object *ob = ED_object_context(C);
ID *data = (ob) ? ob->data : NULL;
Key *key = BKE_key_from_object(ob);
return (ob && !ID_IS_LINKED(ob) && data && !ID_IS_LINKED(data) &&
- ob->mode != OB_MODE_EDIT && key && key->totkey > 1);
+ (workspace->object_mode != OB_MODE_EDIT) && key && key->totkey > 1);
}
static int shape_key_poll(bContext *C)
diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c
index 100b9018d00..b336b560ef2 100644
--- a/source/blender/editors/object/object_transform.c
+++ b/source/blender/editors/object/object_transform.c
@@ -245,6 +245,7 @@ static int object_clear_transform_generic_exec(bContext *C, wmOperator *op,
void (*clear_func)(Object *, const bool),
const char default_ksName[])
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Scene *scene = CTX_data_scene(C);
KeyingSet *ks;
const bool clear_delta = RNA_boolean_get(op->ptr, "clear_delta");
@@ -263,7 +264,7 @@ static int object_clear_transform_generic_exec(bContext *C, wmOperator *op,
*/
CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects)
{
- if (!(ob->mode & OB_MODE_WEIGHT_PAINT)) {
+ if (!(workspace->object_mode & OB_MODE_WEIGHT_PAINT)) {
/* run provided clearing function */
clear_func(ob, clear_delta);
@@ -982,7 +983,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
/* Function to recenter armatures in editarmature.c
* Bone + object locations are handled there.
*/
- ED_armature_origin_set(scene, ob, cursor, centermode, around);
+ ED_armature_origin_set(ob, cursor, centermode, around);
tot_change++;
arm->id.tag |= LIB_TAG_DOIT;
diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c
index bf2da284591..8c6ccb7e8f0 100644
--- a/source/blender/editors/object/object_vgroup.c
+++ b/source/blender/editors/object/object_vgroup.c
@@ -43,6 +43,7 @@
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "DNA_workspace_types.h"
#include "BLI_alloca.h"
#include "BLI_array.h"
@@ -84,9 +85,9 @@
#include "object_intern.h"
/************************ Exported Functions **********************/
-static bool vertex_group_use_vert_sel(Object *ob)
+static bool vertex_group_use_vert_sel(const Object *ob)
{
- if (ob->mode == OB_MODE_EDIT) {
+ if (BKE_object_is_in_editmode(ob)) {
return true;
}
else if (ob->type == OB_MESH && ((Mesh *)ob->data)->editflag & ME_EDIT_PAINT_VERT_SEL) {
@@ -107,13 +108,15 @@ static Lattice *vgroup_edit_lattice(Object *ob)
bool ED_vgroup_sync_from_pose(Object *ob)
{
Object *armobj = BKE_object_pose_armature_get(ob);
- if (armobj && (armobj->mode & OB_MODE_POSE)) {
+ if (armobj) {
struct bArmature *arm = armobj->data;
- if (arm->act_bone) {
- int def_num = defgroup_name_index(ob, arm->act_bone->name);
- if (def_num != -1) {
- ob->actdef = def_num + 1;
- return true;
+ if (arm->flag & ARM_POSEMODE) {
+ if (arm->act_bone) {
+ int def_num = defgroup_name_index(ob, arm->act_bone->name);
+ if (def_num != -1) {
+ ob->actdef = def_num + 1;
+ return true;
+ }
}
}
}
@@ -255,9 +258,10 @@ bool ED_vgroup_parray_alloc(ID *id, MDeformVert ***dvert_arr, int *dvert_tot, co
*
* \note \a dvert_array has mirrored weights filled in, incase cleanup operations are needed on both.
*/
-void ED_vgroup_parray_mirror_sync(Object *ob,
- MDeformVert **dvert_array, const int dvert_tot,
- const bool *vgroup_validmap, const int vgroup_tot)
+void ED_vgroup_parray_mirror_sync(
+ Object *ob,
+ MDeformVert **dvert_array, const int dvert_tot,
+ const bool *vgroup_validmap, const int vgroup_tot)
{
BMEditMesh *em = BKE_editmesh_from_object(ob);
MDeformVert **dvert_array_all = NULL;
@@ -300,8 +304,9 @@ void ED_vgroup_parray_mirror_sync(Object *ob,
*
* similar to #ED_vgroup_parray_mirror_sync but only fill in mirror points.
*/
-void ED_vgroup_parray_mirror_assign(Object *ob,
- MDeformVert **dvert_array, const int dvert_tot)
+void ED_vgroup_parray_mirror_assign(
+ Object *ob,
+ MDeformVert **dvert_array, const int dvert_tot)
{
BMEditMesh *em = BKE_editmesh_from_object(ob);
MDeformVert **dvert_array_all = NULL;
@@ -332,9 +337,10 @@ void ED_vgroup_parray_mirror_assign(Object *ob,
MEM_freeN(dvert_array_all);
}
-void ED_vgroup_parray_remove_zero(MDeformVert **dvert_array, const int dvert_tot,
- const bool *vgroup_validmap, const int vgroup_tot,
- const float epsilon, const bool keep_single)
+void ED_vgroup_parray_remove_zero(
+ MDeformVert **dvert_array, const int dvert_tot,
+ const bool *vgroup_validmap, const int vgroup_tot,
+ const float epsilon, const bool keep_single)
{
MDeformVert *dv;
int i;
@@ -484,9 +490,10 @@ void ED_vgroup_parray_from_weight_array(
/* TODO, cache flip data to speedup calls within a loop. */
-static void mesh_defvert_mirror_update_internal(Object *ob,
- MDeformVert *dvert_dst, MDeformVert *dvert_src,
- const int def_nr)
+static void mesh_defvert_mirror_update_internal(
+ Object *ob,
+ MDeformVert *dvert_dst, MDeformVert *dvert_src,
+ const int def_nr)
{
if (def_nr == -1) {
/* all vgroups, add groups where neded */
@@ -504,8 +511,9 @@ static void mesh_defvert_mirror_update_internal(Object *ob,
}
}
-static void ED_mesh_defvert_mirror_update_em(Object *ob, BMVert *eve, int def_nr, int vidx,
- const int cd_dvert_offset)
+static void ED_mesh_defvert_mirror_update_em(
+ Object *ob, BMVert *eve, int def_nr, int vidx,
+ const int cd_dvert_offset)
{
Mesh *me = ob->data;
BMEditMesh *em = me->edit_btmesh;
@@ -713,26 +721,30 @@ const EnumPropertyItem *ED_object_vgroup_selection_itemf_helper(
return item;
}
-static const EnumPropertyItem *rna_vertex_group_with_single_itemf(bContext *C, PointerRNA *ptr,
- PropertyRNA *prop, bool *r_free)
+static const EnumPropertyItem *rna_vertex_group_with_single_itemf(
+ bContext *C, PointerRNA *ptr,
+ PropertyRNA *prop, bool *r_free)
{
return ED_object_vgroup_selection_itemf_helper(C, ptr, prop, r_free, WT_VGROUP_MASK_ALL);
}
-static const EnumPropertyItem *rna_vertex_group_select_itemf(bContext *C, PointerRNA *ptr,
- PropertyRNA *prop, bool *r_free)
+static const EnumPropertyItem *rna_vertex_group_select_itemf(
+ bContext *C, PointerRNA *ptr,
+ PropertyRNA *prop, bool *r_free)
{
- return ED_object_vgroup_selection_itemf_helper(C, ptr, prop, r_free, WT_VGROUP_MASK_ALL & ~(1 << WT_VGROUP_ACTIVE));
+ return ED_object_vgroup_selection_itemf_helper(
+ C, ptr, prop, r_free, WT_VGROUP_MASK_ALL & ~(1 << WT_VGROUP_ACTIVE));
}
static void vgroup_operator_subset_select_props(wmOperatorType *ot, bool use_active)
{
PropertyRNA *prop;
- prop = RNA_def_enum(ot->srna,
- "group_select_mode", DummyRNA_NULL_items,
- use_active ? WT_VGROUP_ACTIVE : WT_VGROUP_ALL, "Subset",
- "Define which subset of Groups shall be used");
+ prop = RNA_def_enum(
+ ot->srna,
+ "group_select_mode", DummyRNA_NULL_items,
+ use_active ? WT_VGROUP_ACTIVE : WT_VGROUP_ALL, "Subset",
+ "Define which subset of Groups shall be used");
if (use_active) {
RNA_def_enum_funcs(prop, rna_vertex_group_with_single_itemf);
@@ -749,9 +761,10 @@ static void vgroup_operator_subset_select_props(wmOperatorType *ot, bool use_act
/* for Mesh in Object mode */
/* allows editmode for Lattice */
-static void ED_vgroup_nr_vert_add(Object *ob,
- const int def_nr, const int vertnum,
- const float weight, const int assignmode)
+static void ED_vgroup_nr_vert_add(
+ Object *ob,
+ const int def_nr, const int vertnum,
+ const float weight, const int assignmode)
{
/* add the vert to the deform group with the
* specified number
@@ -1222,9 +1235,10 @@ static void getSingleCoordinate(MVert *points, int count, float coord[3])
* compute the amount of vertical distance relative to the plane and store it in dists,
* then get the horizontal and vertical change and store them in changes
*/
-static void getVerticalAndHorizontalChange(const float norm[3], float d, const float coord[3],
- const float start[3], float distToStart,
- float *end, float (*changes)[2], float *dists, int index)
+static void getVerticalAndHorizontalChange(
+ const float norm[3], float d, const float coord[3],
+ const float start[3], float distToStart,
+ float *end, float (*changes)[2], float *dists, int index)
{
/* A = Q - ((Q - P).N)N
* D = (a * x0 + b * y0 +c * z0 + d) */
@@ -1275,8 +1289,9 @@ static DerivedMesh *dm_deform_recalc(EvaluationContext *eval_ctx, Scene *scene,
* norm and d are the plane's properties for the equation: ax + by + cz + d = 0
* coord is a point on the plane
*/
-static void moveCloserToDistanceFromPlane(EvaluationContext *eval_ctx, Scene *scene, Object *ob, Mesh *me, int index, float norm[3],
- float coord[3], float d, float distToBe, float strength, float cp)
+static void moveCloserToDistanceFromPlane(
+ EvaluationContext *eval_ctx, Scene *scene, Object *ob, Mesh *me, int index, float norm[3],
+ float coord[3], float d, float distToBe, float strength, float cp)
{
DerivedMesh *dm;
MDeformWeight *dw;
@@ -1499,9 +1514,10 @@ static void vgroup_fix(const bContext *C, Scene *scene, Object *ob, float distTo
}
}
-static void vgroup_levels_subset(Object *ob, const bool *vgroup_validmap, const int vgroup_tot,
- const int UNUSED(subset_count),
- const float offset, const float gain)
+static void vgroup_levels_subset(
+ Object *ob, const bool *vgroup_validmap, const int vgroup_tot,
+ const int UNUSED(subset_count),
+ const float offset, const float gain)
{
MDeformWeight *dw;
MDeformVert *dv, **dvert_array = NULL;
@@ -1536,8 +1552,9 @@ static void vgroup_levels_subset(Object *ob, const bool *vgroup_validmap, const
}
if (use_mirror && use_vert_sel) {
- ED_vgroup_parray_mirror_sync(ob, dvert_array, dvert_tot,
- vgroup_validmap, vgroup_tot);
+ ED_vgroup_parray_mirror_sync(
+ ob, dvert_array, dvert_tot,
+ vgroup_validmap, vgroup_tot);
}
MEM_freeN(dvert_array);
@@ -1594,12 +1611,14 @@ static bool vgroup_normalize_all(
/* in case its not selected */
if ((dv = dvert_array[i])) {
if (lock_flags) {
- defvert_normalize_lock_map(dv, vgroup_validmap, vgroup_tot,
- lock_flags, defbase_tot);
+ defvert_normalize_lock_map(
+ dv, vgroup_validmap, vgroup_tot,
+ lock_flags, defbase_tot);
}
else if (lock_active) {
- defvert_normalize_lock_single(dv, vgroup_validmap, vgroup_tot,
- def_nr);
+ defvert_normalize_lock_single(
+ dv, vgroup_validmap, vgroup_tot,
+ def_nr);
}
else {
defvert_normalize_subset(dv, vgroup_validmap, vgroup_tot);
@@ -1666,9 +1685,10 @@ static void vgroup_lock_all(Object *ob, int action)
}
}
-static void vgroup_invert_subset(Object *ob,
- const bool *vgroup_validmap, const int vgroup_tot,
- const int UNUSED(subset_count), const bool auto_assign, const bool auto_remove)
+static void vgroup_invert_subset(
+ Object *ob,
+ const bool *vgroup_validmap, const int vgroup_tot,
+ const int UNUSED(subset_count), const bool auto_assign, const bool auto_remove)
{
MDeformWeight *dw;
MDeformVert *dv, **dvert_array = NULL;
@@ -1707,14 +1727,16 @@ static void vgroup_invert_subset(Object *ob,
}
if (use_mirror && use_vert_sel) {
- ED_vgroup_parray_mirror_sync(ob, dvert_array, dvert_tot,
- vgroup_validmap, vgroup_tot);
+ ED_vgroup_parray_mirror_sync(
+ ob, dvert_array, dvert_tot,
+ vgroup_validmap, vgroup_tot);
}
if (auto_remove) {
- ED_vgroup_parray_remove_zero(dvert_array, dvert_tot,
- vgroup_validmap, vgroup_tot,
- 0.0f, false);
+ ED_vgroup_parray_remove_zero(
+ dvert_array, dvert_tot,
+ vgroup_validmap, vgroup_tot,
+ 0.0f, false);
}
MEM_freeN(dvert_array);
@@ -1934,8 +1956,9 @@ static void vgroup_smooth_subset(
/* not so efficient to get 'dvert_array' again just so unselected verts are NULL'd */
if (use_mirror) {
ED_vgroup_parray_alloc(ob->data, &dvert_array, &dvert_tot, true);
- ED_vgroup_parray_mirror_sync(ob, dvert_array, dvert_tot,
- vgroup_validmap, vgroup_tot);
+ ED_vgroup_parray_mirror_sync(
+ ob, dvert_array, dvert_tot,
+ vgroup_validmap, vgroup_tot);
if (dvert_array)
MEM_freeN(dvert_array);
}
@@ -1959,11 +1982,12 @@ static int inv_cmp_mdef_vert_weights(const void *a1, const void *a2)
/* Used for limiting the number of influencing bones per vertex when exporting
* skinned meshes. if all_deform_weights is True, limit all deform modifiers
* to max_weights regardless of type, otherwise, only limit the number of influencing bones per vertex*/
-static int vgroup_limit_total_subset(Object *ob,
- const bool *vgroup_validmap,
- const int vgroup_tot,
- const int subset_count,
- const int max_weights)
+static int vgroup_limit_total_subset(
+ Object *ob,
+ const bool *vgroup_validmap,
+ const int vgroup_tot,
+ const int subset_count,
+ const int max_weights)
{
MDeformVert *dv, **dvert_array = NULL;
int i, dvert_tot = 0;
@@ -2030,8 +2054,9 @@ static int vgroup_limit_total_subset(Object *ob,
}
-static void vgroup_clean_subset(Object *ob, const bool *vgroup_validmap, const int vgroup_tot, const int UNUSED(subset_count),
- const float epsilon, const bool keep_single)
+static void vgroup_clean_subset(
+ Object *ob, const bool *vgroup_validmap, const int vgroup_tot, const int UNUSED(subset_count),
+ const float epsilon, const bool keep_single)
{
MDeformVert **dvert_array = NULL;
int dvert_tot = 0;
@@ -2048,16 +2073,18 @@ static void vgroup_clean_subset(Object *ob, const bool *vgroup_validmap, const i
ED_vgroup_parray_mirror_assign(ob, dvert_array, dvert_tot);
}
- ED_vgroup_parray_remove_zero(dvert_array, dvert_tot,
- vgroup_validmap, vgroup_tot,
- epsilon, keep_single);
+ ED_vgroup_parray_remove_zero(
+ dvert_array, dvert_tot,
+ vgroup_validmap, vgroup_tot,
+ epsilon, keep_single);
MEM_freeN(dvert_array);
}
}
-static void vgroup_quantize_subset(Object *ob, const bool *vgroup_validmap, const int vgroup_tot, const int UNUSED(subset_count),
- const int steps)
+static void vgroup_quantize_subset(
+ Object *ob, const bool *vgroup_validmap, const int vgroup_tot, const int UNUSED(subset_count),
+ const int steps)
{
MDeformVert **dvert_array = NULL;
int dvert_tot = 0;
@@ -2095,11 +2122,12 @@ static void vgroup_quantize_subset(Object *ob, const bool *vgroup_validmap, cons
}
}
-static void dvert_mirror_op(MDeformVert *dvert, MDeformVert *dvert_mirr,
- const char sel, const char sel_mirr,
- const int *flip_map, const int flip_map_len,
- const bool mirror_weights, const bool flip_vgroups, const bool all_vgroups,
- const int act_vgroup)
+static void dvert_mirror_op(
+ MDeformVert *dvert, MDeformVert *dvert_mirr,
+ const char sel, const char sel_mirr,
+ const int *flip_map, const int flip_map_len,
+ const bool mirror_weights, const bool flip_vgroups, const bool all_vgroups,
+ const int act_vgroup)
{
BLI_assert(sel || sel_mirr);
@@ -2158,10 +2186,11 @@ static void dvert_mirror_op(MDeformVert *dvert, MDeformVert *dvert_mirr,
/* TODO, vgroup locking */
/* TODO, face masking */
-void ED_vgroup_mirror(Object *ob,
- const bool mirror_weights, const bool flip_vgroups,
- const bool all_vgroups, const bool use_topology,
- int *r_totmirr, int *r_totfail)
+void ED_vgroup_mirror(
+ Object *ob,
+ const bool mirror_weights, const bool flip_vgroups,
+ const bool all_vgroups, const bool use_topology,
+ int *r_totmirr, int *r_totfail)
{
#define VGROUP_MIRR_OP \
@@ -2521,12 +2550,13 @@ static int vertex_group_vert_poll_ex(bContext *C, const bool needs_select, const
return false;
}
+ const WorkSpace *workspace = CTX_wm_workspace(C);
if (BKE_object_is_in_editmode_vgroup(ob)) {
return true;
}
- else if (ob->mode & OB_MODE_WEIGHT_PAINT) {
+ else if (workspace->object_mode & OB_MODE_WEIGHT_PAINT) {
if (needs_select) {
- if (BKE_object_is_in_wpaint_select_vert(ob)) {
+ if (BKE_object_is_in_wpaint_select_vert(ob, workspace->object_mode)) {
return true;
}
else {
@@ -2578,8 +2608,9 @@ static int vertex_group_vert_select_unlocked_poll(bContext *C)
if (!(ob && !ID_IS_LINKED(ob) && data && !ID_IS_LINKED(data)))
return 0;
+ const WorkSpace *workspace = CTX_wm_workspace(C);
if (!(BKE_object_is_in_editmode_vgroup(ob) ||
- BKE_object_is_in_wpaint_select_vert(ob)))
+ BKE_object_is_in_wpaint_select_vert(ob, workspace->object_mode)))
{
return 0;
}
@@ -2605,8 +2636,9 @@ static int vertex_group_vert_select_mesh_poll(bContext *C)
if (ob->type != OB_MESH)
return 0;
+ const WorkSpace *workspace = CTX_wm_workspace(C);
return (BKE_object_is_in_editmode_vgroup(ob) ||
- BKE_object_is_in_wpaint_select_vert(ob));
+ BKE_object_is_in_wpaint_select_vert(ob, workspace->object_mode));
}
static int vertex_group_add_exec(bContext *C, wmOperator *UNUSED(op))
@@ -3282,12 +3314,13 @@ static int vertex_group_mirror_exec(bContext *C, wmOperator *op)
Object *ob = ED_object_context(C);
int totmirr = 0, totfail = 0;
- ED_vgroup_mirror(ob,
- RNA_boolean_get(op->ptr, "mirror_weights"),
- RNA_boolean_get(op->ptr, "flip_group_names"),
- RNA_boolean_get(op->ptr, "all_groups"),
- RNA_boolean_get(op->ptr, "use_topology"),
- &totmirr, &totfail);
+ ED_vgroup_mirror(
+ ob,
+ RNA_boolean_get(op->ptr, "mirror_weights"),
+ RNA_boolean_get(op->ptr, "flip_group_names"),
+ RNA_boolean_get(op->ptr, "all_groups"),
+ RNA_boolean_get(op->ptr, "use_topology"),
+ &totmirr, &totfail);
ED_mesh_report_mirror(op, totmirr, totfail);
@@ -3489,7 +3522,8 @@ static char *vgroup_init_remap(Object *ob)
return name_array;
}
-static int vgroup_do_remap(Object *ob, const char *name_array, wmOperator *op)
+static int vgroup_do_remap(
+ const EvaluationContext *eval_ctx, Object *ob, const char *name_array, wmOperator *op)
{
MDeformVert *dvert = NULL;
bDeformGroup *def;
@@ -3510,7 +3544,7 @@ static int vgroup_do_remap(Object *ob, const char *name_array, wmOperator *op)
BLI_assert(sort_map[i] != -1);
}
- if (ob->mode == OB_MODE_EDIT) {
+ if (eval_ctx->object_mode == OB_MODE_EDIT) {
if (ob->type == OB_MESH) {
BMEditMesh *em = BKE_editmesh_from_object(ob);
const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT);
@@ -3608,6 +3642,8 @@ enum {
static int vertex_group_sort_exec(bContext *C, wmOperator *op)
{
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
Object *ob = ED_object_context(C);
char *name_array;
int ret;
@@ -3627,7 +3663,7 @@ static int vertex_group_sort_exec(bContext *C, wmOperator *op)
}
/*remap vgroup data to map to correct names*/
- ret = vgroup_do_remap(ob, name_array, op);
+ ret = vgroup_do_remap(&eval_ctx, ob, name_array, op);
if (ret != OPERATOR_CANCELLED) {
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
@@ -3663,6 +3699,8 @@ void OBJECT_OT_vertex_group_sort(wmOperatorType *ot)
static int vgroup_move_exec(bContext *C, wmOperator *op)
{
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
Object *ob = ED_object_context(C);
bDeformGroup *def;
char *name_array;
@@ -3677,7 +3715,7 @@ static int vgroup_move_exec(bContext *C, wmOperator *op)
name_array = vgroup_init_remap(ob);
if (BLI_listbase_link_move(&ob->defbase, def, dir)) {
- ret = vgroup_do_remap(ob, name_array, op);
+ ret = vgroup_do_remap(&eval_ctx, ob, name_array, op);
if (ret != OPERATOR_CANCELLED) {
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c
index 89dd46681cb..376e4659b92 100644
--- a/source/blender/editors/physics/particle_edit.c
+++ b/source/blender/editors/physics/particle_edit.c
@@ -43,9 +43,10 @@
#include "DNA_view3d_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
+#include "DNA_workspace_types.h"
#include "BLI_math.h"
-#include "BLI_lasso.h"
+#include "BLI_lasso_2d.h"
#include "BLI_listbase.h"
#include "BLI_string.h"
#include "BLI_kdtree.h"
@@ -113,26 +114,28 @@ void update_world_cos(Object *ob, PTCacheEdit *edit);
int PE_poll(bContext *C)
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Scene *scene= CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *ob= CTX_data_active_object(C);
- if (!scene || !view_layer || !ob || !(ob->mode & OB_MODE_PARTICLE_EDIT))
+ if (!scene || !view_layer || !ob || !(workspace->object_mode & OB_MODE_PARTICLE_EDIT)) {
return 0;
-
+ }
return (PE_get_current(scene, view_layer, ob) != NULL);
}
int PE_hair_poll(bContext *C)
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Scene *scene= CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *ob= CTX_data_active_object(C);
PTCacheEdit *edit;
- if (!scene || !ob || !(ob->mode & OB_MODE_PARTICLE_EDIT))
+ if (!scene || !ob || !(workspace->object_mode & OB_MODE_PARTICLE_EDIT)) {
return 0;
-
+ }
edit= PE_get_current(scene, view_layer, ob);
return (edit && edit->psys);
@@ -312,12 +315,12 @@ PTCacheEdit *PE_get_current(Scene *scene, ViewLayer *view_layer, Object *ob)
PTCacheEdit *PE_create_current(const EvaluationContext *eval_ctx, Scene *scene, Object *ob)
{
- return pe_get_current(eval_ctx, scene, NULL, ob, 1);
+ return pe_get_current(eval_ctx, scene, eval_ctx->view_layer, ob, 1);
}
void PE_current_changed(const EvaluationContext *eval_ctx, Scene *scene, Object *ob)
{
- if (ob->mode == OB_MODE_PARTICLE_EDIT) {
+ if (eval_ctx->object_mode == OB_MODE_PARTICLE_EDIT) {
PE_create_current(eval_ctx, scene, ob);
}
}
@@ -1312,6 +1315,8 @@ void PE_update_object(const EvaluationContext *eval_ctx, Scene *scene, ViewLayer
if (edit->psys)
edit->psys->flag &= ~PSYS_HAIR_UPDATED;
+
+ DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
}
/************************************************/
@@ -2840,7 +2845,8 @@ void PARTICLE_OT_delete(wmOperatorType *ot)
/*************************** mirror operator **************************/
-static void PE_mirror_x(Scene *scene, ViewLayer *view_layer, Object *ob, int tagged)
+static void PE_mirror_x(
+ Scene *scene, ViewLayer *view_layer, Object *ob, int tagged)
{
Mesh *me= (Mesh *)(ob->data);
ParticleSystemModifierData *psmd;
@@ -3865,6 +3871,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
(sqrtf(dx * dx + dy * dy) > pset->brush[PE_BRUSH_ADD].step) : (dx != 0 || dy != 0)) || bedit->first)
{
PEData data= bedit->data;
+ data.context = C; // TODO(mai): why isnt this set in bedit->data?
view3d_operator_needs_opengl(C);
selected= (short)count_selected_keys(scene, edit);
@@ -4779,26 +4786,24 @@ static int particle_edit_toggle_poll(bContext *C)
static int particle_edit_toggle_exec(bContext *C, wmOperator *op)
{
+ struct WorkSpace *workspace = CTX_wm_workspace(C);
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
Scene *scene = CTX_data_scene(C);
Object *ob = CTX_data_active_object(C);
const int mode_flag = OB_MODE_PARTICLE_EDIT;
- const bool is_mode_set = (ob->mode & mode_flag) != 0;
-
- BKE_report(op->reports, RPT_INFO, "Particles are changing, editing is not possible");
- return OPERATOR_CANCELLED;
+ const bool is_mode_set = (eval_ctx.object_mode & mode_flag) != 0;
if (!is_mode_set) {
- if (!ED_object_mode_compat_set(C, ob, mode_flag, op->reports)) {
+ if (!ED_object_mode_compat_set(C, workspace, mode_flag, op->reports)) {
return OPERATOR_CANCELLED;
}
}
if (!is_mode_set) {
PTCacheEdit *edit;
- EvaluationContext eval_ctx;
- CTX_data_eval_ctx(C, &eval_ctx);
- ob->mode |= mode_flag;
+ workspace->object_mode |= mode_flag;
edit= PE_create_current(&eval_ctx, scene, ob);
/* mesh may have changed since last entering editmode.
@@ -4810,7 +4815,7 @@ static int particle_edit_toggle_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_PARTICLE, NULL);
}
else {
- ob->mode &= ~mode_flag;
+ workspace->object_mode &= ~mode_flag;
toggle_particle_cursor(C, 0);
WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_OBJECT, NULL);
}
diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c
index 1536c15525f..7a22a0d81d9 100644
--- a/source/blender/editors/physics/particle_object.c
+++ b/source/blender/editors/physics/particle_object.c
@@ -133,23 +133,25 @@ void OBJECT_OT_particle_system_add(wmOperatorType *ot)
static int particle_system_remove_exec(bContext *C, wmOperator *UNUSED(op))
{
+ WorkSpace *workspace = CTX_wm_workspace(C);
Object *ob = ED_object_context(C);
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
- int mode_orig;
+ eObjectMode mode_orig;
if (!scene || !ob)
return OPERATOR_CANCELLED;
- mode_orig = ob->mode;
+ mode_orig = workspace->object_mode;
object_remove_particle_system(scene, ob);
/* possible this isn't the active object
* object_remove_particle_system() clears the mode on the last psys
*/
if (mode_orig & OB_MODE_PARTICLE_EDIT) {
- if ((ob->mode & OB_MODE_PARTICLE_EDIT) == 0) {
+ if ((workspace->object_mode & OB_MODE_PARTICLE_EDIT) == 0) {
if (view_layer->basact && view_layer->basact->object == ob) {
+ workspace->object_mode &= ~OB_MODE_PARTICLE_EDIT;
WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_OBJECT, NULL);
}
}
diff --git a/source/blender/editors/physics/physics_fluid.c b/source/blender/editors/physics/physics_fluid.c
index 12e01228e1e..d9a7d288f9c 100644
--- a/source/blender/editors/physics/physics_fluid.c
+++ b/source/blender/editors/physics/physics_fluid.c
@@ -39,7 +39,7 @@
/* types */
#include "DNA_action_types.h"
#include "DNA_object_types.h"
-#include "DNA_object_fluidsim.h"
+#include "DNA_object_fluidsim_types.h"
#include "BLI_blenlib.h"
#include "BLI_math.h"
diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c
index 3be890f2c36..0130b93babf 100644
--- a/source/blender/editors/render/render_internal.c
+++ b/source/blender/editors/render/render_internal.c
@@ -339,12 +339,12 @@ static int screen_render_exec(bContext *C, wmOperator *op)
RE_SetReports(re, op->reports);
- BLI_begin_threaded_malloc();
+ BLI_threaded_malloc_begin();
if (is_animation)
RE_BlenderAnim(re, mainp, scene, camera_override, lay_override, scene->r.sfra, scene->r.efra, scene->r.frame_step);
else
RE_BlenderFrame(re, mainp, scene, view_layer, camera_override, lay_override, scene->r.cfra, is_write_still);
- BLI_end_threaded_malloc();
+ BLI_threaded_malloc_end();
RE_SetReports(re, NULL);
@@ -873,6 +873,8 @@ static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *even
* This is a problem for animation rendering since you cannot abort them.
* This also does not open an image editor space. */
if (RE_engine_is_opengl(re_type)) {
+ /* ensure at least 1 area shows result */
+ render_view_open(C, event->x, event->y, op->reports);
return screen_render_exec(C, op);
}
@@ -1442,8 +1444,10 @@ static bool render_view3d_flag_changed(RenderEngine *engine, const bContext *C)
job_update_flag |= PR_UPDATE_DATABASE;
/* load editmesh */
- if (scene->obedit)
- ED_object_editmode_load(scene->obedit);
+ Object *obedit = CTX_data_edit_object(C);
+ if (obedit) {
+ ED_object_editmode_load(obedit);
+ }
}
engine->update_flag = 0;
diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c
index 6e969067985..8eb9283790b 100644
--- a/source/blender/editors/render/render_opengl.c
+++ b/source/blender/editors/render/render_opengl.c
@@ -652,7 +652,7 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op)
sizey = (scene->r.size * scene->r.ysch) / 100;
/* corrects render size with actual size, not every card supports non-power-of-two dimensions */
- ofs = GPU_offscreen_create(sizex, sizey, full_samples ? 0 : samples, true, err_out);
+ ofs = GPU_offscreen_create(sizex, sizey, full_samples ? 0 : samples, true, true, err_out);
if (!ofs) {
BKE_reportf(op->reports, RPT_ERROR, "Failed to create OpenGL off-screen buffer, %s", err_out);
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index 2e3091268a9..c76a6aa175a 100644
--- a/source/blender/editors/render/render_preview.c
+++ b/source/blender/editors/render/render_preview.c
@@ -455,9 +455,18 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty
}
else {
/* use current scene world to light sphere */
- if (mat->pr_type == MA_SPHERE_A) {
+ if (mat->pr_type == MA_SPHERE_A && sp->pr_method == PR_BUTS_RENDER) {
+ /* Use current scene world to light sphere. */
sce->world = preview_get_localized_world(sp, scene->world);
}
+ else if (sce->world) {
+ /* Use a default world color. Using the current
+ * scene world can be slow if it has big textures. */
+ sce->world->use_nodes = false;
+ sce->world->horr = 0.5f;
+ sce->world->horg = 0.5f;
+ sce->world->horb = 0.5f;
+ }
}
if (sp->pr_method == PR_ICON_RENDER) {
@@ -466,10 +475,6 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty
}
else {
set_preview_layer(view_layer, MA_SPHERE_A);
-
- /* same as above, use current scene world to light sphere */
- if (BKE_scene_use_new_shading_nodes(scene))
- sce->world = preview_get_localized_world(sp, scene->world);
}
}
else {
@@ -569,6 +574,14 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty
}
else {
set_preview_layer(view_layer, MA_LAMP);
+
+ if (sce->world) {
+ /* Only use lighting from the lamp. */
+ sce->world->use_nodes = false;
+ sce->world->horr = 0.0f;
+ sce->world->horg = 0.0f;
+ sce->world->horb = 0.0f;
+ }
}
for (Base *base = view_layer->object_bases.first; base; base = base->next) {
diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c
index 270ba2a7947..222e0e20dff 100644
--- a/source/blender/editors/render/render_shading.c
+++ b/source/blender/editors/render/render_shading.c
@@ -99,6 +99,7 @@
static int material_slot_add_exec(bContext *C, wmOperator *UNUSED(op))
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Object *ob = ED_object_context(C);
if (!ob)
@@ -106,7 +107,7 @@ static int material_slot_add_exec(bContext *C, wmOperator *UNUSED(op))
BKE_object_material_slot_add(ob);
- if (ob->mode & OB_MODE_TEXTURE_PAINT) {
+ if (workspace->object_mode & OB_MODE_TEXTURE_PAINT) {
Scene *scene = CTX_data_scene(C);
BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL);
@@ -136,6 +137,7 @@ void OBJECT_OT_material_slot_add(wmOperatorType *ot)
static int material_slot_remove_exec(bContext *C, wmOperator *op)
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Object *ob = ED_object_context(C);
if (!ob)
@@ -149,7 +151,7 @@ static int material_slot_remove_exec(bContext *C, wmOperator *op)
BKE_object_material_slot_remove(ob);
- if (ob->mode & OB_MODE_TEXTURE_PAINT) {
+ if (workspace->object_mode & OB_MODE_TEXTURE_PAINT) {
Scene *scene = CTX_data_scene(C);
BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL);
diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c
index 4943222f038..7b2fcc15649 100644
--- a/source/blender/editors/render/render_update.c
+++ b/source/blender/editors/render/render_update.c
@@ -202,7 +202,7 @@ void ED_render_engine_changed(Main *bmain)
update_ctx.bmain = bmain;
for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
update_ctx.scene = scene;
- BLI_LISTBASE_FOREACH(ViewLayer *, view_layer, &scene->view_layers) {
+ LISTBASE_FOREACH(ViewLayer *, view_layer, &scene->view_layers) {
/* TDODO(sergey): Iterate over depsgraphs instead? */
update_ctx.depsgraph = BKE_scene_get_depsgraph(scene, view_layer, true);
update_ctx.view_layer = view_layer;
@@ -401,10 +401,12 @@ static void texture_changed(Main *bmain, Tex *tex)
/* icons */
BKE_icon_changed(BKE_icon_id_ensure(&tex->id));
+ const eObjectMode object_mode = WM_windows_object_mode_get(bmain->wm.first);
+
/* paint overlays */
for (scene = bmain->scene.first; scene; scene = scene->id.next) {
for (view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) {
- BKE_paint_invalidate_overlay_tex(scene, view_layer, tex);
+ BKE_paint_invalidate_overlay_tex(scene, view_layer, tex, object_mode);
}
}
@@ -524,8 +526,18 @@ static void scene_changed(Main *bmain, Scene *scene)
Object *ob;
/* glsl */
- for (ob = bmain->object.first; ob; ob = ob->id.next) {
- if (ob->mode & OB_MODE_TEXTURE_PAINT) {
+ bool has_texture_mode = false;
+ wmWindowManager *wm = bmain->wm.first;
+ for (wmWindow *win = wm->windows.first; win; win = win->next) {
+ WorkSpace *workspace = WM_window_get_active_workspace(win);
+ if (workspace->object_mode & OB_MODE_TEXTURE_PAINT) {
+ has_texture_mode = true;
+ break;
+ }
+ }
+
+ if (has_texture_mode) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
BKE_texpaint_slots_refresh_object(scene, ob);
BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
GPU_drawobject_free(ob->derivedFinal);
@@ -558,8 +570,10 @@ void ED_render_id_flush_update(const DEGEditorUpdateContext *update_ctx, ID *id)
lamp_changed(bmain, (Lamp *)id);
break;
case ID_IM:
+ {
image_changed(bmain, (Image *)id);
break;
+ }
case ID_SCE:
scene_changed(bmain, (Scene *)id);
render_engine_flag_changed(bmain, RE_ENGINE_UPDATE_OTHER);
diff --git a/source/blender/editors/scene/scene_edit.c b/source/blender/editors/scene/scene_edit.c
index 812f9a736bf..d0077df73e4 100644
--- a/source/blender/editors/scene/scene_edit.c
+++ b/source/blender/editors/scene/scene_edit.c
@@ -186,13 +186,15 @@ bool ED_scene_view_layer_delete(
return false;
}
+ /* We need to unset nodetrees before removing the layer, otherwise its index will be -1. */
+ view_layer_remove_unset_nodetrees(bmain, scene, layer);
+
BLI_remlink(&scene->view_layers, layer);
BLI_assert(BLI_listbase_is_empty(&scene->view_layers) == false);
scene->active_view_layer = 0;
ED_workspace_view_layer_unset(bmain, scene, layer, scene->view_layers.first);
BKE_workspace_view_layer_remove_references(bmain, layer);
- view_layer_remove_unset_nodetrees(bmain, scene, layer);
BKE_view_layer_free(layer);
diff --git a/source/blender/editors/screen/CMakeLists.txt b/source/blender/editors/screen/CMakeLists.txt
index 02584a4611b..29b9971eabb 100644
--- a/source/blender/editors/screen/CMakeLists.txt
+++ b/source/blender/editors/screen/CMakeLists.txt
@@ -26,6 +26,7 @@ set(INC
../../blenloader
../../blentranslation
../../bmesh
+ ../../depsgraph
../../gpu
../../imbuf
../../makesdna
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index f886a6ad613..397090388ff 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -52,7 +52,6 @@
#include "WM_api.h"
#include "WM_types.h"
#include "WM_message.h"
-#include "wm_subwindow.h"
#include "ED_screen.h"
#include "ED_screen_types.h"
@@ -91,7 +90,7 @@ static void region_draw_emboss(const ARegion *ar, const rcti *scirct)
/* set transp line */
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
Gwn_VertFormat *format = immVertexFormat();
unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
@@ -450,7 +449,7 @@ static void region_draw_azones(ScrArea *sa, ARegion *ar)
glLineWidth(1.0f);
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
gpuPushMatrix();
gpuTranslate2f(-ar->winrct.xmin, -ar->winrct.ymin);
@@ -495,23 +494,6 @@ static void region_draw_azones(ScrArea *sa, ARegion *ar)
glDisable(GL_BLEND);
}
-/* only exported for WM */
-/* makes region ready for drawing, sets pixelspace */
-void ED_region_set(const bContext *C, ARegion *ar)
-{
- wmWindow *win = CTX_wm_window(C);
- ScrArea *sa = CTX_wm_area(C);
-
- ar->drawrct = ar->winrct;
-
- /* note; this sets state, so we can use wmOrtho and friends */
- wmSubWindowScissorSet(win, ar->swinid, &ar->drawrct, true);
-
- UI_SetTheme(sa ? sa->spacetype : 0, ar->type ? ar->type->regionid : 0);
-
- ED_region_pixelspace(ar);
-}
-
/* Follow wmMsgNotifyFn spec */
void ED_region_do_msg_notify_tag_redraw(
bContext *UNUSED(C), wmMsgSubscribeKey *UNUSED(msg_key), wmMsgSubscribeValue *msg_val)
@@ -546,27 +528,15 @@ void ED_region_do_draw(bContext *C, ARegion *ar)
wmWindow *win = CTX_wm_window(C);
ScrArea *sa = CTX_wm_area(C);
ARegionType *at = ar->type;
- bool scissor_pad;
/* see BKE_spacedata_draw_locks() */
if (at->do_lock)
return;
- /* if no partial draw rect set, full rect */
- if (ar->drawrct.xmin == ar->drawrct.xmax) {
- ar->drawrct = ar->winrct;
- scissor_pad = true;
- }
- else {
- /* extra clip for safety */
- BLI_rcti_isect(&ar->winrct, &ar->drawrct, &ar->drawrct);
- scissor_pad = false;
- }
-
ar->do_draw |= RGN_DRAWING;
- /* note; this sets state, so we can use wmOrtho and friends */
- wmSubWindowScissorSet(win, ar->swinid, &ar->drawrct, scissor_pad);
+ /* Set viewport, scissor, ortho and ar->drawrct. */
+ wmPartialViewport(&ar->drawrct, &ar->winrct, &ar->drawrct);
wmOrtho2_region_pixelspace(ar);
@@ -1470,24 +1440,14 @@ static void area_calc_totrct(ScrArea *sa, int window_size_x, int window_size_y)
/* used for area initialize below */
-static void region_subwindow(wmWindow *win, ARegion *ar, bool activate)
+static void region_subwindow(ARegion *ar)
{
bool hidden = (ar->flag & (RGN_FLAG_HIDDEN | RGN_FLAG_TOO_SMALL)) != 0;
if ((ar->alignment & RGN_SPLIT_PREV) && ar->prev)
hidden = hidden || (ar->prev->flag & (RGN_FLAG_HIDDEN | RGN_FLAG_TOO_SMALL));
- if (hidden) {
- if (ar->swinid)
- wm_subwindow_close(win, ar->swinid);
- ar->swinid = 0;
- }
- else if (ar->swinid == 0) {
- ar->swinid = wm_subwindow_open(win, &ar->winrct, activate);
- }
- else {
- wm_subwindow_position(win, ar->swinid, &ar->winrct, activate);
- }
+ ar->visible = !hidden;
}
static void ed_default_handlers(wmWindowManager *wm, ScrArea *sa, ListBase *handlers, int flag)
@@ -1570,7 +1530,7 @@ void screen_area_update_region_sizes(wmWindowManager *wm, wmWindow *win, ScrArea
region_rect_recursive(win, area, area->regionbase.first, &rect, 0, false);
for (ARegion *ar = area->regionbase.first; ar; ar = ar->next) {
- region_subwindow(win, ar, false);
+ region_subwindow(ar);
/* region size may have changed, init does necessary adjustments */
if (ar->type->init) {
@@ -1620,9 +1580,9 @@ void ED_area_initialize(wmWindowManager *wm, wmWindow *win, ScrArea *sa)
/* region windows, default and own handlers */
for (ar = sa->regionbase.first; ar; ar = ar->next) {
- region_subwindow(win, ar, false);
+ region_subwindow(ar);
- if (ar->swinid) {
+ if (ar->visible) {
/* default region handlers */
ed_default_handlers(wm, sa, &ar->handlers, ar->type->keymapflag);
/* own handlers */
@@ -1649,22 +1609,16 @@ static void region_update_rect(ARegion *ar)
/**
* Call to move a popup window (keep OpenGL context free!)
*/
-void ED_region_update_rect(bContext *C, ARegion *ar)
+void ED_region_update_rect(bContext *UNUSED(C), ARegion *ar)
{
- wmWindow *win = CTX_wm_window(C);
-
- wm_subwindow_rect_set(win, ar->swinid, &ar->winrct);
-
region_update_rect(ar);
}
/* externally called for floating regions like menus */
-void ED_region_init(bContext *C, ARegion *ar)
+void ED_region_init(bContext *UNUSED(C), ARegion *ar)
{
-// ARegionType *at = ar->type;
-
/* refresh can be called before window opened */
- region_subwindow(CTX_wm_window(C), ar, false);
+ region_subwindow(ar);
region_update_rect(ar);
}
@@ -2327,7 +2281,7 @@ void ED_region_info_draw_multiline(ARegion *ar, const char *text_array[], float
BLI_rcti_size_x(&rect) + 1, BLI_rcti_size_y(&rect) + 1);
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
Gwn_VertFormat *format = immVertexFormat();
unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c
index 7ce16efdb97..cd53655a0bb 100644
--- a/source/blender/editors/screen/glutil.c
+++ b/source/blender/editors/screen/glutil.c
@@ -354,142 +354,6 @@ void immDrawPixelsTex_clipping(IMMDrawPixelsTexState *state,
clip_min_x, clip_min_y, clip_max_x, clip_max_y, xzoom, yzoom, color);
}
-/* 2D Drawing Assistance */
-
-void glaDefine2DArea(rcti *screen_rect)
-{
- const int sc_w = BLI_rcti_size_x(screen_rect) + 1;
- const int sc_h = BLI_rcti_size_y(screen_rect) + 1;
-
- glViewport(screen_rect->xmin, screen_rect->ymin, sc_w, sc_h);
- glScissor(screen_rect->xmin, screen_rect->ymin, sc_w, sc_h);
-
- /* The GLA_PIXEL_OFS magic number is to shift the matrix so that
- * both raster and vertex integer coordinates fall at pixel
- * centers properly. For a longer discussion see the OpenGL
- * Programming Guide, Appendix H, Correctness Tips.
- */
-
- gpuOrtho2D(GLA_PIXEL_OFS, sc_w + GLA_PIXEL_OFS, GLA_PIXEL_OFS, sc_h + GLA_PIXEL_OFS);
- gpuLoadIdentity();
-}
-
-/* TODO(merwin): put the following 2D code to use, or build new 2D code inspired & informd by it */
-
-#if 0 /* UNUSED */
-
-struct gla2DDrawInfo {
- int orig_vp[4], orig_sc[4];
- float orig_projmat[16], orig_viewmat[16];
-
- rcti screen_rect;
- rctf world_rect;
-
- float wo_to_sc[2];
-};
-
-void gla2DGetMap(gla2DDrawInfo *di, rctf *rect)
-{
- *rect = di->world_rect;
-}
-
-void gla2DSetMap(gla2DDrawInfo *di, rctf *rect)
-{
- int sc_w, sc_h;
- float wo_w, wo_h;
-
- di->world_rect = *rect;
-
- sc_w = BLI_rcti_size_x(&di->screen_rect);
- sc_h = BLI_rcti_size_y(&di->screen_rect);
- wo_w = BLI_rcti_size_x(&di->world_rect);
- wo_h = BLI_rcti_size_y(&di->world_rect);
-
- di->wo_to_sc[0] = sc_w / wo_w;
- di->wo_to_sc[1] = sc_h / wo_h;
-}
-
-/** Save the current OpenGL state and initialize OpenGL for 2D
- * rendering. glaEnd2DDraw should be called on the returned structure
- * to free it and to return OpenGL to its previous state. The
- * scissor rectangle is set to match the viewport.
- *
- * See glaDefine2DArea for an explanation of why this function uses integers.
- *
- * \param screen_rect The screen rectangle to be used for 2D drawing.
- * \param world_rect The world rectangle that the 2D area represented
- * by \a screen_rect is supposed to represent. If NULL it is assumed the
- * world has a 1 to 1 mapping to the screen.
- */
-gla2DDrawInfo *glaBegin2DDraw(rcti *screen_rect, rctf *world_rect)
-{
- gla2DDrawInfo *di = MEM_mallocN(sizeof(*di), "gla2DDrawInfo");
- int sc_w, sc_h;
- float wo_w, wo_h;
-
- glGetIntegerv(GL_VIEWPORT, (GLint *)di->orig_vp);
- glGetIntegerv(GL_SCISSOR_BOX, (GLint *)di->orig_sc);
- gpuGetProjectionMatrix(di->orig_projmat);
- gpuGetModelViewMatrix(di->orig_viewmat);
-
- di->screen_rect = *screen_rect;
- if (world_rect) {
- di->world_rect = *world_rect;
- }
- else {
- di->world_rect.xmin = di->screen_rect.xmin;
- di->world_rect.ymin = di->screen_rect.ymin;
- di->world_rect.xmax = di->screen_rect.xmax;
- di->world_rect.ymax = di->screen_rect.ymax;
- }
-
- sc_w = BLI_rcti_size_x(&di->screen_rect);
- sc_h = BLI_rcti_size_y(&di->screen_rect);
- wo_w = BLI_rcti_size_x(&di->world_rect);
- wo_h = BLI_rcti_size_y(&di->world_rect);
-
- di->wo_to_sc[0] = sc_w / wo_w;
- di->wo_to_sc[1] = sc_h / wo_h;
-
- glaDefine2DArea(&di->screen_rect);
-
- return di;
-}
-
-/**
- * Translate the (\a wo_x, \a wo_y) point from world coordinates into screen space.
- */
-void gla2DDrawTranslatePt(gla2DDrawInfo *di, float wo_x, float wo_y, int *r_sc_x, int *r_sc_y)
-{
- *r_sc_x = (wo_x - di->world_rect.xmin) * di->wo_to_sc[0];
- *r_sc_y = (wo_y - di->world_rect.ymin) * di->wo_to_sc[1];
-}
-
-/**
- * Translate the \a world point from world coordinates into screen space.
- */
-void gla2DDrawTranslatePtv(gla2DDrawInfo *di, float world[2], int r_screen[2])
-{
- screen_r[0] = (world[0] - di->world_rect.xmin) * di->wo_to_sc[0];
- screen_r[1] = (world[1] - di->world_rect.ymin) * di->wo_to_sc[1];
-}
-
-/**
- * Restores the previous OpenGL state and frees the auxiliary gla data.
- */
-void glaEnd2DDraw(gla2DDrawInfo *di)
-{
- glViewport(di->orig_vp[0], di->orig_vp[1], di->orig_vp[2], di->orig_vp[3]);
- glScissor(di->orig_vp[0], di->orig_vp[1], di->orig_vp[2], di->orig_vp[3]);
- gpuLoadProjectionMatrix(di->orig_projmat);
- gpuLoadMatrix(di->orig_viewmat);
-
- MEM_freeN(di);
-}
-
-#endif /* UNUSED */
-
-
/* *************** glPolygonOffset hack ************* */
/**
diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c
index 4c62253bef6..2a48ae46b12 100644
--- a/source/blender/editors/screen/screen_context.c
+++ b/source/blender/editors/screen/screen_context.c
@@ -53,6 +53,8 @@
#include "BKE_sequencer.h"
#include "BKE_workspace.h"
+#include "DEG_depsgraph.h"
+
#include "RNA_access.h"
#include "ED_armature.h"
@@ -90,8 +92,8 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
Scene *scene = WM_window_get_active_scene(win);
WorkSpace *workspace = BKE_workspace_active_get(win->workspace_hook);
ViewLayer *view_layer = BKE_view_layer_from_workspace_get(scene, workspace);
- Object *obedit = scene->obedit;
Object *obact = (view_layer && view_layer->basact) ? view_layer->basact->object : NULL;
+ Object *obedit = BKE_workspace_edit_object(workspace, scene);
if (CTX_data_dir(member)) {
CTX_data_dir_set(result, screen_context_dir);
@@ -371,31 +373,31 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
return 1;
}
else if (CTX_data_equals(member, "sculpt_object")) {
- if (obact && (obact->mode & OB_MODE_SCULPT))
+ if (obact && (workspace->object_mode & OB_MODE_SCULPT)) {
CTX_data_id_pointer_set(result, &obact->id);
-
+ }
return 1;
}
else if (CTX_data_equals(member, "vertex_paint_object")) {
- if (obact && (obact->mode & OB_MODE_VERTEX_PAINT))
+ if (obact && (workspace->object_mode & OB_MODE_VERTEX_PAINT))
CTX_data_id_pointer_set(result, &obact->id);
return 1;
}
else if (CTX_data_equals(member, "weight_paint_object")) {
- if (obact && (obact->mode & OB_MODE_WEIGHT_PAINT))
+ if (obact && (workspace->object_mode & OB_MODE_WEIGHT_PAINT))
CTX_data_id_pointer_set(result, &obact->id);
return 1;
}
else if (CTX_data_equals(member, "image_paint_object")) {
- if (obact && (obact->mode & OB_MODE_TEXTURE_PAINT))
+ if (obact && (workspace->object_mode & OB_MODE_TEXTURE_PAINT))
CTX_data_id_pointer_set(result, &obact->id);
return 1;
}
else if (CTX_data_equals(member, "particle_edit_object")) {
- if (obact && (obact->mode & OB_MODE_PARTICLE_EDIT))
+ if (obact && (workspace->object_mode & OB_MODE_PARTICLE_EDIT))
CTX_data_id_pointer_set(result, &obact->id);
return 1;
diff --git a/source/blender/editors/screen/screen_draw.c b/source/blender/editors/screen/screen_draw.c
index 2e4e9127ed6..c749d77869f 100644
--- a/source/blender/editors/screen/screen_draw.c
+++ b/source/blender/editors/screen/screen_draw.c
@@ -213,7 +213,7 @@ static void draw_join_shape(ScrArea *sa, char dir, unsigned int pos)
*/
static void scrarea_draw_shape_dark(ScrArea *sa, char dir, unsigned int pos)
{
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
immUniformColor4ub(0, 0, 0, 50);
draw_join_shape(sa, dir, pos);
@@ -298,7 +298,7 @@ void ED_screen_draw_edges(wmWindow *win)
ScrArea *sa;
- wmSubWindowSet(win, screen->mainwin);
+ wmWindowViewport(win);
unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -499,7 +499,7 @@ static void screen_preview_draw(const bScreen *screen, int size_x, int size_y)
void ED_screen_preview_render(const bScreen *screen, int size_x, int size_y, unsigned int *r_rect)
{
char err_out[256] = "unknown";
- GPUOffScreen *offscreen = GPU_offscreen_create(size_x, size_y, 0, false, err_out);
+ GPUOffScreen *offscreen = GPU_offscreen_create(size_x, size_y, 0, true, false, err_out);
GPU_offscreen_bind(offscreen, true);
glClearColor(0.0, 0.0, 0.0, 0.0);
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index 57f45bf95ce..2e738d71a91 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -68,9 +68,6 @@
#include "WM_message.h"
-/* XXX actually should be not here... solve later */
-#include "wm_subwindow.h"
-
#include "screen_intern.h" /* own module include */
@@ -699,14 +696,14 @@ static void screen_vertices_scale(
/* ****************** EXPORTED API TO OTHER MODULES *************************** */
-/* screen sets cursor based on swinid */
-static void region_cursor_set(wmWindow *win, int swinid, int swin_changed)
+/* screen sets cursor based on active region */
+static void region_cursor_set(wmWindow *win, bool swin_changed)
{
bScreen *screen = WM_window_get_active_screen(win);
for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) {
- if (ar->swinid == swinid) {
+ if (ar == screen->active_region) {
if (swin_changed || (ar->type && ar->type->event_cursor)) {
if (ar->manipulator_map != NULL) {
if (WM_manipulatormap_cursor_set(ar->manipulator_map, win)) {
@@ -741,7 +738,7 @@ void ED_screen_do_listen(bContext *C, wmNotifier *note)
break;
case NC_SCENE:
if (note->data == ND_MODE)
- region_cursor_set(win, note->swinid, true);
+ region_cursor_set(win, true);
break;
}
}
@@ -770,12 +767,6 @@ void ED_screen_refresh(wmWindowManager *wm, wmWindow *win)
const int window_size_y = WM_window_pixels_y(win);
const int screen_size_x = WM_window_screen_pixels_x(win);
const int screen_size_y = WM_window_screen_pixels_y(win);
- rcti window_rect;
-
- window_rect.xmin = 0;
- window_rect.xmax = window_size_x - 1;
- window_rect.ymin = 0;
- window_rect.ymax = window_size_y - 1;
/* header size depends on DPI, let's verify */
WM_window_set_dpi(win);
@@ -783,13 +774,6 @@ void ED_screen_refresh(wmWindowManager *wm, wmWindow *win)
screen_vertices_scale(win, screen, window_size_x, window_size_y, screen_size_x, screen_size_y);
- if (screen->mainwin == 0) {
- screen->mainwin = wm_subwindow_open(win, &window_rect, false);
- }
- else {
- wm_subwindow_position(win, screen->mainwin, &window_rect, false);
- }
-
ED_screen_areas_iter(win, screen, area) {
/* set spacetype and region callbacks, calls init() */
/* sets subwindows for regions, adds handlers */
@@ -881,10 +865,7 @@ void ED_region_exit(bContext *C, ARegion *ar)
WM_event_remove_handlers(C, &ar->handlers);
WM_event_modal_handler_region_replace(win, ar, NULL);
- if (ar->swinid) {
- wm_subwindow_close(win, ar->swinid);
- ar->swinid = 0;
- }
+ ar->visible = 0;
if (ar->headerstr) {
MEM_freeN(ar->headerstr);
@@ -936,10 +917,7 @@ void ED_screen_exit(bContext *C, wmWindow *window, bScreen *screen)
screen->animtimer = NULL;
screen->scrubbing = false;
- if (screen->mainwin)
- wm_subwindow_close(window, screen->mainwin);
- screen->mainwin = 0;
- screen->subwinactive = 0;
+ screen->active_region = NULL;
for (ar = screen->regionbase.first; ar; ar = ar->next) {
ED_region_exit(C, ar);
@@ -1008,7 +986,7 @@ static void screen_cursor_set(wmWindow *win, const wmEvent *event)
/* called in wm_event_system.c. sets state vars in screen, cursors */
/* event type is mouse move */
-void ED_screen_set_subwinactive(bContext *C, const wmEvent *event)
+void ED_screen_set_active_region(bContext *C, const wmEvent *event)
{
wmWindow *win = CTX_wm_window(C);
bScreen *scr = WM_window_get_active_screen(win);
@@ -1016,7 +994,7 @@ void ED_screen_set_subwinactive(bContext *C, const wmEvent *event)
if (scr) {
ScrArea *sa = NULL;
ARegion *ar;
- int oldswin = scr->subwinactive;
+ ARegion *old_ar = scr->active_region;
ED_screen_areas_iter(win, scr, area_iter) {
if (event->x > area_iter->totrct.xmin && event->x < area_iter->totrct.xmax) {
@@ -1032,22 +1010,22 @@ void ED_screen_set_subwinactive(bContext *C, const wmEvent *event)
/* make overlap active when mouse over */
for (ar = sa->regionbase.first; ar; ar = ar->next) {
if (BLI_rcti_isect_pt_v(&ar->winrct, &event->x)) {
- scr->subwinactive = ar->swinid;
+ scr->active_region = ar;
break;
}
}
}
else
- scr->subwinactive = scr->mainwin;
+ scr->active_region = NULL;
/* check for redraw headers */
- if (oldswin != scr->subwinactive) {
+ if (old_ar != scr->active_region) {
ED_screen_areas_iter(win, scr, area_iter) {
bool do_draw = false;
for (ar = area_iter->regionbase.first; ar; ar = ar->next) {
- if (ar->swinid == oldswin || ar->swinid == scr->subwinactive) {
+ if (ar == old_ar || ar == scr->active_region) {
do_draw = true;
}
}
@@ -1063,13 +1041,13 @@ void ED_screen_set_subwinactive(bContext *C, const wmEvent *event)
}
/* cursors, for time being set always on edges, otherwise aregion doesnt switch */
- if (scr->subwinactive == scr->mainwin) {
+ if (scr->active_region == NULL) {
screen_cursor_set(win, event);
}
else {
/* notifier invokes freeing the buttons... causing a bit too much redraws */
- if (oldswin != scr->subwinactive) {
- region_cursor_set(win, scr->subwinactive, true);
+ if (old_ar != scr->active_region) {
+ region_cursor_set(win, true);
/* this used to be a notifier, but needs to be done immediate
* because it can undo setting the right button as active due
@@ -1077,7 +1055,7 @@ void ED_screen_set_subwinactive(bContext *C, const wmEvent *event)
UI_screen_free_active_but(C, scr);
}
else
- region_cursor_set(win, scr->subwinactive, false);
+ region_cursor_set(win, false);
}
}
}
@@ -1096,7 +1074,7 @@ int ED_screen_area_active(const bContext *C)
return 1;
for (ar = sa->regionbase.first; ar; ar = ar->next)
- if (ar->swinid == sc->subwinactive)
+ if (ar == sc->active_region)
return 1;
}
return 0;
@@ -1114,7 +1092,7 @@ void ED_screen_global_topbar_area_create(const bContext *C, wmWindow *win, const
sa->v2 = MEM_callocN(sizeof(*sa->v2), __func__);
sa->v3 = MEM_callocN(sizeof(*sa->v3), __func__);
sa->v4 = MEM_callocN(sizeof(*sa->v4), __func__);
- /* Actual coordinates of area verts are set later (screen_test_scale) */
+ /* Actual coordinates of area verts are set later (screen_vertices_scale) */
sa->spacetype = sa->butspacetype = SPACE_TOPBAR;
sa->fixed_height = size_y;
@@ -1755,10 +1733,14 @@ bool ED_screen_stereo3d_required(const bScreen *screen, const Scene *scene)
* Find the scene displayed in \a screen.
* \note Assumes \a screen to be visible/active!
*/
-Scene *ED_screen_scene_find(const bScreen *screen, const wmWindowManager *wm)
+
+Scene *ED_screen_scene_find_with_window(const bScreen *screen, const wmWindowManager *wm, struct wmWindow **r_window)
{
for (wmWindow *win = wm->windows.first; win; win = win->next) {
if (WM_window_get_active_screen(win) == screen) {
+ if (r_window) {
+ *r_window = win;
+ }
return WM_window_get_active_scene(win);
}
}
@@ -1766,3 +1748,20 @@ Scene *ED_screen_scene_find(const bScreen *screen, const wmWindowManager *wm)
BLI_assert(0);
return NULL;
}
+
+
+Scene *ED_screen_scene_find(const bScreen *screen, const wmWindowManager *wm)
+{
+ return ED_screen_scene_find_with_window(screen, wm, NULL);
+}
+
+
+wmWindow *ED_screen_window_find(const bScreen *screen, const wmWindowManager *wm)
+{
+ for (wmWindow *win = wm->windows.first; win; win = win->next) {
+ if (WM_window_get_active_screen(win) == screen) {
+ return win;
+ }
+ }
+ return NULL;
+}
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 09af0d86f84..4596c2e5cf1 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -68,6 +68,8 @@
#include "WM_api.h"
#include "WM_types.h"
+#include "DEG_depsgraph.h"
+
#include "ED_armature.h"
#include "ED_clip.h"
#include "ED_image.h"
@@ -136,7 +138,7 @@ int ED_operator_screen_mainwinactive(bContext *C)
if (CTX_wm_window(C) == NULL) return 0;
screen = CTX_wm_screen(C);
if (screen == NULL) return 0;
- if (screen->subwinactive != screen->mainwin) return 0;
+ if (screen->active_region != NULL) return 0;
return 1;
}
@@ -150,6 +152,7 @@ int ED_operator_scene_editable(bContext *C)
int ED_operator_objectmode(bContext *C)
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Scene *scene = CTX_data_scene(C);
Object *obact = CTX_data_active_object(C);
@@ -159,7 +162,7 @@ int ED_operator_objectmode(bContext *C)
return 0;
/* add a check for ob->mode too? */
- if (obact && (obact->mode != OB_MODE_OBJECT))
+ if (obact && (workspace->object_mode != OB_MODE_OBJECT))
return 0;
return 1;
@@ -301,35 +304,39 @@ int ED_operator_console_active(bContext *C)
return ed_spacetype_test(C, SPACE_CONSOLE);
}
-static int ed_object_hidden(Object *ob)
+static int ed_object_hidden(Object *ob, eObjectMode object_mode)
{
/* 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_VIEW) && !(object_mode & OB_MODE_EDIT));
}
int ED_operator_object_active(bContext *C)
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Object *ob = ED_object_active_context(C);
- return ((ob != NULL) && !ed_object_hidden(ob));
+ return ((ob != NULL) && !ed_object_hidden(ob, workspace->object_mode));
}
int ED_operator_object_active_editable(bContext *C)
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Object *ob = ED_object_active_context(C);
- return ((ob != NULL) && !ID_IS_LINKED(ob) && !ed_object_hidden(ob));
+ return ((ob != NULL) && !ID_IS_LINKED(ob) && !ed_object_hidden(ob, workspace->object_mode));
}
int ED_operator_object_active_editable_mesh(bContext *C)
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Object *ob = ED_object_active_context(C);
- return ((ob != NULL) && !ID_IS_LINKED(ob) && !ed_object_hidden(ob) &&
+ return ((ob != NULL) && !ID_IS_LINKED(ob) && !ed_object_hidden(ob, workspace->object_mode) &&
(ob->type == OB_MESH) && !ID_IS_LINKED(ob->data));
}
int ED_operator_object_active_editable_font(bContext *C)
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Object *ob = ED_object_active_context(C);
- return ((ob != NULL) && !ID_IS_LINKED(ob) && !ed_object_hidden(ob) &&
+ return ((ob != NULL) && !ID_IS_LINKED(ob) && !ed_object_hidden(ob, workspace->object_mode) &&
(ob->type == OB_FONT));
}
@@ -374,11 +381,14 @@ int ED_operator_posemode_exclusive(bContext *C)
{
Object *obact = CTX_data_active_object(C);
- if (obact && !(obact->mode & OB_MODE_EDIT)) {
- Object *obpose;
- if ((obpose = BKE_object_pose_armature_get(obact))) {
- if (obact == obpose) {
- return 1;
+ if (obact) {
+ const WorkSpace *workspace = CTX_wm_workspace(C);
+ if ((workspace->object_mode & OB_MODE_EDIT) == 0) {
+ Object *obpose;
+ if ((obpose = BKE_object_pose_armature_get(obact))) {
+ if (obact == obpose) {
+ return 1;
+ }
}
}
}
@@ -392,9 +402,15 @@ int ED_operator_posemode_context(bContext *C)
{
Object *obpose = ED_pose_object_from_context(C);
- if (obpose && !(obpose->mode & OB_MODE_EDIT)) {
- if (BKE_object_pose_context_check(obpose)) {
- return 1;
+ if (obpose) {
+ const WorkSpace *workspace = CTX_wm_workspace(C);
+ /* TODO, should we allow this out of pose mode? */
+ if (workspace->object_mode & OB_MODE_POSE) {
+ // if ((workspace->object_mode & OB_MODE_EDIT) == 0) {
+ if (BKE_object_pose_context_check(obpose)) {
+ return 1;
+ }
+ // }
}
}
@@ -405,11 +421,17 @@ int ED_operator_posemode(bContext *C)
{
Object *obact = CTX_data_active_object(C);
- if (obact && !(obact->mode & OB_MODE_EDIT)) {
- Object *obpose;
- if ((obpose = BKE_object_pose_armature_get(obact))) {
- if ((obact == obpose) || (obact->mode & OB_MODE_WEIGHT_PAINT)) {
- return 1;
+
+ if (obact) {
+ const WorkSpace *workspace = CTX_wm_workspace(C);
+ if ((workspace->object_mode & OB_MODE_EDIT) == 0) {
+ Object *obpose;
+ if ((obpose = BKE_object_pose_armature_get(obact))) {
+ if (((workspace->object_mode & OB_MODE_POSE) && (obact == obpose)) ||
+ (workspace->object_mode & OB_MODE_WEIGHT_PAINT))
+ {
+ return 1;
+ }
}
}
}
@@ -545,9 +567,10 @@ int ED_operator_mask(bContext *C)
}
case SPACE_IMAGE:
{
+ WorkSpace *workspace = CTX_wm_workspace(C);
SpaceImage *sima = sa->spacedata.first;
ViewLayer *view_layer = CTX_data_view_layer(C);
- return ED_space_image_check_show_maskedit(view_layer, sima);
+ return ED_space_image_check_show_maskedit(sima, workspace, view_layer);
}
}
}
diff --git a/source/blender/editors/screen/workspace_edit.c b/source/blender/editors/screen/workspace_edit.c
index da9cb69b528..6ec1ac2e239 100644
--- a/source/blender/editors/screen/workspace_edit.c
+++ b/source/blender/editors/screen/workspace_edit.c
@@ -79,33 +79,9 @@ WorkSpace *ED_workspace_add(
BKE_workspace_view_layer_set(workspace, act_view_layer, scene);
BKE_viewrender_copy(&workspace->view_render, view_render);
-#ifdef USE_WORKSPACE_MODE
- BKE_workspace_object_mode_set(workspace, scene, OB_MODE_OBJECT);
-#endif
-
return workspace;
}
-#ifdef USE_WORKSPACE_MODE
-/**
- * Changes the object mode (if needed) to the one set in \a workspace_new.
- * Object mode is still stored on object level. In future it should all be workspace level instead.
- */
-static void workspace_change_update_mode(
- const WorkSpace *workspace_old, const WorkSpace *workspace_new,
- bContext *C, Object *ob_act, ReportList *reports)
-{
- const Scene *scene = CTX_data_scene(C);
- eObjectMode mode_old = BKE_workspace_object_mode_get(workspace_old, scene);
- eObjectMode mode_new = BKE_workspace_object_mode_get(workspace_new, scene);
-
- if (mode_old != mode_new) {
- ED_object_mode_compat_set(C, ob_act, mode_new, reports);
- ED_object_toggle_modes(C, mode_new);
- }
-}
-#endif
-
static void workspace_change_update_view_layer(
WorkSpace *workspace_new, const WorkSpace *workspace_old,
Scene *scene)
@@ -117,15 +93,10 @@ static void workspace_change_update_view_layer(
static void workspace_change_update(
WorkSpace *workspace_new, const WorkSpace *workspace_old,
- bContext *C, wmWindowManager *wm)
+ bContext *C)
{
/* needs to be done before changing mode! (to ensure right context) */
workspace_change_update_view_layer(workspace_new, workspace_old, CTX_data_scene(C));
-#ifdef USE_WORKSPACE_MODE
- workspace_change_update_mode(workspace_old, workspace_new, C, CTX_data_active_object(C), &wm->reports);
-#else
- UNUSED_VARS(C, wm);
-#endif
}
static bool workspace_change_find_new_layout_cb(const WorkSpaceLayout *layout, void *UNUSED(arg))
@@ -177,7 +148,7 @@ static WorkSpaceLayout *workspace_change_get_new_layout(
* \returns if workspace changing was successful.
*/
bool ED_workspace_change(
- WorkSpace *workspace_new, bContext *C, wmWindowManager *wm, wmWindow *win)
+ WorkSpace *workspace_new, bContext *C, wmWindow *win)
{
Main *bmain = CTX_data_main(C);
WorkSpace *workspace_old = WM_window_get_active_workspace(win);
@@ -200,7 +171,7 @@ bool ED_workspace_change(
/* update screen *after* changing workspace - which also causes the actual screen change */
screen_changed_update(C, win, screen_new);
- workspace_change_update(workspace_new, workspace_old, C, wm);
+ workspace_change_update(workspace_new, workspace_old, C);
BLI_assert(BKE_workspace_view_layer_get(workspace_new, CTX_data_scene(C)) != NULL);
BLI_assert(CTX_wm_workspace(C) == workspace_new);
@@ -231,9 +202,6 @@ WorkSpace *ED_workspace_duplicate(
ListBase *transform_orientations_old = BKE_workspace_transform_orientations_get(workspace_old);
ListBase *transform_orientations_new = BKE_workspace_transform_orientations_get(workspace_new);
-#ifdef USE_WORKSPACE_MODE
- BKE_workspace_object_mode_set(workspace_new, scene, BKE_workspace_object_mode_get(workspace_old, scene));
-#endif
BLI_duplicatelist(transform_orientations_new, transform_orientations_old);
workspace_new->tool = workspace_old->tool;
@@ -264,7 +232,7 @@ bool ED_workspace_delete(
WorkSpace *prev = workspace_id->prev;
WorkSpace *next = workspace_id->next;
- ED_workspace_change((prev != NULL) ? prev : next, C, wm, win);
+ ED_workspace_change((prev != NULL) ? prev : next, C, win);
}
BKE_libblock_free(bmain, workspace_id);
diff --git a/source/blender/editors/sculpt_paint/paint_curve.c b/source/blender/editors/sculpt_paint/paint_curve.c
index 337f7a1ef2b..c9ad4a46a13 100644
--- a/source/blender/editors/sculpt_paint/paint_curve.c
+++ b/source/blender/editors/sculpt_paint/paint_curve.c
@@ -32,6 +32,7 @@
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
#include "DNA_view3d_types.h"
+#include "DNA_workspace_types.h"
#include "BLI_math_vector.h"
#include "BLI_string.h"
@@ -40,6 +41,8 @@
#include "BKE_main.h"
#include "BKE_paint.h"
+#include "DEG_depsgraph.h"
+
#include "ED_paint.h"
#include "ED_view3d.h"
@@ -59,12 +62,13 @@
int paint_curve_poll(bContext *C)
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Object *ob = CTX_data_active_object(C);
Paint *p;
RegionView3D *rv3d = CTX_wm_region_view3d(C);
SpaceImage *sima;
- if (rv3d && !(ob && ((ob->mode & OB_MODE_ALL_PAINT) != 0)))
+ if (rv3d && !(ob && ((workspace->object_mode & OB_MODE_ALL_PAINT) != 0)))
return false;
sima = CTX_wm_space_image(C);
diff --git a/source/blender/editors/sculpt_paint/paint_hide.c b/source/blender/editors/sculpt_paint/paint_hide.c
index 8377b22756e..b175a33934a 100644
--- a/source/blender/editors/sculpt_paint/paint_hide.c
+++ b/source/blender/editors/sculpt_paint/paint_hide.c
@@ -384,7 +384,7 @@ static int hide_show_exec(bContext *C, wmOperator *op)
clip_planes_from_rect(C, clip_planes, &rect);
dm = mesh_get_derived_final(&eval_ctx, CTX_data_scene(C), ob, CD_MASK_BAREMESH);
- pbvh = dm->getPBVH(ob, dm);
+ pbvh = dm->getPBVH(ob, dm, eval_ctx.object_mode);
ob->sculpt->pbvh = pbvh;
get_pbvh_nodes(pbvh, &nodes, &totnode, clip_planes, area);
@@ -418,7 +418,7 @@ static int hide_show_exec(bContext *C, wmOperator *op)
MEM_freeN(nodes);
/* end undo */
- sculpt_undo_push_end(C);
+ sculpt_undo_push_end();
/* ensure that edges and faces get hidden as well (not used by
* sculpt but it looks wrong when entering editmode otherwise) */
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index aebd0c10e9c..1cb37fc10cd 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -590,11 +590,13 @@ static int image_paint_poll(bContext *C)
{
Object *obact;
- if (!image_paint_brush(C))
+ if (!image_paint_brush(C)) {
return 0;
+ }
+ const WorkSpace *workspace = CTX_wm_workspace(C);
obact = CTX_data_active_object(C);
- if ((obact && obact->mode & OB_MODE_TEXTURE_PAINT) && CTX_wm_region_view3d(C)) {
+ if ((obact && workspace->object_mode & OB_MODE_TEXTURE_PAINT) && CTX_wm_region_view3d(C)) {
return 1;
}
else {
@@ -1374,19 +1376,20 @@ static int texture_paint_toggle_poll(bContext *C)
static int texture_paint_toggle_exec(bContext *C, wmOperator *op)
{
+ WorkSpace *workspace = CTX_wm_workspace(C);
Scene *scene = CTX_data_scene(C);
Object *ob = CTX_data_active_object(C);
const int mode_flag = OB_MODE_TEXTURE_PAINT;
- const bool is_mode_set = (ob->mode & mode_flag) != 0;
+ const bool is_mode_set = (workspace->object_mode & mode_flag) != 0;
if (!is_mode_set) {
- if (!ED_object_mode_compat_set(C, ob, mode_flag, op->reports)) {
+ if (!ED_object_mode_compat_set(C, workspace, mode_flag, op->reports)) {
return OPERATOR_CANCELLED;
}
}
- if (ob->mode & mode_flag) {
- ob->mode &= ~mode_flag;
+ if (workspace->object_mode & mode_flag) {
+ workspace->object_mode &= ~mode_flag;
if (U.glreslimit != 0)
GPU_free_images();
@@ -1426,15 +1429,17 @@ static int texture_paint_toggle_exec(bContext *C, wmOperator *op)
if (sl->spacetype == SPACE_IMAGE) {
SpaceImage *sima = (SpaceImage *)sl;
- if (!sima->pin)
- ED_space_image_set(sima, scene, scene->obedit, ima);
+ if (!sima->pin) {
+ Object *obedit = CTX_data_edit_object(C);
+ ED_space_image_set(sima, scene, obedit, ima);
+ }
}
}
}
}
}
- ob->mode |= mode_flag;
+ workspace->object_mode |= mode_flag;
BKE_paint_init(scene, ePaintTextureProjective, PAINT_CURSOR_TEXTURE_PAINT);
@@ -1471,9 +1476,10 @@ static int brush_colors_flip_exec(bContext *C, wmOperator *UNUSED(op))
{
UnifiedPaintSettings *ups = &CTX_data_tool_settings(C)->unified_paint_settings;
- Brush *br;
+ WorkSpace *workspace = CTX_wm_workspace(C);
Object *ob = CTX_data_active_object(C);
- if (!(ob && (ob->mode & OB_MODE_VERTEX_PAINT))) {
+ Brush *br;
+ if (!(ob && (workspace->object_mode & OB_MODE_VERTEX_PAINT))) {
br = image_paint_brush(C);
}
else {
@@ -1504,8 +1510,11 @@ static int brush_colors_flip_poll(bContext *C)
}
else {
Object *ob = CTX_data_active_object(C);
- if (ob && (ob->mode & OB_MODE_VERTEX_PAINT)) {
- return 1;
+ if (ob) {
+ WorkSpace *workspace = CTX_wm_workspace(C);
+ if (workspace->object_mode & OB_MODE_VERTEX_PAINT) {
+ return 1;
+ }
}
}
return 0;
@@ -1545,10 +1554,12 @@ void ED_imapaint_bucket_fill(struct bContext *C, float color[3], wmOperator *op)
static int texture_paint_poll(bContext *C)
{
- if (texture_paint_toggle_poll(C))
- if (CTX_data_active_object(C)->mode & OB_MODE_TEXTURE_PAINT)
+ if (texture_paint_toggle_poll(C)) {
+ WorkSpace *workspace = CTX_wm_workspace(C);
+ if (workspace->object_mode & OB_MODE_TEXTURE_PAINT) {
return 1;
-
+ }
+ }
return 0;
}
@@ -1559,16 +1570,19 @@ int image_texture_paint_poll(bContext *C)
int facemask_paint_poll(bContext *C)
{
- return BKE_paint_select_face_test(CTX_data_active_object(C));
+ const WorkSpace *workspace = CTX_wm_workspace(C);
+ return BKE_paint_select_face_test(CTX_data_active_object(C), workspace->object_mode);
}
int vert_paint_poll(bContext *C)
{
- return BKE_paint_select_vert_test(CTX_data_active_object(C));
+ const WorkSpace *workspace = CTX_wm_workspace(C);
+ return BKE_paint_select_vert_test(CTX_data_active_object(C), workspace->object_mode);
}
int mask_paint_poll(bContext *C)
{
- return BKE_paint_select_elem_test(CTX_data_active_object(C));
+ const WorkSpace *workspace = CTX_wm_workspace(C);
+ return BKE_paint_select_elem_test(CTX_data_active_object(C), workspace->object_mode);
}
diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c
index 4a14e985827..ae5b825e4ae 100644
--- a/source/blender/editors/sculpt_paint/paint_image_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_image_proj.c
@@ -2694,7 +2694,7 @@ static void project_paint_face_init(
int face_seam_flag;
if (threaded)
- BLI_lock_thread(LOCK_CUSTOM1); /* Other threads could be modifying these vars */
+ BLI_thread_lock(LOCK_CUSTOM1); /* Other threads could be modifying these vars */
face_seam_flag = ps->faceSeamFlags[tri_index];
@@ -2711,7 +2711,7 @@ static void project_paint_face_init(
if ((face_seam_flag & (PROJ_FACE_SEAM1 | PROJ_FACE_SEAM2 | PROJ_FACE_SEAM3)) == 0) {
if (threaded)
- BLI_unlock_thread(LOCK_CUSTOM1); /* Other threads could be modifying these vars */
+ BLI_thread_unlock(LOCK_CUSTOM1); /* Other threads could be modifying these vars */
}
else {
@@ -2737,7 +2737,7 @@ static void project_paint_face_init(
/* ps->faceSeamUVs cant be modified when threading, now this is done we can unlock */
if (threaded)
- BLI_unlock_thread(LOCK_CUSTOM1); /* Other threads could be modifying these vars */
+ BLI_thread_unlock(LOCK_CUSTOM1); /* Other threads could be modifying these vars */
vCoSS[0] = ps->screenCoords[lt_vtri[0]];
vCoSS[1] = ps->screenCoords[lt_vtri[1]];
@@ -4138,7 +4138,7 @@ static bool project_bucket_iter_next(
const int diameter = 2 * ps->brush_size;
if (ps->thread_tot > 1)
- BLI_lock_thread(LOCK_CUSTOM1);
+ BLI_thread_lock(LOCK_CUSTOM1);
//printf("%d %d\n", ps->context_bucket_x, ps->context_bucket_y);
@@ -4155,7 +4155,7 @@ static bool project_bucket_iter_next(
ps->context_bucket_x++;
if (ps->thread_tot > 1)
- BLI_unlock_thread(LOCK_CUSTOM1);
+ BLI_thread_unlock(LOCK_CUSTOM1);
return 1;
}
@@ -4164,7 +4164,7 @@ static bool project_bucket_iter_next(
}
if (ps->thread_tot > 1)
- BLI_unlock_thread(LOCK_CUSTOM1);
+ BLI_thread_unlock(LOCK_CUSTOM1);
return 0;
}
@@ -4883,7 +4883,7 @@ static bool project_paint_op(void *state, const float lastpos[2], const float po
}
if (ps->thread_tot > 1)
- BLI_init_threads(&threads, do_projectpaint_thread, ps->thread_tot);
+ BLI_threadpool_init(&threads, do_projectpaint_thread, ps->thread_tot);
pool = BKE_image_pool_new();
@@ -4913,11 +4913,11 @@ static bool project_paint_op(void *state, const float lastpos[2], const float po
handles[a].pool = pool;
if (ps->thread_tot > 1)
- BLI_insert_thread(&threads, &handles[a]);
+ BLI_threadpool_insert(&threads, &handles[a]);
}
if (ps->thread_tot > 1) /* wait for everything to be done */
- BLI_end_threads(&threads);
+ BLI_threadpool_end(&threads);
else
do_projectpaint_thread(&handles[0]);
@@ -5941,11 +5941,11 @@ static int add_simple_uvs_exec(bContext *C, wmOperator *UNUSED(op))
static int add_simple_uvs_poll(bContext *C)
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Object *ob = CTX_data_active_object(C);
-
- if (!ob || ob->type != OB_MESH || ob->mode != OB_MODE_TEXTURE_PAINT)
+ if (!ob || (ob->type != OB_MESH) || (workspace->object_mode != OB_MODE_TEXTURE_PAINT)) {
return false;
-
+ }
return true;
}
diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c
index ff261a808da..64969075d89 100644
--- a/source/blender/editors/sculpt_paint/paint_mask.c
+++ b/source/blender/editors/sculpt_paint/paint_mask.c
@@ -39,7 +39,7 @@
#include "BLI_math_matrix.h"
#include "BLI_math_geom.h"
#include "BLI_utildefines.h"
-#include "BLI_lasso.h"
+#include "BLI_lasso_2d.h"
#include "BLI_task.h"
#include "BKE_pbvh.h"
@@ -171,7 +171,7 @@ static int mask_flood_fill_exec(bContext *C, wmOperator *op)
if (multires)
multires_mark_as_modified(ob, MULTIRES_COORDS_MODIFIED);
- sculpt_undo_push_end(C);
+ sculpt_undo_push_end();
if (nodes)
MEM_freeN(nodes);
@@ -327,7 +327,7 @@ int ED_sculpt_mask_box_select(struct bContext *C, ViewContext *vc, const rcti *r
if (multires)
multires_mark_as_modified(ob, MULTIRES_COORDS_MODIFIED);
- sculpt_undo_push_end(C);
+ sculpt_undo_push_end();
ED_region_tag_redraw(ar);
@@ -514,7 +514,7 @@ static int paint_mask_gesture_lasso_exec(bContext *C, wmOperator *op)
if (multires)
multires_mark_as_modified(ob, MULTIRES_COORDS_MODIFIED);
- sculpt_undo_push_end(C);
+ sculpt_undo_push_end();
ED_region_tag_redraw(vc.ar);
MEM_freeN((void *)mcords);
diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c
index 004d2757a71..c031a733630 100644
--- a/source/blender/editors/sculpt_paint/paint_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_ops.c
@@ -40,6 +40,8 @@
#include "BKE_paint.h"
#include "BKE_main.h"
+#include "DEG_depsgraph.h"
+
#include "ED_paint.h"
#include "ED_screen.h"
#include "ED_image.h"
@@ -260,7 +262,9 @@ static void PALETTE_OT_color_delete(wmOperatorType *ot)
}
static int brush_reset_exec(bContext *C, wmOperator *UNUSED(op))
+
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Paint *paint = BKE_paint_get_active_from_context(C);
Brush *brush = BKE_paint_brush(paint);
Object *ob = CTX_data_active_object(C);
@@ -268,7 +272,7 @@ static int brush_reset_exec(bContext *C, wmOperator *UNUSED(op))
if (!ob || !brush) return OPERATOR_CANCELLED;
/* TODO: other modes */
- if (ob->mode & OB_MODE_SCULPT) {
+ if (workspace->object_mode & OB_MODE_SCULPT) {
BKE_brush_sculpt_reset(brush);
}
else {
@@ -401,6 +405,7 @@ static int brush_generic_tool_set(Main *bmain, Paint *paint, const int tool,
static int brush_select_exec(bContext *C, wmOperator *op)
{
+ WorkSpace *workspace = CTX_wm_workspace(C);
Main *bmain = CTX_data_main(C);
ToolSettings *toolsettings = CTX_data_tool_settings(C);
Paint *paint = NULL;
@@ -414,7 +419,7 @@ static int brush_select_exec(bContext *C, wmOperator *op)
Object *ob = CTX_data_active_object(C);
if (ob) {
/* select current paint mode */
- paint_mode = ob->mode & OB_MODE_ALL_PAINT;
+ paint_mode = workspace->object_mode & OB_MODE_ALL_PAINT;
}
else {
return OPERATOR_CANCELLED;
diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c
index 1ec1e052d43..6b14f97d80c 100644
--- a/source/blender/editors/sculpt_paint/paint_utils.c
+++ b/source/blender/editors/sculpt_paint/paint_utils.c
@@ -566,10 +566,11 @@ static int brush_curve_preset_exec(bContext *C, wmOperator *op)
Brush *br = BKE_paint_brush(BKE_paint_get_active_from_context(C));
if (br) {
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
BKE_brush_curve_preset(br, RNA_enum_get(op->ptr, "shape"));
- BKE_paint_invalidate_cursor_overlay(scene, view_layer, br->curve);
+ BKE_paint_invalidate_cursor_overlay(scene, view_layer, br->curve, workspace->object_mode);
}
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c
index 0c1df71b1aa..8ce0af068d6 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex.c
@@ -199,9 +199,12 @@ static void paint_last_stroke_update(Scene *scene, ARegion *ar, const float mval
/* Returns true if vertex paint mode is active */
int vertex_paint_mode_poll(bContext *C)
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Object *ob = CTX_data_active_object(C);
-
- return ob && ob->mode == OB_MODE_VERTEX_PAINT && ((Mesh *)ob->data)->totpoly;
+ return (ob &&
+ (ob->type == OB_MESH) &&
+ ((Mesh *)ob->data)->totpoly &&
+ (workspace->object_mode & OB_MODE_VERTEX_PAINT));
}
int vertex_paint_poll(bContext *C)
@@ -221,18 +224,22 @@ int vertex_paint_poll(bContext *C)
int weight_paint_mode_poll(bContext *C)
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Object *ob = CTX_data_active_object(C);
-
- return ob && ob->mode == OB_MODE_WEIGHT_PAINT && ((Mesh *)ob->data)->totpoly;
+ return (ob &&
+ (ob->type == OB_MESH) &&
+ ((Mesh *)ob->data)->totpoly &&
+ (workspace->object_mode == OB_MODE_WEIGHT_PAINT));
}
int weight_paint_poll(bContext *C)
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Object *ob = CTX_data_active_object(C);
ScrArea *sa;
if ((ob != NULL) &&
- (ob->mode & OB_MODE_WEIGHT_PAINT) &&
+ (workspace->object_mode & OB_MODE_WEIGHT_PAINT) &&
(BKE_paint_brush(&CTX_data_tool_settings(C)->wpaint->paint) != NULL) &&
(sa = CTX_wm_area(C)) &&
(sa->spacetype == SPACE_VIEW3D))
@@ -940,23 +947,27 @@ static void do_weight_paint_vertex(
/* Toggle operator for turning vertex paint mode on or off (copied from sculpt.c) */
static void vertex_paint_init_session(const EvaluationContext *eval_ctx, Scene *scene, Object *ob)
{
+ /* Create persistent sculpt mode data */
+ BKE_sculpt_toolsettings_data_ensure(scene);
+
if (ob->sculpt == NULL) {
ob->sculpt = MEM_callocN(sizeof(SculptSession), "sculpt session");
BKE_sculpt_update_mesh_elements(eval_ctx, scene, scene->toolsettings->sculpt, ob, 0, false);
}
}
-static void vertex_paint_init_session_data(const ToolSettings *ts, Object *ob)
+static void vertex_paint_init_session_data(
+ const EvaluationContext *eval_ctx, const ToolSettings *ts, Object *ob)
{
/* Create maps */
struct SculptVertexPaintGeomMap *gmap = NULL;
const Brush *brush = NULL;
- if (ob->mode == OB_MODE_VERTEX_PAINT) {
+ if (eval_ctx->object_mode == OB_MODE_VERTEX_PAINT) {
gmap = &ob->sculpt->mode.vpaint.gmap;
brush = BKE_paint_brush(&ts->vpaint->paint);
ob->sculpt->mode_type = OB_MODE_VERTEX_PAINT;
}
- else if (ob->mode == OB_MODE_WEIGHT_PAINT) {
+ else if (eval_ctx->object_mode == OB_MODE_WEIGHT_PAINT) {
gmap = &ob->sculpt->mode.wpaint.gmap;
brush = BKE_paint_brush(&ts->wpaint->paint);
ob->sculpt->mode_type = OB_MODE_WEIGHT_PAINT;
@@ -985,7 +996,7 @@ static void vertex_paint_init_session_data(const ToolSettings *ts, Object *ob)
}
/* Create average brush arrays */
- if (ob->mode == OB_MODE_VERTEX_PAINT) {
+ if (eval_ctx->object_mode == OB_MODE_VERTEX_PAINT) {
if (!brush_use_accumulate(brush)) {
if (ob->sculpt->mode.vpaint.previous_color == NULL) {
ob->sculpt->mode.vpaint.previous_color =
@@ -996,7 +1007,7 @@ static void vertex_paint_init_session_data(const ToolSettings *ts, Object *ob)
MEM_SAFE_FREE(ob->sculpt->mode.vpaint.previous_color);
}
}
- else if (ob->mode == OB_MODE_WEIGHT_PAINT) {
+ else if (eval_ctx->object_mode == OB_MODE_WEIGHT_PAINT) {
if (!brush_use_accumulate(brush)) {
if (ob->sculpt->mode.wpaint.alpha_weight == NULL) {
ob->sculpt->mode.wpaint.alpha_weight =
@@ -1024,75 +1035,200 @@ static void vertex_paint_init_session_data(const ToolSettings *ts, Object *ob)
}
-/* *************** set wpaint operator ****************** */
+/* -------------------------------------------------------------------- */
+/** \name Enter Vertex/Weight Paint Mode
+ * \{ */
-/**
- * \note Keep in sync with #vpaint_mode_toggle_exec
- */
-static int wpaint_mode_toggle_exec(bContext *C, wmOperator *op)
+static void ed_vwpaintmode_enter_generic(
+ const EvaluationContext *eval_ctx,
+ wmWindowManager *wm,
+ WorkSpace *workspace, Scene *scene,
+ Object *ob, const eObjectMode mode_flag)
{
- Object *ob = CTX_data_active_object(C);
- const int mode_flag = OB_MODE_WEIGHT_PAINT;
- const bool is_mode_set = (ob->mode & mode_flag) != 0;
- Scene *scene = CTX_data_scene(C);
- VPaint *wp = scene->toolsettings->wpaint;
- Mesh *me;
+ workspace->object_mode |= mode_flag;
+ Mesh *me = BKE_mesh_from_object(ob);
- if (!is_mode_set) {
- if (!ED_object_mode_compat_set(C, ob, mode_flag, op->reports)) {
- return OPERATOR_CANCELLED;
- }
- }
+ if (mode_flag == OB_MODE_VERTEX_PAINT) {
+ const ePaintMode paint_mode = ePaintVertex;
+ ED_mesh_color_ensure(me, NULL);
- me = BKE_mesh_from_object(ob);
+ if (scene->toolsettings->vpaint == NULL) {
+ scene->toolsettings->vpaint = new_vpaint();
+ }
- if (ob->mode & mode_flag) {
- ob->mode &= ~mode_flag;
+ Paint *paint = BKE_paint_get_active_from_paintmode(scene, paint_mode);
+ paint_cursor_start_explicit(paint, wm, vertex_paint_poll);
+ BKE_paint_init(scene, paint_mode, PAINT_CURSOR_VERTEX_PAINT);
+ }
+ else if (mode_flag == OB_MODE_WEIGHT_PAINT) {
+ const ePaintMode paint_mode = ePaintWeight;
- if (me->editflag & ME_EDIT_PAINT_VERT_SEL) {
- BKE_mesh_flush_select_from_verts(me);
- }
- else if (me->editflag & ME_EDIT_PAINT_FACE_SEL) {
- BKE_mesh_flush_select_from_polys(me);
+ if (scene->toolsettings->wpaint == NULL) {
+ scene->toolsettings->wpaint = new_vpaint();
}
+ Paint *paint = BKE_paint_get_active_from_paintmode(scene, paint_mode);
+ paint_cursor_start_explicit(paint, wm, weight_paint_poll);
+ BKE_paint_init(scene, paint_mode, PAINT_CURSOR_WEIGHT_PAINT);
+
/* weight paint specific */
- ED_mesh_mirror_spatial_table(NULL, NULL, NULL, NULL, 'e');
- ED_mesh_mirror_topo_table(NULL, NULL, 'e');
+ ED_mesh_mirror_spatial_table(ob, NULL, NULL, NULL, 's');
+ ED_vgroup_sync_from_pose(ob);
+ }
+ else {
+ BLI_assert(0);
+ }
- /* If the cache is not released by a cancel or a done, free it now. */
+ /* Create vertex/weight paint mode session data */
+ if (ob->sculpt) {
if (ob->sculpt->cache) {
sculpt_cache_free(ob->sculpt->cache);
ob->sculpt->cache = NULL;
}
-
BKE_sculptsession_free(ob);
+ }
+
+ vertex_paint_init_session(eval_ctx, scene, ob);
+}
+
+void ED_object_vpaintmode_enter_ex(
+ const EvaluationContext *eval_ctx, wmWindowManager *wm,
+ WorkSpace *workspace, Scene *scene, Object *ob)
+{
+ ed_vwpaintmode_enter_generic(
+ eval_ctx, wm, workspace, scene, ob, OB_MODE_VERTEX_PAINT);
+}
+void ED_object_vpaintmode_enter(struct bContext *C)
+{
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
+ wmWindowManager *wm = CTX_wm_manager(C);
+ WorkSpace *workspace = CTX_wm_workspace(C);
+ Scene *scene = CTX_data_scene(C);
+ Object *ob = CTX_data_active_object(C);
+ ED_object_vpaintmode_enter_ex(&eval_ctx, wm, workspace, scene, ob);
+}
+
+void ED_object_wpaintmode_enter_ex(
+ const EvaluationContext *eval_ctx, wmWindowManager *wm,
+ WorkSpace *workspace, Scene *scene, Object *ob)
+{
+ ed_vwpaintmode_enter_generic(
+ eval_ctx, wm, workspace, scene, ob, OB_MODE_WEIGHT_PAINT);
+}
+void ED_object_wpaintmode_enter(struct bContext *C)
+{
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
+ wmWindowManager *wm = CTX_wm_manager(C);
+ WorkSpace *workspace = CTX_wm_workspace(C);
+ Scene *scene = CTX_data_scene(C);
+ Object *ob = CTX_data_active_object(C);
+ ED_object_wpaintmode_enter_ex(&eval_ctx, wm, workspace, scene, ob);
+}
- paint_cursor_delete_textures();
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Exit Vertex/Weight Paint Mode
+ * \{ */
+
+static void ed_vwpaintmode_exit_generic(
+ WorkSpace *workspace,
+ Object *ob, const eObjectMode mode_flag)
+{
+ Mesh *me = BKE_mesh_from_object(ob);
+ workspace->object_mode &= ~mode_flag;
+
+ if (mode_flag == OB_MODE_VERTEX_PAINT) {
+ if (me->editflag & ME_EDIT_PAINT_FACE_SEL) {
+ BKE_mesh_flush_select_from_polys(me);
+ }
+ else if (me->editflag & ME_EDIT_PAINT_VERT_SEL) {
+ BKE_mesh_flush_select_from_verts(me);
+ }
+ }
+ else if (mode_flag == OB_MODE_WEIGHT_PAINT) {
+ if (me->editflag & ME_EDIT_PAINT_VERT_SEL) {
+ BKE_mesh_flush_select_from_verts(me);
+ }
+ else if (me->editflag & ME_EDIT_PAINT_FACE_SEL) {
+ BKE_mesh_flush_select_from_polys(me);
+ }
}
else {
- EvaluationContext eval_ctx;
+ BLI_assert(0);
+ }
- CTX_data_eval_ctx(C, &eval_ctx);
+ /* If the cache is not released by a cancel or a done, free it now. */
+ if (ob->sculpt->cache) {
+ sculpt_cache_free(ob->sculpt->cache);
+ ob->sculpt->cache = NULL;
+ }
- ob->mode |= mode_flag;
+ BKE_sculptsession_free(ob);
- if (wp == NULL)
- wp = scene->toolsettings->wpaint = new_vpaint();
+ paint_cursor_delete_textures();
- paint_cursor_start(C, weight_paint_poll);
+ if (mode_flag == OB_MODE_WEIGHT_PAINT) {
+ ED_mesh_mirror_spatial_table(NULL, NULL, NULL, NULL, 'e');
+ ED_mesh_mirror_topo_table(NULL, NULL, 'e');
+ }
+}
- BKE_paint_init(scene, ePaintWeight, PAINT_CURSOR_WEIGHT_PAINT);
+void ED_object_vpaintmode_exit_ex(WorkSpace *workspace, Object *ob)
+{
+ ed_vwpaintmode_exit_generic(workspace, ob, OB_MODE_VERTEX_PAINT);
+}
+void ED_object_vpaintmode_exit(struct bContext *C)
+{
+ WorkSpace *workspace = CTX_wm_workspace(C);
+ Object *ob = CTX_data_active_object(C);
+ ED_object_vpaintmode_exit_ex(workspace, ob);
+}
- /* weight paint specific */
- ED_mesh_mirror_spatial_table(ob, NULL, NULL, NULL, 's');
- ED_vgroup_sync_from_pose(ob);
+void ED_object_wpaintmode_exit_ex(WorkSpace *workspace, Object *ob)
+{
+ ed_vwpaintmode_exit_generic(workspace, ob, OB_MODE_WEIGHT_PAINT);
+}
+void ED_object_wpaintmode_exit(struct bContext *C)
+{
+ WorkSpace *workspace = CTX_wm_workspace(C);
+ Object *ob = CTX_data_active_object(C);
+ ED_object_wpaintmode_exit_ex(workspace, ob);
+}
- /* Create vertex/weight paint mode session data */
- if (ob->sculpt) {
- BKE_sculptsession_free(ob);
+/** \} */
+
+/* *************** set wpaint operator ****************** */
+
+/**
+ * \note Keep in sync with #vpaint_mode_toggle_exec
+ */
+static int wpaint_mode_toggle_exec(bContext *C, wmOperator *op)
+{
+ WorkSpace *workspace = CTX_wm_workspace(C);
+ Object *ob = CTX_data_active_object(C);
+ const int mode_flag = OB_MODE_WEIGHT_PAINT;
+ const bool is_mode_set = (workspace->object_mode & mode_flag) != 0;
+ Scene *scene = CTX_data_scene(C);
+
+ if (!is_mode_set) {
+ if (!ED_object_mode_compat_set(C, workspace, mode_flag, op->reports)) {
+ return OPERATOR_CANCELLED;
}
- vertex_paint_init_session(&eval_ctx, scene, ob);
+ }
+
+ Mesh *me = BKE_mesh_from_object(ob);
+
+ if (is_mode_set) {
+ ED_object_wpaintmode_exit_ex(workspace, ob);
+ }
+ else {
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
+ wmWindowManager *wm = CTX_wm_manager(C);
+ ED_object_wpaintmode_enter_ex(&eval_ctx, wm, workspace, scene, ob);
}
BKE_mesh_batch_cache_dirty(ob->data, BKE_MESH_BATCH_DIRTY_ALL);
@@ -1393,7 +1529,7 @@ static bool wpaint_stroke_test_start(bContext *C, wmOperator *op, const float mo
/* If not previously created, create vertex/weight paint mode session data */
vertex_paint_init_session(&eval_ctx, scene, ob);
vwpaint_update_cache_invariants(C, vp, ss, op, mouse);
- vertex_paint_init_session_data(ts, ob);
+ vertex_paint_init_session_data(&eval_ctx, ts, ob);
if (ob->sculpt->mode.wpaint.dvert_prev != NULL) {
MDeformVert *dv = ob->sculpt->mode.wpaint.dvert_prev;
@@ -1832,7 +1968,8 @@ static void wpaint_paint_leaves(
/* threaded loop over nodes */
SculptThreadedTaskData data = {
- .sd = sd, .ob = ob, .brush = brush, .nodes = nodes, .vp = vp, .wpd = wpd, .wpi = wpi, .me = me, .C = C,
+ .C = C, .sd = sd, .ob = ob, .brush = brush, .nodes = nodes,
+ .vp = vp, .wpd = wpd, .wpi = wpi, .me = me,
};
/* Use this so average can modify its weight without touching the brush. */
@@ -2208,67 +2345,29 @@ void PAINT_OT_weight_paint(wmOperatorType *ot)
*/
static int vpaint_mode_toggle_exec(bContext *C, wmOperator *op)
{
+ WorkSpace *workspace = CTX_wm_workspace(C);
Object *ob = CTX_data_active_object(C);
const int mode_flag = OB_MODE_VERTEX_PAINT;
- const bool is_mode_set = (ob->mode & mode_flag) != 0;
+ const bool is_mode_set = (workspace->object_mode & mode_flag) != 0;
Scene *scene = CTX_data_scene(C);
- VPaint *vp = scene->toolsettings->vpaint;
- Mesh *me;
if (!is_mode_set) {
- if (!ED_object_mode_compat_set(C, ob, mode_flag, op->reports)) {
+ if (!ED_object_mode_compat_set(C, workspace, mode_flag, op->reports)) {
return OPERATOR_CANCELLED;
}
}
- me = BKE_mesh_from_object(ob);
+ Mesh *me = BKE_mesh_from_object(ob);
/* toggle: end vpaint */
if (is_mode_set) {
- ob->mode &= ~mode_flag;
-
- if (me->editflag & ME_EDIT_PAINT_FACE_SEL) {
- BKE_mesh_flush_select_from_polys(me);
- }
- else if (me->editflag & ME_EDIT_PAINT_VERT_SEL) {
- BKE_mesh_flush_select_from_verts(me);
- }
-
- /* If the cache is not released by a cancel or a done, free it now. */
- if (ob->sculpt->cache) {
- sculpt_cache_free(ob->sculpt->cache);
- ob->sculpt->cache = NULL;
- }
-
- BKE_sculptsession_free(ob);
-
- paint_cursor_delete_textures();
+ ED_object_vpaintmode_exit_ex(workspace, ob);
}
else {
EvaluationContext eval_ctx;
-
CTX_data_eval_ctx(C, &eval_ctx);
-
- ob->mode |= mode_flag;
-
- ED_mesh_color_ensure(me, NULL);
-
- if (vp == NULL)
- vp = scene->toolsettings->vpaint = new_vpaint();
-
- paint_cursor_start(C, vertex_paint_poll);
-
- BKE_paint_init(scene, ePaintVertex, PAINT_CURSOR_VERTEX_PAINT);
-
- /* Create vertex/weight paint mode session data */
- if (ob->sculpt) {
- if (ob->sculpt->cache) {
- sculpt_cache_free(ob->sculpt->cache);
- ob->sculpt->cache = NULL;
- }
- BKE_sculptsession_free(ob);
- }
- vertex_paint_init_session(&eval_ctx, scene, ob);
+ wmWindowManager *wm = CTX_wm_manager(C);
+ ED_object_vpaintmode_enter_ex(&eval_ctx, wm, workspace, scene, ob);
}
BKE_mesh_batch_cache_dirty(ob->data, BKE_MESH_BATCH_DIRTY_ALL);
@@ -2417,7 +2516,7 @@ static bool vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const f
/* If not previously created, create vertex/weight paint mode session data */
vertex_paint_init_session(&eval_ctx, scene, ob);
vwpaint_update_cache_invariants(C, vp, ss, op, mouse);
- vertex_paint_init_session_data(ts, ob);
+ vertex_paint_init_session_data(&eval_ctx, ts, ob);
if (ob->sculpt->mode.vpaint.previous_color != NULL) {
memset(ob->sculpt->mode.vpaint.previous_color, 0, sizeof(uint) * me->totloop);
@@ -2871,8 +2970,8 @@ static void vpaint_paint_leaves(
const Brush *brush = ob->sculpt->cache->brush;
SculptThreadedTaskData data = {
- .sd = sd, .ob = ob, .brush = brush, .nodes = nodes, .vp = vp, .vpd = vpd,
- .lcol = (uint *)me->mloopcol, .me = me, .C = C,
+ .C = C, .sd = sd, .ob = ob, .brush = brush, .nodes = nodes, .vp = vp, .vpd = vpd,
+ .lcol = (uint *)me->mloopcol, .me = me,
};
ParallelRangeSettings settings;
BLI_parallel_range_settings_defaults(&settings);
diff --git a/source/blender/editors/sculpt_paint/paint_vertex_color_ops.c b/source/blender/editors/sculpt_paint/paint_vertex_color_ops.c
index d7668a48139..f442c12cbe9 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex_color_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex_color_ops.c
@@ -28,6 +28,7 @@
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "DNA_workspace_types.h"
#include "BLI_math_base.h"
#include "BLI_math_color.h"
@@ -51,9 +52,10 @@
static int vertex_weight_paint_mode_poll(bContext *C)
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Object *ob = CTX_data_active_object(C);
Mesh *me = BKE_mesh_from_object(ob);
- return (ob && (ob->mode == OB_MODE_VERTEX_PAINT || ob->mode == OB_MODE_WEIGHT_PAINT)) &&
+ return (ob && ELEM(workspace->object_mode, OB_MODE_VERTEX_PAINT, OB_MODE_WEIGHT_PAINT)) &&
(me && me->totpoly && me->dvert);
}
diff --git a/source/blender/editors/sculpt_paint/paint_vertex_proj.c b/source/blender/editors/sculpt_paint/paint_vertex_proj.c
index 999c9dc7880..336f851d4c1 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex_proj.c
@@ -78,8 +78,9 @@ struct VertProjUpdate {
/* -------------------------------------------------------------------- */
/* Internal Init */
-static void vpaint_proj_dm_map_cosnos_init__map_cb(void *userData, int index, const float co[3],
- const float no_f[3], const short no_s[3])
+static void vpaint_proj_dm_map_cosnos_init__map_cb(
+ void *userData, int index, const float co[3],
+ const float no_f[3], const short no_s[3])
{
struct VertProjHandle *vp_handle = userData;
DMCoNo *co_no = &vp_handle->vcosnos[index];
@@ -131,8 +132,9 @@ static void vpaint_proj_dm_map_cosnos_init(
/* Same as init but take mouse location into account */
-static void vpaint_proj_dm_map_cosnos_update__map_cb(void *userData, int index, const float co[3],
- const float no_f[3], const short no_s[3])
+static void vpaint_proj_dm_map_cosnos_update__map_cb(
+ void *userData, int index, const float co[3],
+ const float no_f[3], const short no_s[3])
{
struct VertProjUpdate *vp_update = userData;
struct VertProjHandle *vp_handle = vp_update->vp_handle;
@@ -144,9 +146,10 @@ static void vpaint_proj_dm_map_cosnos_update__map_cb(void *userData, int index,
/* first find distance to this vertex */
float co_ss[2]; /* screenspace */
- if (ED_view3d_project_float_object(vp_update->ar,
- co, co_ss,
- V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK)
+ if (ED_view3d_project_float_object(
+ vp_update->ar,
+ co, co_ss,
+ V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK)
{
const float dist_sq = len_squared_v2v2(vp_update->mval_fl, co_ss);
if (dist_sq > vp_handle->dists_sq[index]) {
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 1348847167c..72e2e7b323d 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c
@@ -118,9 +118,10 @@ static void wpaint_prev_destroy(struct WPaintPrev *wpp)
static int weight_from_bones_poll(bContext *C)
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Object *ob = CTX_data_active_object(C);
- return (ob && (ob->mode & OB_MODE_WEIGHT_PAINT) && modifiers_isDeformedByArmature(ob));
+ return (ob && (workspace->object_mode & OB_MODE_WEIGHT_PAINT) && modifiers_isDeformedByArmature(ob));
}
static int weight_from_bones_exec(bContext *C, wmOperator *op)
diff --git a/source/blender/editors/sculpt_paint/paint_vertex_weight_utils.c b/source/blender/editors/sculpt_paint/paint_vertex_weight_utils.c
index 4d70d82d5c6..51cd759b260 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex_weight_utils.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex_weight_utils.c
@@ -43,6 +43,7 @@
#include "BKE_modifier.h"
#include "BKE_object_deform.h"
#include "BKE_report.h"
+#include "BKE_object.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -58,7 +59,6 @@ bool ED_wpaint_ensure_data(
bContext *C, struct ReportList *reports,
enum eWPaintFlag flag, struct WPaintVGroupIndex *vgroup_index)
{
- Scene *scene = CTX_data_scene(C);
Object *ob = CTX_data_active_object(C);
Mesh *me = BKE_mesh_from_object(ob);
@@ -67,7 +67,7 @@ bool ED_wpaint_ensure_data(
vgroup_index->mirror = -1;
}
- if (scene->obedit) {
+ if (BKE_object_is_in_editmode(ob)) {
return false;
}
@@ -308,4 +308,4 @@ float ED_wpaint_blend_tool(
}
}
-/** \} */ \ No newline at end of file
+/** \} */
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index c9d550aa4bd..8df3d4e9f90 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -37,7 +37,7 @@
#include "BLI_math.h"
#include "BLI_blenlib.h"
-#include "BLI_dial.h"
+#include "BLI_dial_2d.h"
#include "BLI_task.h"
#include "BLI_utildefines.h"
#include "BLI_ghash.h"
@@ -4082,8 +4082,9 @@ static void sculpt_update_tex(const Scene *scene, Sculpt *sd, SculptSession *ss)
int sculpt_mode_poll(bContext *C)
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Object *ob = CTX_data_active_object(C);
- return ob && ob->mode & OB_MODE_SCULPT;
+ return ob && workspace->object_mode & OB_MODE_SCULPT;
}
int sculpt_mode_poll_view3d(bContext *C)
@@ -4595,19 +4596,17 @@ static bool sculpt_any_smooth_mode(const Brush *brush,
(brush->mask_tool == BRUSH_MASK_SMOOTH)));
}
-static void sculpt_stroke_modifiers_check(const bContext *C, Object *ob)
+static void sculpt_stroke_modifiers_check(const bContext *C, Object *ob, const Brush *brush)
{
SculptSession *ss = ob->sculpt;
if (ss->kb || ss->modifiers_active) {
EvaluationContext eval_ctx;
- Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
- Brush *brush = BKE_paint_brush(&sd->paint);
-
CTX_data_eval_ctx(C, &eval_ctx);
-
- BKE_sculpt_update_mesh_elements(&eval_ctx, CTX_data_scene(C), sd, ob,
- sculpt_any_smooth_mode(brush, ss->cache, 0), false);
+ Scene *scene = CTX_data_scene(C);
+ Sculpt *sd = scene->toolsettings->sculpt;
+ bool need_pmap = sculpt_any_smooth_mode(brush, ss->cache, 0);
+ BKE_sculpt_update_mesh_elements(&eval_ctx, scene, sd, ob, need_pmap, false);
}
}
@@ -4736,7 +4735,9 @@ bool sculpt_stroke_get_location(bContext *C, float out[3], const float mouse[2])
cache = ss->cache;
original = (cache) ? cache->original : 0;
- sculpt_stroke_modifiers_check(C, ob);
+ const Brush *brush = BKE_paint_brush(BKE_paint_get_active_from_context(C));
+
+ sculpt_stroke_modifiers_check(C, ob, brush);
depth = sculpt_raycast_init(&vc, mouse, ray_start, ray_end, ray_normal, original);
@@ -4762,7 +4763,6 @@ bool sculpt_stroke_get_location(bContext *C, float out[3], const float mouse[2])
}
if (hit == false) {
- const Brush *brush = BKE_paint_brush(BKE_paint_get_active_from_context(C));
if (ELEM(brush->falloff_shape, PAINT_FALLOFF_SHAPE_TUBE)) {
SculptFindNearestToRayData srd = {
.original = original,
@@ -4953,7 +4953,7 @@ static void sculpt_stroke_update_step(bContext *C, struct PaintStroke *UNUSED(st
SculptSession *ss = ob->sculpt;
const Brush *brush = BKE_paint_brush(&sd->paint);
- sculpt_stroke_modifiers_check(C, ob);
+ sculpt_stroke_modifiers_check(C, ob, brush);
sculpt_update_cache_variants(C, sd, ob, itemptr);
sculpt_restore_mesh(sd, ob);
@@ -5028,7 +5028,7 @@ static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(str
BLI_assert(brush == ss->cache->brush); /* const, so we shouldn't change. */
ups->draw_inverted = false;
- sculpt_stroke_modifiers_check(C, ob);
+ sculpt_stroke_modifiers_check(C, ob, brush);
/* Alt-Smooth */
if (ss->cache->alt_smooth) {
@@ -5047,7 +5047,7 @@ static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(str
sculpt_cache_free(ss->cache);
ss->cache = NULL;
- sculpt_undo_push_end(C);
+ sculpt_undo_push_end();
BKE_pbvh_update(ss->pbvh, PBVH_UpdateOriginalBB, NULL);
@@ -5219,7 +5219,7 @@ void sculpt_pbvh_clear(Object *ob)
BKE_pbvh_free(ss->pbvh);
ss->pbvh = NULL;
if (dm)
- dm->getPBVH(NULL, dm);
+ dm->getPBVH(NULL, dm, OB_MODE_OBJECT);
BKE_object_free_derived_caches(ob);
}
@@ -5255,24 +5255,21 @@ void sculpt_dyntopo_node_layers_add(SculptSession *ss)
}
-void sculpt_update_after_dynamic_topology_toggle(bContext *C)
+void sculpt_update_after_dynamic_topology_toggle(
+ const EvaluationContext *eval_ctx,
+ Scene *scene, Object *ob)
{
- Scene *scene = CTX_data_scene(C);
- Object *ob = CTX_data_active_object(C);
- EvaluationContext eval_ctx;
Sculpt *sd = scene->toolsettings->sculpt;
- CTX_data_eval_ctx(C, &eval_ctx);
-
/* Create the PBVH */
- BKE_sculpt_update_mesh_elements(&eval_ctx, scene, sd, ob, false, false);
- WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
+ BKE_sculpt_update_mesh_elements(eval_ctx, scene, sd, ob, false, false);
+ WM_main_add_notifier(NC_OBJECT | ND_DRAW, ob);
}
-void sculpt_dynamic_topology_enable(bContext *C)
+void sculpt_dynamic_topology_enable_ex(
+ const EvaluationContext *eval_ctx,
+ Scene *scene, Object *ob)
{
- Scene *scene = CTX_data_scene(C);
- Object *ob = CTX_data_active_object(C);
SculptSession *ss = ob->sculpt;
Mesh *me = ob->data;
const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(me);
@@ -5308,17 +5305,17 @@ void sculpt_dynamic_topology_enable(bContext *C)
ss->bm_log = BM_log_create(ss->bm);
/* Refresh */
- sculpt_update_after_dynamic_topology_toggle(C);
+ sculpt_update_after_dynamic_topology_toggle(eval_ctx, scene, ob);
}
/* Free the sculpt BMesh and BMLog
*
* If 'unode' is given, the BMesh's data is copied out to the unode
* before the BMesh is deleted so that it can be restored from */
-void sculpt_dynamic_topology_disable(bContext *C,
- SculptUndoNode *unode)
+void sculpt_dynamic_topology_disable_ex(
+ const EvaluationContext *eval_ctx,
+ Scene *scene, Object *ob, SculptUndoNode *unode)
{
- Object *ob = CTX_data_active_object(C);
SculptSession *ss = ob->sculpt;
Mesh *me = ob->data;
@@ -5367,28 +5364,59 @@ void sculpt_dynamic_topology_disable(bContext *C,
}
/* Refresh */
- sculpt_update_after_dynamic_topology_toggle(C);
+ sculpt_update_after_dynamic_topology_toggle(eval_ctx, scene, ob);
+}
+
+void sculpt_dynamic_topology_disable(bContext *C, SculptUndoNode *unode)
+{
+ Scene *scene = CTX_data_scene(C);
+ Object *ob = CTX_data_active_object(C);
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
+ sculpt_dynamic_topology_disable_ex(&eval_ctx, scene, ob, unode);
+}
+
+static void sculpt_dynamic_topology_disable_with_undo(
+ const EvaluationContext *eval_ctx, Scene *scene, Object *ob)
+{
+ SculptSession *ss = ob->sculpt;
+ if (ss->bm) {
+ sculpt_undo_push_begin("Dynamic topology disable");
+ sculpt_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_END);
+ sculpt_dynamic_topology_disable_ex(eval_ctx, scene, ob, NULL);
+ sculpt_undo_push_end();
+ }
}
+static void sculpt_dynamic_topology_enable_with_undo(
+ const EvaluationContext *eval_ctx,
+ Scene *scene, Object *ob)
+{
+ SculptSession *ss = ob->sculpt;
+ if (ss->bm == NULL) {
+ sculpt_undo_push_begin("Dynamic topology enable");
+ sculpt_dynamic_topology_enable_ex(eval_ctx, scene, ob);
+ sculpt_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_BEGIN);
+ sculpt_undo_push_end();
+ }
+}
static int sculpt_dynamic_topology_toggle_exec(bContext *C, wmOperator *UNUSED(op))
{
+ Scene *scene = CTX_data_scene(C);
Object *ob = CTX_data_active_object(C);
SculptSession *ss = ob->sculpt;
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
WM_cursor_wait(1);
if (ss->bm) {
- sculpt_undo_push_begin("Dynamic topology disable");
- sculpt_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_END);
- sculpt_dynamic_topology_disable(C, NULL);
+ sculpt_dynamic_topology_disable_with_undo(&eval_ctx, scene, ob);
}
else {
- sculpt_undo_push_begin("Dynamic topology enable");
- sculpt_dynamic_topology_enable(C);
- sculpt_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_BEGIN);
+ sculpt_dynamic_topology_enable_with_undo(&eval_ctx, scene, ob);
}
- sculpt_undo_push_end(C);
WM_cursor_wait(0);
@@ -5576,7 +5604,7 @@ static int sculpt_symmetrize_exec(bContext *C, wmOperator *UNUSED(op))
/* Finish undo */
BM_log_all_added(ss->bm, ss->bm_log);
- sculpt_undo_push_end(C);
+ sculpt_undo_push_end();
/* Redraw */
sculpt_pbvh_clear(ob);
@@ -5599,31 +5627,81 @@ static void SCULPT_OT_symmetrize(wmOperatorType *ot)
/**** Toggle operator for turning sculpt mode on or off ****/
-static void sculpt_init_session(const bContext *C, Scene *scene, Object *ob)
+static void sculpt_init_session(const EvaluationContext *eval_ctx, Scene *scene, Object *ob)
{
- EvaluationContext eval_ctx;
-
- CTX_data_eval_ctx(C, &eval_ctx);
+ /* Create persistent sculpt mode data */
+ BKE_sculpt_toolsettings_data_ensure(scene);
ob->sculpt = MEM_callocN(sizeof(SculptSession), "sculpt session");
+ ob->sculpt->mode_type = OB_MODE_SCULPT;
+ BKE_sculpt_update_mesh_elements(eval_ctx, scene, scene->toolsettings->sculpt, ob, 0, false);
+}
+
+void ED_object_sculptmode_exit_ex(
+ const EvaluationContext *eval_ctx,
+ WorkSpace *workspace, Scene *scene, Object *ob)
+{
+ const int mode_flag = OB_MODE_SCULPT;
+ Mesh *me = BKE_mesh_from_object(ob);
- BKE_sculpt_update_mesh_elements(&eval_ctx, scene, scene->toolsettings->sculpt, ob, 0, false);
+ MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob);
+ if (mmd) {
+ multires_force_update(ob);
+ }
+
+ /* Always for now, so leaving sculpt mode always ensures scene is in
+ * a consistent state.
+ */
+ if (true || /* flush_recalc || */ (ob->sculpt && ob->sculpt->bm)) {
+ DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ }
+
+ if (me->flag & ME_SCULPT_DYNAMIC_TOPOLOGY) {
+ /* Dynamic topology must be disabled before exiting sculpt
+ * mode to ensure the undo stack stays in a consistent
+ * state */
+ sculpt_dynamic_topology_disable_with_undo(eval_ctx, scene, ob);
+
+ /* store so we know to re-enable when entering sculpt mode */
+ me->flag |= ME_SCULPT_DYNAMIC_TOPOLOGY;
+ }
+
+ /* Leave sculptmode */
+ workspace->object_mode &= ~mode_flag;
+
+ BKE_sculptsession_free(ob);
+
+ paint_cursor_delete_textures();
+
+ /* VBO no longer valid */
+ if (ob->derivedFinal) {
+ GPU_drawobject_free(ob->derivedFinal);
+ }
}
+void ED_object_sculptmode_exit(bContext *C)
+{
+ WorkSpace *workspace = CTX_wm_workspace(C);
+ Scene *scene = CTX_data_scene(C);
+ Object *ob = CTX_data_active_object(C);
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
+ ED_object_sculptmode_exit_ex(&eval_ctx, workspace, scene, ob);
+}
static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op)
{
+ WorkSpace *workspace = CTX_wm_workspace(C);
Scene *scene = CTX_data_scene(C);
- ToolSettings *ts = CTX_data_tool_settings(C);
Object *ob = CTX_data_active_object(C);
const int mode_flag = OB_MODE_SCULPT;
- const bool is_mode_set = (ob->mode & mode_flag) != 0;
+ const bool is_mode_set = (workspace->object_mode & mode_flag) != 0;
Mesh *me;
MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob);
int flush_recalc = 0;
if (!is_mode_set) {
- if (!ED_object_mode_compat_set(C, ob, mode_flag, op->reports)) {
+ if (!ED_object_mode_compat_set(C, workspace, mode_flag, op->reports)) {
return OPERATOR_CANCELLED;
}
}
@@ -5636,70 +5714,25 @@ static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op)
flush_recalc |= sculpt_has_active_modifiers(scene, ob);
if (is_mode_set) {
- if (mmd)
- multires_force_update(ob);
-
- /* Always for now, so leaving sculpt mode always ensures scene is in
- * a consistent state.
- */
- if (true || flush_recalc || (ob->sculpt && ob->sculpt->bm)) {
- DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
- }
-
- if (me->flag & ME_SCULPT_DYNAMIC_TOPOLOGY) {
- /* Dynamic topology must be disabled before exiting sculpt
- * mode to ensure the undo stack stays in a consistent
- * state */
- sculpt_dynamic_topology_toggle_exec(C, NULL);
-
- /* store so we know to re-enable when entering sculpt mode */
- me->flag |= ME_SCULPT_DYNAMIC_TOPOLOGY;
- }
-
- /* Leave sculptmode */
- ob->mode &= ~mode_flag;
-
- BKE_sculptsession_free(ob);
-
- paint_cursor_delete_textures();
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
+ ED_object_sculptmode_exit_ex(&eval_ctx, workspace, scene, ob);
}
else {
/* Enter sculptmode */
- ob->mode |= mode_flag;
+ workspace->object_mode |= mode_flag;
if (flush_recalc)
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
- /* Create persistent sculpt mode data */
- if (!ts->sculpt) {
- ts->sculpt = MEM_callocN(sizeof(Sculpt), "sculpt mode data");
-
- /* Turn on X plane mirror symmetry by default */
- ts->sculpt->paint.symmetry_flags |= PAINT_SYMM_X;
- ts->sculpt->paint.flags |= PAINT_SHOW_BRUSH;
-
- /* Make sure at least dyntopo subdivision is enabled */
- ts->sculpt->flags |= SCULPT_DYNTOPO_SUBDIVIDE | SCULPT_DYNTOPO_COLLAPSE;
- }
-
- if (!ts->sculpt->detail_size)
- ts->sculpt->detail_size = 12;
- if (!ts->sculpt->detail_percent)
- ts->sculpt->detail_percent = 25;
- if (ts->sculpt->constant_detail == 0.0f)
- ts->sculpt->constant_detail = 3.0f;
-
- /* Set sane default tiling offsets */
- if (!ts->sculpt->paint.tile_offset[0]) ts->sculpt->paint.tile_offset[0] = 1.0f;
- if (!ts->sculpt->paint.tile_offset[1]) ts->sculpt->paint.tile_offset[1] = 1.0f;
- if (!ts->sculpt->paint.tile_offset[2]) ts->sculpt->paint.tile_offset[2] = 1.0f;
-
-
/* Create sculpt mode session data */
- if (ob->sculpt)
+ if (ob->sculpt) {
BKE_sculptsession_free(ob);
+ }
- sculpt_init_session(C, scene, ob);
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
+ sculpt_init_session(&eval_ctx, scene, ob);
/* Mask layer is required */
if (mmd) {
@@ -5756,7 +5789,7 @@ static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op)
if (message_unsupported == NULL) {
/* undo push is needed to prevent memory leak */
sculpt_undo_push_begin("Dynamic topology enable");
- sculpt_dynamic_topology_enable(C);
+ sculpt_dynamic_topology_enable_ex(&eval_ctx, scene, ob);
sculpt_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_BEGIN);
}
else {
@@ -5766,10 +5799,12 @@ static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op)
me->flag &= ~ME_SCULPT_DYNAMIC_TOPOLOGY;
}
}
- }
- if (ob->derivedFinal) /* VBO no longer valid */
- GPU_drawobject_free(ob->derivedFinal);
+ /* VBO no longer valid */
+ if (ob->derivedFinal) {
+ GPU_drawobject_free(ob->derivedFinal);
+ }
+ }
WM_event_add_notifier(C, NC_SCENE | ND_MODE, scene);
@@ -5839,7 +5874,7 @@ static int sculpt_detail_flood_fill_exec(bContext *C, wmOperator *UNUSED(op))
}
MEM_freeN(nodes);
- sculpt_undo_push_end(C);
+ sculpt_undo_push_end();
/* force rebuild of pbvh for better BB placement */
sculpt_pbvh_clear(ob);
@@ -5876,7 +5911,9 @@ static void sample_detail(bContext *C, int ss_co[2])
sd = CTX_data_tool_settings(C)->sculpt;
ob = vc.obact;
- sculpt_stroke_modifiers_check(C, ob);
+ Brush *brush = BKE_paint_brush(&sd->paint);
+
+ sculpt_stroke_modifiers_check(C, ob, brush);
depth = sculpt_raycast_init(&vc, mouse, ray_start, ray_end, ray_normal, false);
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index 5fb9eee805f..54cdbb18693 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -60,10 +60,19 @@ bool sculpt_stroke_get_location(struct bContext *C, float out[3], const float mo
/* Dynamic topology */
void sculpt_pbvh_clear(Object *ob);
void sculpt_dyntopo_node_layers_add(struct SculptSession *ss);
-void sculpt_update_after_dynamic_topology_toggle(struct bContext *C);
-void sculpt_dynamic_topology_enable(struct bContext *C);
-void sculpt_dynamic_topology_disable(struct bContext *C,
- struct SculptUndoNode *unode);
+void sculpt_update_after_dynamic_topology_toggle(
+ const struct EvaluationContext *eval_ctx,
+ struct Scene *scene, struct Object *ob);
+void sculpt_dynamic_topology_enable_ex(
+ const struct EvaluationContext *eval_ctx,
+ struct Scene *scene, struct Object *ob);
+void sculpt_dynamic_topology_enable(bContext *C);
+
+void sculpt_dynamic_topology_disable_ex(
+ const struct EvaluationContext *eval_ctx,
+ struct Scene *scene, struct Object *ob,
+ struct SculptUndoNode *unode);
+void sculpt_dynamic_topology_disable(bContext *C, struct SculptUndoNode *unode);
/* Undo */
@@ -342,7 +351,7 @@ void sculpt_cache_free(StrokeCache *cache);
SculptUndoNode *sculpt_undo_push_node(Object *ob, PBVHNode *node, SculptUndoType type);
SculptUndoNode *sculpt_undo_get_node(PBVHNode *node);
void sculpt_undo_push_begin(const char *name);
-void sculpt_undo_push_end(const struct bContext *C);
+void sculpt_undo_push_end(void);
void sculpt_vertcos_to_key(Object *ob, KeyBlock *kb, float (*vertCos)[3]);
diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c
index 63017a0e576..55950a51fba 100644
--- a/source/blender/editors/sculpt_paint/sculpt_undo.c
+++ b/source/blender/editors/sculpt_paint/sculpt_undo.c
@@ -368,8 +368,8 @@ static void sculpt_undo_bmesh_restore_generic(bContext *C,
}
/* Create empty sculpt BMesh and enable logging */
-static void sculpt_undo_bmesh_enable(Object *ob,
- SculptUndoNode *unode)
+static void sculpt_undo_bmesh_enable(
+ Object *ob, SculptUndoNode *unode)
{
SculptSession *ss = ob->sculpt;
Mesh *me = ob->data;
@@ -896,7 +896,7 @@ SculptUndoNode *sculpt_undo_push_node(Object *ob, PBVHNode *node,
SculptUndoNode *unode;
/* list is manipulated by multiple threads, so we lock */
- BLI_lock_thread(LOCK_CUSTOM1);
+ BLI_thread_lock(LOCK_CUSTOM1);
if (ss->bm ||
ELEM(type,
@@ -906,17 +906,17 @@ SculptUndoNode *sculpt_undo_push_node(Object *ob, PBVHNode *node,
/* Dynamic topology stores only one undo node per stroke,
* regardless of the number of PBVH nodes modified */
unode = sculpt_undo_bmesh_push(ob, node, type);
- BLI_unlock_thread(LOCK_CUSTOM1);
+ BLI_thread_unlock(LOCK_CUSTOM1);
return unode;
}
else if ((unode = sculpt_undo_get_node(node))) {
- BLI_unlock_thread(LOCK_CUSTOM1);
+ BLI_thread_unlock(LOCK_CUSTOM1);
return unode;
}
unode = sculpt_undo_alloc_node(ob, node, type);
- BLI_unlock_thread(LOCK_CUSTOM1);
+ BLI_thread_unlock(LOCK_CUSTOM1);
/* copy threaded, hopefully this is the performance critical part */
@@ -964,7 +964,7 @@ void sculpt_undo_push_begin(const char *name)
sculpt_undo_restore, sculpt_undo_free, sculpt_undo_cleanup);
}
-void sculpt_undo_push_end(const bContext *C)
+void sculpt_undo_push_end(void)
{
ListBase *lb = undo_paint_push_get_list(UNDO_PAINT_MESH);
SculptUndoNode *unode;
@@ -982,5 +982,5 @@ void sculpt_undo_push_end(const bContext *C)
ED_undo_paint_push_end(UNDO_PAINT_MESH);
- WM_file_tag_modified(C);
+ WM_file_tag_modified();
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_uv.c b/source/blender/editors/sculpt_paint/sculpt_uv.c
index c9453f94e61..700b0969277 100644
--- a/source/blender/editors/sculpt_paint/sculpt_uv.c
+++ b/source/blender/editors/sculpt_paint/sculpt_uv.c
@@ -652,7 +652,7 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm
UvElement *element;
NearestHit hit;
Image *ima = CTX_data_edit_image(C);
- uv_find_nearest_vert(scene, ima, em, co, NULL, &hit);
+ uv_find_nearest_vert(scene, ima, obedit, em, co, NULL, &hit);
element = BM_uv_element_get(data->elementMap, hit.efa, hit.l);
island_index = element->island;
@@ -759,7 +759,7 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm
MEM_freeN(uniqueUv);
/* Allocate connectivity data, we allocate edges once */
- data->uvedges = MEM_mallocN(sizeof(*data->uvedges) * BLI_ghash_size(edgeHash), "uv_brush_edge_connectivity_data");
+ data->uvedges = MEM_mallocN(sizeof(*data->uvedges) * BLI_ghash_len(edgeHash), "uv_brush_edge_connectivity_data");
if (!data->uvedges) {
BLI_ghash_free(edgeHash, NULL, NULL);
MEM_freeN(edges);
@@ -772,7 +772,7 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm
GHASH_ITER (gh_iter, edgeHash) {
data->uvedges[i++] = *((UvEdge *)BLI_ghashIterator_getKey(&gh_iter));
}
- data->totalUvEdges = BLI_ghash_size(edgeHash);
+ data->totalUvEdges = BLI_ghash_len(edgeHash);
/* cleanup temporary stuff */
BLI_ghash_free(edgeHash, NULL, NULL);
diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c
index 110c4d1789d..3c3a71d00fd 100644
--- a/source/blender/editors/space_action/action_select.c
+++ b/source/blender/editors/space_action/action_select.c
@@ -36,7 +36,7 @@
#include "BLI_blenlib.h"
#include "BLI_dlrbTree.h"
-#include "BLI_lasso.h"
+#include "BLI_lasso_2d.h"
#include "BLI_utildefines.h"
#include "DNA_anim_types.h"
diff --git a/source/blender/editors/space_buttons/CMakeLists.txt b/source/blender/editors/space_buttons/CMakeLists.txt
index 397d79e1dbe..ec866780122 100644
--- a/source/blender/editors/space_buttons/CMakeLists.txt
+++ b/source/blender/editors/space_buttons/CMakeLists.txt
@@ -23,6 +23,7 @@ set(INC
../../blenkernel
../../blenlib
../../blentranslation
+ ../../depsgraph
../../gpu
../../makesdna
../../makesrna
diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c
index 8866c6b6c40..ebb14d3caeb 100644
--- a/source/blender/editors/space_buttons/buttons_context.c
+++ b/source/blender/editors/space_buttons/buttons_context.c
@@ -62,6 +62,8 @@
#include "RNA_access.h"
+#include "DEG_depsgraph.h"
+
#include "ED_buttons.h"
#include "ED_armature.h"
#include "ED_screen.h"
@@ -423,8 +425,9 @@ static int buttons_context_path_brush(const bContext *C, ButsContextPath *path)
scene = path->ptr[path->len - 1].data;
if (scene) {
+ const WorkSpace *workspace = CTX_wm_workspace(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
- br = BKE_paint_brush(BKE_paint_get_active(scene, view_layer));
+ br = BKE_paint_brush(BKE_paint_get_active(scene, view_layer, workspace->object_mode));
}
if (br) {
diff --git a/source/blender/editors/space_buttons/buttons_texture.c b/source/blender/editors/space_buttons/buttons_texture.c
index 036db87e846..d0e69a3dd7e 100644
--- a/source/blender/editors/space_buttons/buttons_texture.c
+++ b/source/blender/editors/space_buttons/buttons_texture.c
@@ -45,7 +45,7 @@
#include "DNA_material_types.h"
#include "DNA_node_types.h"
#include "DNA_object_types.h"
-#include "DNA_object_force.h"
+#include "DNA_object_force_types.h"
#include "DNA_particle_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c
index 09d225fc1b8..96968a14883 100644
--- a/source/blender/editors/space_clip/clip_draw.c
+++ b/source/blender/editors/space_clip/clip_draw.c
@@ -157,7 +157,7 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc
MovieTrackingReconstruction *reconstruction = BKE_tracking_get_active_reconstruction(tracking);
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
/* cache background */
ED_region_cache_draw_background(ar);
@@ -314,7 +314,7 @@ static void draw_movieclip_buffer(const bContext *C, SpaceClip *sc, ARegion *ar,
/* checkerboard for case alpha */
if (ibuf->planes == 32) {
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
imm_draw_box_checker_2d(x, y, x + zoomx * ibuf->x, y + zoomy * ibuf->y);
}
@@ -1126,7 +1126,7 @@ static void draw_plane_marker_image(Scene *scene,
if (plane_track->image_opacity != 1.0f || ibuf->planes == 32) {
transparent = true;
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
}
glGenTextures(1, (GLuint *)&texid);
diff --git a/source/blender/editors/space_clip/clip_utils.c b/source/blender/editors/space_clip/clip_utils.c
index 7f9d9bf577c..9f79e8ffd6b 100644
--- a/source/blender/editors/space_clip/clip_utils.c
+++ b/source/blender/editors/space_clip/clip_utils.c
@@ -302,7 +302,7 @@ void clip_draw_sfra_efra(View2D *v2d, Scene *scene)
UI_view2d_view_ortho(v2d);
/* currently clip editor supposes that editing clip length is equal to scene frame range */
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
diff --git a/source/blender/editors/space_clip/tracking_select.c b/source/blender/editors/space_clip/tracking_select.c
index 4ee85ace271..ecbc1f5ae1e 100644
--- a/source/blender/editors/space_clip/tracking_select.c
+++ b/source/blender/editors/space_clip/tracking_select.c
@@ -37,7 +37,7 @@
#include "BLI_utildefines.h"
#include "BLI_math.h"
#include "BLI_rect.h"
-#include "BLI_lasso.h"
+#include "BLI_lasso_2d.h"
#include "BKE_context.h"
#include "BKE_tracking.h"
diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c
index c1e298c426f..4bf377ddc1a 100644
--- a/source/blender/editors/space_file/file_draw.c
+++ b/source/blender/editors/space_file/file_draw.c
@@ -375,7 +375,7 @@ static void file_draw_preview(
xco = sx + (int)dx;
yco = sy - layout->prv_h + (int)dy;
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
/* shadow */
if (use_dropshadow) {
diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c
index 3c90f2957df..0fe51ea1c70 100644
--- a/source/blender/editors/space_file/space_file.c
+++ b/source/blender/editors/space_file/space_file.c
@@ -189,6 +189,9 @@ static SpaceLink *file_duplicate(SpaceLink *sl)
/* clear or remove stuff from old */
sfilen->op = NULL; /* file window doesn't own operators */
+ sfilen->previews_timer = NULL;
+ sfilen->smoothscroll_timer = NULL;
+
if (sfileo->params) {
sfilen->files = filelist_new(sfileo->params->type);
sfilen->params = MEM_dupallocN(sfileo->params);
diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c
index d917e3b85a2..74349d52169 100644
--- a/source/blender/editors/space_graph/graph_draw.c
+++ b/source/blender/editors/space_graph/graph_draw.c
@@ -1232,7 +1232,7 @@ void graph_draw_channel_names(bContext *C, bAnimContext *ac, ARegion *ar)
y = (float)ACHANNEL_FIRST(ac);
/* set blending again, as may not be set in previous step */
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
for (ale = anim_data.first, i = 0; ale; ale = ale->next, i++) {
diff --git a/source/blender/editors/space_graph/graph_select.c b/source/blender/editors/space_graph/graph_select.c
index 392db4ef4b5..0b7ce7d7310 100644
--- a/source/blender/editors/space_graph/graph_select.c
+++ b/source/blender/editors/space_graph/graph_select.c
@@ -37,7 +37,7 @@
#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
-#include "BLI_lasso.h"
+#include "BLI_lasso_2d.h"
#include "DNA_anim_types.h"
#include "DNA_screen_types.h"
diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c
index 23c4fbbe45e..43d5348da3e 100644
--- a/source/blender/editors/space_image/image_draw.c
+++ b/source/blender/editors/space_image/image_draw.c
@@ -170,7 +170,7 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, bool color_manage, bool use_d
float hue = 0, sat = 0, val = 0, lum = 0, u = 0, v = 0;
float col[4], finalcol[4];
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
@@ -482,8 +482,6 @@ static void draw_image_buffer(const bContext *C, SpaceImage *sima, ARegion *ar,
{
int x, y;
- glaDefine2DArea(&ar->winrct);
-
/* find window pixel coordinates of origin */
UI_view2d_view_to_region(&ar->v2d, fx, fy, &x, &y);
@@ -506,7 +504,7 @@ static void draw_image_buffer(const bContext *C, SpaceImage *sima, ARegion *ar,
imm_draw_box_checker_2d(x, y, x + ibuf->x * zoomx, y + ibuf->y * zoomy);
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
}
/* If RGBA display with color management */
@@ -733,7 +731,7 @@ static void draw_image_paint_helpers(const bContext *C, ARegion *ar, Scene *scen
}
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR);
immDrawPixelsTex(&state, x, y, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_NEAREST, display_buffer, zoomx, zoomy, col);
@@ -794,7 +792,7 @@ void draw_image_main(const bContext *C, ARegion *ar)
* other images are not modifying in such a way so they does not require
* lock (sergey)
*/
- BLI_lock_thread(LOCK_DRAW_IMAGE);
+ BLI_thread_lock(LOCK_DRAW_IMAGE);
}
if (show_stereo3d) {
@@ -838,7 +836,7 @@ void draw_image_main(const bContext *C, ARegion *ar)
draw_image_paint_helpers(C, ar, scene, zoomx, zoomy);
if (show_viewer) {
- BLI_unlock_thread(LOCK_DRAW_IMAGE);
+ BLI_thread_unlock(LOCK_DRAW_IMAGE);
}
/* render info */
@@ -879,7 +877,7 @@ void draw_image_cache(const bContext *C, ARegion *ar)
}
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
/* Draw cache background. */
ED_region_cache_draw_background(ar);
diff --git a/source/blender/editors/space_image/image_edit.c b/source/blender/editors/space_image/image_edit.c
index 587689eda78..95ed8967380 100644
--- a/source/blender/editors/space_image/image_edit.c
+++ b/source/blender/editors/space_image/image_edit.c
@@ -44,6 +44,8 @@
#include "IMB_imbuf_types.h"
+#include "DEG_depsgraph.h"
+
#include "ED_image.h" /* own include */
#include "ED_mesh.h"
#include "ED_screen.h"
@@ -321,15 +323,16 @@ bool ED_image_slot_cycle(struct Image *image, int direction)
void ED_space_image_scopes_update(const struct bContext *C, struct SpaceImage *sima, struct ImBuf *ibuf, bool use_view_settings)
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Scene *scene = CTX_data_scene(C);
Object *ob = CTX_data_active_object(C);
-
+
/* scope update can be expensive, don't update during paint modes */
if (sima->mode == SI_MODE_PAINT)
return;
- if (ob && ((ob->mode & (OB_MODE_TEXTURE_PAINT | OB_MODE_EDIT)) != 0))
+ if (ob && ((workspace->object_mode & (OB_MODE_TEXTURE_PAINT | OB_MODE_EDIT)) != 0)) {
return;
-
+ }
/* We also don't update scopes of render result during render. */
if (G.is_rendering) {
const Image *image = sima->image;
@@ -374,11 +377,12 @@ bool ED_space_image_show_uvedit(SpaceImage *sima, Object *obedit)
}
/* matches clip function */
-bool ED_space_image_check_show_maskedit(ViewLayer *view_layer, SpaceImage *sima)
+bool ED_space_image_check_show_maskedit(
+ SpaceImage *sima, const WorkSpace *workspace, ViewLayer *view_layer)
{
/* check editmode - this is reserved for UV editing */
Object *ob = OBACT(view_layer);
- if (ob && ob->mode & OB_MODE_EDIT && ED_space_image_show_uvedit(sima, ob)) {
+ if (ob && (workspace->object_mode & OB_MODE_EDIT) && ED_space_image_show_uvedit(sima, ob)) {
return false;
}
@@ -388,10 +392,10 @@ bool ED_space_image_check_show_maskedit(ViewLayer *view_layer, SpaceImage *sima)
int ED_space_image_maskedit_poll(bContext *C)
{
SpaceImage *sima = CTX_wm_space_image(C);
-
if (sima) {
+ WorkSpace *workspace = CTX_wm_workspace(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
- return ED_space_image_check_show_maskedit(view_layer, sima);
+ return ED_space_image_check_show_maskedit(sima, workspace, view_layer);
}
return false;
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index de158f84a4d..84179eb3b3a 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -275,12 +275,14 @@ int space_image_main_region_poll(bContext *C)
/* For IMAGE_OT_curves_point_set to avoid sampling when in uv smooth mode or editmode */
static int space_image_main_area_not_uv_brush_poll(bContext *C)
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
SpaceImage *sima = CTX_wm_space_image(C);
Scene *scene = CTX_data_scene(C);
ToolSettings *toolsettings = scene->toolsettings;
- if (sima && !toolsettings->uvsculpt && !scene->obedit)
+ if (sima && !toolsettings->uvsculpt && ((workspace->object_mode & OB_MODE_EDIT) == 0)) {
return 1;
+ }
return 0;
}
@@ -791,6 +793,7 @@ void IMAGE_OT_view_all(wmOperatorType *ot)
static int image_view_selected_exec(bContext *C, wmOperator *UNUSED(op))
{
+ WorkSpace *workspace = CTX_wm_workspace(C);
SpaceImage *sima;
ARegion *ar;
Scene *scene;
@@ -814,7 +817,7 @@ static int image_view_selected_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_CANCELLED;
}
}
- else if (ED_space_image_check_show_maskedit(view_layer, sima)) {
+ else if (ED_space_image_check_show_maskedit(sima, workspace, view_layer)) {
if (!ED_mask_selected_minmax(C, min, max)) {
return OPERATOR_CANCELLED;
}
@@ -2458,7 +2461,7 @@ static int image_new_exec(bContext *C, wmOperator *op)
SpaceImage *sima_other = (SpaceImage *)sl;
if (!sima_other->pin) {
- ED_space_image_set(sima_other, scene, scene->obedit, ima);
+ ED_space_image_set(sima_other, scene, obedit, ima);
}
}
}
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index a89ae2b869a..c66d588c50d 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -551,7 +551,7 @@ static void image_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, Sc
{
ViewLayer *view_layer = BKE_view_layer_from_workspace_get(scene, workspace);
Object *ob = OBACT(view_layer);
- if (ob && (ob == wmn->reference) && (ob->mode & OB_MODE_EDIT)) {
+ if (ob && (ob == wmn->reference) && (workspace->object_mode & OB_MODE_EDIT)) {
if (sima->lock && (sima->flag & SI_DRAWSHADOW)) {
ED_area_tag_refresh(sa);
ED_area_tag_redraw(sa);
@@ -725,6 +725,9 @@ static void image_main_region_init(wmWindowManager *wm, ARegion *ar)
static void image_main_region_draw(const bContext *C, ARegion *ar)
{
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
+
/* draw entirely, view changes should be handled here */
SpaceImage *sima = CTX_wm_space_image(C);
Object *obact = CTX_data_active_object(C);
@@ -759,7 +762,7 @@ static void image_main_region_draw(const bContext *C, ARegion *ar)
ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW);
- ED_uvedit_draw_main(sima, ar, scene, view_layer, obedit, obact, depsgraph);
+ ED_uvedit_draw_main(sima, &eval_ctx, ar, scene, view_layer, obedit, obact, depsgraph);
/* check for mask (delay draw) */
if (ED_space_image_show_uvedit(sima, obedit)) {
@@ -800,14 +803,14 @@ static void image_main_region_draw(const bContext *C, ARegion *ar)
/* ED_space_image_get* will acquire image buffer which requires
* lock here by the same reason why lock is needed in draw_image_main
*/
- BLI_lock_thread(LOCK_DRAW_IMAGE);
+ BLI_thread_lock(LOCK_DRAW_IMAGE);
}
ED_space_image_get_size(sima, &width, &height);
ED_space_image_get_aspect(sima, &aspx, &aspy);
if (show_viewer)
- BLI_unlock_thread(LOCK_DRAW_IMAGE);
+ BLI_thread_unlock(LOCK_DRAW_IMAGE);
ED_mask_draw_region(mask, ar,
sima->mask_info.draw_flag,
diff --git a/source/blender/editors/space_info/info_report.c b/source/blender/editors/space_info/info_report.c
index 31df9b199ea..a6b3dad239c 100644
--- a/source/blender/editors/space_info/info_report.c
+++ b/source/blender/editors/space_info/info_report.c
@@ -133,9 +133,6 @@ static int select_report_pick_invoke(bContext *C, wmOperator *op, const wmEvent
ReportList *reports = CTX_wm_reports(C);
Report *report;
- /* uses opengl */
- wmSubWindowSet(CTX_wm_window(C), ar->swinid);
-
report = info_text_pick(sinfo, ar, reports, event->mval[1]);
RNA_int_set(op->ptr, "report_index", BLI_findindex(&reports->list, report));
diff --git a/source/blender/editors/space_info/info_stats.c b/source/blender/editors/space_info/info_stats.c
index 3cf833756ef..800560c380c 100644
--- a/source/blender/editors/space_info/info_stats.c
+++ b/source/blender/editors/space_info/info_stats.c
@@ -36,6 +36,7 @@
#include "DNA_lattice_types.h"
#include "DNA_meta_types.h"
#include "DNA_scene_types.h"
+#include "DNA_workspace_types.h"
#include "BLI_math.h"
#include "BLI_string.h"
@@ -53,6 +54,7 @@
#include "BKE_paint.h"
#include "BKE_particle.h"
#include "BKE_editmesh.h"
+#include "BKE_object.h"
#include "ED_info.h"
#include "ED_armature.h"
@@ -365,28 +367,29 @@ static void stats_dupli_object(Base *base, Object *ob, SceneStats *stats)
}
}
-static bool stats_is_object_dynamic_topology_sculpt(Object *ob)
+static bool stats_is_object_dynamic_topology_sculpt(Object *ob, const eObjectMode object_mode)
{
- return (ob && (ob->mode & OB_MODE_SCULPT) &&
+ return (ob &&
+ (object_mode & OB_MODE_SCULPT) &&
ob->sculpt && ob->sculpt->bm);
}
/* Statistics displayed in info header. Called regularly on scene changes. */
-static void stats_update(Scene *scene, ViewLayer *view_layer)
+static void stats_update(ViewLayer *view_layer, Object *obedit, const eObjectMode object_mode)
{
SceneStats stats = {0};
Object *ob = (view_layer->basact) ? view_layer->basact->object : NULL;
Base *base;
-
- if (scene->obedit) {
+
+ if (obedit) {
/* Edit Mode */
- stats_object_edit(scene->obedit, &stats);
+ stats_object_edit(ob, &stats);
}
- else if (ob && (ob->mode & OB_MODE_POSE)) {
+ else if (ob && (object_mode & OB_MODE_POSE)) {
/* Pose Mode */
stats_object_pose(ob, &stats);
}
- else if (stats_is_object_dynamic_topology_sculpt(ob)) {
+ else if (stats_is_object_dynamic_topology_sculpt(ob, object_mode)) {
/* Dynamic-topology sculpt mode */
stats_object_sculpt_dynamic_topology(ob, &stats);
}
@@ -405,7 +408,7 @@ static void stats_update(Scene *scene, ViewLayer *view_layer)
*(view_layer->stats) = stats;
}
-static void stats_string(Scene *scene, ViewLayer *view_layer)
+static void stats_string(ViewLayer *view_layer, Object *obedit, const eObjectMode object_mode)
{
#define MAX_INFO_MEM_LEN 64
SceneStats *stats = view_layer->stats;
@@ -471,17 +474,17 @@ static void stats_string(Scene *scene, ViewLayer *view_layer)
ofs += BLI_snprintf(s + ofs, MAX_INFO_LEN - ofs, "%s | ", versionstr);
- if (scene->obedit) {
- if (BKE_keyblock_from_object(scene->obedit))
+ if (obedit) {
+ if (BKE_keyblock_from_object(obedit))
ofs += BLI_strncpy_rlen(s + ofs, IFACE_("(Key) "), MAX_INFO_LEN - ofs);
- if (scene->obedit->type == OB_MESH) {
+ if (obedit->type == OB_MESH) {
ofs += BLI_snprintf(s + ofs, MAX_INFO_LEN - ofs,
IFACE_("Verts:%s/%s | Edges:%s/%s | Faces:%s/%s | Tris:%s"),
stats_fmt.totvertsel, stats_fmt.totvert, stats_fmt.totedgesel, stats_fmt.totedge,
stats_fmt.totfacesel, stats_fmt.totface, stats_fmt.tottri);
}
- else if (scene->obedit->type == OB_ARMATURE) {
+ else if (obedit->type == OB_ARMATURE) {
ofs += BLI_snprintf(s + ofs, MAX_INFO_LEN - ofs, IFACE_("Verts:%s/%s | Bones:%s/%s"), stats_fmt.totvertsel,
stats_fmt.totvert, stats_fmt.totbonesel, stats_fmt.totbone);
}
@@ -493,11 +496,11 @@ static void stats_string(Scene *scene, ViewLayer *view_layer)
ofs += BLI_strncpy_rlen(s + ofs, memstr, MAX_INFO_LEN - ofs);
ofs += BLI_strncpy_rlen(s + ofs, gpumemstr, MAX_INFO_LEN - ofs);
}
- else if (ob && (ob->mode & OB_MODE_POSE)) {
+ else if (ob && (object_mode & OB_MODE_POSE)) {
ofs += BLI_snprintf(s + ofs, MAX_INFO_LEN - ofs, IFACE_("Bones:%s/%s %s%s"),
stats_fmt.totbonesel, stats_fmt.totbone, memstr, gpumemstr);
}
- else if (stats_is_object_dynamic_topology_sculpt(ob)) {
+ else if (stats_is_object_dynamic_topology_sculpt(ob, object_mode)) {
ofs += BLI_snprintf(s + ofs, MAX_INFO_LEN - ofs, IFACE_("Verts:%s | Tris:%s%s"), stats_fmt.totvert,
stats_fmt.tottri, gpumemstr);
}
@@ -525,12 +528,16 @@ void ED_info_stats_clear(ViewLayer *view_layer)
}
}
-const char *ED_info_stats_string(Scene *scene, ViewLayer *view_layer)
+const char *ED_info_stats_string(Scene *UNUSED(scene), WorkSpace *workspace, ViewLayer *view_layer)
{
+ Object *obact = (view_layer->basact) ? view_layer->basact->object : NULL;
+ Object *obedit = (obact && (workspace->object_mode & OB_MODE_EDIT) &&
+ BKE_object_is_in_editmode(obact)) ? obact : NULL;
+
if (!view_layer->stats) {
- stats_update(scene, view_layer);
+ stats_update(view_layer, obedit, workspace->object_mode);
}
- stats_string(scene, view_layer);
+ stats_string(view_layer, obedit, workspace->object_mode);
return view_layer->stats->infostr;
}
diff --git a/source/blender/editors/space_info/textview.c b/source/blender/editors/space_info/textview.c
index 3eb0158e7b5..3f35cadd820 100644
--- a/source/blender/editors/space_info/textview.c
+++ b/source/blender/editors/space_info/textview.c
@@ -82,7 +82,7 @@ static void console_draw_sel(const char *str, const int sel[2], const int xy[2],
const int end = txt_utf8_offset_to_column(str, min_ii(sel[1], str_len_draw));
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
Gwn_VertFormat *format = immVertexFormat();
unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c
index cb20b76a3ee..a18a692c0a3 100644
--- a/source/blender/editors/space_nla/nla_draw.c
+++ b/source/blender/editors/space_nla/nla_draw.c
@@ -408,7 +408,7 @@ static void nla_draw_strip(SpaceNla *snla, AnimData *adt, NlaTrack *nlt, NlaStri
*/
if ((strip->extendmode != NLASTRIP_EXTEND_NOTHING) && (non_solo == 0)) {
/* enable transparency... */
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
switch (strip->extendmode) {
@@ -709,7 +709,7 @@ void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *ar)
/* just draw a semi-shaded rect spanning the width of the viewable area if there's data,
* and a second darker rect within which we draw keyframe indicator dots if there's data
*/
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
/* get colors for drawing */
@@ -826,7 +826,7 @@ void draw_nla_channel_list(const bContext *C, bAnimContext *ac, ARegion *ar)
y = (float)(-NLACHANNEL_HEIGHT(snla));
/* set blending again, as may not be set in previous step */
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
/* loop through channels, and set up drawing depending on their type */
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index 1bee2716e65..68934ebedd6 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -986,7 +986,7 @@ static void node_shader_buts_normal_map(uiLayout *layout, bContext *C, PointerRN
{
uiItemR(layout, ptr, "space", 0, "", 0);
- if (RNA_enum_get(ptr, "space") == SHD_NORMAL_MAP_TANGENT) {
+ if (RNA_enum_get(ptr, "space") == SHD_SPACE_TANGENT) {
PointerRNA obptr = CTX_data_pointer_get(C, "active_object");
if (obptr.data && RNA_enum_get(&obptr, "type") == OB_MESH) {
@@ -998,6 +998,11 @@ static void node_shader_buts_normal_map(uiLayout *layout, bContext *C, PointerRN
}
}
+static void node_shader_buts_displacement(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "space", 0, "", 0);
+}
+
static void node_shader_buts_tangent(uiLayout *layout, bContext *C, PointerRNA *ptr)
{
uiLayout *split, *row;
@@ -1027,6 +1032,12 @@ static void node_shader_buts_glossy(uiLayout *layout, bContext *UNUSED(C), Point
uiItemR(layout, ptr, "distribution", 0, "", ICON_NONE);
}
+static void node_shader_buts_principled(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "distribution", 0, "", ICON_NONE);
+ uiItemR(layout, ptr, "subsurface_method", 0, "", ICON_NONE);
+}
+
static void node_shader_buts_anisotropic(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "distribution", 0, "", ICON_NONE);
@@ -1189,15 +1200,21 @@ static void node_shader_set_butfunc(bNodeType *ntype)
case SH_NODE_NORMAL_MAP:
ntype->draw_buttons = node_shader_buts_normal_map;
break;
+ case SH_NODE_DISPLACEMENT:
+ case SH_NODE_VECTOR_DISPLACEMENT:
+ ntype->draw_buttons = node_shader_buts_displacement;
+ break;
case SH_NODE_TANGENT:
ntype->draw_buttons = node_shader_buts_tangent;
break;
case SH_NODE_BSDF_GLOSSY:
case SH_NODE_BSDF_GLASS:
case SH_NODE_BSDF_REFRACTION:
- case SH_NODE_BSDF_PRINCIPLED:
ntype->draw_buttons = node_shader_buts_glossy;
break;
+ case SH_NODE_BSDF_PRINCIPLED:
+ ntype->draw_buttons = node_shader_buts_principled;
+ break;
case SH_NODE_BSDF_ANISOTROPIC:
ntype->draw_buttons = node_shader_buts_anisotropic;
break;
@@ -3205,8 +3222,6 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode, b
gpuPushMatrix();
/* somehow the offset has to be calculated inverse */
-
- glaDefine2DArea(&ar->winrct);
wmOrtho2_region_pixelspace(ar);
x = (ar->winx - snode->zoom * ibuf->x) / 2 + snode->xof;
@@ -3239,7 +3254,7 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode, b
}
else if (snode->flag & SNODE_USE_ALPHA) {
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glaDrawImBuf_glsl_ctx(C, ibuf, x, y, GL_NEAREST, snode->zoom, snode->zoom);
diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c
index 231039b2e22..94bd752cf81 100644
--- a/source/blender/editors/space_node/node_draw.c
+++ b/source/blender/editors/space_node/node_draw.c
@@ -705,7 +705,7 @@ static void node_draw_preview(bNodePreview *preview, rctf *prv)
node_draw_preview_background(BLI_rctf_size_x(prv) / 10.0f, &draw_rect);
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); /* premul graphics */
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); /* premul graphics */
IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR);
immDrawPixelsTex(&state, draw_rect.xmin, draw_rect.ymin, preview->xsize, preview->ysize, GL_RGBA, GL_UNSIGNED_BYTE, GL_LINEAR, preview->rect,
@@ -1336,7 +1336,7 @@ void drawnodespace(const bContext *C, ARegion *ar)
ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW);
/* only set once */
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
/* nodes */
snode_set_context(C);
@@ -1404,7 +1404,6 @@ void drawnodespace(const bContext *C, ARegion *ar)
gpuPushMatrix();
gpuLoadIdentity();
- glaDefine2DArea(&ar->winrct);
wmOrtho2_pixelspace(ar->winx, ar->winy);
WM_manipulatormap_draw(ar->manipulator_map, C, WM_MANIPULATORMAP_DRAWSTEP_2D);
diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c
index dc7863bb354..4b4add0e698 100644
--- a/source/blender/editors/space_node/node_select.c
+++ b/source/blender/editors/space_node/node_select.c
@@ -34,7 +34,7 @@
#include "BLI_utildefines.h"
#include "BLI_rect.h"
-#include "BLI_lasso.h"
+#include "BLI_lasso_2d.h"
#include "BLI_math.h"
#include "BLI_string.h"
#include "BLI_string_utf8.h"
diff --git a/source/blender/editors/space_outliner/outliner_collections.c b/source/blender/editors/space_outliner/outliner_collections.c
index 8999555521a..efc28eea917 100644
--- a/source/blender/editors/space_outliner/outliner_collections.c
+++ b/source/blender/editors/space_outliner/outliner_collections.c
@@ -37,6 +37,7 @@
#include "DEG_depsgraph_build.h"
#include "DNA_group_types.h"
+#include "DNA_object_types.h"
#include "ED_screen.h"
@@ -91,6 +92,30 @@ static int view_layer_editor_poll(bContext *C)
return (so != NULL) && (so->outlinevis == SO_VIEW_LAYER);
}
+static int outliner_either_collection_editor_poll(bContext *C)
+{
+ SpaceOops *so = CTX_wm_space_outliner(C);
+ return (so != NULL) && (ELEM(so->outlinevis, SO_VIEW_LAYER, SO_COLLECTIONS));
+}
+
+static int outliner_objects_collection_poll(bContext *C)
+{
+ SpaceOops *so = CTX_wm_space_outliner(C);
+ if (so == NULL) {
+ return 0;
+ }
+
+ /* Groups don't support filtering. */
+ if ((so->outlinevis != SO_GROUPS) &&
+ ((so->filter & (SO_FILTER_ENABLE | SO_FILTER_NO_COLLECTION)) ==
+ (SO_FILTER_ENABLE | SO_FILTER_NO_COLLECTION)))
+ {
+ return 0;
+ }
+
+ return ELEM(so->outlinevis, SO_VIEW_LAYER, SO_COLLECTIONS, SO_GROUPS);
+}
+
/* -------------------------------------------------------------------- */
/* collection manager operators */
@@ -317,7 +342,8 @@ static int collection_new_exec(bContext *C, wmOperator *UNUSED(op))
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
- SceneCollection *scene_collection = BKE_collection_add(&scene->id, NULL, COLLECTION_TYPE_NONE, NULL);
+ SceneCollection *scene_collection_parent = BKE_collection_master(&scene->id);
+ SceneCollection *scene_collection = BKE_collection_add(&scene->id, scene_collection_parent, COLLECTION_TYPE_NONE, NULL);
BKE_collection_link(view_layer, scene_collection);
DEG_relations_tag_update(bmain);
@@ -468,7 +494,7 @@ static int collection_objects_add_exec(bContext *C, wmOperator *op)
CTX_DATA_BEGIN (C, struct Object *, ob, selected_objects)
{
- BLI_LISTBASE_FOREACH (LinkData *, link, &data.scene_collections_array) {
+ LISTBASE_FOREACH (LinkData *, link, &data.scene_collections_array) {
SceneCollection *scene_collection = link->data;
BKE_collection_object_add(
&scene->id,
@@ -523,7 +549,7 @@ static int collection_objects_remove_exec(bContext *C, wmOperator *op)
CTX_DATA_BEGIN (C, struct Object *, ob, selected_objects)
{
- BLI_LISTBASE_FOREACH (LinkData *, link, &data.scene_collections_array) {
+ LISTBASE_FOREACH (LinkData *, link, &data.scene_collections_array) {
SceneCollection *scene_collection = link->data;
BKE_collection_object_remove(
bmain,
@@ -557,6 +583,139 @@ void OUTLINER_OT_collection_objects_remove(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+static TreeElement *outliner_collection_parent_element_get(TreeElement *te)
+{
+ TreeElement *te_parent = te;
+ while ((te_parent = te_parent->parent)) {
+ if (outliner_scene_collection_from_tree_element(te->parent)) {
+ return te_parent;
+ }
+ }
+ return NULL;
+}
+
+static int object_collection_remove_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ SpaceOops *soops = CTX_wm_space_outliner(C);
+ Main *bmain = CTX_data_main(C);
+
+ struct ObjectsSelectedData data = {
+ .objects_selected_array = {NULL, NULL},
+ };
+
+ outliner_tree_traverse(soops, &soops->tree, 0, TSE_SELECTED, outliner_find_selected_objects, &data);
+
+ LISTBASE_FOREACH (LinkData *, link, &data.objects_selected_array) {
+ TreeElement *te = (TreeElement *)link->data;
+ Object *ob = (Object *)TREESTORE(te)->id;
+ SceneCollection *scene_collection = NULL;
+
+ TreeElement *te_parent = outliner_collection_parent_element_get(te);
+ if (te_parent != NULL) {
+ scene_collection = outliner_scene_collection_from_tree_element(te_parent);
+ ID *owner_id = TREESTORE(te_parent)->id;
+ BKE_collection_object_remove(bmain, owner_id, scene_collection, ob, true);
+ DEG_id_tag_update(owner_id, DEG_TAG_BASE_FLAGS_UPDATE);
+ }
+ }
+
+ BLI_freelistN(&data.objects_selected_array);
+
+ outliner_cleanup_tree(soops);
+ DEG_relations_tag_update(bmain);
+
+ WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
+ WM_main_add_notifier(NC_SCENE | ND_OB_ACTIVE, NULL);
+ WM_main_add_notifier(NC_SCENE | ND_OB_SELECT, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void OUTLINER_OT_object_remove_from_collection(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Remove Object from Collection";
+ ot->idname = "OUTLINER_OT_object_remove_from_collection";
+ ot->description = "Remove selected objects from their respective collection";
+
+ /* api callbacks */
+ ot->exec = object_collection_remove_exec;
+ ot->poll = outliner_objects_collection_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+static int object_add_to_new_collection_exec(bContext *C, wmOperator *op)
+{
+ int operator_result = OPERATOR_CANCELLED;
+
+ SpaceOops *soops = CTX_wm_space_outliner(C);
+ Main *bmain = CTX_data_main(C);
+
+ SceneCollection *scene_collection_parent, *scene_collection_new;
+ TreeElement *te_active, *te_parent;
+
+ struct ObjectsSelectedData data = {NULL}, active = {NULL};
+
+ outliner_tree_traverse(soops, &soops->tree, 0, TSE_HIGHLIGHTED, outliner_find_selected_objects, &active);
+ if (BLI_listbase_is_empty(&active.objects_selected_array)) {
+ BKE_report(op->reports, RPT_ERROR, "No object is selected");
+ goto cleanup;
+ }
+
+ outliner_tree_traverse(soops, &soops->tree, 0, TSE_SELECTED, outliner_find_selected_objects, &data);
+ if (BLI_listbase_is_empty(&data.objects_selected_array)) {
+ BKE_report(op->reports, RPT_ERROR, "No objects are selected");
+ goto cleanup;
+ }
+
+ /* Heuristic to get the "active" / "last object" */
+ te_active = ((LinkData *)active.objects_selected_array.first)->data;
+ te_parent = outliner_collection_parent_element_get(te_active);
+
+ if (te_parent == NULL) {
+ BKE_reportf(op->reports, RPT_ERROR, "Couldn't find collection of \"%s\" object", te_active->name);
+ goto cleanup;
+ }
+
+ ID *owner_id = TREESTORE(te_parent)->id;
+ scene_collection_parent = outliner_scene_collection_from_tree_element(te_parent);
+ scene_collection_new = BKE_collection_add(owner_id, scene_collection_parent, scene_collection_parent->type, NULL);
+
+ LISTBASE_FOREACH (LinkData *, link, &data.objects_selected_array) {
+ TreeElement *te = (TreeElement *)link->data;
+ Object *ob = (Object *)TREESTORE(te)->id;
+ BKE_collection_object_add(owner_id, scene_collection_new, ob);
+ }
+
+ outliner_cleanup_tree(soops);
+ DEG_relations_tag_update(bmain);
+
+ WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
+
+ operator_result = OPERATOR_FINISHED;
+cleanup:
+ BLI_freelistN(&active.objects_selected_array);
+ BLI_freelistN(&data.objects_selected_array);
+ return operator_result;
+}
+
+void OUTLINER_OT_object_add_to_new_collection(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Add Objects to New Collection";
+ ot->idname = "OUTLINER_OT_object_add_to_new_collection";
+ ot->description = "Add objects to a new collection";
+
+ /* api callbacks */
+ ot->exec = object_add_to_new_collection_exec;
+ ot->poll = outliner_objects_collection_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
struct CollectionDeleteData {
Scene *scene;
SpaceOops *soops;
@@ -757,3 +916,139 @@ void OUTLINER_OT_collection_toggle(wmOperatorType *ot)
#undef ACTION_TOGGLE
#undef ACTION_ENABLE
#undef ACTION_DISABLE
+
+struct CollectionObjectsSelectData {
+ bool error;
+ LayerCollection *layer_collection;
+};
+
+static TreeTraversalAction outliner_find_first_selected_layer_collection(TreeElement *te, void *customdata)
+{
+ struct CollectionObjectsSelectData *data = customdata;
+ TreeStoreElem *tselem = TREESTORE(te);
+
+ switch (tselem->type) {
+ case TSE_LAYER_COLLECTION:
+ data->layer_collection = te->directdata;
+ return TRAVERSE_BREAK;
+ case TSE_LAYER_COLLECTION_BASE:
+ return TRAVERSE_CONTINUE;
+ default:
+ return TRAVERSE_SKIP_CHILDS;
+ }
+}
+
+static LayerCollection *outliner_active_layer_collection(bContext *C)
+{
+ SpaceOops *soops = CTX_wm_space_outliner(C);
+
+ struct CollectionObjectsSelectData data = {
+ .layer_collection = NULL,
+ };
+
+ outliner_tree_traverse(soops, &soops->tree, 0, TSE_SELECTED, outliner_find_first_selected_layer_collection, &data);
+ return data.layer_collection;
+}
+
+static int collection_objects_select_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ LayerCollection *layer_collection = outliner_active_layer_collection(C);
+
+ if (layer_collection == NULL) {
+ return OPERATOR_CANCELLED;
+ }
+
+ BKE_layer_collection_objects_select(layer_collection);
+ WM_main_add_notifier(NC_SCENE | ND_OB_SELECT, CTX_data_scene(C));
+
+ return OPERATOR_FINISHED;
+}
+
+void OUTLINER_OT_collection_objects_select(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Select Objects";
+ ot->idname = "OUTLINER_OT_collection_objects_select";
+ ot->description = "Select all the collection objects";
+
+ /* api callbacks */
+ ot->exec = collection_objects_select_exec;
+ ot->poll = view_layer_editor_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+struct CollectionDuplicateData {
+ TreeElement *te;
+};
+
+static TreeTraversalAction outliner_find_first_selected_collection(TreeElement *te, void *customdata)
+{
+ struct CollectionDuplicateData *data = customdata;
+ TreeStoreElem *tselem = TREESTORE(te);
+
+ switch (tselem->type) {
+ case TSE_LAYER_COLLECTION:
+ case TSE_SCENE_COLLECTION:
+ data->te = te;
+ return TRAVERSE_BREAK;
+ case TSE_LAYER_COLLECTION_BASE:
+ default:
+ return TRAVERSE_CONTINUE;
+ }
+}
+
+static TreeElement *outliner_active_collection(bContext *C)
+{
+ SpaceOops *soops = CTX_wm_space_outliner(C);
+
+ struct CollectionDuplicateData data = {
+ .te = NULL,
+ };
+
+ outliner_tree_traverse(soops, &soops->tree, 0, TSE_SELECTED, outliner_find_first_selected_collection, &data);
+ return data.te;
+}
+
+static int collection_duplicate_exec(bContext *C, wmOperator *op)
+{
+ SpaceOops *soops = CTX_wm_space_outliner(C);
+ TreeElement *te = outliner_active_collection(C);
+
+ BLI_assert(te != NULL);
+ if (BKE_collection_master(TREESTORE(te)->id) == outliner_scene_collection_from_tree_element(te)) {
+ BKE_report(op->reports, RPT_ERROR, "You can't duplicate the master collection");
+ return OPERATOR_CANCELLED;
+ }
+
+ switch (soops->outlinevis) {
+ case SO_COLLECTIONS:
+ BKE_collection_duplicate(TREESTORE(te)->id, (SceneCollection *)te->directdata);
+ break;
+ case SO_VIEW_LAYER:
+ case SO_GROUPS:
+ BKE_layer_collection_duplicate(TREESTORE(te)->id, (LayerCollection *)te->directdata);
+ break;
+ }
+
+ DEG_relations_tag_update(CTX_data_main(C));
+ WM_main_add_notifier(NC_SCENE | ND_LAYER, CTX_data_scene(C));
+
+ return OPERATOR_FINISHED;
+}
+
+void OUTLINER_OT_collection_duplicate(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Duplicate Collection";
+ ot->idname = "OUTLINER_OT_collection_duplicate";
+ ot->description = "Duplicate collection";
+
+ /* api callbacks */
+ ot->exec = collection_duplicate_exec;
+ ot->poll = outliner_either_collection_editor_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index 1478792b38b..90e59a677ac 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -409,7 +409,8 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname)
case TSE_LAYER_COLLECTION:
{
SceneCollection *sc = outliner_scene_collection_from_tree_element(te);
- BKE_collection_rename(scene, sc, te->name);
+ BKE_collection_rename(tselem->id, sc, te->name);
+ WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene);
break;
}
}
@@ -671,7 +672,7 @@ static void outliner_draw_userbuts(uiBlock *block, ARegion *ar, SpaceOops *soops
}
}
-static void UNUSED_FUNCTION(outliner_draw_rnacols)(ARegion *ar, int sizex)
+static void outliner_draw_rnacols(ARegion *ar, int sizex)
{
View2D *v2d = &ar->v2d;
@@ -697,7 +698,6 @@ static void UNUSED_FUNCTION(outliner_draw_rnacols)(ARegion *ar, int sizex)
immUnbindProgram();
}
-#if 0
static void outliner_draw_rnabuts(uiBlock *block, ARegion *ar, SpaceOops *soops, int sizex, ListBase *lb)
{
TreeElement *te;
@@ -742,7 +742,6 @@ static void outliner_draw_rnabuts(uiBlock *block, ARegion *ar, SpaceOops *soops,
UI_block_emboss_set(block, UI_EMBOSS);
}
-#endif
static void outliner_buttons(const bContext *C, uiBlock *block, ARegion *ar, TreeElement *te)
{
@@ -1236,8 +1235,9 @@ static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeSto
#undef ICON_DRAW
}
-static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, ViewLayer *view_layer, SpaceOops *soops,
- ListBase *lb, int level, int xmax, int *offsx, int ys, float alpha_fac)
+static void outliner_draw_iconrow(
+ bContext *C, uiBlock *block, Scene *scene, ViewLayer *view_layer, Object *obedit, SpaceOops *soops,
+ ListBase *lb, int level, int xmax, int *offsx, int ys, float alpha_fac)
{
TreeElement *te;
TreeStoreElem *tselem;
@@ -1258,7 +1258,7 @@ static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, Vie
if (te->idcode == ID_OB) {
active = (OBACT(view_layer) == (Object *)tselem->id) ? OL_DRAWSEL_NORMAL : OL_DRAWSEL_NONE;
}
- else if (scene->obedit && scene->obedit->data == tselem->id) {
+ else if (obedit && obedit->data == tselem->id) {
active = OL_DRAWSEL_NORMAL;
}
else {
@@ -1298,7 +1298,9 @@ static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, Vie
/* this tree element always has same amount of branches, so don't draw */
if (tselem->type != TSE_R_LAYER)
- outliner_draw_iconrow(C, block, scene, view_layer, soops, &te->subtree, level + 1, xmax, offsx, ys, alpha_fac);
+ outliner_draw_iconrow(
+ C, block, scene, view_layer, obedit, soops,
+ &te->subtree, level + 1, xmax, offsx, ys, alpha_fac);
}
}
@@ -1322,7 +1324,7 @@ static void outliner_set_coord_tree_element(TreeElement *te, int startx, int sta
static void outliner_draw_tree_element(
- bContext *C, uiBlock *block, const uiFontStyle *fstyle, Scene *scene, ViewLayer *view_layer,
+ bContext *C, uiBlock *block, const uiFontStyle *fstyle, Scene *scene, ViewLayer *view_layer, Object *obedit,
ARegion *ar, SpaceOops *soops, TreeElement *te, bool draw_grayed_out,
int startx, int *starty, TreeElement **te_edit, TreeElement **te_floating)
{
@@ -1386,7 +1388,7 @@ static void outliner_draw_tree_element(
}
}
- else if (scene->obedit && scene->obedit->data == tselem->id) {
+ else if (obedit && obedit->data == tselem->id) {
rgba_float_args_set(color, 1.0f, 1.0f, 1.0f, alpha);
active = OL_DRAWSEL_ACTIVE;
}
@@ -1516,8 +1518,9 @@ static void outliner_draw_tree_element(
immUnbindProgram();
}
- outliner_draw_iconrow(C, block, scene, view_layer, soops, &te->subtree, 0, xmax, &tempx,
- *starty, alpha_fac);
+ outliner_draw_iconrow(
+ C, block, scene, view_layer, obedit, soops, &te->subtree, 0, xmax, &tempx,
+ *starty, alpha_fac);
glDisable(GL_BLEND);
}
@@ -1536,8 +1539,10 @@ static void outliner_draw_tree_element(
/* check if element needs to be drawn grayed out, but also gray out
* childs of a grayed out parent (pass on draw_grayed_out to childs) */
bool draw_childs_grayed_out = draw_grayed_out || (ten->drag_data != NULL);
- outliner_draw_tree_element(C, block, fstyle, scene, view_layer, ar, soops, ten, draw_childs_grayed_out,
- startx + UI_UNIT_X, starty, te_edit, te_floating);
+ outliner_draw_tree_element(
+ C, block, fstyle, scene, view_layer, obedit,
+ ar, soops, ten, draw_childs_grayed_out,
+ startx + UI_UNIT_X, starty, te_edit, te_floating);
}
}
else {
@@ -1776,15 +1781,15 @@ static void outliner_draw_highlights(ARegion *ar, SpaceOops *soops, int startx,
}
static void outliner_draw_tree(
- bContext *C, uiBlock *block, Scene *scene, ViewLayer *view_layer, ARegion *ar,
- SpaceOops *soops, const bool has_restrict_icons,
+ bContext *C, uiBlock *block, Scene *scene, ViewLayer *view_layer, Object *obedit,
+ ARegion *ar, SpaceOops *soops, const bool has_restrict_icons,
TreeElement **te_edit)
{
const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
TreeElement *te_floating = NULL;
int starty, startx;
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // only once
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); // only once
if (soops->outlinevis == SO_DATABLOCKS) {
/* struct marks */
@@ -1817,8 +1822,10 @@ static void outliner_draw_tree(
starty = (int)ar->v2d.tot.ymax - UI_UNIT_Y - OL_Y_OFFSET;
startx = 0;
for (TreeElement *te = soops->tree.first; te; te = te->next) {
- outliner_draw_tree_element(C, block, fstyle, scene, view_layer, ar, soops, te, te->drag_data != NULL,
- startx, &starty, te_edit, &te_floating);
+ outliner_draw_tree_element(
+ C, block, fstyle, scene, view_layer, obedit,
+ ar, soops, te, te->drag_data != NULL,
+ startx, &starty, te_edit, &te_floating);
}
if (te_floating && te_floating->drag_data->insert_handle) {
outliner_draw_tree_element_floating(ar, te_floating);
@@ -1893,6 +1900,9 @@ static void outliner_draw_restrictcols(ARegion *ar)
void draw_outliner(const bContext *C)
{
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
+ Object *obedit = OBEDIT_FROM_EVAL_CTX(&eval_ctx);
Main *mainvar = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
@@ -1904,7 +1914,7 @@ void draw_outliner(const bContext *C)
TreeElement *te_edit = NULL;
bool has_restrict_icons;
- outliner_build_tree(mainvar, scene, view_layer, soops, ar); // always
+ outliner_build_tree(mainvar, &eval_ctx, scene, view_layer, soops, ar); // always
/* get extents of data */
outliner_height(soops, &soops->tree, &sizey);
@@ -1955,9 +1965,16 @@ void draw_outliner(const bContext *C)
/* draw outliner stuff (background, hierarchy lines and names) */
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);
+ outliner_draw_tree(
+ (bContext *)C, block, scene, view_layer, obedit,
+ ar, soops, has_restrict_icons, &te_edit);
- if ((soops->outlinevis == SO_ID_ORPHANS) && has_restrict_icons) {
+ if (soops->outlinevis == SO_DATABLOCKS) {
+ /* draw rna buttons */
+ outliner_draw_rnacols(ar, sizex_rna);
+ outliner_draw_rnabuts(block, ar, soops, sizex_rna, &soops->tree);
+ }
+ else if ((soops->outlinevis == SO_ID_ORPHANS) && has_restrict_icons) {
/* draw user toggle columns */
outliner_draw_restrictcols(ar);
outliner_draw_userbuts(block, ar, soops, &soops->tree);
diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c
index fc0e30c78ce..6bbec6a1a48 100644
--- a/source/blender/editors/space_outliner/outliner_edit.c
+++ b/source/blender/editors/space_outliner/outliner_edit.c
@@ -64,6 +64,7 @@
#include "BKE_material.h"
#include "BKE_group.h"
+#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
#include "../blenloader/BLO_readfile.h"
@@ -977,6 +978,7 @@ static int outliner_open_back(TreeElement *te)
static int outliner_show_active_exec(bContext *C, wmOperator *UNUSED(op))
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
SpaceOops *so = CTX_wm_space_outliner(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
ARegion *ar = CTX_wm_region(C);
@@ -997,13 +999,13 @@ static int outliner_show_active_exec(bContext *C, wmOperator *UNUSED(op))
/* traverse down the bone hierarchy in case of armature */
TreeElement *te_obact = te;
- if (obact->mode & OB_MODE_POSE) {
+ if (workspace->object_mode & OB_MODE_POSE) {
bPoseChannel *pchan = CTX_data_active_pose_bone(C);
if (pchan) {
te = outliner_find_posechannel(&te_obact->subtree, pchan);
}
}
- else if (obact->mode & OB_MODE_EDIT) {
+ else if (workspace->object_mode & OB_MODE_EDIT) {
EditBone *ebone = CTX_data_active_bone(C);
if (ebone) {
te = outliner_find_editbone(&te_obact->subtree, ebone);
diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h
index b06c9b85eb8..148af52050d 100644
--- a/source/blender/editors/space_outliner/outliner_intern.h
+++ b/source/blender/editors/space_outliner/outliner_intern.h
@@ -37,6 +37,7 @@
/* internal exports only */
struct ARegion;
+struct ListBase;
struct wmOperatorType;
struct TreeElement;
struct TreeStoreElem;
@@ -50,7 +51,7 @@ struct bPoseChannel;
struct EditBone;
struct wmEvent;
struct wmKeyConfig;
-
+struct EvaluationContext;
typedef enum TreeElementInsertType {
TE_INSERT_BEFORE,
@@ -191,8 +192,16 @@ void outliner_cleanup_tree(struct SpaceOops *soops);
void outliner_free_tree_element(TreeElement *element, ListBase *parent_subtree);
void outliner_remove_treestore_element(struct SpaceOops *soops, TreeStoreElem *tselem);
-void outliner_build_tree(struct Main *mainvar, struct Scene *scene, struct ViewLayer *view_layer,
- struct SpaceOops *soops, struct ARegion *ar);
+void outliner_build_tree(
+ struct Main *mainvar, const struct EvaluationContext *eval_ctx,
+ struct Scene *scene, struct ViewLayer *view_layer,
+ struct SpaceOops *soops, struct ARegion *ar);
+
+typedef struct ObjectsSelectedData {
+ struct ListBase objects_selected_array;
+} ObjectsSelectedData;
+
+TreeTraversalAction outliner_find_selected_objects(struct TreeElement *te, void *customdata);
/* outliner_draw.c ---------------------------------------------- */
@@ -344,7 +353,11 @@ void OUTLINER_OT_collection_toggle(struct wmOperatorType *ot);
void OUTLINER_OT_collection_link(struct wmOperatorType *ot);
void OUTLINER_OT_collection_unlink(struct wmOperatorType *ot);
void OUTLINER_OT_collection_new(struct wmOperatorType *ot);
+void OUTLINER_OT_collection_duplicate(struct wmOperatorType *ot);
void OUTLINER_OT_collection_objects_remove(struct wmOperatorType *ot);
+void OUTLINER_OT_collection_objects_select(struct wmOperatorType *ot);
+void OUTLINER_OT_object_add_to_new_collection(struct wmOperatorType *ot);
+void OUTLINER_OT_object_remove_from_collection(struct wmOperatorType *ot);
void OUTLINER_OT_collection_objects_add(struct wmOperatorType *ot);
void OUTLINER_OT_collection_nested_new(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_outliner/outliner_ops.c b/source/blender/editors/space_outliner/outliner_ops.c
index 52f27b9708e..ba501ac7db5 100644
--- a/source/blender/editors/space_outliner/outliner_ops.c
+++ b/source/blender/editors/space_outliner/outliner_ops.c
@@ -474,11 +474,15 @@ void outliner_operatortypes(void)
WM_operatortype_append(OUTLINER_OT_collection_link);
WM_operatortype_append(OUTLINER_OT_collection_unlink);
WM_operatortype_append(OUTLINER_OT_collection_new);
+ WM_operatortype_append(OUTLINER_OT_collection_duplicate);
WM_operatortype_append(OUTLINER_OT_collection_nested_new);
WM_operatortype_append(OUTLINER_OT_collection_delete_selected);
WM_operatortype_append(OUTLINER_OT_collection_objects_add);
WM_operatortype_append(OUTLINER_OT_collection_objects_remove);
+ WM_operatortype_append(OUTLINER_OT_collection_objects_select);
+ WM_operatortype_append(OUTLINER_OT_object_add_to_new_collection);
+ WM_operatortype_append(OUTLINER_OT_object_remove_from_collection);
}
static wmKeyMap *outliner_item_drag_drop_modal_keymap(wmKeyConfig *keyconf)
diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c
index b9222e62bb0..16f3aeaf110 100644
--- a/source/blender/editors/space_outliner/outliner_select.c
+++ b/source/blender/editors/space_outliner/outliner_select.c
@@ -193,10 +193,10 @@ static eOLDrawState tree_element_set_active_object(
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
}
}
-
- if (ob != scene->obedit)
+
+ if (CTX_data_edit_object(C)) {
ED_object_editmode_exit(C, EM_FREEDATA | EM_FREEUNDO | EM_WAITCURSOR | EM_DO_UNDO);
-
+ }
return OL_DRAWSEL_NORMAL;
}
@@ -547,7 +547,7 @@ static eOLDrawState tree_element_active_bone(
/* ebones only draw in editmode armature */
-static void tree_element_active_ebone__sel(bContext *C, Scene *scene, bArmature *arm, EditBone *ebone, short sel)
+static void tree_element_active_ebone__sel(bContext *C, Object *obedit, bArmature *arm, EditBone *ebone, short sel)
{
if (sel) {
ebone->flag |= BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL;
@@ -561,34 +561,34 @@ static void tree_element_active_ebone__sel(bContext *C, Scene *scene, bArmature
if (ebone->parent && (ebone->flag & BONE_CONNECTED)) ebone->parent->flag &= ~BONE_TIPSEL;
}
- WM_event_add_notifier(C, NC_OBJECT | ND_BONE_ACTIVE, scene->obedit);
+ WM_event_add_notifier(C, NC_OBJECT | ND_BONE_ACTIVE, obedit);
}
static eOLDrawState tree_element_active_ebone(
- bContext *C, Scene *scene, TreeElement *te, TreeStoreElem *UNUSED(tselem), const eOLSetState set, bool recursive)
+ bContext *C, TreeElement *te, TreeStoreElem *UNUSED(tselem), const eOLSetState set, bool recursive)
{
- BLI_assert(scene->obedit != NULL);
-
- bArmature *arm = scene->obedit->data;
+ Object *obedit = CTX_data_edit_object(C);
+ BLI_assert(obedit != NULL);
+ bArmature *arm = obedit->data;
EditBone *ebone = te->directdata;
eOLDrawState status = OL_DRAWSEL_NONE;
if (set != OL_SETSEL_NONE) {
if (set == OL_SETSEL_NORMAL) {
if (!(ebone->flag & BONE_HIDDEN_A)) {
- ED_armature_deselect_all(scene->obedit);
- tree_element_active_ebone__sel(C, scene, arm, ebone, true);
+ ED_armature_deselect_all(obedit);
+ tree_element_active_ebone__sel(C, obedit, arm, ebone, true);
status = OL_DRAWSEL_NORMAL;
}
}
else if (set == OL_SETSEL_EXTEND) {
if (!(ebone->flag & BONE_HIDDEN_A)) {
if (!(ebone->flag & BONE_SELECTED)) {
- tree_element_active_ebone__sel(C, scene, arm, ebone, true);
+ tree_element_active_ebone__sel(C, obedit, arm, ebone, true);
status = OL_DRAWSEL_NORMAL;
}
else {
/* entirely selected, so de-select */
- tree_element_active_ebone__sel(C, scene, arm, ebone, false);
+ tree_element_active_ebone__sel(C, obedit, arm, ebone, false);
status = OL_DRAWSEL_NONE;
}
}
@@ -656,8 +656,9 @@ static eOLDrawState tree_element_active_text(
}
static eOLDrawState tree_element_active_pose(
- bContext *C, Scene *scene, ViewLayer *view_layer, TreeElement *UNUSED(te), TreeStoreElem *tselem, const eOLSetState set)
+ bContext *C, ViewLayer *view_layer, TreeElement *UNUSED(te), TreeStoreElem *tselem, const eOLSetState set)
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Object *ob = (Object *)tselem->id;
Base *base = BKE_view_layer_base_find(view_layer, ob);
@@ -667,16 +668,18 @@ static eOLDrawState tree_element_active_pose(
}
if (set != OL_SETSEL_NONE) {
- if (scene->obedit)
+ if (workspace->object_mode & OB_MODE_EDIT) {
ED_object_editmode_exit(C, EM_FREEDATA | EM_FREEUNDO | EM_WAITCURSOR | EM_DO_UNDO);
-
- if (ob->mode & OB_MODE_POSE)
+ }
+ if (workspace->object_mode & OB_MODE_POSE) {
ED_armature_exit_posemode(C, base);
- else
+ }
+ else {
ED_armature_enter_posemode(C, base);
+ }
}
else {
- if (ob->mode & OB_MODE_POSE) {
+ if (workspace->object_mode & OB_MODE_POSE) {
return OL_DRAWSEL_NORMAL;
}
}
@@ -847,7 +850,7 @@ eOLDrawState tree_element_type_active(
case TSE_BONE:
return tree_element_active_bone(C, view_layer, te, tselem, set, recursive);
case TSE_EBONE:
- return tree_element_active_ebone(C, scene, te, tselem, set, recursive);
+ return tree_element_active_ebone(C, te, tselem, set, recursive);
case TSE_MODIFIER:
return tree_element_active_modifier(C, scene, view_layer, te, tselem, set);
case TSE_LINKED_OB:
@@ -861,7 +864,7 @@ eOLDrawState tree_element_type_active(
case TSE_LINKED_PSYS:
return tree_element_active_psys(C, scene, te, tselem, set);
case TSE_POSE_BASE:
- return tree_element_active_pose(C, scene, view_layer, te, tselem, set);
+ return tree_element_active_pose(C, view_layer, te, tselem, set);
case TSE_POSE_CHANNEL:
return tree_element_active_posechannel(C, scene, view_layer, te, tselem, set, recursive);
case TSE_CONSTRAINT:
diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c
index 9f0165d1272..b97046d1470 100644
--- a/source/blender/editors/space_outliner/outliner_tools.c
+++ b/source/blender/editors/space_outliner/outliner_tools.c
@@ -419,9 +419,9 @@ static void object_delete_cb(
}
// check also library later
- if (scene->obedit == ob)
+ if (ob == CTX_data_edit_object(C)) {
ED_object_editmode_exit(C, EM_FREEDATA | EM_FREEUNDO | EM_WAITCURSOR | EM_DO_UNDO);
-
+ }
ED_object_base_free_and_unlink(CTX_data_main(C), scene, ob);
/* leave for ED_outliner_id_unref to handle */
#if 0
@@ -675,7 +675,9 @@ typedef enum eOutliner_PropModifierOps {
typedef enum eOutliner_PropCollectionOps {
OL_COLLECTION_OP_OBJECTS_ADD = 1,
OL_COLLECTION_OP_OBJECTS_REMOVE,
+ OL_COLLECTION_OP_OBJECTS_SELECT,
OL_COLLECTION_OP_COLLECTION_NEW,
+ OL_COLLECTION_OP_COLLECTION_COPY,
OL_COLLECTION_OP_COLLECTION_DEL,
OL_COLLECTION_OP_COLLECTION_UNLINK,
OL_COLLECTION_OP_GROUP_CREATE,
@@ -860,6 +862,10 @@ static void collection_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tsel
WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene);
te->store_elem->flag &= ~TSE_SELECTED;
}
+ else if (event == OL_COLLECTION_OP_OBJECTS_SELECT) {
+ BKE_layer_collection_objects_select(lc);
+ WM_main_add_notifier(NC_SCENE | ND_OB_SELECT, scene);
+ }
else if (event == OL_COLLECTION_OP_COLLECTION_NEW) {
if (GS(id->name) == ID_GR) {
BKE_collection_add(id, sc, COLLECTION_TYPE_GROUP_INTERNAL, NULL);
@@ -870,6 +876,11 @@ static void collection_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tsel
}
WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene);
}
+ else if (event == OL_COLLECTION_OP_COLLECTION_COPY) {
+ BKE_layer_collection_duplicate(id, lc);
+ DEG_relations_tag_update(CTX_data_main(C));
+ WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene);
+ }
else if (event == OL_COLLECTION_OP_COLLECTION_UNLINK) {
ViewLayer *view_layer = CTX_data_view_layer(C);
@@ -969,7 +980,7 @@ static void object_delete_hierarchy_cb(
{
ViewLayer *view_layer = CTX_data_view_layer(C);
Base *base = (Base *)te->directdata;
- Object *obedit = scene->obedit;
+ Object *obedit = CTX_data_edit_object(C);
if (!base) {
base = BKE_view_layer_base_find(view_layer, (Object *)tselem->id);
@@ -1841,39 +1852,18 @@ void OUTLINER_OT_modifier_operation(wmOperatorType *ot)
/* ******************** */
-static EnumPropertyItem prop_collection_op_none_types[] = {
+static EnumPropertyItem prop_collection_op_types[] = {
{OL_COLLECTION_OP_OBJECTS_ADD, "OBJECTS_ADD", ICON_ZOOMIN, "Add Selected", "Add selected objects to collection"},
{OL_COLLECTION_OP_OBJECTS_REMOVE, "OBJECTS_REMOVE", ICON_X, "Remove Selected", "Remove selected objects from collection"},
+ {OL_COLLECTION_OP_OBJECTS_SELECT, "OBJECTS_SELECT", ICON_RESTRICT_SELECT_OFF, "Select Objects", "Selected collection objects"},
{OL_COLLECTION_OP_COLLECTION_NEW, "COLLECTION_NEW", ICON_NEW, "New Collection", "Add a new nested collection"},
+ {OL_COLLECTION_OP_COLLECTION_COPY, "COLLECTION_DUPLI", ICON_NONE, "Duplicate Collection", "Duplicate the collection"},
{OL_COLLECTION_OP_COLLECTION_UNLINK, "COLLECTION_UNLINK", ICON_UNLINKED, "Unlink", "Unlink collection"},
{OL_COLLECTION_OP_COLLECTION_DEL, "COLLECTION_DEL", ICON_X, "Delete Collection", "Delete the collection"},
{OL_COLLECTION_OP_GROUP_CREATE, "GROUP_CREATE", ICON_GROUP, "Create Group", "Turn the collection into a group collection"},
{0, NULL, 0, NULL, NULL}
};
-static EnumPropertyItem prop_collection_op_group_internal_types[] = {
- {OL_COLLECTION_OP_OBJECTS_ADD, "OBJECTS_ADD", ICON_ZOOMIN, "Add Selected", "Add selected objects to collection"},
- {OL_COLLECTION_OP_OBJECTS_REMOVE, "OBJECTS_REMOVE", ICON_X, "Remove Selected", "Remove selected objects from collection"},
- {OL_COLLECTION_OP_COLLECTION_NEW, "COLLECTION_NEW", ICON_NEW, "New Collection", "Add a new nested collection"},
- {OL_COLLECTION_OP_COLLECTION_DEL, "COLLECTION_DEL", ICON_X, "Delete Collection", "Delete the collection"},
- {0, NULL, 0, NULL, NULL}
-};
-
-static const EnumPropertyItem *outliner_collection_operation_type_itemf(
- bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free)
-{
- *r_free = false;
- SpaceOops *soops = CTX_wm_space_outliner(C);
-
- switch (soops->outlinevis) {
- case SO_GROUPS:
- return prop_collection_op_group_internal_types;
- case SO_VIEW_LAYER:
- return prop_collection_op_none_types;
- }
- return NULL;
-}
-
static int outliner_collection_operation_exec(bContext *C, wmOperator *op)
{
SpaceOops *soops = CTX_wm_space_outliner(C);
@@ -1892,6 +1882,31 @@ static int outliner_collection_operation_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
+static int outliner_collection_operation_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ SpaceOops *soops = CTX_wm_space_outliner(C);
+ wmOperatorType *ot = op->type;
+ EnumPropertyItem *prop = &prop_collection_op_types[0];
+
+ uiPopupMenu *pup = UI_popup_menu_begin(C, "Collection", ICON_NONE);
+ uiLayout *layout = UI_popup_menu_layout(pup);
+
+ for (int i = 0; i < (ARRAY_SIZE(prop_collection_op_types) - 1); i++, prop++) {
+ if (soops->outlinevis != SO_GROUPS ||
+ !ELEM(prop->value,
+ OL_COLLECTION_OP_OBJECTS_SELECT,
+ OL_COLLECTION_OP_COLLECTION_UNLINK,
+ OL_COLLECTION_OP_GROUP_CREATE))
+ {
+ uiItemEnumO_ptr(layout, ot, NULL, prop->icon, "type", prop->value);
+ }
+ }
+
+ UI_popup_menu_end(C, pup);
+
+ return OPERATOR_INTERFACE;
+}
+
void OUTLINER_OT_collection_operation(wmOperatorType *ot)
{
PropertyRNA *prop;
@@ -1902,14 +1917,13 @@ void OUTLINER_OT_collection_operation(wmOperatorType *ot)
ot->description = "";
/* callbacks */
- ot->invoke = WM_menu_invoke;
+ ot->invoke = outliner_collection_operation_invoke;
ot->exec = outliner_collection_operation_exec;
ot->poll = ED_operator_outliner_active;
ot->flag = 0;
- prop = RNA_def_enum(ot->srna, "type", DummyRNA_NULL_items, 0, "Collection Operation", "");
- RNA_def_enum_funcs(prop, outliner_collection_operation_type_itemf);
+ prop = RNA_def_enum(ot->srna, "type", prop_collection_op_types, OL_COLLECTION_OP_OBJECTS_ADD, "Collection Operation", "");
RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
ot->prop = prop;
}
diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c
index 06b3319935d..00eb4efde02 100644
--- a/source/blender/editors/space_outliner/outliner_tree.c
+++ b/source/blender/editors/space_outliner/outliner_tree.c
@@ -92,10 +92,12 @@
/* prototypes */
static void outliner_add_layer_collections_recursive(
- SpaceOops *soops, ListBase *tree, ID *id, ListBase *layer_collections, TreeElement *parent_ten,
+ SpaceOops *soops, const EvaluationContext *eval_ctx,
+ ListBase *tree, ID *id, ListBase *layer_collections, TreeElement *parent_ten,
const bool show_objects);
static void outliner_add_view_layer(
- SpaceOops *soops, ListBase *tree, TreeElement *parent,
+ SpaceOops *soops, const EvaluationContext *eval_ctx,
+ ListBase *tree, TreeElement *parent,
Scene *scene, ViewLayer *layer, const bool show_objects);
static void outliner_make_hierarchy(ListBase *lb);
@@ -129,7 +131,7 @@ static void outliner_storage_cleanup(SpaceOops *soops)
}
if (unused) {
- if (BLI_mempool_count(ts) == unused) {
+ if (BLI_mempool_len(ts) == unused) {
BLI_mempool_destroy(ts);
soops->treestore = NULL;
if (soops->treehash) {
@@ -139,7 +141,7 @@ static void outliner_storage_cleanup(SpaceOops *soops)
}
else {
TreeStoreElem *tsenew;
- BLI_mempool *new_ts = BLI_mempool_create(sizeof(TreeStoreElem), BLI_mempool_count(ts) - unused,
+ BLI_mempool *new_ts = BLI_mempool_create(sizeof(TreeStoreElem), BLI_mempool_len(ts) - unused,
512, BLI_MEMPOOL_ALLOW_ITER);
BLI_mempool_iternew(ts, &iter);
while ((tselem = BLI_mempool_iterstep(&iter))) {
@@ -233,23 +235,25 @@ void outliner_free_tree_element(TreeElement *element, ListBase *parent_subtree)
/* ********************************************************* */
/* Prototype, see functions below */
-static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *idv,
- TreeElement *parent, short type, short index);
+static TreeElement *outliner_add_element(
+ SpaceOops *soops, const EvaluationContext *eval_ctx,
+ ListBase *lb, void *idv, TreeElement *parent, short type, short index);
/* -------------------------------------------------------- */
/* special handling of hierarchical non-lib data */
-static void outliner_add_bone(SpaceOops *soops, ListBase *lb, ID *id, Bone *curBone,
- TreeElement *parent, int *a)
+static void outliner_add_bone(
+ SpaceOops *soops, const EvaluationContext *eval_ctx,
+ ListBase *lb, ID *id, Bone *curBone, TreeElement *parent, int *a)
{
- TreeElement *te = outliner_add_element(soops, lb, id, parent, TSE_BONE, *a);
+ TreeElement *te = outliner_add_element(soops, eval_ctx, lb, id, parent, TSE_BONE, *a);
(*a)++;
te->name = curBone->name;
te->directdata = curBone;
for (curBone = curBone->childbase.first; curBone; curBone = curBone->next) {
- outliner_add_bone(soops, &te->subtree, id, curBone, te, a);
+ outliner_add_bone(soops, eval_ctx, &te->subtree, id, curBone, te, a);
}
}
@@ -257,7 +261,9 @@ static void outliner_add_bone(SpaceOops *soops, ListBase *lb, ID *id, Bone *curB
#define LOG2I(x) (int)(log(x) / M_LN2)
-static void outliner_add_passes(SpaceOops *soops, TreeElement *tenla, ID *id, ViewLayer *view_layer)
+static void outliner_add_passes(
+ SpaceOops *soops, const EvaluationContext *eval_ctx,
+ TreeElement *tenla, ID *id, ViewLayer *view_layer)
{
TreeStoreElem *tselem = NULL;
TreeElement *te = NULL;
@@ -265,7 +271,7 @@ static void outliner_add_passes(SpaceOops *soops, TreeElement *tenla, ID *id, Vi
/* log stuff is to convert bitflags (powers of 2) to small integers,
* in order to not overflow short tselem->nr */
- te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_COMBINED));
+ te = outliner_add_element(soops, eval_ctx, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_COMBINED));
te->name = IFACE_("Combined");
te->directdata = &view_layer->passflag;
@@ -274,71 +280,71 @@ static void outliner_add_passes(SpaceOops *soops, TreeElement *tenla, ID *id, Vi
if (tselem->flag & TSE_CLOSED)
return;
- te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_Z));
+ te = outliner_add_element(soops, eval_ctx, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_Z));
te->name = IFACE_("Z");
te->directdata = &view_layer->passflag;
- te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_VECTOR));
+ te = outliner_add_element(soops, eval_ctx, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_VECTOR));
te->name = IFACE_("Vector");
te->directdata = &view_layer->passflag;
- te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_NORMAL));
+ te = outliner_add_element(soops, eval_ctx, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_NORMAL));
te->name = IFACE_("Normal");
te->directdata = &view_layer->passflag;
- te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_UV));
+ te = outliner_add_element(soops, eval_ctx, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_UV));
te->name = IFACE_("UV");
te->directdata = &view_layer->passflag;
- te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_MIST));
+ te = outliner_add_element(soops, eval_ctx, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_MIST));
te->name = IFACE_("Mist");
te->directdata = &view_layer->passflag;
- te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_INDEXOB));
+ te = outliner_add_element(soops, eval_ctx, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_INDEXOB));
te->name = IFACE_("Index Object");
te->directdata = &view_layer->passflag;
- te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_INDEXMA));
+ te = outliner_add_element(soops, eval_ctx, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_INDEXMA));
te->name = IFACE_("Index Material");
te->directdata = &view_layer->passflag;
- te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_RGBA));
+ te = outliner_add_element(soops, eval_ctx, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_RGBA));
te->name = IFACE_("Color");
te->directdata = &view_layer->passflag;
- te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_DIFFUSE));
+ te = outliner_add_element(soops, eval_ctx, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_DIFFUSE));
te->name = IFACE_("Diffuse");
te->directdata = &view_layer->passflag;
- te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_SPEC));
+ te = outliner_add_element(soops, eval_ctx, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_SPEC));
te->name = IFACE_("Specular");
te->directdata = &view_layer->passflag;
- te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_SHADOW));
+ te = outliner_add_element(soops, eval_ctx, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_SHADOW));
te->name = IFACE_("Shadow");
te->directdata = &view_layer->passflag;
- te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_AO));
+ te = outliner_add_element(soops, eval_ctx, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_AO));
te->name = IFACE_("AO");
te->directdata = &view_layer->passflag;
- te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_REFLECT));
+ te = outliner_add_element(soops, eval_ctx, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_REFLECT));
te->name = IFACE_("Reflection");
te->directdata = &view_layer->passflag;
- te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_REFRACT));
+ te = outliner_add_element(soops, eval_ctx, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_REFRACT));
te->name = IFACE_("Refraction");
te->directdata = &view_layer->passflag;
- te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_INDIRECT));
+ te = outliner_add_element(soops, eval_ctx, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_INDIRECT));
te->name = IFACE_("Indirect");
te->directdata = &view_layer->passflag;
- te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_ENVIRONMENT));
+ te = outliner_add_element(soops, eval_ctx, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_ENVIRONMENT));
te->name = IFACE_("Environment");
te->directdata = &view_layer->passflag;
- te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_EMIT));
+ te = outliner_add_element(soops, eval_ctx, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_EMIT));
te->name = IFACE_("Emit");
te->directdata = &view_layer->passflag;
}
@@ -373,41 +379,43 @@ static void outliner_add_line_styles(SpaceOops *soops, ListBase *lb, Scene *sce,
if (!(linestyle->id.tag & LIB_TAG_DOIT))
continue;
linestyle->id.tag &= ~LIB_TAG_DOIT;
- outliner_add_element(soops, lb, linestyle, te, 0, 0);
+ outliner_add_element(soops, eval_ctx, lb, linestyle, te, 0, 0);
}
}
}
}
#endif
-static void outliner_add_scene_contents(SpaceOops *soops, ListBase *lb, Scene *sce, TreeElement *te)
+static void outliner_add_scene_contents(
+ SpaceOops *soops, const EvaluationContext *eval_ctx,
+ ListBase *lb, Scene *sce, TreeElement *te)
{
ViewLayer *view_layer;
- TreeElement *tenla = outliner_add_element(soops, lb, sce, te, TSE_R_LAYER_BASE, 0);
+ TreeElement *tenla = outliner_add_element(soops, eval_ctx, lb, sce, te, TSE_R_LAYER_BASE, 0);
int a;
tenla->name = IFACE_("View Layers");
for (a = 0, view_layer = sce->view_layers.first; view_layer; view_layer = view_layer->next, a++) {
- TreeElement *tenlay = outliner_add_element(soops, &tenla->subtree, sce, te, TSE_R_LAYER, a);
+ TreeElement *tenlay = outliner_add_element(soops, eval_ctx, &tenla->subtree, sce, te, TSE_R_LAYER, a);
tenlay->name = view_layer->name;
tenlay->directdata = &view_layer->flag;
TreeElement *te_view_layers;
- te_view_layers = outliner_add_element(soops, &tenlay->subtree, sce, tenlay, TSE_LAYER_COLLECTION_BASE, 0);
+ te_view_layers = outliner_add_element(soops, eval_ctx, &tenlay->subtree, sce, tenlay, TSE_LAYER_COLLECTION_BASE, 0);
te_view_layers->name = IFACE_("Collections");
- outliner_add_view_layer(soops, &te_view_layers->subtree, te_view_layers, sce, view_layer, false);
+ outliner_add_view_layer(soops, eval_ctx, &te_view_layers->subtree, te_view_layers, sce, view_layer, false);
TreeElement *te_passes;
- te_passes = outliner_add_element(soops, &tenlay->subtree, sce, tenlay, TSE_LAYER_COLLECTION_BASE, 0);
+ te_passes = outliner_add_element(soops, eval_ctx, &tenlay->subtree, sce, tenlay, TSE_LAYER_COLLECTION_BASE, 0);
te_passes->name = IFACE_("Passes");
- outliner_add_passes(soops, te_passes, &sce->id, view_layer);
+ outliner_add_passes(soops, eval_ctx, te_passes, &sce->id, view_layer);
}
// TODO: move this to the front?
if (outliner_animdata_test(sce->adt))
- outliner_add_element(soops, lb, sce, te, TSE_ANIM_DATA, 0);
+ outliner_add_element(soops, eval_ctx, lb, sce, te, TSE_ANIM_DATA, 0);
- outliner_add_element(soops, lb, sce->gpd, te, 0, 0);
+ outliner_add_element(soops, eval_ctx, lb, sce->gpd, te, 0, 0);
#ifdef WITH_FREESTYLE
if (STREQ(sce->view_render->engine_id, RE_engine_id_BLENDER_RENDER) && (sce->r.mode & R_EDGE_FRS))
@@ -415,11 +423,7 @@ static void outliner_add_scene_contents(SpaceOops *soops, ListBase *lb, Scene *s
#endif
}
-struct ObjectsSelectedData {
- ListBase objects_selected_array;
-};
-
-static TreeTraversalAction outliner_find_selected_objects(TreeElement *te, void *customdata)
+TreeTraversalAction outliner_find_selected_objects(TreeElement *te, void *customdata)
{
struct ObjectsSelectedData *data = customdata;
TreeStoreElem *tselem = TREESTORE(te);
@@ -465,7 +469,7 @@ static void outliner_object_reorder(
TREESTORE(insert_element)->flag |= TSE_SELECTED;
outliner_tree_traverse(soops, &soops->tree, 0, TSE_SELECTED, outliner_find_selected_objects, &data);
- BLI_LISTBASE_FOREACH (LinkData *, link, &data.objects_selected_array) {
+ LISTBASE_FOREACH (LinkData *, link, &data.objects_selected_array) {
TreeElement *ten_selected = (TreeElement *)link->data;
Object *ob = (Object *)TREESTORE(ten_selected)->id;
@@ -516,37 +520,41 @@ static bool outliner_object_reorder_poll(
}
// can be inlined if necessary
-static void outliner_add_object_contents(SpaceOops *soops, TreeElement *te, TreeStoreElem *tselem, Object *ob)
+static void outliner_add_object_contents(
+ SpaceOops *soops, const EvaluationContext *eval_ctx,
+ TreeElement *te, TreeStoreElem *tselem, Object *ob)
{
te->reinsert = outliner_object_reorder;
te->reinsert_poll = outliner_object_reorder_poll;
if (outliner_animdata_test(ob->adt))
- outliner_add_element(soops, &te->subtree, ob, te, TSE_ANIM_DATA, 0);
+ outliner_add_element(soops, eval_ctx, &te->subtree, ob, te, TSE_ANIM_DATA, 0);
- outliner_add_element(soops, &te->subtree, ob->poselib, te, 0, 0); // XXX FIXME.. add a special type for this
+ outliner_add_element(soops, eval_ctx, &te->subtree, ob->poselib, te, 0, 0); // XXX FIXME.. add a special type for this
if (ob->proxy && !ID_IS_LINKED(ob))
- outliner_add_element(soops, &te->subtree, ob->proxy, te, TSE_PROXY, 0);
+ outliner_add_element(soops, eval_ctx, &te->subtree, ob->proxy, te, TSE_PROXY, 0);
- outliner_add_element(soops, &te->subtree, ob->gpd, te, 0, 0);
+ outliner_add_element(soops, eval_ctx, &te->subtree, ob->gpd, te, 0, 0);
- outliner_add_element(soops, &te->subtree, ob->data, te, 0, 0);
+ outliner_add_element(soops, eval_ctx, &te->subtree, ob->data, te, 0, 0);
if (ob->pose) {
bArmature *arm = ob->data;
bPoseChannel *pchan;
- TreeElement *tenla = outliner_add_element(soops, &te->subtree, ob, te, TSE_POSE_BASE, 0);
+ TreeElement *tenla = outliner_add_element(
+ soops, eval_ctx, &te->subtree, ob, te, TSE_POSE_BASE, 0);
tenla->name = IFACE_("Pose");
/* channels undefined in editmode, but we want the 'tenla' pose icon itself */
- if ((arm->edbo == NULL) && (ob->mode & OB_MODE_POSE)) {
+ if ((arm->edbo == NULL) && (eval_ctx->object_mode & OB_MODE_POSE)) {
TreeElement *ten;
int a = 0, const_index = 1000; /* ensure unique id for bone constraints */
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next, a++) {
- ten = outliner_add_element(soops, &tenla->subtree, ob, tenla, TSE_POSE_CHANNEL, a);
+ ten = outliner_add_element(
+ soops, eval_ctx, &tenla->subtree, ob, tenla, TSE_POSE_CHANNEL, a);
ten->name = pchan->name;
ten->directdata = pchan;
pchan->temp = (void *)ten;
@@ -555,12 +563,14 @@ static void outliner_add_object_contents(SpaceOops *soops, TreeElement *te, Tree
//Object *target;
bConstraint *con;
TreeElement *ten1;
- TreeElement *tenla1 = outliner_add_element(soops, &ten->subtree, ob, ten, TSE_CONSTRAINT_BASE, 0);
+ TreeElement *tenla1 = outliner_add_element(
+ soops, eval_ctx, &ten->subtree, ob, ten, TSE_CONSTRAINT_BASE, 0);
//char *str;
tenla1->name = IFACE_("Constraints");
for (con = pchan->constraints.first; con; con = con->next, const_index++) {
- ten1 = outliner_add_element(soops, &tenla1->subtree, ob, tenla1, TSE_CONSTRAINT, const_index);
+ ten1 = outliner_add_element(
+ soops, eval_ctx, &tenla1->subtree, ob, tenla1, TSE_CONSTRAINT, const_index);
#if 0 /* disabled as it needs to be reworked for recoded constraints system */
target = get_constraint_target(con, &str);
if (str && str[0]) ten1->name = str;
@@ -594,13 +604,15 @@ static void outliner_add_object_contents(SpaceOops *soops, TreeElement *te, Tree
/* Pose Groups */
if (ob->pose->agroups.first) {
bActionGroup *agrp;
- TreeElement *ten_bonegrp = outliner_add_element(soops, &te->subtree, ob, te, TSE_POSEGRP_BASE, 0);
+ TreeElement *ten_bonegrp = outliner_add_element(
+ soops, eval_ctx, &te->subtree, ob, te, TSE_POSEGRP_BASE, 0);
int a = 0;
ten_bonegrp->name = IFACE_("Bone Groups");
for (agrp = ob->pose->agroups.first; agrp; agrp = agrp->next, a++) {
TreeElement *ten;
- ten = outliner_add_element(soops, &ten_bonegrp->subtree, ob, ten_bonegrp, TSE_POSEGRP, a);
+ ten = outliner_add_element(
+ soops, eval_ctx, &ten_bonegrp->subtree, ob, ten_bonegrp, TSE_POSEGRP, a);
ten->name = agrp->name;
ten->directdata = agrp;
}
@@ -608,20 +620,21 @@ static void outliner_add_object_contents(SpaceOops *soops, TreeElement *te, Tree
}
for (int a = 0; a < ob->totcol; a++) {
- outliner_add_element(soops, &te->subtree, ob->mat[a], te, 0, a);
+ outliner_add_element(
+ soops, eval_ctx, &te->subtree, ob->mat[a], te, 0, a);
}
if (ob->constraints.first) {
//Object *target;
bConstraint *con;
TreeElement *ten;
- TreeElement *tenla = outliner_add_element(soops, &te->subtree, ob, te, TSE_CONSTRAINT_BASE, 0);
+ TreeElement *tenla = outliner_add_element(soops, eval_ctx, &te->subtree, ob, te, TSE_CONSTRAINT_BASE, 0);
//char *str;
int a;
tenla->name = IFACE_("Constraints");
for (con = ob->constraints.first, a = 0; con; con = con->next, a++) {
- ten = outliner_add_element(soops, &tenla->subtree, ob, tenla, TSE_CONSTRAINT, a);
+ ten = outliner_add_element(soops, eval_ctx, &tenla->subtree, ob, tenla, TSE_CONSTRAINT, a);
#if 0 /* disabled due to constraints system targets recode... code here needs review */
target = get_constraint_target(con, &str);
if (str && str[0]) ten->name = str;
@@ -636,32 +649,38 @@ static void outliner_add_object_contents(SpaceOops *soops, TreeElement *te, Tree
if (ob->modifiers.first) {
ModifierData *md;
- TreeElement *ten_mod = outliner_add_element(soops, &te->subtree, ob, te, TSE_MODIFIER_BASE, 0);
+ TreeElement *ten_mod = outliner_add_element(soops, eval_ctx, &te->subtree, ob, te, TSE_MODIFIER_BASE, 0);
int index;
ten_mod->name = IFACE_("Modifiers");
for (index = 0, md = ob->modifiers.first; md; index++, md = md->next) {
- TreeElement *ten = outliner_add_element(soops, &ten_mod->subtree, ob, ten_mod, TSE_MODIFIER, index);
+ TreeElement *ten = outliner_add_element(
+ soops, eval_ctx, &ten_mod->subtree, ob, ten_mod, TSE_MODIFIER, index);
ten->name = md->name;
ten->directdata = md;
if (md->type == eModifierType_Lattice) {
- outliner_add_element(soops, &ten->subtree, ((LatticeModifierData *) md)->object, ten, TSE_LINKED_OB, 0);
+ outliner_add_element(
+ soops, eval_ctx, &ten->subtree, ((LatticeModifierData *) md)->object, ten, TSE_LINKED_OB, 0);
}
else if (md->type == eModifierType_Curve) {
- outliner_add_element(soops, &ten->subtree, ((CurveModifierData *) md)->object, ten, TSE_LINKED_OB, 0);
+ outliner_add_element(
+ soops, eval_ctx, &ten->subtree, ((CurveModifierData *) md)->object, ten, TSE_LINKED_OB, 0);
}
else if (md->type == eModifierType_Armature) {
- outliner_add_element(soops, &ten->subtree, ((ArmatureModifierData *) md)->object, ten, TSE_LINKED_OB, 0);
+ outliner_add_element(
+ soops, eval_ctx, &ten->subtree, ((ArmatureModifierData *) md)->object, ten, TSE_LINKED_OB, 0);
}
else if (md->type == eModifierType_Hook) {
- outliner_add_element(soops, &ten->subtree, ((HookModifierData *) md)->object, ten, TSE_LINKED_OB, 0);
+ outliner_add_element(
+ soops, eval_ctx, &ten->subtree, ((HookModifierData *) md)->object, ten, TSE_LINKED_OB, 0);
}
else if (md->type == eModifierType_ParticleSystem) {
ParticleSystem *psys = ((ParticleSystemModifierData *) md)->psys;
TreeElement *ten_psys;
- ten_psys = outliner_add_element(soops, &ten->subtree, ob, te, TSE_LINKED_PSYS, 0);
+ ten_psys = outliner_add_element(
+ soops, eval_ctx, &ten->subtree, ob, te, TSE_LINKED_PSYS, 0);
ten_psys->directdata = psys;
ten_psys->name = psys->part->id.name + 2;
}
@@ -672,25 +691,29 @@ static void outliner_add_object_contents(SpaceOops *soops, TreeElement *te, Tree
if (ob->defbase.first) {
bDeformGroup *defgroup;
TreeElement *ten;
- TreeElement *tenla = outliner_add_element(soops, &te->subtree, ob, te, TSE_DEFGROUP_BASE, 0);
+ TreeElement *tenla = outliner_add_element(
+ soops, eval_ctx, &te->subtree, ob, te, TSE_DEFGROUP_BASE, 0);
int a;
tenla->name = IFACE_("Vertex Groups");
for (defgroup = ob->defbase.first, a = 0; defgroup; defgroup = defgroup->next, a++) {
- ten = outliner_add_element(soops, &tenla->subtree, ob, tenla, TSE_DEFGROUP, a);
+ ten = outliner_add_element(soops, eval_ctx, &tenla->subtree, ob, tenla, TSE_DEFGROUP, a);
ten->name = defgroup->name;
ten->directdata = defgroup;
}
}
/* duplicated group */
- if (ob->dup_group)
- outliner_add_element(soops, &te->subtree, ob->dup_group, te, 0, 0);
+ if (ob->dup_group) {
+ outliner_add_element(soops, eval_ctx, &te->subtree, ob->dup_group, te, 0, 0);
+ }
}
// can be inlined if necessary
-static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStoreElem *tselem, ID *id)
+static void outliner_add_id_contents(
+ SpaceOops *soops, const EvaluationContext *eval_ctx,
+ TreeElement *te, TreeStoreElem *tselem, ID *id)
{
/* tuck pointer back in object, to construct hierarchy */
if (GS(id->name) == ID_OB) id->newid = (ID *)te;
@@ -704,25 +727,26 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor
}
case ID_SCE:
{
- outliner_add_scene_contents(soops, &te->subtree, (Scene *)id, te);
+ outliner_add_scene_contents(soops, eval_ctx, &te->subtree, (Scene *)id, te);
break;
}
case ID_OB:
{
- outliner_add_object_contents(soops, te, tselem, (Object *)id);
+ outliner_add_object_contents(soops, eval_ctx, te, tselem, (Object *)id);
break;
}
case ID_ME:
{
Mesh *me = (Mesh *)id;
int a;
-
- if (outliner_animdata_test(me->adt))
- outliner_add_element(soops, &te->subtree, me, te, TSE_ANIM_DATA, 0);
-
- outliner_add_element(soops, &te->subtree, me->key, te, 0, 0);
+
+ if (outliner_animdata_test(me->adt)) {
+ outliner_add_element(soops, eval_ctx, &te->subtree, me, te, TSE_ANIM_DATA, 0);
+ }
+
+ outliner_add_element(soops, eval_ctx, &te->subtree, me->key, te, 0, 0);
for (a = 0; a < me->totcol; a++)
- outliner_add_element(soops, &te->subtree, me->mat[a], te, 0, a);
+ outliner_add_element(soops, eval_ctx, &te->subtree, me->mat[a], te, 0, a);
/* could do tfaces with image links, but the images are not grouped nicely.
* would require going over all tfaces, sort images in use. etc... */
break;
@@ -733,10 +757,10 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor
int a;
if (outliner_animdata_test(cu->adt))
- outliner_add_element(soops, &te->subtree, cu, te, TSE_ANIM_DATA, 0);
+ outliner_add_element(soops, eval_ctx, &te->subtree, cu, te, TSE_ANIM_DATA, 0);
for (a = 0; a < cu->totcol; a++)
- outliner_add_element(soops, &te->subtree, cu->mat[a], te, 0, a);
+ outliner_add_element(soops, eval_ctx, &te->subtree, cu->mat[a], te, 0, a);
break;
}
case ID_MB:
@@ -745,10 +769,10 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor
int a;
if (outliner_animdata_test(mb->adt))
- outliner_add_element(soops, &te->subtree, mb, te, TSE_ANIM_DATA, 0);
+ outliner_add_element(soops, eval_ctx, &te->subtree, mb, te, TSE_ANIM_DATA, 0);
for (a = 0; a < mb->totcol; a++)
- outliner_add_element(soops, &te->subtree, mb->mat[a], te, 0, a);
+ outliner_add_element(soops, eval_ctx, &te->subtree, mb->mat[a], te, 0, a);
break;
}
case ID_MA:
@@ -756,11 +780,14 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor
Material *ma = (Material *)id;
int a;
- if (outliner_animdata_test(ma->adt))
- outliner_add_element(soops, &te->subtree, ma, te, TSE_ANIM_DATA, 0);
+ if (outliner_animdata_test(ma->adt)) {
+ outliner_add_element(soops, eval_ctx, &te->subtree, ma, te, TSE_ANIM_DATA, 0);
+ }
for (a = 0; a < MAX_MTEX; a++) {
- if (ma->mtex[a]) outliner_add_element(soops, &te->subtree, ma->mtex[a]->tex, te, 0, a);
+ if (ma->mtex[a]) {
+ outliner_add_element(soops, eval_ctx, &te->subtree, ma->mtex[a]->tex, te, 0, a);
+ }
}
break;
}
@@ -768,10 +795,10 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor
{
Tex *tex = (Tex *)id;
- if (outliner_animdata_test(tex->adt))
- outliner_add_element(soops, &te->subtree, tex, te, TSE_ANIM_DATA, 0);
-
- outliner_add_element(soops, &te->subtree, tex->ima, te, 0, 0);
+ if (outliner_animdata_test(tex->adt)) {
+ outliner_add_element(soops, eval_ctx, &te->subtree, tex, te, TSE_ANIM_DATA, 0);
+ }
+ outliner_add_element(soops, eval_ctx, &te->subtree, tex->ima, te, 0, 0);
break;
}
case ID_CA:
@@ -779,7 +806,7 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor
Camera *ca = (Camera *)id;
if (outliner_animdata_test(ca->adt))
- outliner_add_element(soops, &te->subtree, ca, te, TSE_ANIM_DATA, 0);
+ outliner_add_element(soops, eval_ctx, &te->subtree, ca, te, TSE_ANIM_DATA, 0);
break;
}
case ID_CF:
@@ -787,7 +814,7 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor
CacheFile *cache_file = (CacheFile *)id;
if (outliner_animdata_test(cache_file->adt)) {
- outliner_add_element(soops, &te->subtree, cache_file, te, TSE_ANIM_DATA, 0);
+ outliner_add_element(soops, eval_ctx, &te->subtree, cache_file, te, TSE_ANIM_DATA, 0);
}
break;
@@ -798,10 +825,12 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor
int a;
if (outliner_animdata_test(la->adt))
- outliner_add_element(soops, &te->subtree, la, te, TSE_ANIM_DATA, 0);
+ outliner_add_element(soops, eval_ctx, &te->subtree, la, te, TSE_ANIM_DATA, 0);
for (a = 0; a < MAX_MTEX; a++) {
- if (la->mtex[a]) outliner_add_element(soops, &te->subtree, la->mtex[a]->tex, te, 0, a);
+ if (la->mtex[a]) {
+ outliner_add_element(soops, eval_ctx, &te->subtree, la->mtex[a]->tex, te, 0, a);
+ }
}
break;
}
@@ -809,16 +838,18 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor
{
Speaker *spk = (Speaker *)id;
- if (outliner_animdata_test(spk->adt))
- outliner_add_element(soops, &te->subtree, spk, te, TSE_ANIM_DATA, 0);
+ if (outliner_animdata_test(spk->adt)) {
+ outliner_add_element(soops, eval_ctx, &te->subtree, spk, te, TSE_ANIM_DATA, 0);
+ }
break;
}
case ID_LP:
{
LightProbe *prb = (LightProbe *)id;
- if (outliner_animdata_test(prb->adt))
- outliner_add_element(soops, &te->subtree, prb, te, TSE_ANIM_DATA, 0);
+ if (outliner_animdata_test(prb->adt)) {
+ outliner_add_element(soops, eval_ctx, &te->subtree, prb, te, TSE_ANIM_DATA, 0);
+ }
break;
}
case ID_WO:
@@ -826,11 +857,13 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor
World *wrld = (World *)id;
int a;
- if (outliner_animdata_test(wrld->adt))
- outliner_add_element(soops, &te->subtree, wrld, te, TSE_ANIM_DATA, 0);
-
+ if (outliner_animdata_test(wrld->adt)) {
+ outliner_add_element(soops, eval_ctx, &te->subtree, wrld, te, TSE_ANIM_DATA, 0);
+ }
for (a = 0; a < MAX_MTEX; a++) {
- if (wrld->mtex[a]) outliner_add_element(soops, &te->subtree, wrld->mtex[a]->tex, te, 0, a);
+ if (wrld->mtex[a]) {
+ outliner_add_element(soops, eval_ctx, &te->subtree, wrld->mtex[a]->tex, te, 0, a);
+ }
}
break;
}
@@ -838,8 +871,9 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor
{
Key *key = (Key *)id;
- if (outliner_animdata_test(key->adt))
- outliner_add_element(soops, &te->subtree, key, te, TSE_ANIM_DATA, 0);
+ if (outliner_animdata_test(key->adt)) {
+ outliner_add_element(soops, eval_ctx, &te->subtree, key, te, TSE_ANIM_DATA, 0);
+ }
break;
}
case ID_AC:
@@ -853,15 +887,15 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor
bArmature *arm = (bArmature *)id;
int a = 0;
- if (outliner_animdata_test(arm->adt))
- outliner_add_element(soops, &te->subtree, arm, te, TSE_ANIM_DATA, 0);
-
+ if (outliner_animdata_test(arm->adt)) {
+ outliner_add_element(soops, eval_ctx, &te->subtree, arm, te, TSE_ANIM_DATA, 0);
+ }
if (arm->edbo) {
EditBone *ebone;
TreeElement *ten;
for (ebone = arm->edbo->first; ebone; ebone = ebone->next, a++) {
- ten = outliner_add_element(soops, &te->subtree, id, te, TSE_EBONE, a);
+ ten = outliner_add_element(soops, eval_ctx, &te->subtree, id, te, TSE_EBONE, a);
ten->directdata = ebone;
ten->name = ebone->name;
ebone->temp.p = ten;
@@ -883,13 +917,17 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor
else {
/* do not extend Armature when we have posemode */
tselem = TREESTORE(te->parent);
- if (GS(tselem->id->name) == ID_OB && ((Object *)tselem->id)->mode & OB_MODE_POSE) {
+ if (GS(tselem->id->name) == ID_OB &&
+ (eval_ctx->object_mode & OB_MODE_POSE)
+ /* (((Object *)tselem->id)->mode & OB_MODE_POSE) */
+ )
+ {
/* pass */
}
else {
Bone *curBone;
for (curBone = arm->bonebase.first; curBone; curBone = curBone->next) {
- outliner_add_bone(soops, &te->subtree, id, curBone, te, &a);
+ outliner_add_bone(soops, eval_ctx, &te->subtree, id, curBone, te, &a);
}
}
}
@@ -899,13 +937,14 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor
{
FreestyleLineStyle *linestyle = (FreestyleLineStyle *)id;
int a;
-
- if (outliner_animdata_test(linestyle->adt))
- outliner_add_element(soops, &te->subtree, linestyle, te, TSE_ANIM_DATA, 0);
+
+ if (outliner_animdata_test(linestyle->adt)) {
+ outliner_add_element(soops, eval_ctx, &te->subtree, linestyle, te, TSE_ANIM_DATA, 0);
+ }
for (a = 0; a < MAX_MTEX; a++) {
if (linestyle->mtex[a])
- outliner_add_element(soops, &te->subtree, linestyle->mtex[a]->tex, te, 0, a);
+ outliner_add_element(soops, eval_ctx, &te->subtree, linestyle->mtex[a]->tex, te, 0, a);
}
break;
}
@@ -916,11 +955,11 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor
int a = 0;
if (outliner_animdata_test(gpd->adt))
- outliner_add_element(soops, &te->subtree, gpd, te, TSE_ANIM_DATA, 0);
+ outliner_add_element(soops, eval_ctx, &te->subtree, gpd, te, TSE_ANIM_DATA, 0);
// TODO: base element for layers?
for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
- outliner_add_element(soops, &te->subtree, gpl, te, TSE_GP_LAYER, a);
+ outliner_add_element(soops, eval_ctx, &te->subtree, gpl, te, TSE_GP_LAYER, a);
a++;
}
break;
@@ -932,8 +971,9 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor
// TODO: this function needs to be split up! It's getting a bit too large...
// Note: "ID" is not always a real ID
-static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *idv,
- TreeElement *parent, short type, short index)
+static TreeElement *outliner_add_element(
+ SpaceOops *soops, const EvaluationContext *eval_ctx,
+ ListBase *lb, void *idv, TreeElement *parent, short type, short index)
{
TreeElement *te;
TreeStoreElem *tselem;
@@ -1006,7 +1046,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
/* ID datablock */
if (tsepar == NULL || tsepar->type != TSE_ID_BASE)
- outliner_add_id_contents(soops, te, tselem, id);
+ outliner_add_id_contents(soops, eval_ctx, te, tselem, id);
}
else if (type == TSE_ANIM_DATA) {
IdAdtTemplate *iat = (IdAdtTemplate *)idv;
@@ -1017,11 +1057,11 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
te->directdata = adt;
/* Action */
- outliner_add_element(soops, &te->subtree, adt->action, te, 0, 0);
+ outliner_add_element(soops, eval_ctx, &te->subtree, adt->action, te, 0, 0);
/* Drivers */
if (adt->drivers.first) {
- TreeElement *ted = outliner_add_element(soops, &te->subtree, adt, te, TSE_DRIVER_BASE, 0);
+ TreeElement *ted = outliner_add_element(soops, eval_ctx, &te->subtree, adt, te, TSE_DRIVER_BASE, 0);
ID *lastadded = NULL;
FCurve *fcu;
@@ -1038,7 +1078,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
{
if (lastadded != dtar->id) {
// XXX this lastadded check is rather lame, and also fails quite badly...
- outliner_add_element(soops, &ted->subtree, dtar->id, ted, TSE_LINKED_OB, 0);
+ outliner_add_element(soops, eval_ctx, &ted->subtree, dtar->id, ted, TSE_LINKED_OB, 0);
lastadded = dtar->id;
}
}
@@ -1050,14 +1090,14 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
/* NLA Data */
if (adt->nla_tracks.first) {
- TreeElement *tenla = outliner_add_element(soops, &te->subtree, adt, te, TSE_NLA, 0);
+ TreeElement *tenla = outliner_add_element(soops, eval_ctx, &te->subtree, adt, te, TSE_NLA, 0);
NlaTrack *nlt;
int a = 0;
tenla->name = IFACE_("NLA Tracks");
for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
- TreeElement *tenlt = outliner_add_element(soops, &tenla->subtree, nlt, tenla, TSE_NLA_TRACK, a);
+ TreeElement *tenlt = outliner_add_element(soops, eval_ctx, &tenla->subtree, nlt, tenla, TSE_NLA_TRACK, a);
NlaStrip *strip;
TreeElement *ten;
int b = 0;
@@ -1065,7 +1105,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
tenlt->name = nlt->name;
for (strip = nlt->strips.first; strip; strip = strip->next, b++) {
- ten = outliner_add_element(soops, &tenlt->subtree, strip->act, tenlt, TSE_NLA_ACTION, b);
+ ten = outliner_add_element(soops, eval_ctx, &tenlt->subtree, strip->act, tenlt, TSE_NLA_ACTION, b);
if (ten) ten->directdata = strip;
}
}
@@ -1100,12 +1140,12 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
if (seq->type == SEQ_TYPE_META) {
p = seq->seqbase.first;
while (p) {
- outliner_add_element(soops, &te->subtree, (void *)p, te, TSE_SEQUENCE, index);
+ outliner_add_element(soops, eval_ctx, &te->subtree, (void *)p, te, TSE_SEQUENCE, index);
p = p->next;
}
}
else
- outliner_add_element(soops, &te->subtree, (void *)seq->strip, te, TSE_SEQ_STRIP, index);
+ outliner_add_element(soops, eval_ctx, &te->subtree, (void *)seq->strip, te, TSE_SEQ_STRIP, index);
}
}
else if (type == TSE_SEQ_STRIP) {
@@ -1166,7 +1206,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
for (a = 0; a < tot; a++) {
RNA_property_collection_lookup_int(ptr, iterprop, a, &propptr);
if (!(RNA_property_flag(propptr.data) & PROP_HIDDEN)) {
- outliner_add_element(soops, &te->subtree, (void *)ptr, te, TSE_RNA_PROPERTY, a);
+ outliner_add_element(soops, eval_ctx, &te->subtree, (void *)ptr, te, TSE_RNA_PROPERTY, a);
}
}
}
@@ -1195,7 +1235,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
if (pptr.data) {
if (TSELEM_OPEN(tselem, soops))
- outliner_add_element(soops, &te->subtree, (void *)&pptr, te, TSE_RNA_STRUCT, -1);
+ outliner_add_element(soops, eval_ctx, &te->subtree, (void *)&pptr, te, TSE_RNA_STRUCT, -1);
else
te->flag |= TE_LAZY_CLOSED;
}
@@ -1207,7 +1247,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
if (TSELEM_OPEN(tselem, soops)) {
for (a = 0; a < tot; a++) {
RNA_property_collection_lookup_int(ptr, prop, a, &pptr);
- outliner_add_element(soops, &te->subtree, (void *)&pptr, te, TSE_RNA_STRUCT, a);
+ outliner_add_element(soops, eval_ctx, &te->subtree, (void *)&pptr, te, TSE_RNA_STRUCT, a);
}
}
else if (tot)
@@ -1219,7 +1259,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
if (TSELEM_OPEN(tselem, soops)) {
for (a = 0; a < tot; a++)
- outliner_add_element(soops, &te->subtree, (void *)ptr, te, TSE_RNA_ARRAY_ELEM, a);
+ outliner_add_element(soops, eval_ctx, &te->subtree, (void *)ptr, te, TSE_RNA_ARRAY_ELEM, a);
}
else if (tot)
te->flag |= TE_LAZY_CLOSED;
@@ -1267,7 +1307,8 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
}
if (ot || kmi->propvalue) {
- TreeElement *ten = outliner_add_element(soops, &te->subtree, kmi, te, TSE_KEYMAP_ITEM, a);
+ TreeElement *ten = outliner_add_element(
+ soops, eval_ctx, &te->subtree, kmi, te, TSE_KEYMAP_ITEM, a);
ten->directdata = kmi;
@@ -1289,7 +1330,8 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
if ((type != TSE_LAYER_COLLECTION) && (te->idcode == ID_GR)) {
Group *group = (Group *)id;
- outliner_add_layer_collections_recursive(soops, &te->subtree, id, &group->view_layer->layer_collections, NULL, true);
+ outliner_add_layer_collections_recursive(
+ soops, eval_ctx, &te->subtree, id, &group->view_layer->layer_collections, NULL, true);
}
return te;
@@ -1345,7 +1387,9 @@ static int need_add_seq_dup(Sequence *seq)
return(1);
}
-static void outliner_add_seq_dup(SpaceOops *soops, Sequence *seq, TreeElement *te, short index)
+static void outliner_add_seq_dup(
+ SpaceOops *soops, const EvaluationContext *eval_ctx,
+ Sequence *seq, TreeElement *te, short index)
{
/* TreeElement *ch; */ /* UNUSED */
Sequence *p;
@@ -1358,7 +1402,8 @@ static void outliner_add_seq_dup(SpaceOops *soops, Sequence *seq, TreeElement *t
}
if (STREQ(p->strip->stripdata->name, seq->strip->stripdata->name))
- /* ch = */ /* UNUSED */ outliner_add_element(soops, &te->subtree, (void *)p, te, TSE_SEQUENCE, index);
+ /* ch = */ /* UNUSED */ outliner_add_element(
+ soops, eval_ctx, &te->subtree, (void *)p, te, TSE_SEQUENCE, index);
p = p->next;
}
}
@@ -1367,7 +1412,9 @@ static void outliner_add_seq_dup(SpaceOops *soops, Sequence *seq, TreeElement *t
/* ----------------------------------------------- */
-static void outliner_add_library_contents(Main *mainvar, SpaceOops *soops, TreeElement *te, Library *lib)
+static void outliner_add_library_contents(
+ Main *mainvar, SpaceOops *soops, const EvaluationContext *eval_ctx,
+ TreeElement *te, Library *lib)
{
TreeElement *ten;
ListBase *lbarray[MAX_LIBARRAY];
@@ -1384,7 +1431,7 @@ static void outliner_add_library_contents(Main *mainvar, SpaceOops *soops, TreeE
break;
if (id) {
- ten = outliner_add_element(soops, &te->subtree, lbarray[a], NULL, TSE_ID_BASE, 0);
+ ten = outliner_add_element(soops, eval_ctx, &te->subtree, lbarray[a], NULL, TSE_ID_BASE, 0);
ten->directdata = lbarray[a];
ten->name = BKE_idcode_to_name_plural(GS(id->name));
@@ -1393,7 +1440,7 @@ static void outliner_add_library_contents(Main *mainvar, SpaceOops *soops, TreeE
for (id = lbarray[a]->first; id; id = id->next) {
if (id->lib == lib)
- outliner_add_element(soops, &ten->subtree, id, ten, 0, 0);
+ outliner_add_element(soops, eval_ctx, &ten->subtree, id, ten, 0, 0);
}
}
}
@@ -1401,7 +1448,7 @@ static void outliner_add_library_contents(Main *mainvar, SpaceOops *soops, TreeE
}
-static void outliner_add_orphaned_datablocks(Main *mainvar, SpaceOops *soops)
+static void outliner_add_orphaned_datablocks(Main *mainvar, SpaceOops *soops, const EvaluationContext *eval_ctx)
{
TreeElement *ten;
ListBase *lbarray[MAX_LIBARRAY];
@@ -1424,7 +1471,7 @@ static void outliner_add_orphaned_datablocks(Main *mainvar, SpaceOops *soops)
* - Add a parameter to BKE_idcode_to_name_plural to get a sane "user-visible" name instead?
* - Ensure that this uses nice icons for the datablock type involved instead of the dot?
*/
- ten = outliner_add_element(soops, &soops->tree, lbarray[a], NULL, TSE_ID_BASE, 0);
+ ten = outliner_add_element(soops, eval_ctx, &soops->tree, lbarray[a], NULL, TSE_ID_BASE, 0);
ten->directdata = lbarray[a];
ten->name = BKE_idcode_to_name_plural(GS(id->name));
@@ -1434,7 +1481,7 @@ static void outliner_add_orphaned_datablocks(Main *mainvar, SpaceOops *soops)
/* add the orphaned datablocks - these will not be added with any subtrees attached */
for (id = lbarray[a]->first; id; id = id->next) {
if (ID_REAL_USERS(id) <= 0)
- outliner_add_element(soops, &ten->subtree, id, ten, 0, 0);
+ outliner_add_element(soops, eval_ctx, &ten->subtree, id, ten, 0, 0);
}
}
}
@@ -1480,22 +1527,24 @@ static bool outliner_layer_collections_reorder_poll(
}
static void outliner_add_layer_collections_recursive(
- SpaceOops *soops, ListBase *tree, ID *id, ListBase *layer_collections, TreeElement *parent_ten,
+ SpaceOops *soops, const EvaluationContext *eval_ctx,
+ ListBase *tree, ID *id, ListBase *layer_collections, TreeElement *parent_ten,
const bool show_objects)
{
for (LayerCollection *collection = layer_collections->first; collection; collection = collection->next) {
- TreeElement *ten = outliner_add_element(soops, tree, id, parent_ten, TSE_LAYER_COLLECTION, 0);
+ TreeElement *ten = outliner_add_element(soops, eval_ctx, tree, id, parent_ten, TSE_LAYER_COLLECTION, 0);
ten->name = collection->scene_collection->name;
ten->directdata = collection;
ten->reinsert = outliner_layer_collections_reorder;
ten->reinsert_poll = outliner_layer_collections_reorder_poll;
- outliner_add_layer_collections_recursive(soops, &ten->subtree, id, &collection->layer_collections, ten, show_objects);
+ outliner_add_layer_collections_recursive(
+ soops, eval_ctx, &ten->subtree, id, &collection->layer_collections, ten, show_objects);
if (show_objects) {
for (LinkData *link = collection->object_bases.first; link; link = link->next) {
Base *base = (Base *)link->data;
- TreeElement *te_object = outliner_add_element(soops, &ten->subtree, base->object, ten, 0, 0);
+ TreeElement *te_object = outliner_add_element(soops, eval_ctx, &ten->subtree, base->object, ten, 0, 0);
te_object->directdata = base;
}
}
@@ -1503,10 +1552,13 @@ static void outliner_add_layer_collections_recursive(
}
}
-static void outliner_add_view_layer(SpaceOops *soops, ListBase *tree, TreeElement *parent,
- Scene *scene, ViewLayer *layer, const bool show_objects)
+static void outliner_add_view_layer(
+ SpaceOops *soops, const EvaluationContext *eval_ctx,
+ ListBase *tree, TreeElement *parent,
+ Scene *scene, ViewLayer *layer, const bool show_objects)
{
- outliner_add_layer_collections_recursive(soops, tree, &scene->id, &layer->layer_collections, parent, show_objects);
+ outliner_add_layer_collections_recursive(
+ soops, eval_ctx, tree, &scene->id, &layer->layer_collections, parent, show_objects);
}
static void outliner_scene_collections_reorder(
@@ -1577,35 +1629,40 @@ BLI_INLINE void outliner_add_scene_collection_init(TreeElement *te, SceneCollect
}
BLI_INLINE void outliner_add_scene_collection_objects(
- SpaceOops *soops, ListBase *tree, SceneCollection *collection, TreeElement *parent)
+ SpaceOops *soops, const EvaluationContext *eval_ctx,
+ ListBase *tree, SceneCollection *collection, TreeElement *parent)
{
for (LinkData *link = collection->objects.first; link; link = link->next) {
- outliner_add_element(soops, tree, link->data, parent, 0, 0);
+ outliner_add_element(soops, eval_ctx, tree, link->data, parent, 0, 0);
}
}
static TreeElement *outliner_add_scene_collection_recursive(
- SpaceOops *soops, ListBase *tree, ID *id, SceneCollection *scene_collection, TreeElement *parent_ten)
+ SpaceOops *soops, const EvaluationContext *eval_ctx,
+ ListBase *tree, ID *id, SceneCollection *scene_collection, TreeElement *parent_ten)
{
- TreeElement *ten = outliner_add_element(soops, tree, id, parent_ten, TSE_SCENE_COLLECTION, 0);
+ TreeElement *ten = outliner_add_element(soops, eval_ctx, tree, id, parent_ten, TSE_SCENE_COLLECTION, 0);
outliner_add_scene_collection_init(ten, scene_collection);
- outliner_add_scene_collection_objects(soops, &ten->subtree, scene_collection, ten);
+ outliner_add_scene_collection_objects(soops, eval_ctx, &ten->subtree, scene_collection, ten);
for (SceneCollection *scene_collection_nested = scene_collection->scene_collections.first;
scene_collection_nested != NULL;
scene_collection_nested = scene_collection_nested->next)
{
- outliner_add_scene_collection_recursive(soops, &ten->subtree, id, scene_collection_nested, ten);
+ outliner_add_scene_collection_recursive(
+ soops, eval_ctx, &ten->subtree, id, scene_collection_nested, ten);
}
outliner_make_hierarchy(&ten->subtree);
return ten;
}
-static void outliner_add_collections(SpaceOops *soops, Scene *scene)
+static void outliner_add_collections(
+ SpaceOops *soops, const EvaluationContext *eval_ctx, Scene *scene)
{
SceneCollection *master_collection = BKE_collection_master(&scene->id);
- TreeElement *ten = outliner_add_scene_collection_recursive(soops, &soops->tree, &scene->id, master_collection, NULL);
+ TreeElement *ten = outliner_add_scene_collection_recursive(
+ soops, eval_ctx, &soops->tree, &scene->id, master_collection, NULL);
/* Master Collection should always be expanded. */
TREESTORE(ten)->flag &= ~TSE_CLOSED;
}
@@ -2170,11 +2227,13 @@ static void outliner_filter_tree(SpaceOops *soops, ViewLayer *view_layer)
/* Main entry point for building the tree data-structure that the outliner represents */
// TODO: split each mode into its own function?
-void outliner_build_tree(Main *mainvar, Scene *scene, ViewLayer *view_layer, SpaceOops *soops, ARegion *ar)
+void outliner_build_tree(
+ Main *mainvar, const EvaluationContext *eval_ctx, Scene *scene,
+ ViewLayer *view_layer, SpaceOops *soops, ARegion *ar)
{
TreeElement *te = NULL, *ten;
TreeStoreElem *tselem;
- int show_opened = !soops->treestore || !BLI_mempool_count(soops->treestore); /* on first view, we open scenes */
+ int show_opened = !soops->treestore || !BLI_mempool_len(soops->treestore); /* on first view, we open scenes */
/* Are we looking for something - we want to tag parents to filter child matches
* - NOT in datablocks view - searching all datablocks takes way too long to be useful
@@ -2203,20 +2262,20 @@ void outliner_build_tree(Main *mainvar, Scene *scene, ViewLayer *view_layer, Spa
Library *lib;
/* current file first - mainvar provides tselem with unique pointer - not used */
- ten = outliner_add_element(soops, &soops->tree, mainvar, NULL, TSE_ID_BASE, 0);
+ ten = outliner_add_element(soops, eval_ctx, &soops->tree, mainvar, NULL, TSE_ID_BASE, 0);
ten->name = IFACE_("Current File");
tselem = TREESTORE(ten);
if (!tselem->used)
tselem->flag &= ~TSE_CLOSED;
- outliner_add_library_contents(mainvar, soops, ten, NULL);
+ outliner_add_library_contents(mainvar, soops, eval_ctx, ten, NULL);
for (lib = mainvar->library.first; lib; lib = lib->id.next) {
- ten = outliner_add_element(soops, &soops->tree, lib, NULL, 0, 0);
+ ten = outliner_add_element(soops, eval_ctx, &soops->tree, lib, NULL, 0, 0);
lib->id.newid = (ID *)ten;
- outliner_add_library_contents(mainvar, soops, ten, lib);
+ outliner_add_library_contents(mainvar, soops, eval_ctx, ten, lib);
}
/* make hierarchy */
@@ -2236,8 +2295,8 @@ void outliner_build_tree(Main *mainvar, Scene *scene, ViewLayer *view_layer, Spa
}
else {
/* Else, make a new copy of the libtree for our parent. */
- TreeElement *dupten = outliner_add_element(soops, &par->subtree, lib, NULL, 0, 0);
- outliner_add_library_contents(mainvar, soops, dupten, lib);
+ TreeElement *dupten = outliner_add_element(soops, eval_ctx, &par->subtree, lib, NULL, 0, 0);
+ outliner_add_library_contents(mainvar, soops, eval_ctx, dupten, lib);
dupten->parent = par;
}
}
@@ -2251,7 +2310,7 @@ void outliner_build_tree(Main *mainvar, Scene *scene, ViewLayer *view_layer, Spa
else if (soops->outlinevis == SO_SCENES) {
Scene *sce;
for (sce = mainvar->scene.first; sce; sce = sce->id.next) {
- te = outliner_add_element(soops, &soops->tree, sce, NULL, 0, 0);
+ te = outliner_add_element(soops, eval_ctx, &soops->tree, sce, NULL, 0, 0);
tselem = TREESTORE(te);
if (sce == scene && show_opened) {
@@ -2264,7 +2323,7 @@ void outliner_build_tree(Main *mainvar, Scene *scene, ViewLayer *view_layer, Spa
else if (soops->outlinevis == SO_GROUPS) {
Group *group;
for (group = mainvar->group.first; group; group = group->id.next) {
- te = outliner_add_element(soops, &soops->tree, group, NULL, 0, 0);
+ te = outliner_add_element(soops, eval_ctx, &soops->tree, group, NULL, 0, 0);
outliner_make_hierarchy(&te->subtree);
}
}
@@ -2283,11 +2342,11 @@ void outliner_build_tree(Main *mainvar, Scene *scene, ViewLayer *view_layer, Spa
while (seq) {
op = need_add_seq_dup(seq);
if (op == 1) {
- /* ten = */ outliner_add_element(soops, &soops->tree, (void *)seq, NULL, TSE_SEQUENCE, 0);
+ /* ten = */ outliner_add_element(soops, eval_ctx, &soops->tree, (void *)seq, NULL, TSE_SEQUENCE, 0);
}
else if (op == 0) {
- ten = outliner_add_element(soops, &soops->tree, (void *)seq, NULL, TSE_SEQUENCE_DUP, 0);
- outliner_add_seq_dup(soops, seq, ten, 0);
+ ten = outliner_add_element(soops, eval_ctx, &soops->tree, (void *)seq, NULL, TSE_SEQUENCE_DUP, 0);
+ outliner_add_seq_dup(soops, eval_ctx, seq, ten, 0);
}
seq = seq->next;
}
@@ -2297,7 +2356,7 @@ void outliner_build_tree(Main *mainvar, Scene *scene, ViewLayer *view_layer, Spa
RNA_main_pointer_create(mainvar, &mainptr);
- ten = outliner_add_element(soops, &soops->tree, (void *)&mainptr, NULL, TSE_RNA_STRUCT, -1);
+ ten = outliner_add_element(soops, eval_ctx, &soops->tree, (void *)&mainptr, NULL, TSE_RNA_STRUCT, -1);
if (show_opened) {
tselem = TREESTORE(ten);
@@ -2305,36 +2364,36 @@ void outliner_build_tree(Main *mainvar, Scene *scene, ViewLayer *view_layer, Spa
}
}
else if (soops->outlinevis == SO_ID_ORPHANS) {
- outliner_add_orphaned_datablocks(mainvar, soops);
+ outliner_add_orphaned_datablocks(mainvar, soops, eval_ctx);
}
else if (soops->outlinevis == SO_VIEW_LAYER) {
if ((soops->filter & SO_FILTER_ENABLE) && (soops->filter & SO_FILTER_NO_COLLECTION)) {
for (Base *base = view_layer->object_bases.first; base; base = base->next) {
- TreeElement *te_object = outliner_add_element(soops, &soops->tree, base->object, NULL, 0, 0);
+ TreeElement *te_object = outliner_add_element(soops, eval_ctx, &soops->tree, base->object, NULL, 0, 0);
te_object->directdata = base;
}
outliner_make_hierarchy(&soops->tree);
}
else {
- outliner_add_view_layer(soops, &soops->tree, NULL, scene, view_layer, true);
+ outliner_add_view_layer(soops, eval_ctx, &soops->tree, NULL, scene, view_layer, true);
}
}
else if (soops->outlinevis == SO_COLLECTIONS) {
if ((soops->filter & SO_FILTER_ENABLE) && (soops->filter & SO_FILTER_NO_COLLECTION)) {
FOREACH_SCENE_OBJECT(scene, ob)
{
- outliner_add_element(soops, &soops->tree, ob, NULL, 0, 0);
+ outliner_add_element(soops, eval_ctx, &soops->tree, ob, NULL, 0, 0);
}
FOREACH_SCENE_OBJECT_END
outliner_make_hierarchy(&soops->tree);
}
else {
- outliner_add_collections(soops, scene);
+ outliner_add_collections(soops, eval_ctx, scene);
}
}
else {
if (BASACT(view_layer)) {
- ten = outliner_add_element(soops, &soops->tree, OBACT(view_layer), NULL, 0, 0);
+ ten = outliner_add_element(soops, eval_ctx, &soops->tree, OBACT(view_layer), NULL, 0, 0);
ten->directdata = BASACT(view_layer);
}
}
diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c
index 04dbab0b853..db0593ef2d1 100644
--- a/source/blender/editors/space_sequencer/sequencer_draw.c
+++ b/source/blender/editors/space_sequencer/sequencer_draw.c
@@ -330,7 +330,7 @@ static void drawmeta_contents(Scene *scene, Sequence *seqm, float x1, float y1,
}
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
for (seq = seqbase->first; seq; seq = seq->next) {
chan_min = min_ii(chan_min, seq->machine);
@@ -435,7 +435,7 @@ static void draw_seq_handle(View2D *v2d, Sequence *seq, const float handsize_cla
{
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
if (seq->flag & whichsel) {
immUniformColor4ub(0, 0, 0, 80);
@@ -620,7 +620,7 @@ static void draw_sequence_extensions(Scene *scene, ARegion *ar, Sequence *seq, u
if (seq->startofs || seq->endofs) {
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
color3ubv_from_seq(scene, seq, col);
@@ -664,7 +664,7 @@ static void draw_sequence_extensions(Scene *scene, ARegion *ar, Sequence *seq, u
if (seq->startstill || seq->endstill) {
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
color3ubv_from_seq(scene, seq, col);
UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.5f, 60);
@@ -730,7 +730,7 @@ static void draw_seq_strip(const bContext *C, SpaceSeq *sseq, Scene *scene, AReg
background_col[3] = 128;
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
}
else {
background_col[3] = 255;
@@ -842,7 +842,7 @@ static void draw_seq_strip(const bContext *C, SpaceSeq *sseq, Scene *scene, AReg
col[3] = 96;
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
immUniformColor4ubv(col);
}
@@ -1226,7 +1226,7 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
if (sseq->mainb == SEQ_DRAW_IMG_IMBUF && sseq->flag & SEQ_USE_ALPHA) {
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
}
/* Format needs to be created prior to any immBindProgram call.
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index cb0c5bd3717..e1163fd3207 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -2785,7 +2785,7 @@ static int sequencer_view_zoom_ratio_exec(bContext *C, wmOperator *op)
float facx = BLI_rcti_size_x(&v2d->mask) / winx;
float facy = BLI_rcti_size_y(&v2d->mask) / winy;
- BLI_rctf_resize(&v2d->cur, floorf(winx * facx / ratio + 0.5f), floorf(winy * facy / ratio + 0.5f));
+ BLI_rctf_resize(&v2d->cur, ceilf(winx * facx / ratio + 0.5f), ceilf(winy * facy / ratio + 0.5f));
ED_region_tag_redraw(CTX_wm_region(C));
diff --git a/source/blender/editors/space_text/text_draw.c b/source/blender/editors/space_text/text_draw.c
index 62fde49cade..3949aa928c9 100644
--- a/source/blender/editors/space_text/text_draw.c
+++ b/source/blender/editors/space_text/text_draw.c
@@ -1207,7 +1207,7 @@ static void draw_text_decoration(SpaceText *st, ARegion *ar)
immUniformColor4ub(255, 255, 255, 32);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
immRecti(pos, x1 - 4, y1, x2, y2);
glDisable(GL_BLEND);
diff --git a/source/blender/editors/space_time/space_time.c b/source/blender/editors/space_time/space_time.c
index 283dbf3b4e2..9a736ae977f 100644
--- a/source/blender/editors/space_time/space_time.c
+++ b/source/blender/editors/space_time/space_time.c
@@ -83,7 +83,7 @@ static void time_draw_sfra_efra(Scene *scene, View2D *v2d)
/* draw darkened area outside of active timeline
* frame range used is preview range or scene range
*/
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
Gwn_VertFormat *format = immVertexFormat();
@@ -402,6 +402,7 @@ static void time_draw_caches_keyframes(Main *bmain, ViewLayer *view_layer, View2
/* draw keyframe lines for timeline */
static void time_draw_keyframes(const bContext *C, ARegion *ar)
{
+ WorkSpace *workspace = CTX_wm_workspace(C);
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *ob = CTX_data_active_object(C);
@@ -443,7 +444,7 @@ static void time_draw_keyframes(const bContext *C, ARegion *ar)
*/
UI_GetThemeColor3ubv(TH_TIME_KEYFRAME, color);
- if (ob && ((ob->mode == OB_MODE_POSE) || onlysel)) {
+ if (ob && ((workspace->object_mode == OB_MODE_POSE) || onlysel)) {
/* draw keyframes for active object only */
time_draw_idblock_keyframes(v2d, (ID *)ob, onlysel, color);
}
diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c
index 77cd64be7c1..f0adf307bda 100644
--- a/source/blender/editors/space_view3d/drawarmature.c
+++ b/source/blender/editors/space_view3d/drawarmature.c
@@ -2667,8 +2667,10 @@ static void ghost_poses_tag_unselected(Object *ob, short unset)
* note: object should be in posemode
*/
static void draw_ghost_poses_range(
- const EvaluationContext *eval_ctx, Scene *scene, ViewLayer *view_layer, View3D *v3d, ARegion *ar, Base *base)
+ const EvaluationContext *eval_ctx_init,
+ Scene *scene, ViewLayer *view_layer, View3D *v3d, ARegion *ar, Base *base)
{
+ EvaluationContext eval_ctx = *eval_ctx_init;
Object *ob = base->object;
AnimData *adt = BKE_animdata_from_id(&ob->id);
bArmature *arm = ob->data;
@@ -2690,7 +2692,7 @@ static void draw_ghost_poses_range(
range = (float)(end - start);
/* store values */
- ob->mode &= ~OB_MODE_POSE;
+ eval_ctx.object_mode &= ~OB_MODE_POSE;
cfrao = CFRA;
flago = arm->flag;
arm->flag &= ~(ARM_DRAWNAMES | ARM_DRAWAXES);
@@ -2711,8 +2713,8 @@ static void draw_ghost_poses_range(
UI_GetThemeColorShadeAlpha4ubv(TH_WIRE, 0, -128 - (int)(120.0f * sqrtf(colfac)), col);
BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
- BKE_pose_where_is(eval_ctx, scene, ob);
- draw_pose_bones(eval_ctx, scene, view_layer, v3d, ar, base, OB_WIRE, col, true, false);
+ BKE_pose_where_is(&eval_ctx, scene, ob);
+ draw_pose_bones(&eval_ctx, scene, view_layer, v3d, ar, base, OB_WIRE, col, true, false);
}
glDisable(GL_BLEND);
if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
@@ -2728,16 +2730,17 @@ static void draw_ghost_poses_range(
CFRA = cfrao;
ob->pose = poseo;
arm->flag = flago;
- ob->mode |= OB_MODE_POSE;
+ eval_ctx.object_mode |= OB_MODE_POSE;
}
/* draw ghosts on keyframes in action within range
* - object should be in posemode
*/
static void draw_ghost_poses_keys(
- const struct EvaluationContext *eval_ctx, Scene *scene, ViewLayer *view_layer,
+ const struct EvaluationContext *eval_ctx_init, Scene *scene, ViewLayer *view_layer,
View3D *v3d, ARegion *ar, Base *base)
{
+ EvaluationContext eval_ctx = *eval_ctx_init;
Object *ob = base->object;
AnimData *adt = BKE_animdata_from_id(&ob->id);
bAction *act = (adt) ? adt->action : NULL;
@@ -2771,7 +2774,7 @@ static void draw_ghost_poses_keys(
if (range == 0) return;
/* store values */
- ob->mode &= ~OB_MODE_POSE;
+ eval_ctx.object_mode &= ~OB_MODE_POSE;
cfrao = CFRA;
flago = arm->flag;
arm->flag &= ~(ARM_DRAWNAMES | ARM_DRAWAXES);
@@ -2794,8 +2797,8 @@ static void draw_ghost_poses_keys(
CFRA = (int)ak->cfra;
BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
- BKE_pose_where_is(eval_ctx, scene, ob);
- draw_pose_bones(eval_ctx, scene, view_layer, v3d, ar, base, OB_WIRE, col, true, false);
+ BKE_pose_where_is(&eval_ctx, scene, ob);
+ draw_pose_bones(&eval_ctx, scene, view_layer, v3d, ar, base, OB_WIRE, col, true, false);
}
glDisable(GL_BLEND);
if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
@@ -2812,16 +2815,17 @@ static void draw_ghost_poses_keys(
CFRA = cfrao;
ob->pose = poseo;
arm->flag = flago;
- ob->mode |= OB_MODE_POSE;
+ eval_ctx.object_mode |= OB_MODE_POSE;
}
/* draw ghosts around current frame
* - object is supposed to be armature in posemode
*/
static void draw_ghost_poses(
- const struct EvaluationContext *eval_ctx, Scene *scene, ViewLayer *view_layer,
+ const struct EvaluationContext *eval_ctx_init, Scene *scene, ViewLayer *view_layer,
View3D *v3d, ARegion *ar, Base *base)
{
+ EvaluationContext eval_ctx = *eval_ctx_init;
Object *ob = base->object;
AnimData *adt = BKE_animdata_from_id(&ob->id);
bArmature *arm = ob->data;
@@ -2846,7 +2850,7 @@ static void draw_ghost_poses(
range = (float)(arm->ghostep) * stepsize + 0.5f; /* plus half to make the for loop end correct */
/* store values */
- ob->mode &= ~OB_MODE_POSE;
+ eval_ctx.object_mode &= ~OB_MODE_POSE;
cfrao = CFRA;
actframe = BKE_nla_tweakedit_remap(adt, (float)CFRA, 0);
flago = arm->flag;
@@ -2874,8 +2878,8 @@ static void draw_ghost_poses(
if (CFRA != cfrao) {
BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
- BKE_pose_where_is(eval_ctx, scene, ob);
- draw_pose_bones(eval_ctx, scene, view_layer, v3d, ar, base, OB_WIRE, col, true, false);
+ BKE_pose_where_is(&eval_ctx, scene, ob);
+ draw_pose_bones(&eval_ctx, scene, view_layer, v3d, ar, base, OB_WIRE, col, true, false);
}
}
@@ -2889,8 +2893,8 @@ static void draw_ghost_poses(
if (CFRA != cfrao) {
BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
- BKE_pose_where_is(eval_ctx, scene, ob);
- draw_pose_bones(eval_ctx, scene, view_layer, v3d, ar, base, OB_WIRE, col, true, false);
+ BKE_pose_where_is(&eval_ctx, scene, ob);
+ draw_pose_bones(&eval_ctx, scene, view_layer, v3d, ar, base, OB_WIRE, col, true, false);
}
}
}
@@ -2908,7 +2912,7 @@ static void draw_ghost_poses(
CFRA = cfrao;
ob->pose = poseo;
arm->flag = flago;
- ob->mode |= OB_MODE_POSE;
+ eval_ctx.object_mode |= OB_MODE_POSE;
}
/* ********************************** Armature Drawing - Main ************************* */
@@ -2970,11 +2974,11 @@ bool draw_armature(
}
else
#endif
- if (ob->mode & OB_MODE_POSE) {
+ if (eval_ctx->object_mode & OB_MODE_POSE) {
arm->flag |= ARM_POSEMODE;
}
}
- else if (ob->mode & OB_MODE_POSE) {
+ else if (eval_ctx->object_mode & OB_MODE_POSE) {
if (arm->ghosttype == ARM_GHOST_RANGE) {
draw_ghost_poses_range(eval_ctx, scene, view_layer, v3d, ar, base);
}
@@ -2988,7 +2992,7 @@ bool draw_armature(
if ((dflag & DRAW_SCENESET) == 0) {
if (ob == OBACT(view_layer))
arm->flag |= ARM_POSEMODE;
- else if (OBACT(view_layer) && (OBACT(view_layer)->mode & OB_MODE_WEIGHT_PAINT)) {
+ else if (OBACT(view_layer) && (eval_ctx->object_mode & OB_MODE_WEIGHT_PAINT)) {
if (ob == modifiers_isDeformedByArmature(OBACT(view_layer)))
arm->flag |= ARM_POSEMODE;
}
diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c
index f8f2d5598de..c014c2b12a0 100644
--- a/source/blender/editors/space_view3d/drawmesh.c
+++ b/source/blender/editors/space_view3d/drawmesh.c
@@ -59,6 +59,8 @@
#include "UI_resources.h"
+#include "DEG_depsgraph.h"
+
#include "GPU_draw.h"
#include "GPU_material.h"
#include "GPU_basic_shader.h"
@@ -177,7 +179,7 @@ void draw_mesh_face_select(RegionView3D *rv3d, Mesh *me, DerivedMesh *dm, bool d
/* Draw Selected Faces */
if (me->drawflag & ME_DRAWFACES) {
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
/* dull unselected faces so as not to get in the way of seeing color */
glColor4ub(96, 96, 96, 64);
dm->drawMappedFaces(dm, draw_mesh_face_select__drawFaceOptsInv, NULL, NULL, (void *)me, DM_DRAW_SKIP_HIDDEN);
@@ -325,8 +327,10 @@ void draw_mesh_paint_weight_edges(RegionView3D *rv3d, DerivedMesh *dm,
}
}
-void draw_mesh_paint(View3D *v3d, RegionView3D *rv3d,
- Object *ob, DerivedMesh *dm, const int draw_flags)
+void draw_mesh_paint(
+ const EvaluationContext *eval_ctx,
+ View3D *v3d, RegionView3D *rv3d,
+ Object *ob, DerivedMesh *dm, const int draw_flags)
{
DMSetDrawOptions facemask = NULL;
Mesh *me = ob->data;
@@ -336,21 +340,21 @@ void draw_mesh_paint(View3D *v3d, RegionView3D *rv3d,
if (me->editflag & (ME_EDIT_PAINT_VERT_SEL | ME_EDIT_PAINT_FACE_SEL))
facemask = wpaint__setSolidDrawOptions_facemask;
- if (ob->mode & OB_MODE_WEIGHT_PAINT) {
+ if (eval_ctx->object_mode & OB_MODE_WEIGHT_PAINT) {
draw_mesh_paint_weight_faces(dm, use_light, facemask, me);
}
- else if (ob->mode & OB_MODE_VERTEX_PAINT) {
+ else if (eval_ctx->object_mode & OB_MODE_VERTEX_PAINT) {
draw_mesh_paint_vcolor_faces(dm, use_light, facemask, me, me);
}
/* draw face selection on top */
if (draw_flags & DRAW_FACE_SELECT) {
- bool draw_select_edges = (ob->mode & OB_MODE_TEXTURE_PAINT) == 0;
+ bool draw_select_edges = (eval_ctx->object_mode & OB_MODE_TEXTURE_PAINT) == 0;
draw_mesh_face_select(rv3d, me, dm, draw_select_edges);
}
else if ((use_light == false) || (ob->dtx & OB_DRAWWIRE)) {
- const bool use_depth = (v3d->flag & V3D_ZBUF_SELECT) || !(ob->mode & OB_MODE_WEIGHT_PAINT);
- const bool use_alpha = (ob->mode & OB_MODE_VERTEX_PAINT) == 0;
+ const bool use_depth = (v3d->flag & V3D_ZBUF_SELECT) || !(eval_ctx->object_mode & OB_MODE_WEIGHT_PAINT);
+ const bool use_alpha = (eval_ctx->object_mode & OB_MODE_VERTEX_PAINT) == 0;
if (use_alpha == false) {
set_inverted_drawing(1);
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index 51dc56bafaf..75c217c4f0c 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -314,13 +314,15 @@ static bool check_ob_drawface_dot(Scene *sce, View3D *vd, char dt)
/* check for glsl drawing */
-bool draw_glsl_material(Scene *scene, ViewLayer *view_layer, Object *ob, View3D *v3d, const char dt)
+bool draw_glsl_material(
+ const EvaluationContext *eval_ctx, Scene *scene, ViewLayer *view_layer,
+ Object *ob, View3D *v3d, const char dt)
{
if (G.f & G_PICKSEL)
return false;
if (!check_object_draw_texture(scene, v3d, dt))
return false;
- if (ob == OBACT(view_layer) && (ob && ob->mode & OB_MODE_WEIGHT_PAINT))
+ if (ob == OBACT(view_layer) && (ob && eval_ctx->object_mode & OB_MODE_WEIGHT_PAINT))
return false;
if (v3d->flag2 & V3D_SHOW_SOLID_MATCAP)
@@ -334,7 +336,7 @@ bool draw_glsl_material(Scene *scene, ViewLayer *view_layer, Object *ob, View3D
return false;
}
-static bool check_alpha_pass(Base *base)
+static bool check_alpha_pass(const EvaluationContext *eval_ctx, Base *base)
{
if (base->flag_legacy & OB_FROMDUPLI)
return false;
@@ -342,8 +344,9 @@ static bool check_alpha_pass(Base *base)
if (G.f & G_PICKSEL)
return false;
- if (base->object->mode & OB_MODE_ALL_PAINT)
+ if (eval_ctx->object_mode & OB_MODE_ALL_PAINT) {
return false;
+ }
return (base->object->dtx & OB_DRAWTRANSP);
}
@@ -727,7 +730,7 @@ static void draw_empty_image(Object *ob, const short dflag, const unsigned char
if (use_blend) {
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
}
Gwn_VertFormat *format = immVertexFormat();
@@ -777,7 +780,7 @@ static void draw_empty_image(Object *ob, const short dflag, const unsigned char
if (!use_blend) {
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
}
imm_draw_box_wire_2d(pos, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
@@ -1184,7 +1187,7 @@ static void draw_transp_spot_volume(Lamp *la, float x, float z, unsigned pos)
draw_spot_cone(la, x, z, pos);
/* restore state */
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_BLEND);
glDepthMask(GL_TRUE);
glDisable(GL_CULL_FACE);
@@ -1228,7 +1231,7 @@ static void draw_transp_sun_volume(Lamp *la, unsigned pos)
imm_draw_box(box, true, pos);
/* restore state */
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_BLEND);
glDepthMask(GL_TRUE);
glDisable(GL_CULL_FACE);
@@ -1324,7 +1327,7 @@ void drawlamp(View3D *v3d, RegionView3D *rv3d, Base *base,
GPU_enable_program_point_size();
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
immBindBuiltinProgram(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA);
immUniform1f("size", lampdot_size);
@@ -3892,8 +3895,9 @@ static DMDrawOption draw_em_fancy__setGLSLFaceOpts(void *userData, int index)
}
}
-static void draw_em_fancy(Scene *scene, ViewLayer *view_layer, ARegion *ar, View3D *v3d,
- Object *ob, BMEditMesh *em, DerivedMesh *cageDM, DerivedMesh *finalDM, const char dt)
+static void draw_em_fancy(
+ const EvaluationContext *eval_ctx, Scene *scene, ViewLayer *view_layer, ARegion *ar, View3D *v3d,
+ Object *ob, BMEditMesh *em, DerivedMesh *cageDM, DerivedMesh *finalDM, const char dt)
{
RegionView3D *rv3d = ar->regiondata;
@@ -3930,7 +3934,7 @@ static void draw_em_fancy(Scene *scene, ViewLayer *view_layer, ARegion *ar, View
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
}
else if (check_object_draw_texture(scene, v3d, dt)) {
- if (draw_glsl_material(scene, view_layer, ob, v3d, dt)) {
+ if (draw_glsl_material(eval_ctx, scene, view_layer, ob, v3d, dt)) {
glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
finalDM->drawMappedFacesGLSL(finalDM, GPU_object_material_bind,
@@ -4223,10 +4227,12 @@ static void draw_em_fancy_new(Scene *UNUSED(scene), ARegion *UNUSED(ar), View3D
/* Mesh drawing routines */
-void draw_mesh_object_outline(View3D *v3d, Object *ob, DerivedMesh *dm, const unsigned char ob_wire_col[4]) /* LEGACY */
+void draw_mesh_object_outline(
+ const EvaluationContext *eval_ctx, View3D *v3d,
+ Object *ob, DerivedMesh *dm, const unsigned char ob_wire_col[4]) /* LEGACY */
{
if ((v3d->transp == false) && /* not when we draw the transparent pass */
- (ob->mode & OB_MODE_ALL_PAINT) == false) /* not when painting (its distracting) - campbell */
+ (eval_ctx->object_mode & OB_MODE_ALL_PAINT) == false) /* not when painting (its distracting) - campbell */
{
glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f);
glDepthMask(GL_FALSE);
@@ -4249,10 +4255,12 @@ void draw_mesh_object_outline(View3D *v3d, Object *ob, DerivedMesh *dm, const un
}
}
-static void draw_mesh_object_outline_new(View3D *v3d, RegionView3D *rv3d, Object *ob, Mesh *me, const bool is_active)
+static void draw_mesh_object_outline_new(
+ const EvaluationContext *eval_ctx, View3D *v3d, RegionView3D *rv3d,
+ Mesh *me, const bool is_active)
{
if ((v3d->transp == false) && /* not when we draw the transparent pass */
- (ob->mode & OB_MODE_ALL_PAINT) == false) /* not when painting (its distracting) - campbell */
+ (eval_ctx->object_mode & OB_MODE_ALL_PAINT) == false) /* not when painting (its distracting) - campbell */
{
glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f);
glDepthMask(GL_FALSE);
@@ -4302,7 +4310,9 @@ static void draw_mesh_fancy(
const char dt, const unsigned char ob_wire_col[4], const short dflag)
{
#ifdef WITH_GAMEENGINE
- Object *ob = (rv3d->rflag & RV3D_IS_GAME_ENGINE) ? BKE_object_lod_meshob_get(base->object, view_layer) : base->object;
+ Object *ob = (
+ (rv3d->rflag & RV3D_IS_GAME_ENGINE) ?
+ BKE_object_lod_meshob_get(base->object, view_layer, eval_ctx->object_mode) : base->object);
#else
Object *ob = base->object;
#endif
@@ -4311,7 +4321,7 @@ static void draw_mesh_fancy(
bool /* no_verts,*/ no_edges, no_faces;
DerivedMesh *dm = mesh_get_derived_final(eval_ctx, scene, ob, scene->customdata_mask);
const bool is_obact = (ob == OBACT(view_layer));
- int draw_flags = (is_obact && BKE_paint_select_face_test(ob)) ? DRAW_FACE_SELECT : 0;
+ int draw_flags = (is_obact && BKE_paint_select_face_test(ob, eval_ctx->object_mode)) ? DRAW_FACE_SELECT : 0;
if (!dm)
return;
@@ -4349,7 +4359,7 @@ static void draw_mesh_fancy(
draw_bounding_volume(ob, ob->boundtype, ob_wire_col);
}
else if ((no_faces && no_edges) ||
- ((!is_obact || (ob->mode == OB_MODE_OBJECT)) && object_is_halo(scene, ob)))
+ ((!is_obact || (eval_ctx->object_mode == OB_MODE_OBJECT)) && object_is_halo(scene, ob)))
{
glPointSize(1.5f);
dm->drawVerts(dm);
@@ -4357,7 +4367,7 @@ static void draw_mesh_fancy(
else if ((dt == OB_WIRE) || no_faces) {
draw_wire = OBDRAW_WIRE_ON; /* draw wire only, no depth buffer stuff */
}
- else if (((is_obact && ob->mode & OB_MODE_TEXTURE_PAINT)) ||
+ else if (((is_obact && eval_ctx->object_mode & OB_MODE_TEXTURE_PAINT)) ||
check_object_draw_texture(scene, v3d, dt))
{
bool draw_loose = true;
@@ -4368,15 +4378,17 @@ static void draw_mesh_fancy(
!(G.f & G_PICKSEL || (draw_flags & DRAW_FACE_SELECT)) &&
(draw_wire == OBDRAW_WIRE_OFF))
{
- draw_mesh_object_outline(v3d, ob, dm, ob_wire_col);
+ draw_mesh_object_outline(eval_ctx, v3d, ob, dm, ob_wire_col);
}
- if (draw_glsl_material(scene, view_layer, ob, v3d, dt) && !(draw_flags & DRAW_MODIFIERS_PREVIEW)) {
+ if (draw_glsl_material(eval_ctx, scene, view_layer, ob, v3d, dt) && !(draw_flags & DRAW_MODIFIERS_PREVIEW)) {
Paint *p;
glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
- if ((v3d->flag2 & V3D_SHOW_SOLID_MATCAP) && ob->sculpt && (p = BKE_paint_get_active(scene, view_layer))) {
+ if ((v3d->flag2 & V3D_SHOW_SOLID_MATCAP) && ob->sculpt &&
+ (p = BKE_paint_get_active(scene, view_layer, eval_ctx->object_mode)))
+ {
GPUVertexAttribs gattribs;
float planes[4][4];
float (*fpl)[4] = NULL;
@@ -4439,7 +4451,7 @@ static void draw_mesh_fancy(
(draw_wire == OBDRAW_WIRE_OFF) &&
(ob->sculpt == NULL))
{
- draw_mesh_object_outline(v3d, ob, dm, ob_wire_col);
+ draw_mesh_object_outline(eval_ctx, v3d, ob, dm, ob_wire_col);
}
/* materials arent compatible with vertex colors */
@@ -4463,12 +4475,12 @@ static void draw_mesh_fancy(
(draw_wire == OBDRAW_WIRE_OFF) &&
(ob->sculpt == NULL))
{
- draw_mesh_object_outline(v3d, ob, dm, ob_wire_col);
+ draw_mesh_object_outline(eval_ctx, v3d, ob, dm, ob_wire_col);
}
glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
- if (ob->sculpt && (p = BKE_paint_get_active(scene, view_layer))) {
+ if (ob->sculpt && (p = BKE_paint_get_active(scene, view_layer, eval_ctx->object_mode))) {
float planes[4][4];
float (*fpl)[4] = NULL;
const bool fast = (p->flags & PAINT_FAST_NAVIGATE) && (rv3d->rflag & RV3D_NAVIGATING);
@@ -4500,7 +4512,7 @@ static void draw_mesh_fancy(
}
}
else if (dt == OB_PAINT) {
- draw_mesh_paint(v3d, rv3d, ob, dm, draw_flags);
+ draw_mesh_paint(eval_ctx, v3d, rv3d, ob, dm, draw_flags);
/* since we already draw wire as wp guide, don't draw over the top */
draw_wire = OBDRAW_WIRE_OFF;
@@ -4515,7 +4527,7 @@ static void draw_mesh_fancy(
* with the background. */
if ((dflag & DRAW_CONSTCOLOR) == 0) {
- if (is_obact && (ob->mode & OB_MODE_PARTICLE_EDIT)) {
+ if (is_obact && (eval_ctx->object_mode & OB_MODE_PARTICLE_EDIT)) {
float color[3];
ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.15f, color);
glColor3fv(color);
@@ -4548,7 +4560,7 @@ static void draw_mesh_fancy(
}
}
- if (is_obact && BKE_paint_select_vert_test(ob)) {
+ if (is_obact && BKE_paint_select_vert_test(ob, eval_ctx->object_mode)) {
const bool use_depth = (v3d->flag & V3D_ZBUF_SELECT) != 0;
glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE));
@@ -4567,7 +4579,7 @@ static bool draw_mesh_object(
const char dt, const unsigned char ob_wire_col[4], const short dflag)
{
Object *ob = base->object;
- Object *obedit = scene->obedit;
+ Object *obedit = OBEDIT_FROM_EVAL_CTX(eval_ctx);
Mesh *me = ob->data;
BMEditMesh *em = me->edit_btmesh;
bool do_alpha_after = false, drawlinked = false, retval = false;
@@ -4617,13 +4629,13 @@ static bool draw_mesh_object(
if (use_material) {
if (dt > OB_WIRE) {
- const bool glsl = draw_glsl_material(scene, view_layer, ob, v3d, dt);
+ const bool glsl = draw_glsl_material(eval_ctx, scene, view_layer, ob, v3d, dt);
- GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, glsl, NULL);
+ GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, glsl, eval_ctx->object_mode, NULL);
}
}
- draw_em_fancy(scene, view_layer, ar, v3d, ob, em, cageDM, finalDM, dt);
+ draw_em_fancy(eval_ctx, scene, view_layer, ar, v3d, ob, em, cageDM, finalDM, dt);
if (use_material) {
GPU_end_object_materials();
@@ -4636,12 +4648,13 @@ static bool draw_mesh_object(
/* ob->bb was set by derived mesh system, do NULL check just to be sure */
if (me->totpoly <= 4 || (!ob->bb || ED_view3d_boundbox_clip(rv3d, ob->bb))) {
if (dt > OB_WIRE) {
- const bool glsl = draw_glsl_material(scene, view_layer, ob, v3d, dt);
+ const bool glsl = draw_glsl_material(eval_ctx, scene, view_layer, ob, v3d, dt);
if (dt == OB_SOLID || glsl) {
- const bool check_alpha = check_alpha_pass(base);
- GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, glsl,
- (check_alpha) ? &do_alpha_after : NULL);
+ const bool check_alpha = check_alpha_pass(eval_ctx, base);
+ GPU_begin_object_materials(
+ v3d, rv3d, scene, view_layer, ob,
+ glsl, eval_ctx->object_mode, (check_alpha) ? &do_alpha_after : NULL);
}
}
@@ -4707,8 +4720,10 @@ static void make_color_variations(const unsigned char base_ubyte[4], float low[4
high[3] = base[3];
}
-static void draw_mesh_fancy_new(EvaluationContext *eval_ctx, Scene *scene, ViewLayer *view_layer, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base,
- const char dt, const unsigned char ob_wire_col[4], const short dflag, const bool other_obedit)
+static void draw_mesh_fancy_new(
+ const EvaluationContext *eval_ctx, Scene *scene, ViewLayer *view_layer,
+ ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base,
+ const char dt, const unsigned char ob_wire_col[4], const short dflag, const bool other_obedit)
{
if (dflag & (DRAW_PICKING | DRAW_CONSTCOLOR)) {
/* too complicated! use existing methods */
@@ -4718,7 +4733,9 @@ static void draw_mesh_fancy_new(EvaluationContext *eval_ctx, Scene *scene, ViewL
}
#ifdef WITH_GAMEENGINE
- Object *ob = (rv3d->rflag & RV3D_IS_GAME_ENGINE) ? BKE_object_lod_meshob_get(base->object, view_layer) : base->object;
+ Object *ob = (
+ (rv3d->rflag & RV3D_IS_GAME_ENGINE) ?
+ BKE_object_lod_meshob_get(base->object, view_layer, eval_ctx->object_mode) : base->object);
#else
Object *ob = base->object;
#endif
@@ -4727,7 +4744,7 @@ static void draw_mesh_fancy_new(EvaluationContext *eval_ctx, Scene *scene, ViewL
bool no_edges, no_faces;
DerivedMesh *dm = mesh_get_derived_final(eval_ctx, scene, ob, scene->customdata_mask);
const bool is_obact = (ob == OBACT(view_layer));
- int draw_flags = (is_obact && BKE_paint_select_face_test(ob)) ? DRAW_FACE_SELECT : 0;
+ int draw_flags = (is_obact && BKE_paint_select_face_test(ob, eval_ctx->object_mode)) ? DRAW_FACE_SELECT : 0;
if (!dm)
return;
@@ -4770,7 +4787,7 @@ static void draw_mesh_fancy_new(EvaluationContext *eval_ctx, Scene *scene, ViewL
draw_bounding_volume(ob, ob->boundtype, ob_wire_col);
}
else if ((no_faces && no_edges) ||
- ((!is_obact || (ob->mode == OB_MODE_OBJECT)) && object_is_halo(scene, ob)))
+ ((!is_obact || (eval_ctx->object_mode == OB_MODE_OBJECT)) && object_is_halo(scene, ob)))
{
glPointSize(1.5f);
// dm->drawVerts(dm);
@@ -4836,7 +4853,7 @@ static void draw_mesh_fancy_new(EvaluationContext *eval_ctx, Scene *scene, ViewL
GWN_batch_draw(batch);
#endif
}
- else if (((is_obact && ob->mode & OB_MODE_TEXTURE_PAINT)) ||
+ else if (((is_obact && eval_ctx->object_mode & OB_MODE_TEXTURE_PAINT)) ||
check_object_draw_texture(scene, v3d, dt))
{
bool draw_loose = true;
@@ -4847,15 +4864,17 @@ static void draw_mesh_fancy_new(EvaluationContext *eval_ctx, Scene *scene, ViewL
!(G.f & G_PICKSEL || (draw_flags & DRAW_FACE_SELECT)) &&
(draw_wire == OBDRAW_WIRE_OFF))
{
- draw_mesh_object_outline_new(v3d, rv3d, ob, me, (ob == OBACT(view_layer)));
+ draw_mesh_object_outline_new(eval_ctx, v3d, rv3d, me, (ob == OBACT(view_layer)));
}
- if (draw_glsl_material(scene, view_layer, ob, v3d, dt) && !(draw_flags & DRAW_MODIFIERS_PREVIEW)) {
+ if (draw_glsl_material(eval_ctx, scene, view_layer, ob, v3d, dt) && !(draw_flags & DRAW_MODIFIERS_PREVIEW)) {
Paint *p;
glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
- if ((v3d->flag2 & V3D_SHOW_SOLID_MATCAP) && ob->sculpt && (p = BKE_paint_get_active(scene, view_layer))) {
+ if ((v3d->flag2 & V3D_SHOW_SOLID_MATCAP) && ob->sculpt &&
+ (p = BKE_paint_get_active(scene, view_layer, eval_ctx->object_mode)))
+ {
GPUVertexAttribs gattribs;
float planes[4][4];
float (*fpl)[4] = NULL;
@@ -4914,7 +4933,7 @@ static void draw_mesh_fancy_new(EvaluationContext *eval_ctx, Scene *scene, ViewL
(draw_wire == OBDRAW_WIRE_OFF) &&
(ob->sculpt == NULL))
{
- draw_mesh_object_outline_new(v3d, rv3d, ob, me, (ob == OBACT(view_layer)));
+ draw_mesh_object_outline_new(eval_ctx, v3d, rv3d, me, (ob == OBACT(view_layer)));
}
/* materials arent compatible with vertex colors */
@@ -4939,12 +4958,12 @@ static void draw_mesh_fancy_new(EvaluationContext *eval_ctx, Scene *scene, ViewL
(ob->sculpt == NULL))
{
/* TODO: move this into a separate pass */
- draw_mesh_object_outline_new(v3d, rv3d, ob, me, (ob == OBACT(view_layer)));
+ draw_mesh_object_outline_new(eval_ctx, v3d, rv3d, me, (ob == OBACT(view_layer)));
}
glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
- if (ob->sculpt && (p = BKE_paint_get_active(scene, view_layer))) {
+ if (ob->sculpt && (p = BKE_paint_get_active(scene, view_layer, eval_ctx->object_mode))) {
float planes[4][4];
float (*fpl)[4] = NULL;
const bool fast = (p->flags & PAINT_FAST_NAVIGATE) && (rv3d->rflag & RV3D_NAVIGATING);
@@ -4976,7 +4995,7 @@ static void draw_mesh_fancy_new(EvaluationContext *eval_ctx, Scene *scene, ViewL
}
}
else if (dt == OB_PAINT) {
- draw_mesh_paint(v3d, rv3d, ob, dm, draw_flags);
+ draw_mesh_paint(eval_ctx, v3d, rv3d, ob, dm, draw_flags);
/* since we already draw wire as wp guide, don't draw over the top */
draw_wire = OBDRAW_WIRE_OFF;
@@ -5025,22 +5044,20 @@ static void draw_mesh_fancy_new(EvaluationContext *eval_ctx, Scene *scene, ViewL
dm->release(dm);
}
-static bool UNUSED_FUNCTION(draw_mesh_object_new)(const bContext *C, Scene *scene, ViewLayer *view_layer, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base,
- const char dt, const unsigned char ob_wire_col[4], const short dflag)
+static bool UNUSED_FUNCTION(draw_mesh_object_new)(
+ const EvaluationContext *eval_ctx, Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base,
+ const char dt, const unsigned char ob_wire_col[4], const short dflag)
{
- EvaluationContext eval_ctx;
Object *ob = base->object;
- Object *obedit = scene->obedit;
Mesh *me = ob->data;
BMEditMesh *em = me->edit_btmesh;
bool do_alpha_after = false, drawlinked = false, retval = false;
- CTX_data_eval_ctx(C, &eval_ctx);
-
if (v3d->flag2 & V3D_RENDER_SHADOW) {
/* TODO: handle shadow pass separately */
return true;
}
+ Object *obedit = OBEDIT_FROM_EVAL_CTX(eval_ctx);
if (obedit && ob != obedit && ob->data == obedit->data) {
if (BKE_key_from_object(ob) || BKE_key_from_object(obedit)) {}
@@ -5066,7 +5083,7 @@ static bool UNUSED_FUNCTION(draw_mesh_object_new)(const bContext *C, Scene *scen
}
else {
cageDM = editbmesh_get_derived_cage_and_final(
- &eval_ctx, scene, ob, em, scene->customdata_mask,
+ eval_ctx, scene, ob, em, scene->customdata_mask,
&finalDM);
}
@@ -5085,9 +5102,9 @@ static bool UNUSED_FUNCTION(draw_mesh_object_new)(const bContext *C, Scene *scen
DM_update_materials(cageDM, ob);
}
- const bool glsl = draw_glsl_material(scene, view_layer, ob, v3d, dt);
+ const bool glsl = draw_glsl_material(eval_ctx, scene, eval_ctx->view_layer, ob, v3d, dt);
- GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, glsl, NULL);
+ GPU_begin_object_materials(v3d, rv3d, scene, eval_ctx->view_layer, ob, glsl, eval_ctx->object_mode, NULL);
}
draw_em_fancy_new(scene, ar, v3d, ob, me, em, cageDM, finalDM, dt);
@@ -5103,18 +5120,19 @@ static bool UNUSED_FUNCTION(draw_mesh_object_new)(const bContext *C, Scene *scen
/* ob->bb was set by derived mesh system, do NULL check just to be sure */
if (me->totpoly <= 4 || (!ob->bb || ED_view3d_boundbox_clip(rv3d, ob->bb))) {
if (solid) {
- const bool glsl = draw_glsl_material(scene, view_layer, ob, v3d, dt);
+ const bool glsl = draw_glsl_material(eval_ctx, scene, eval_ctx->view_layer, ob, v3d, dt);
if (dt == OB_SOLID || glsl) {
- const bool check_alpha = check_alpha_pass(base);
- GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, glsl,
- (check_alpha) ? &do_alpha_after : NULL);
+ const bool check_alpha = check_alpha_pass(eval_ctx, base);
+ GPU_begin_object_materials(
+ v3d, rv3d, scene, eval_ctx->view_layer, ob,
+ eval_ctx->object_mode, glsl, (check_alpha) ? &do_alpha_after : NULL);
}
}
const bool other_obedit = obedit && (obedit != ob);
- draw_mesh_fancy_new(&eval_ctx, scene, view_layer, ar, v3d, rv3d, base, dt, ob_wire_col, dflag, other_obedit);
+ draw_mesh_fancy_new(eval_ctx, scene, eval_ctx->view_layer, ar, v3d, rv3d, base, dt, ob_wire_col, dflag, other_obedit);
GPU_end_object_materials();
@@ -5425,7 +5443,9 @@ static void drawCurveDMWired(Object *ob)
}
/* return true when nothing was drawn */
-static bool drawCurveDerivedMesh(Scene *scene, ViewLayer *view_layer, View3D *v3d, RegionView3D *rv3d, Base *base, const char dt)
+static bool drawCurveDerivedMesh(
+ const EvaluationContext *eval_ctx, Scene *scene, ViewLayer *view_layer, View3D *v3d, RegionView3D *rv3d,
+ Base *base, const char dt)
{
Object *ob = base->object;
DerivedMesh *dm = ob->derivedFinal;
@@ -5439,8 +5459,10 @@ static bool drawCurveDerivedMesh(Scene *scene, ViewLayer *view_layer, View3D *v3
glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
if (dt > OB_WIRE && dm->getNumPolys(dm)) {
- bool glsl = draw_glsl_material(scene, view_layer, ob, v3d, dt);
- GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, glsl, NULL);
+ bool glsl = draw_glsl_material(eval_ctx, scene, view_layer, ob, v3d, dt);
+ GPU_begin_object_materials(
+ v3d, rv3d, scene, view_layer, ob,
+ eval_ctx->object_mode, glsl, NULL);
if (!glsl)
dm->drawFacesSolid(dm, NULL, 0, GPU_object_material_bind);
@@ -5461,8 +5483,9 @@ static bool drawCurveDerivedMesh(Scene *scene, ViewLayer *view_layer, View3D *v3
* Only called by #drawDispList
* \return true when nothing was drawn
*/
-static bool drawDispList_nobackface(Scene *scene, ViewLayer *view_layer, View3D *v3d, RegionView3D *rv3d, Base *base,
- const char dt, const short dflag, const unsigned char ob_wire_col[4])
+static bool drawDispList_nobackface(
+ const EvaluationContext *eval_ctx, Scene *scene, ViewLayer *view_layer, View3D *v3d, RegionView3D *rv3d,
+ Base *base, const char dt, const short dflag, const unsigned char ob_wire_col[4])
{
Object *ob = base->object;
ListBase *lb = NULL;
@@ -5502,13 +5525,13 @@ static bool drawDispList_nobackface(Scene *scene, ViewLayer *view_layer, View3D
/* pass */
}
else {
- if (draw_glsl_material(scene, view_layer, ob, v3d, dt)) {
- GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, 1, NULL);
+ if (draw_glsl_material(eval_ctx, scene, view_layer, ob, v3d, dt)) {
+ GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, 1, eval_ctx->object_mode, NULL);
drawDispListsolid(lb, ob, dflag, ob_wire_col, true);
GPU_end_object_materials();
}
else {
- GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, 0, NULL);
+ GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, 0, eval_ctx->object_mode, NULL);
drawDispListsolid(lb, ob, dflag, ob_wire_col, false);
GPU_end_object_materials();
}
@@ -5537,13 +5560,13 @@ static bool drawDispList_nobackface(Scene *scene, ViewLayer *view_layer, View3D
if (dl->nors == NULL) BKE_displist_normals_add(lb);
- if (draw_glsl_material(scene, view_layer, ob, v3d, dt)) {
- GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, 1, NULL);
+ if (draw_glsl_material(eval_ctx, scene, view_layer, ob, v3d, dt)) {
+ GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, 1, eval_ctx->object_mode, NULL);
drawDispListsolid(lb, ob, dflag, ob_wire_col, true);
GPU_end_object_materials();
}
else {
- GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, 0, NULL);
+ GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, 0, eval_ctx->object_mode, NULL);
drawDispListsolid(lb, ob, dflag, ob_wire_col, false);
GPU_end_object_materials();
}
@@ -5562,13 +5585,13 @@ static bool drawDispList_nobackface(Scene *scene, ViewLayer *view_layer, View3D
if (solid) {
- if (draw_glsl_material(scene, view_layer, ob, v3d, dt)) {
- GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, 1, NULL);
+ if (draw_glsl_material(eval_ctx, scene, view_layer, ob, v3d, dt)) {
+ GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, 1, eval_ctx->object_mode, NULL);
drawDispListsolid(lb, ob, dflag, ob_wire_col, true);
GPU_end_object_materials();
}
else {
- GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, 0, NULL);
+ GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, 0, eval_ctx->object_mode, NULL);
drawDispListsolid(lb, ob, dflag, ob_wire_col, false);
GPU_end_object_materials();
}
@@ -5599,7 +5622,7 @@ static bool drawDispList(
ensure_curve_cache(eval_ctx, scene, base->object);
#endif
- if (drawCurveDerivedMesh(scene, view_layer, v3d, rv3d, base, dt) == false) {
+ if (drawCurveDerivedMesh(eval_ctx, scene, view_layer, v3d, rv3d, base, dt) == false) {
retval = false;
}
else {
@@ -5615,7 +5638,7 @@ static bool drawDispList(
glFrontFace(mode);
- retval = drawDispList_nobackface(scene, view_layer, v3d, rv3d, base, dt, dflag, ob_wire_col);
+ retval = drawDispList_nobackface(eval_ctx, scene, view_layer, v3d, rv3d, base, dt, dflag, ob_wire_col);
if (mode != GL_CCW) {
glFrontFace(GL_CCW);
@@ -5939,7 +5962,7 @@ static void draw_new_particle_system(
if (pars == NULL) return;
/* don't draw normal paths in edit mode */
- if (psys_in_edit_mode(eval_ctx->view_layer, psys) && (pset->flag & PE_DRAW_PART) == 0)
+ if (psys_in_edit_mode(eval_ctx, eval_ctx->view_layer, psys) && (pset->flag & PE_DRAW_PART) == 0)
return;
if (part->draw_as == PART_DRAW_REND)
@@ -5955,6 +5978,8 @@ static void draw_new_particle_system(
curvemapping_changed_all(psys->part->clumpcurve);
if ((psys->part->child_flag & PART_CHILD_USE_ROUGH_CURVE) && psys->part->roughcurve)
curvemapping_changed_all(psys->part->roughcurve);
+ if ((psys->part->child_flag & PART_CHILD_USE_TWIST_CURVE) && psys->part->twistcurve)
+ curvemapping_changed_all(psys->part->twistcurve);
/* 2. */
sim.eval_ctx = eval_ctx;
@@ -8296,7 +8321,7 @@ static void draw_object_selected_outline(
if (has_faces && ED_view3d_boundbox_clip(rv3d, ob->bb)) {
glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f);
if (dm) {
- draw_mesh_object_outline(v3d, ob, dm, ob_wire_col);
+ draw_mesh_object_outline(eval_ctx, v3d, ob, dm, ob_wire_col);
}
else {
/* only draw 'solid' parts of the display list as wire. */
@@ -8313,7 +8338,7 @@ static void draw_object_selected_outline(
}
}
else if (ob->type == OB_ARMATURE) {
- if (!(ob->mode & OB_MODE_POSE && base == view_layer->basact)) {
+ if (!(eval_ctx->object_mode & OB_MODE_POSE && base == view_layer->basact)) {
glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f);
draw_armature(eval_ctx, scene, view_layer, v3d, ar, base, OB_WIRE, 0, ob_wire_col, true);
}
@@ -8322,7 +8347,8 @@ static void draw_object_selected_outline(
glDepthMask(GL_TRUE);
}
-static void draw_wire_extra(Scene *scene, RegionView3D *rv3d, Object *ob, const unsigned char ob_wire_col[4])
+static void draw_wire_extra(
+ RegionView3D *rv3d, Object *ob, const bool is_obedit, const unsigned char ob_wire_col[4])
{
if (ELEM(ob->type, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL)) {
unsigned char wire_edit_col[4];
@@ -8339,13 +8365,13 @@ static void draw_wire_extra(Scene *scene, RegionView3D *rv3d, Object *ob, const
drawCurveDMWired(ob);
}
else {
- drawDispListwire(&ob->curve_cache->disp, ob->type, (scene->obedit == ob) ? wire_edit_col : ob_wire_col);
+ drawDispListwire(&ob->curve_cache->disp, ob->type, is_obedit ? wire_edit_col : ob_wire_col);
}
}
}
else if (ob->type == OB_MBALL) {
if (BKE_mball_is_basis(ob)) {
- drawDispListwire(&ob->curve_cache->disp, ob->type, (scene->obedit == ob) ? wire_edit_col : ob_wire_col);
+ drawDispListwire(&ob->curve_cache->disp, ob->type, is_obedit ? wire_edit_col : ob_wire_col);
}
}
@@ -8423,11 +8449,13 @@ static void draw_rigid_body_pivot(bRigidBodyJointConstraint *data,
immUnbindProgram();
}
-void draw_object_wire_color(Scene *scene, ViewLayer *view_layer, Base *base, unsigned char r_ob_wire_col[4])
+void draw_object_wire_color(
+ const EvaluationContext *eval_ctx, ViewLayer *view_layer,
+ Base *base, unsigned char r_ob_wire_col[4])
{
Object *ob = base->object;
int colindex = 0;
- const bool is_edit = (ob->mode & OB_MODE_EDIT) != 0;
+ const bool is_edit = (eval_ctx->object_mode & OB_MODE_EDIT) != 0;
/* confusing logic here, there are 2 methods of setting the color
* 'colortab[colindex]' and 'theme_id', colindex overrides theme_id.
*
@@ -8435,7 +8463,7 @@ void draw_object_wire_color(Scene *scene, ViewLayer *view_layer, Base *base, uns
int theme_id = is_edit ? TH_WIRE_EDIT : TH_WIRE;
int theme_shade = 0;
- if ((scene->obedit == NULL) &&
+ if (((eval_ctx->object_mode & OB_MODE_EDIT) == 0) &&
(G.moving & G_TRANSFORM_OBJ) &&
((base->flag & BASE_SELECTED) || (base->flag_legacy & BA_WAS_SEL)))
{
@@ -8489,10 +8517,12 @@ void draw_object_wire_color(Scene *scene, ViewLayer *view_layer, Base *base, uns
r_ob_wire_col[3] = 255;
}
-static void draw_object_matcap_check(View3D *v3d, Object *ob)
+static void draw_object_matcap_check(
+ const EvaluationContext *eval_ctx, View3D *v3d, Object *ob)
{
/* fixed rule, active object draws as matcap */
- BLI_assert((ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) == 0);
+ BLI_assert((eval_ctx->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) == 0);
+ UNUSED_VARS_NDEBUG(eval_ctx);
(void)ob;
if (v3d->defmaterial == NULL) {
@@ -8579,13 +8609,15 @@ void draw_object(
const unsigned char *ob_wire_col = NULL; /* dont initialize this, use NULL crashes as a way to find invalid use */
bool zbufoff = false, is_paint = false, empty_object = false;
const bool is_obact = (ob == OBACT(view_layer));
+ /* this could be moved to a 'dflag'. */
+ const bool is_obedit = (is_obact && (ob == OBEDIT_FROM_EVAL_CTX(eval_ctx)));
const bool render_override = (v3d->flag2 & V3D_RENDER_OVERRIDE) != 0;
const bool is_picking = (G.f & G_PICKSEL) != 0;
const bool has_particles = (ob->particlesystem.first != NULL);
bool skip_object = false; /* Draw particles but not their emitter object. */
SmokeModifierData *smd = NULL;
- if (ob != scene->obedit) {
+ if (is_obedit == false) {
if (ob->restrictflag & OB_RESTRICT_VIEW)
return;
@@ -8604,7 +8636,7 @@ void draw_object(
return;
}
- if (ob->mode == OB_MODE_OBJECT) {
+ if (eval_ctx->object_mode == OB_MODE_OBJECT) {
ParticleSystem *psys;
skip_object = render_override;
@@ -8644,7 +8676,7 @@ void draw_object(
/* xray delay? */
if ((dflag & DRAW_PICKING) == 0 && (base->flag_legacy & OB_FROMDUPLI) == 0 && (v3d->flag2 & V3D_RENDER_SHADOW) == 0) {
/* don't do xray in particle mode, need the z-buffer */
- if (!(ob->mode & OB_MODE_PARTICLE_EDIT)) {
+ if (!(eval_ctx->object_mode & OB_MODE_PARTICLE_EDIT)) {
/* xray and transp are set when it is drawing the 2nd/3rd pass */
if (!v3d->xray && !v3d->transp && (ob->dtx & OB_DRAWXRAY) && !(ob->dtx & OB_DRAWTRANSP)) {
ED_view3d_after_add(&v3d->afterdraw_xray, base, dflag);
@@ -8666,7 +8698,7 @@ void draw_object(
/* no return after this point, otherwise leaks */
/* only once set now, will be removed too, should become a global standard */
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
/* reset here to avoid having to call all over */
glLineWidth(1.0f);
@@ -8695,7 +8727,7 @@ void draw_object(
ED_view3d_project_base(ar, base);
- draw_object_wire_color(scene, view_layer, base, _ob_wire_col);
+ draw_object_wire_color(eval_ctx, view_layer, base, _ob_wire_col);
ob_wire_col = _ob_wire_col;
//glColor3ubv(ob_wire_col);
@@ -8711,14 +8743,14 @@ void draw_object(
/* faceselect exception: also draw solid when (dt == wire), except in editmode */
if (is_obact) {
- if (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) {
+ if (eval_ctx->object_mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) {
if (ob->type == OB_MESH) {
if (dt < OB_SOLID) {
zbufoff = true;
dt = OB_SOLID;
}
- if (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT)) {
+ if (eval_ctx->object_mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT)) {
dt = OB_PAINT;
}
@@ -8734,13 +8766,13 @@ void draw_object(
(is_paint == false && is_picking == false) &&
((v3d->flag2 & V3D_RENDER_SHADOW) == 0))
{
- draw_object_matcap_check(v3d, ob);
+ draw_object_matcap_check(eval_ctx, v3d, ob);
}
/* draw-extra supported for boundbox drawmode too */
if (dt >= OB_BOUNDBOX) {
dtx = ob->dtx;
- if (ob->mode & OB_MODE_EDIT) {
+ if (eval_ctx->object_mode & OB_MODE_EDIT) {
/* the only 2 extra drawtypes alowed in editmode */
dtx = dtx & (OB_DRAWWIRE | OB_TEXSPACE);
}
@@ -8749,7 +8781,7 @@ void draw_object(
if (!skip_object) {
/* draw outline for selected objects, mesh does itself */
if ((v3d->flag & V3D_SELECT_OUTLINE) && !render_override && ob->type != OB_MESH) {
- if (dt > OB_WIRE && (ob->mode & OB_MODE_EDIT) == 0 && (dflag & DRAW_SCENESET) == 0) {
+ if (dt > OB_WIRE && (eval_ctx->object_mode & OB_MODE_EDIT) == 0 && (dflag & DRAW_SCENESET) == 0) {
if (!(ob->dtx & OB_DRAWWIRE) && (base->flag & BASE_SELECTED) && !(dflag & (DRAW_PICKING | DRAW_CONSTCOLOR))) {
draw_object_selected_outline(eval_ctx, scene, view_layer, v3d, ar, base, ob_wire_col);
}
@@ -8857,7 +8889,7 @@ void draw_object(
case OB_LATTICE:
if (!render_override) {
/* Do not allow boundbox in edit nor pose mode! */
- if ((dt == OB_BOUNDBOX) && (ob->mode & OB_MODE_EDIT))
+ if ((dt == OB_BOUNDBOX) && (eval_ctx->object_mode & OB_MODE_EDIT))
dt = OB_WIRE;
if (dt == OB_BOUNDBOX) {
draw_bounding_volume(ob, ob->boundtype, ob_wire_col);
@@ -8873,7 +8905,7 @@ void draw_object(
case OB_ARMATURE:
if (!render_override) {
/* Do not allow boundbox in edit nor pose mode! */
- if ((dt == OB_BOUNDBOX) && (ob->mode & (OB_MODE_EDIT | OB_MODE_POSE)))
+ if ((dt == OB_BOUNDBOX) && (eval_ctx->object_mode & (OB_MODE_EDIT | OB_MODE_POSE)))
dt = OB_WIRE;
if (dt == OB_BOUNDBOX) {
draw_bounding_volume(ob, ob->boundtype, ob_wire_col);
@@ -8929,7 +8961,7 @@ afterdraw:
/* code for new particle system */
if ((ob->particlesystem.first) &&
- (ob != scene->obedit))
+ (is_obedit == false))
{
ParticleSystem *psys;
@@ -8941,7 +8973,7 @@ afterdraw:
for (psys = ob->particlesystem.first; psys; psys = psys->next) {
/* run this so that possible child particles get cached */
- if (ob->mode & OB_MODE_PARTICLE_EDIT && is_obact) {
+ if (eval_ctx->object_mode & OB_MODE_PARTICLE_EDIT && is_obact) {
PTCacheEdit *edit = PE_create_current(eval_ctx, scene, ob);
if (edit && edit->psys == psys)
draw_update_ptcache_edit(eval_ctx, scene, view_layer, ob, edit);
@@ -8959,10 +8991,10 @@ afterdraw:
/* draw edit particles last so that they can draw over child particles */
if ((dflag & DRAW_PICKING) == 0 &&
- (!scene->obedit))
+ (is_obedit == false))
{
- if (ob->mode & OB_MODE_PARTICLE_EDIT && is_obact) {
+ if (eval_ctx->object_mode & OB_MODE_PARTICLE_EDIT && is_obact) {
PTCacheEdit *edit = PE_create_current(eval_ctx, scene, ob);
if (edit) {
gpuLoadMatrix(rv3d->viewmat);
@@ -9063,7 +9095,7 @@ afterdraw:
}
}
- if ((ob->gameflag & OB_BOUNDS) && (ob->mode == OB_MODE_OBJECT)) {
+ if ((ob->gameflag & OB_BOUNDS) && (eval_ctx->object_mode == OB_MODE_OBJECT)) {
if (ob->boundtype != ob->collision_boundtype || (dtx & OB_DRAWBOUNDOX) == 0) {
setlinestyle(2);
draw_bounding_volume(ob, ob->collision_boundtype, ob_wire_col);
@@ -9108,7 +9140,7 @@ afterdraw:
}
if ((dtx & OB_DRAWWIRE) && dt >= OB_SOLID) {
if ((dflag & DRAW_CONSTCOLOR) == 0) {
- draw_wire_extra(scene, rv3d, ob, ob_wire_col);
+ draw_wire_extra(rv3d, ob, is_obedit, ob_wire_col);
}
}
}
@@ -9159,7 +9191,7 @@ afterdraw:
}
/* object centers, need to be drawn in viewmat space for speed, but OK for picking select */
- if (!is_obact || !(ob->mode & OB_MODE_ALL_PAINT)) {
+ if (!is_obact || !(eval_ctx->object_mode & OB_MODE_ALL_PAINT)) {
int do_draw_center = -1; /* defines below are zero or positive... */
if (render_override) {
@@ -9212,11 +9244,11 @@ afterdraw:
immUniformColor3ubv(ob_wire_col);
/* draw hook center and offset line */
- if (ob != scene->obedit)
+ if (is_obedit == false)
draw_hooks(ob, pos);
/* help lines and so */
- if (ob != scene->obedit && ob->parent) {
+ if ((is_obedit == false) && ob->parent) {
const eObjectVisibilityCheck mode = eval_ctx->mode != DAG_EVAL_VIEWPORT ?
OB_VISIBILITY_CHECK_FOR_RENDER :
OB_VISIBILITY_CHECK_FOR_VIEWPORT;
@@ -9759,7 +9791,7 @@ void draw_object_backbufsel(
switch (ob->type) {
case OB_MESH:
- if (ob->mode & OB_MODE_EDIT) {
+ if (eval_ctx->object_mode & OB_MODE_EDIT) {
Mesh *me = ob->data;
BMEditMesh *em = me->edit_btmesh;
@@ -9805,7 +9837,7 @@ void draw_object_backbufsel(
Mesh *me = 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)))
+ ((eval_ctx->object_mode & OB_MODE_WEIGHT_PAINT) || (eval_ctx->object_mode & OB_MODE_VERTEX_PAINT)))
{
bbs_mesh_solid_verts(eval_ctx, scene, ob);
}
@@ -9834,7 +9866,7 @@ static void draw_object_mesh_instance(
Mesh *me = ob->data;
DerivedMesh *dm = NULL, *edm = NULL;
- if (ob->mode & OB_MODE_EDIT) {
+ if (eval_ctx->object_mode & OB_MODE_EDIT) {
edm = editbmesh_get_derived_base(ob, me->edit_btmesh, CD_MASK_BAREMESH);
DM_update_materials(edm, ob);
}
@@ -9852,11 +9884,11 @@ static void draw_object_mesh_instance(
}
else {
if (outline)
- draw_mesh_object_outline(v3d, ob, dm ? dm : edm, ob_wire_col);
+ draw_mesh_object_outline(eval_ctx, v3d, ob, dm ? dm : edm, ob_wire_col);
if (dm) {
- bool glsl = draw_glsl_material(scene, view_layer, ob, v3d, dt);
- GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, glsl, NULL);
+ bool glsl = draw_glsl_material(eval_ctx, scene, view_layer, ob, v3d, dt);
+ GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, glsl, eval_ctx->object_mode, NULL);
}
glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
@@ -9960,7 +9992,7 @@ void ED_draw_object_facemap(
immUniformColor4fv(col);
/* XXX, alpha isn't working yet, not sure why. */
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
MVert *mvert;
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 6540a1fb234..0eaf1e10086 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -286,7 +286,7 @@ void ED_view3d_stop_render_preview(wmWindowManager *wm, ARegion *ar)
}
}
-void ED_view3d_shade_update(Main *bmain, Scene *scene, View3D *v3d, ScrArea *sa)
+void ED_view3d_shade_update(Main *bmain, View3D *v3d, ScrArea *sa)
{
wmWindowManager *wm = bmain->wm.first;
@@ -298,10 +298,6 @@ void ED_view3d_shade_update(Main *bmain, Scene *scene, View3D *v3d, ScrArea *sa)
ED_view3d_stop_render_preview(wm, ar);
}
}
- else if (scene->obedit != NULL && scene->obedit->type == OB_MESH) {
- /* Tag mesh to load edit data. */
- DEG_id_tag_update(scene->obedit->data, 0);
- }
}
/* ******************** default callbacks for view3d space ***************** */
@@ -901,10 +897,10 @@ static void view3d_main_region_listener(
case ND_SELECT:
{
WM_manipulatormap_tag_refresh(mmap);
- if (scene->obedit) {
- Object *ob = scene->obedit;
+ Object *obedit = OBEDIT_FROM_WINDOW(wmn->window);
+ if (obedit) {
/* TODO(sergey): Notifiers shouldn't really be doing DEG tags. */
- DEG_id_tag_update((ID *)ob->data, DEG_TAG_SELECT_UPDATE);
+ DEG_id_tag_update((ID *)obedit->data, DEG_TAG_SELECT_UPDATE);
}
ATTR_FALLTHROUGH;
}
@@ -1118,9 +1114,8 @@ static void view3d_main_region_message_subscribe(
/* concept is to retrieve cursor type context-less */
static void view3d_main_region_cursor(wmWindow *win, ScrArea *UNUSED(sa), ARegion *UNUSED(ar))
{
- const Scene *scene = WM_window_get_active_scene(win);
-
- if (scene->obedit) {
+ WorkSpace *workspace = WM_window_get_active_workspace(win);
+ if (workspace->object_mode & OB_MODE_EDIT) {
WM_cursor_set(win, CURSOR_EDIT);
}
else {
@@ -1351,9 +1346,9 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
if (view_layer->basact) {
- Object *ob = view_layer->basact->object;
+ const WorkSpace *workspace = CTX_wm_workspace(C);
/* if hidden but in edit mode, we still display, can happen with animation */
- if ((view_layer->basact->flag & BASE_VISIBLED) != 0 || (ob->mode & OB_MODE_EDIT)) {
+ if ((view_layer->basact->flag & BASE_VISIBLED) != 0 || (workspace->object_mode & OB_MODE_EDIT)) {
CTX_data_pointer_set(result, &scene->id, &RNA_ObjectBase, view_layer->basact);
}
}
@@ -1363,9 +1358,10 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes
else if (CTX_data_equals(member, "active_object")) {
ViewLayer *view_layer = CTX_data_view_layer(C);
if (view_layer->basact) {
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Object *ob = view_layer->basact->object;
/* if hidden but in edit mode, we still display, can happen with animation */
- if ((view_layer->basact->flag & BASE_VISIBLED) != 0 || (ob->mode & OB_MODE_EDIT) != 0) {
+ if ((view_layer->basact->flag & BASE_VISIBLED) != 0 || (workspace->object_mode & OB_MODE_EDIT) != 0) {
CTX_data_id_pointer_set(result, &ob->id);
}
}
diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c
index 644a6956e54..bd62a4fc3bf 100644
--- a/source/blender/editors/space_view3d/view3d_buttons.c
+++ b/source/blender/editors/space_view3d/view3d_buttons.c
@@ -787,10 +787,12 @@ static void do_view3d_vgroup_buttons(bContext *C, void *UNUSED(arg), int event)
static int view3d_panel_vgroup_poll(const bContext *C, PanelType *UNUSED(pt))
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *ob = OBACT(view_layer);
+
if (ob && (BKE_object_is_in_editmode_vgroup(ob) ||
- BKE_object_is_in_wpaint_select_vert(ob)))
+ BKE_object_is_in_wpaint_select_vert(ob, workspace->object_mode)))
{
MDeformVert *dvert_act = ED_mesh_active_dvert_get_only(ob);
if (dvert_act) {
@@ -1128,6 +1130,7 @@ static int view3d_panel_transform_poll(const bContext *C, PanelType *UNUSED(pt))
static void view3d_panel_transform(const bContext *C, Panel *pa)
{
uiBlock *block;
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *obedit = CTX_data_edit_object(C);
@@ -1152,7 +1155,7 @@ static void view3d_panel_transform(const bContext *C, Panel *pa)
v3d_editvertex_buts(col, v3d, ob, lim);
}
}
- else if (ob->mode & OB_MODE_POSE) {
+ else if (workspace->object_mode & OB_MODE_POSE) {
v3d_posearmature_buts(col, ob);
}
else {
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index f734bb085d0..6e3a0883489 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -35,7 +35,7 @@
#include "BLI_rect.h"
#include "BLI_string.h"
#include "BLI_threads.h"
-#include "BLI_jitter.h"
+#include "BLI_jitter_2d.h"
#include "BIF_gl.h"
#include "BIF_glutil.h"
@@ -99,15 +99,15 @@
/* ******************** general functions ***************** */
-static bool use_depth_doit(Scene *scene, View3D *v3d)
+static bool use_depth_doit(View3D *v3d, Object *obedit)
{
if (v3d->drawtype > OB_WIRE)
return true;
/* special case (depth for wire color) */
if (v3d->drawtype <= OB_WIRE) {
- if (scene->obedit && scene->obedit->type == OB_MESH) {
- Mesh *me = scene->obedit->data;
+ if (obedit && obedit->type == OB_MESH) {
+ Mesh *me = obedit->data;
if (me->drawflag & ME_DRAWEIGHT) {
return true;
}
@@ -268,28 +268,28 @@ static void view3d_stereo3d_setup(
data = (Camera *)v3d->camera->data;
shiftx = data->shiftx;
- BLI_lock_thread(LOCK_VIEW3D);
+ BLI_thread_lock(LOCK_VIEW3D);
data->shiftx = BKE_camera_multiview_shift_x(&scene->r, v3d->camera, viewname);
BKE_camera_multiview_view_matrix(&scene->r, v3d->camera, is_left, viewmat);
view3d_main_region_setup_view(eval_ctx, scene, v3d, ar, viewmat, NULL, rect);
data->shiftx = shiftx;
- BLI_unlock_thread(LOCK_VIEW3D);
+ BLI_thread_unlock(LOCK_VIEW3D);
}
else { /* SCE_VIEWS_FORMAT_MULTIVIEW */
float viewmat[4][4];
Object *view_ob = v3d->camera;
Object *camera = BKE_camera_multiview_render(scene, v3d->camera, viewname);
- BLI_lock_thread(LOCK_VIEW3D);
+ BLI_thread_lock(LOCK_VIEW3D);
v3d->camera = camera;
BKE_camera_multiview_view_matrix(&scene->r, camera, false, viewmat);
view3d_main_region_setup_view(eval_ctx, scene, v3d, ar, viewmat, NULL, rect);
v3d->camera = view_ob;
- BLI_unlock_thread(LOCK_VIEW3D);
+ BLI_thread_unlock(LOCK_VIEW3D);
}
}
@@ -494,7 +494,7 @@ static void drawviewborder(Scene *scene, const Depsgraph *depsgraph, ARegion *ar
float alpha = 1.0f;
if (ca->passepartalpha != 1.0f) {
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
alpha = ca->passepartalpha;
}
@@ -752,7 +752,7 @@ void ED_view3d_draw_depth(
else
#endif /* WITH_OPENGL_LEGACY */
{
- DRW_draw_depth_loop(graph, ar, v3d);
+ DRW_draw_depth_loop(graph, ar, v3d, eval_ctx->object_mode);
}
if (rv3d->rflag & RV3D_CLIPPING) {
@@ -1326,7 +1326,7 @@ float ED_view3d_grid_scale(Scene *scene, View3D *v3d, const char **grid_unit)
return v3d->grid * ED_scene_grid_scale(scene, grid_unit);
}
-static bool is_cursor_visible(Scene *scene, ViewLayer *view_layer)
+static bool is_cursor_visible(const EvaluationContext *eval_ctx, Scene *scene, ViewLayer *view_layer)
{
if (U.app_flag & USER_APP_VIEW3D_HIDE_CURSOR) {
return false;
@@ -1335,16 +1335,16 @@ static bool is_cursor_visible(Scene *scene, ViewLayer *view_layer)
Object *ob = OBACT(view_layer);
/* don't draw cursor in paint modes, but with a few exceptions */
- if (ob && ob->mode & OB_MODE_ALL_PAINT) {
+ if (ob && eval_ctx->object_mode & OB_MODE_ALL_PAINT) {
/* exception: object is in weight paint and has deforming armature in pose mode */
- if (ob->mode & OB_MODE_WEIGHT_PAINT) {
+ if (eval_ctx->object_mode & OB_MODE_WEIGHT_PAINT) {
if (BKE_object_pose_armature_get(ob) != NULL) {
return true;
}
}
/* exception: object in texture paint mode, clone brush, use_clone_layer disabled */
- else if (ob->mode & OB_MODE_TEXTURE_PAINT) {
- const Paint *p = BKE_paint_get_active(scene, view_layer);
+ else if (eval_ctx->object_mode & OB_MODE_TEXTURE_PAINT) {
+ const Paint *p = BKE_paint_get_active(scene, view_layer, eval_ctx->object_mode);
if (p && p->brush && p->brush->imagepaint_tool == PAINT_TOOL_CLONE) {
if ((scene->toolsettings->imapaint.flag & IMAGEPAINT_PROJECT_LAYER_CLONE) == 0) {
@@ -1422,7 +1422,7 @@ static void drawcursor(Scene *scene, ARegion *ar, View3D *v3d)
}
}
-static void draw_view_axis(RegionView3D *rv3d, rcti *rect)
+static void draw_view_axis(RegionView3D *rv3d, const rcti *rect)
{
const float k = U.rvisize * U.pixelsize; /* axis size */
const int bright = - 20 * (10 - U.rvibright); /* axis alpha offset (rvibright has range 0-10) */
@@ -1455,7 +1455,7 @@ static void draw_view_axis(RegionView3D *rv3d, rcti *rect)
glLineWidth(2.0f);
glEnable(GL_LINE_SMOOTH);
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
Gwn_VertFormat *format = immVertexFormat();
unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
@@ -1498,7 +1498,7 @@ static void UNUSED_FUNCTION(draw_rotation_guide)(RegionView3D *rv3d)
negate_v3_v3(o, rv3d->ofs);
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glDepthMask(GL_FALSE); /* don't overwrite zbuf */
Gwn_VertFormat *format = immVertexFormat();
@@ -1689,7 +1689,7 @@ static const char *view3d_get_name(View3D *v3d, RegionView3D *rv3d)
return name;
}
-static void draw_viewport_name(ARegion *ar, View3D *v3d, rcti *rect)
+static void draw_viewport_name(ARegion *ar, View3D *v3d, const rcti *rect)
{
RegionView3D *rv3d = ar->regiondata;
const char *name = view3d_get_name(v3d, rv3d);
@@ -1718,7 +1718,8 @@ static void draw_viewport_name(ARegion *ar, View3D *v3d, rcti *rect)
* framenum, object name, bone name (if available), marker name (if available)
*/
-static void draw_selected_name(Scene *scene, Object *ob, rcti *rect)
+static void draw_selected_name(
+ Scene *scene, Object *ob, const eObjectMode object_mode, const rcti *rect)
{
const int cfra = CFRA;
const char *msg_pin = " (Pinned)";
@@ -1760,7 +1761,7 @@ static void draw_selected_name(Scene *scene, Object *ob, rcti *rect)
s += BLI_strcpy_rlen(s, arm->act_edbone->name);
}
}
- else if (ob->mode & OB_MODE_POSE) {
+ else if (object_mode & OB_MODE_POSE) {
if (arm->act_bone) {
if (arm->act_bone->layer & arm->layer) {
@@ -1773,9 +1774,9 @@ static void draw_selected_name(Scene *scene, Object *ob, rcti *rect)
else if (ELEM(ob->type, OB_MESH, OB_LATTICE, OB_CURVE)) {
/* try to display active bone and active shapekey too (if they exist) */
- if (ob->type == OB_MESH && ob->mode & OB_MODE_WEIGHT_PAINT) {
+ if (ob->type == OB_MESH && object_mode & OB_MODE_WEIGHT_PAINT) {
Object *armobj = BKE_object_pose_armature_get(ob);
- if (armobj && armobj->mode & OB_MODE_POSE) {
+ if (armobj) {
bArmature *arm = armobj->data;
if (arm->act_bone) {
if (arm->act_bone->layer & arm->layer) {
@@ -1862,9 +1863,10 @@ void view3d_draw_region_info(const bContext *C, ARegion *ar, const int offset)
}
if (U.uiflag & USER_DRAWVIEWINFO) {
+ const WorkSpace *workspace = CTX_wm_workspace(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *ob = OBACT(view_layer);
- draw_selected_name(scene, ob, &rect);
+ draw_selected_name(scene, ob, workspace->object_mode, &rect);
}
#if 0 /* TODO */
if (grid_unit) { /* draw below the viewport name */
@@ -1916,6 +1918,10 @@ void view3d_main_region_draw(const bContext *C, ARegion *ar)
view3d_draw_view(C, ar);
GPU_viewport_unbind(rv3d->viewport);
+ rcti rect = ar->winrct;
+ BLI_rcti_translate(&rect, -ar->winrct.xmin, -ar->winrct.ymin);
+ GPU_viewport_draw_to_screen(rv3d->viewport, &rect);
+
v3d->flag |= V3D_INVALID_BACKBUF;
}
@@ -1951,7 +1957,7 @@ void ED_view3d_draw_offscreen_init(const EvaluationContext *eval_ctx, Scene *sce
RenderEngineType *engine_type = eval_ctx->engine_type;
if (engine_type->flag & RE_USE_LEGACY_PIPELINE) {
/* shadow buffers, before we setup matrices */
- if (draw_glsl_material(scene, view_layer, NULL, v3d, v3d->drawtype)) {
+ if (draw_glsl_material(eval_ctx, scene, view_layer, NULL, v3d, v3d->drawtype)) {
VP_deprecated_gpu_update_lamps_shadows_world(eval_ctx, scene, v3d);
}
}
@@ -2076,7 +2082,9 @@ void ED_view3d_draw_offscreen(
}
}
else {
- DRW_draw_render_loop_offscreen(depsgraph, eval_ctx->engine_type, ar, v3d, do_sky, ofs, viewport);
+ DRW_draw_render_loop_offscreen(
+ eval_ctx->depsgraph, eval_ctx->engine_type, ar, v3d, eval_ctx->object_mode,
+ do_sky, ofs, viewport);
}
/* restore size */
@@ -2126,7 +2134,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(
if (own_ofs) {
/* bind */
- ofs = GPU_offscreen_create(sizex, sizey, use_full_sample ? 0 : samples, false, err_out);
+ ofs = GPU_offscreen_create(sizex, sizey, use_full_sample ? 0 : samples, true, false, err_out);
if (ofs == NULL) {
return NULL;
}
@@ -2352,26 +2360,27 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(
*
* \{ */
-void VP_legacy_drawcursor(Scene *scene, ViewLayer *view_layer, ARegion *ar, View3D *v3d)
+void VP_legacy_drawcursor(
+ const EvaluationContext *eval_ctx, Scene *scene, ViewLayer *view_layer, ARegion *ar, View3D *v3d)
{
- if (is_cursor_visible(scene, view_layer)) {
+ if (is_cursor_visible(eval_ctx, scene, view_layer)) {
drawcursor(scene, ar, v3d);
}
}
-void VP_legacy_draw_view_axis(RegionView3D *rv3d, rcti *rect)
+void VP_legacy_draw_view_axis(RegionView3D *rv3d, const rcti *rect)
{
draw_view_axis(rv3d, rect);
}
-void VP_legacy_draw_viewport_name(ARegion *ar, View3D *v3d, rcti *rect)
+void VP_legacy_draw_viewport_name(ARegion *ar, View3D *v3d, const rcti *rect)
{
draw_viewport_name(ar, v3d, rect);
}
-void VP_legacy_draw_selected_name(Scene *scene, Object *ob, rcti *rect)
+void VP_legacy_draw_selected_name(Scene *scene, Object *ob, eObjectMode object_mode, const rcti *rect)
{
- draw_selected_name(scene, ob, rect);
+ draw_selected_name(scene, ob, object_mode, rect);
}
void VP_legacy_drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char **grid_unit)
@@ -2401,9 +2410,9 @@ void VP_legacy_view3d_stereo3d_setup(const EvaluationContext *eval_ctx, Scene *s
view3d_stereo3d_setup(eval_ctx, scene, v3d, ar, NULL);
}
-bool VP_legacy_use_depth(Scene *scene, View3D *v3d)
+bool VP_legacy_use_depth(View3D *v3d, Object *obedit)
{
- return use_depth_doit(scene, v3d);
+ return use_depth_doit(v3d, obedit);
}
void VP_drawviewborder(Scene *scene, const struct Depsgraph *depsgraph, ARegion *ar, View3D *v3d)
diff --git a/source/blender/editors/space_view3d/view3d_draw_legacy.c b/source/blender/editors/space_view3d/view3d_draw_legacy.c
index 7cb362ffb92..6a746ffe27c 100644
--- a/source/blender/editors/space_view3d/view3d_draw_legacy.c
+++ b/source/blender/editors/space_view3d/view3d_draw_legacy.c
@@ -48,7 +48,7 @@
#include "BLI_blenlib.h"
#include "BLI_math.h"
-#include "BLI_jitter.h"
+#include "BLI_jitter_2d.h"
#include "BLI_utildefines.h"
#include "BLI_endian_switch.h"
#include "BLI_threads.h"
@@ -202,7 +202,7 @@ static void draw_view_icon(RegionView3D *rv3d, rcti *rect)
else return;
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
UI_icon_draw(5.0 + rect->xmin, 5.0 + rect->ymin, icon);
@@ -211,31 +211,32 @@ static void draw_view_icon(RegionView3D *rv3d, rcti *rect)
/* *********************** backdraw for selection *************** */
-static void backdrawview3d(const struct EvaluationContext *eval_ctx, Scene *scene, ViewLayer *view_layer, wmWindow *win, ARegion *ar, View3D *v3d)
+static void backdrawview3d(
+ const struct EvaluationContext *eval_ctx, Scene *scene, ViewLayer *view_layer,
+ ARegion *ar, View3D *v3d)
{
RegionView3D *rv3d = ar->regiondata;
struct Base *base = view_layer->basact;
- int multisample_enabled;
BLI_assert(ar->regiontype == RGN_TYPE_WINDOW);
- if (base && (base->object->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT) ||
- BKE_paint_select_face_test(base->object)))
+ if (base && (eval_ctx->object_mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT) ||
+ BKE_paint_select_face_test(base->object, eval_ctx->object_mode)))
{
/* do nothing */
}
/* texture paint mode sampling */
- else if (base && (base->object->mode & OB_MODE_TEXTURE_PAINT) &&
+ else if (base && (eval_ctx->object_mode & OB_MODE_TEXTURE_PAINT) &&
(v3d->drawtype > OB_WIRE))
{
/* do nothing */
}
- else if ((base && (base->object->mode & OB_MODE_PARTICLE_EDIT)) &&
+ else if ((base && (eval_ctx->object_mode & OB_MODE_PARTICLE_EDIT)) &&
V3D_IS_ZBUF(v3d))
{
/* do nothing */
}
- else if (scene->obedit &&
+ else if ((eval_ctx->object_mode & OB_MODE_EDIT) &&
V3D_IS_ZBUF(v3d))
{
/* do nothing */
@@ -262,14 +263,13 @@ static void backdrawview3d(const struct EvaluationContext *eval_ctx, Scene *scen
/* dithering and AA break color coding, so disable */
glDisable(GL_DITHER);
- multisample_enabled = glIsEnabled(GL_MULTISAMPLE);
- if (multisample_enabled)
- glDisable(GL_MULTISAMPLE);
-
- if (win->multisamples != USER_MULTISAMPLE_NONE) {
+ if (false) {
/* for multisample we use an offscreen FBO. multisample drawing can fail
* with color coded selection drawing, and reading back depths from such
- * a buffer can also cause a few seconds freeze on OS X / NVidia. */
+ * a buffer can also cause a few seconds freeze on OS X / NVidia.
+ *
+ * NOTE: code is no longer used now, but offscreen drawing is likely
+ * what we will always want to do for the new viewport. */
int w = BLI_rcti_size_x(&ar->winrct);
int h = BLI_rcti_size_y(&ar->winrct);
char error[256];
@@ -284,7 +284,7 @@ static void backdrawview3d(const struct EvaluationContext *eval_ctx, Scene *scen
}
if (!rv3d->gpuoffscreen) {
- rv3d->gpuoffscreen = GPU_offscreen_create(w, h, 0, false, error);
+ rv3d->gpuoffscreen = GPU_offscreen_create(w, h, 0, true, false, error);
if (!rv3d->gpuoffscreen)
fprintf(stderr, "Failed to create offscreen selection buffer for multisample: %s\n", error);
@@ -325,8 +325,6 @@ static void backdrawview3d(const struct EvaluationContext *eval_ctx, Scene *scen
v3d->zbuf = false;
glDisable(GL_DEPTH_TEST);
glEnable(GL_DITHER);
- if (multisample_enabled)
- glEnable(GL_MULTISAMPLE);
if (rv3d->rflag & RV3D_CLIPPING)
ED_view3d_clipping_disable();
@@ -356,7 +354,7 @@ static void view3d_opengl_read_Z_pixels(ARegion *ar, int x, int y, int w, int h,
void ED_view3d_backbuf_validate(const struct EvaluationContext *eval_ctx, ViewContext *vc)
{
if (vc->v3d->flag & V3D_INVALID_BACKBUF) {
- backdrawview3d(eval_ctx, vc->scene, vc->view_layer, vc->win, vc->ar, vc->v3d);
+ backdrawview3d(eval_ctx, vc->scene, vc->view_layer, vc->ar, vc->v3d);
}
}
@@ -734,7 +732,7 @@ static void view3d_draw_bgpic(Scene *scene, const Depsgraph *depsgraph,
glDepthMask(GL_FALSE);
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
gpuPushProjectionMatrix();
gpuPushMatrix();
@@ -1302,7 +1300,7 @@ void ED_view3d_draw_select_loop(
for (base = view_layer->object_bases.first; base; base = base->next) {
if ((base->flag & BASE_VISIBLED) != 0) {
if (((base->flag & BASE_SELECTABLED) == 0) ||
- (use_obedit_skip && (scene->obedit->data == base->object->data)))
+ (use_obedit_skip && (vc->obedit->data == base->object->data)))
{
base->object->select_color = 0;
}
@@ -1506,6 +1504,7 @@ static void view3d_draw_objects(
Depsgraph *depsgraph = CTX_data_depsgraph(C);
RegionView3D *rv3d = ar->regiondata;
Base *base;
+ Object *obedit = OBEDIT_FROM_EVAL_CTX(eval_ctx);
const bool do_camera_frame = !draw_offscreen;
const bool draw_grids = !draw_offscreen && (v3d->flag2 & V3D_RENDER_OVERRIDE) == 0;
const bool draw_floor = (rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO);
@@ -1522,7 +1521,7 @@ static void view3d_draw_objects(
view3d_draw_clipping(rv3d);
/* set zbuffer after we draw clipping region */
- v3d->zbuf = VP_legacy_use_depth(scene, v3d);
+ v3d->zbuf = VP_legacy_use_depth(v3d, obedit);
if (v3d->zbuf) {
glEnable(GL_DEPTH_TEST);
@@ -1599,7 +1598,7 @@ static void view3d_draw_objects(
draw_dupli_objects(eval_ctx, scene, view_layer, ar, v3d, base);
}
if ((base->flag & BASE_SELECTED) == 0) {
- if (base->object != scene->obedit)
+ if (base->object != obedit)
draw_object(eval_ctx, scene, view_layer, ar, v3d, base, 0);
}
}
@@ -1611,7 +1610,7 @@ static void view3d_draw_objects(
/* draw selected and editmode */
for (base = view_layer->object_bases.first; base; base = base->next) {
if ((base->flag & BASE_VISIBLED) != 0) {
- if (base->object == scene->obedit || (base->flag & BASE_SELECTED)) {
+ if (base->object == obedit || (base->flag & BASE_SELECTED)) {
draw_object(eval_ctx, scene, view_layer, ar, v3d, base, 0);
}
}
@@ -1946,8 +1945,9 @@ static void update_lods(Scene *scene, float camera_pos[3])
}
#endif
-static void view3d_main_region_draw_objects(const bContext *C, Scene *scene, ViewLayer *view_layer, View3D *v3d,
- ARegion *ar, const char **grid_unit)
+static void view3d_main_region_draw_objects(
+ const bContext *C, Scene *scene, ViewLayer *view_layer, View3D *v3d,
+ ARegion *ar, const char **grid_unit)
{
wmWindow *win = CTX_wm_window(C);
EvaluationContext eval_ctx;
@@ -1960,7 +1960,7 @@ static void view3d_main_region_draw_objects(const bContext *C, Scene *scene, Vie
bool do_compositing = false;
/* shadow buffers, before we setup matrices */
- if (draw_glsl_material(scene, view_layer, NULL, v3d, v3d->drawtype))
+ if (draw_glsl_material(&eval_ctx, scene, view_layer, NULL, v3d, v3d->drawtype))
gpu_update_lamps_shadows_world(&eval_ctx, scene, v3d);
/* reset default OpenGL lights if needed (i.e. after preferences have been altered) */
@@ -2003,11 +2003,6 @@ static void view3d_main_region_draw_objects(const bContext *C, Scene *scene, Vie
do_compositing = GPU_fx_compositor_initialize_passes(rv3d->compositor, &ar->winrct, &ar->drawrct, &fx_settings);
}
- /* enables anti-aliasing for 3D view drawing */
- if (win->multisamples != USER_MULTISAMPLE_NONE) {
- glEnable(GL_MULTISAMPLE);
- }
-
/* main drawing call */
view3d_draw_objects(C, &eval_ctx, scene, v3d, ar, grid_unit, true, false, do_compositing ? rv3d->compositor : NULL);
@@ -2016,11 +2011,6 @@ static void view3d_main_region_draw_objects(const bContext *C, Scene *scene, Vie
GPU_fx_do_composite_pass(rv3d->compositor, rv3d->winmat, rv3d->is_persp, scene, NULL);
}
- /* Disable back anti-aliasing */
- if (win->multisamples != USER_MULTISAMPLE_NONE) {
- glDisable(GL_MULTISAMPLE);
- }
-
if (v3d->lay_used != lay_used) { /* happens when loading old files or loading with UI load */
/* find header and force tag redraw */
ScrArea *sa = CTX_wm_area(C);
@@ -2033,10 +2023,13 @@ static void view3d_main_region_draw_objects(const bContext *C, Scene *scene, Vie
}
}
-static void view3d_main_region_draw_info(const bContext *C, Scene *scene,
- ARegion *ar, View3D *v3d,
- const char *grid_unit, bool render_border)
+static void view3d_main_region_draw_info(
+ const bContext *C, Scene *scene,
+ ARegion *ar, View3D *v3d,
+ const char *grid_unit, bool render_border)
{
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
const Depsgraph *depsgraph = CTX_data_depsgraph(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
wmWindowManager *wm = CTX_wm_manager(C);
@@ -2059,7 +2052,7 @@ static void view3d_main_region_draw_info(const bContext *C, Scene *scene,
}
if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
- VP_legacy_drawcursor(scene, view_layer, ar, v3d); /* 3D cursor */
+ VP_legacy_drawcursor(&eval_ctx, scene, view_layer, ar, v3d); /* 3D cursor */
if (U.uiflag & USER_SHOW_ROTVIEWICON)
VP_legacy_draw_view_axis(rv3d, &rect);
@@ -2068,7 +2061,7 @@ static void view3d_main_region_draw_info(const bContext *C, Scene *scene,
if (U.uiflag & USER_DRAWVIEWINFO) {
Object *ob = OBACT(view_layer);
- VP_legacy_draw_selected_name(scene, ob, &rect);
+ VP_legacy_draw_selected_name(scene, ob, eval_ctx.object_mode, &rect);
}
}
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index 2457a890f71..47778623561 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -244,21 +244,22 @@ void view3d_orbit_apply_dyn_ofs(
static bool view3d_orbit_calc_center(bContext *C, float r_dyn_ofs[3])
{
static float lastofs[3] = {0, 0, 0};
+ const WorkSpace *workspace = CTX_wm_workspace(C);
bool is_set = false;
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *ob_act = OBACT(view_layer);
- if (ob_act && (ob_act->mode & OB_MODE_ALL_PAINT) &&
+ if (ob_act && (workspace->object_mode & OB_MODE_ALL_PAINT) &&
/* with weight-paint + pose-mode, fall through to using calculateTransformCenter */
- ((ob_act->mode & OB_MODE_WEIGHT_PAINT) && BKE_object_pose_armature_get(ob_act)) == 0)
+ ((workspace->object_mode & OB_MODE_WEIGHT_PAINT) && BKE_object_pose_armature_get(ob_act)) == 0)
{
/* in case of sculpting use last average stroke position as a rotation
* center, in other cases it's not clear what rotation center shall be
* so just rotate around object origin
*/
- if (ob_act->mode & (OB_MODE_SCULPT | OB_MODE_TEXTURE_PAINT | OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT)) {
+ if (workspace->object_mode & (OB_MODE_SCULPT | OB_MODE_TEXTURE_PAINT | OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT)) {
float stroke[3];
BKE_paint_stroke_get_average(scene, ob_act, stroke);
copy_v3_v3(lastofs, stroke);
@@ -268,7 +269,7 @@ static bool view3d_orbit_calc_center(bContext *C, float r_dyn_ofs[3])
}
is_set = true;
}
- else if (ob_act && (ob_act->mode & OB_MODE_EDIT) && (ob_act->type == OB_FONT)) {
+ else if (ob_act && (workspace->object_mode & OB_MODE_EDIT) && (ob_act->type == OB_FONT)) {
Curve *cu = ob_act->data;
EditFont *ef = cu->editfont;
int i;
@@ -283,7 +284,7 @@ static bool view3d_orbit_calc_center(bContext *C, float r_dyn_ofs[3])
is_set = true;
}
- else if (ob_act == NULL || ob_act->mode == OB_MODE_OBJECT) {
+ else if (ob_act == NULL || workspace->object_mode == OB_MODE_OBJECT) {
/* object mode use boundbox centers */
Base *base;
unsigned int tot = 0;
@@ -2792,6 +2793,7 @@ void VIEW3D_OT_view_all(wmOperatorType *ot)
/* like a localview without local!, was centerview() in 2.4x */
static int viewselected_exec(bContext *C, wmOperator *op)
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
ARegion *ar = CTX_wm_region(C);
View3D *v3d = CTX_wm_view3d(C);
Scene *scene = CTX_data_scene(C);
@@ -2815,22 +2817,13 @@ static int viewselected_exec(bContext *C, wmOperator *op)
ob = NULL;
}
- if (ob && (ob->mode & OB_MODE_WEIGHT_PAINT)) {
- /* hard-coded exception, we look for the one selected armature */
- /* this is weak code this way, we should make a generic active/selection callback interface once... */
- Base *base;
- for (base = view_layer->object_bases.first; base; base = base->next) {
- if (TESTBASELIB(base)) {
- if (base->object->type == OB_ARMATURE)
- if (base->object->mode & OB_MODE_POSE)
- break;
- }
+ if (ob && (workspace->object_mode & OB_MODE_WEIGHT_PAINT)) {
+ Object *ob_armature = BKE_object_pose_armature_get_visible(ob, view_layer);
+ if (ob_armature) {
+ ob = ob_armature;
}
- if (base)
- ob = base->object;
}
-
if (is_gp_edit) {
CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
{
@@ -2849,17 +2842,17 @@ static int viewselected_exec(bContext *C, wmOperator *op)
else if (obedit) {
ok = ED_view3d_minmax_verts(obedit, min, max); /* only selected */
}
- else if (ob && (ob->mode & OB_MODE_POSE)) {
+ else if (ob && (workspace->object_mode & OB_MODE_POSE)) {
ok = BKE_pose_minmax(ob, min, max, true, true);
}
- else if (BKE_paint_select_face_test(ob)) {
+ else if (BKE_paint_select_face_test(ob, workspace->object_mode)) {
ok = paintface_minmax(ob, min, max);
}
- else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT)) {
+ else if (ob && (workspace->object_mode & OB_MODE_PARTICLE_EDIT)) {
ok = PE_minmax(scene, view_layer, min, max);
}
else if (ob &&
- (ob->mode & (OB_MODE_SCULPT | OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)))
+ (workspace->object_mode & (OB_MODE_SCULPT | OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)))
{
BKE_paint_stroke_get_average(scene, ob, min);
copy_v3_v3(max, min);
@@ -2966,13 +2959,13 @@ static int view_lock_to_active_exec(bContext *C, wmOperator *UNUSED(op))
Object *obact = CTX_data_active_object(C);
if (v3d) {
-
ED_view3d_lock_clear(v3d);
v3d->ob_centre = obact; /* can be NULL */
if (obact && obact->type == OB_ARMATURE) {
- if (obact->mode & OB_MODE_POSE) {
+ const WorkSpace *workspace = CTX_wm_workspace(C);
+ if (workspace->object_mode & OB_MODE_POSE) {
bPoseChannel *pcham_act = BKE_pose_channel_active(obact);
if (pcham_act) {
BLI_strncpy(v3d->ob_centre_bone, pcham_act->name, sizeof(v3d->ob_centre_bone));
@@ -4696,7 +4689,7 @@ static int toggle_render_exec(bContext *C, wmOperator *UNUSED(op))
v3d->prev_drawtype = v3d->drawtype;
v3d->drawtype = OB_RENDER;
}
- ED_view3d_shade_update(CTX_data_main(C), CTX_data_scene(C), v3d, CTX_wm_area(C));
+ ED_view3d_shade_update(CTX_data_main(C), v3d, CTX_wm_area(C));
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c
index a1dc2a21477..bf4abf1852d 100644
--- a/source/blender/editors/space_view3d/view3d_header.c
+++ b/source/blender/editors/space_view3d/view3d_header.c
@@ -95,14 +95,14 @@ static void handle_view3d_lock(bContext *C)
* - uiTemplateLayers in interface/ code for buttons
* - ED_view3d_view_layer_set for RNA
*/
-static void view3d_layers_editmode_ensure(Scene *scene, View3D *v3d)
+static void view3d_layers_editmode_ensure(View3D *v3d, Object *obedit)
{
/* sanity check - when in editmode disallow switching the editmode layer off since its confusing
* an alternative would be to always draw the editmode object. */
- if (scene->obedit && (scene->obedit->lay & v3d->lay) == 0) {
+ if (obedit && (obedit->lay & v3d->lay) == 0) {
int bit;
for (bit = 0; bit < 32; bit++) {
- if (scene->obedit->lay & (1u << bit)) {
+ if (obedit->lay & (1u << bit)) {
v3d->lay |= (1u << bit);
break;
}
@@ -112,9 +112,9 @@ static void view3d_layers_editmode_ensure(Scene *scene, View3D *v3d)
static int view3d_layers_exec(bContext *C, wmOperator *op)
{
- Scene *scene = CTX_data_scene(C);
ScrArea *sa = CTX_wm_area(C);
View3D *v3d = sa->spacedata.first;
+ Object *obedit = CTX_data_edit_object(C);
int nr = RNA_int_get(op->ptr, "nr");
const bool toggle = RNA_boolean_get(op->ptr, "toggle");
@@ -130,7 +130,7 @@ static int view3d_layers_exec(bContext *C, wmOperator *op)
/* return to active layer only */
v3d->lay = v3d->lay_prev;
- view3d_layers_editmode_ensure(scene, v3d);
+ view3d_layers_editmode_ensure(v3d, obedit);
}
else {
v3d->lay_prev = v3d->lay;
@@ -151,7 +151,7 @@ static int view3d_layers_exec(bContext *C, wmOperator *op)
v3d->lay = (1 << nr);
}
- view3d_layers_editmode_ensure(scene, v3d);
+ view3d_layers_editmode_ensure(v3d, obedit);
/* set active layer, ensure to always have one */
if (v3d->lay & (1 << nr))
@@ -276,6 +276,7 @@ void uiTemplateEditModeSelection(uiLayout *layout, struct bContext *C)
void uiTemplateHeader3D(uiLayout *layout, struct bContext *C)
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
bScreen *screen = CTX_wm_screen(C);
ScrArea *sa = CTX_wm_area(C);
View3D *v3d = sa->spacedata.first;
@@ -288,8 +289,10 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C)
bGPdata *gpd = CTX_data_gpencil_data(C);
uiBlock *block;
uiLayout *row;
- bool is_paint = ob && !(gpd && (gpd->flag & GP_DATA_STROKE_EDITMODE)) &&
- ELEM(ob->mode, OB_MODE_SCULPT, OB_MODE_VERTEX_PAINT, OB_MODE_WEIGHT_PAINT, OB_MODE_TEXTURE_PAINT);
+ bool is_paint = (
+ ob && !(gpd && (gpd->flag & GP_DATA_STROKE_EDITMODE)) &&
+ ELEM(workspace->object_mode,
+ OB_MODE_SCULPT, OB_MODE_VERTEX_PAINT, OB_MODE_WEIGHT_PAINT, OB_MODE_TEXTURE_PAINT));
RNA_pointer_create(&screen->id, &RNA_SpaceView3D, v3d, &v3dptr);
RNA_pointer_create(&scene->id, &RNA_ToolSettings, ts, &toolsptr);
@@ -303,18 +306,18 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C)
row = uiLayoutRow(layout, true);
uiItemR(row, &v3dptr, "pivot_point", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
- if (!ob || ELEM(ob->mode, OB_MODE_OBJECT, OB_MODE_POSE, OB_MODE_WEIGHT_PAINT)) {
+ if (!ob || ELEM(workspace->object_mode, OB_MODE_OBJECT, OB_MODE_POSE, OB_MODE_WEIGHT_PAINT)) {
uiItemR(row, &v3dptr, "use_pivot_point_align", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
}
if (obedit == NULL && is_paint) {
/* Manipulators aren't used in paint modes */
- if (!ELEM(ob->mode, OB_MODE_SCULPT, OB_MODE_PARTICLE_EDIT)) {
+ if (!ELEM(workspace->object_mode, OB_MODE_SCULPT, OB_MODE_PARTICLE_EDIT)) {
/* masks aren't used for sculpt and particle painting */
PointerRNA meshptr;
RNA_pointer_create(ob->data, &RNA_Mesh, ob->data, &meshptr);
- if (ob->mode & (OB_MODE_TEXTURE_PAINT)) {
+ if (workspace->object_mode & (OB_MODE_TEXTURE_PAINT)) {
uiItemR(layout, &meshptr, "use_paint_mask", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
}
else {
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index d1968166904..b3300e226e0 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -54,6 +54,7 @@ struct wmKeyConfig;
struct wmManipulatorGroupType;
struct wmManipulatorType;
struct wmWindowManager;
+struct EvaluationContext;
/* drawing flags: */
enum {
@@ -154,13 +155,19 @@ void draw_object_select(
const struct EvaluationContext *eval_ctx, Scene *scene, struct ViewLayer *view_layer, struct ARegion *ar, View3D *v3d,
Base *base, const short dflag);
-void draw_mesh_object_outline(View3D *v3d, struct Object *ob, struct DerivedMesh *dm, const unsigned char ob_wire_col[4]);
+void draw_mesh_object_outline(
+ const struct EvaluationContext *eval_ctx, View3D *v3d,
+ struct Object *ob, struct DerivedMesh *dm, const unsigned char ob_wire_col[4]);
-bool draw_glsl_material(Scene *scene, struct ViewLayer *view_layer, struct Object *ob, View3D *v3d, const char dt);
+bool draw_glsl_material(
+ const struct EvaluationContext *eval_ctx, Scene *scene, struct ViewLayer *view_layer,
+ struct Object *ob, View3D *v3d, const char dt);
void draw_object_instance(const struct EvaluationContext *eval_ctx, Scene *scene, struct ViewLayer *view_layer, View3D *v3d, RegionView3D *rv3d, struct Object *ob, const char dt, int outline, const float wire_col[4]);
void draw_object_backbufsel(const struct EvaluationContext *eval_ctx, Scene *scene, View3D *v3d, RegionView3D *rv3d, struct Object *ob);
-void draw_object_wire_color(Scene *scene, struct ViewLayer *, Base *base, unsigned char r_ob_wire_col[4]);
+void draw_object_wire_color(
+ const struct EvaluationContext *eval_ctx, struct ViewLayer *,
+ Base *base, unsigned char r_ob_wire_col[4]);
void drawaxes(const float viewmat_local[4][4], float size, char drawtype, const unsigned char color[4]);
void drawlamp(View3D *v3d, RegionView3D *rv3d, Base *base,
const char dt, const short dflag, const unsigned char ob_wire_col[4],
@@ -209,8 +216,10 @@ void draw_mesh_paint_vcolor_faces(struct DerivedMesh *dm, const bool use_light,
void draw_mesh_paint_weight_edges(RegionView3D *rv3d, struct DerivedMesh *dm,
const bool use_depth, const bool use_alpha,
void *edgemask_cb, void *user_data);
-void draw_mesh_paint(View3D *v3d, RegionView3D *rv3d,
- struct Object *ob, struct DerivedMesh *dm, const int draw_flags);
+void draw_mesh_paint(
+ const struct EvaluationContext *eval_ctx,
+ View3D *v3d, RegionView3D *rv3d,
+ struct Object *ob, struct DerivedMesh *dm, const int draw_flags);
/* drawsimdebug.c */
void draw_sim_debug_data(Scene *scene, View3D *v3d, ARegion *ar);
@@ -366,17 +375,19 @@ extern bool view3d_camera_border_hack_test;
#endif
/* temporary for legacy viewport to work */
-void VP_legacy_drawcursor(Scene *scene, struct ViewLayer *view_layer, ARegion *ar, View3D *v3d);
-void VP_legacy_draw_view_axis(RegionView3D *rv3d, rcti *rect);
-void VP_legacy_draw_viewport_name(ARegion *ar, View3D *v3d, rcti *rect);
-void VP_legacy_draw_selected_name(Scene *scene, struct Object *ob, rcti *rect);
+void VP_legacy_drawcursor(
+ const struct EvaluationContext *eval_ctx, Scene *scene,
+ struct ViewLayer *view_layer, ARegion *ar, View3D *v3d);
+void VP_legacy_draw_view_axis(RegionView3D *rv3d, const rcti *rect);
+void VP_legacy_draw_viewport_name(ARegion *ar, View3D *v3d, const rcti *rect);
+void VP_legacy_draw_selected_name(Scene *scene, struct Object *ob, eObjectMode object_mode, const rcti *rect);
void VP_legacy_drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char **grid_unit);
void VP_legacy_drawfloor(Scene *scene, View3D *v3d, const char **grid_unit, bool write_depth);
void VP_legacy_view3d_main_region_setup_view(const struct EvaluationContext *eval_ctx, Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4]);
bool VP_legacy_view3d_stereo3d_active(struct wmWindow *win, Scene *scene, View3D *v3d, RegionView3D *rv3d);
void VP_legacy_view3d_stereo3d_setup(const struct EvaluationContext *eval_ctx, Scene *scene, View3D *v3d, ARegion *ar);
void draw_dupli_objects(const struct EvaluationContext *eval_ctx, Scene *scene, ViewLayer *view_layer, ARegion *ar, View3D *v3d, Base *base);
-bool VP_legacy_use_depth(Scene *scene, View3D *v3d);
+bool VP_legacy_use_depth(View3D *v3d, struct Object *obedit);
void VP_drawviewborder(Scene *scene, const struct Depsgraph *depsgraph, ARegion *ar, View3D *v3d);
void VP_drawrenderborder(ARegion *ar, View3D *v3d);
void VP_view3d_draw_background_none(void);
diff --git a/source/blender/editors/space_view3d/view3d_manipulator_forcefield.c b/source/blender/editors/space_view3d/view3d_manipulator_forcefield.c
index 6a34f493caf..e76be448be4 100644
--- a/source/blender/editors/space_view3d/view3d_manipulator_forcefield.c
+++ b/source/blender/editors/space_view3d/view3d_manipulator_forcefield.c
@@ -31,7 +31,7 @@
#include "BKE_object.h"
#include "DNA_object_types.h"
-#include "DNA_object_force.h"
+#include "DNA_object_force_types.h"
#include "ED_screen.h"
#include "ED_manipulator_library.h"
diff --git a/source/blender/editors/space_view3d/view3d_manipulator_navigate_type.c b/source/blender/editors/space_view3d/view3d_manipulator_navigate_type.c
index 424b5dae402..c3f8d92ed7f 100644
--- a/source/blender/editors/space_view3d/view3d_manipulator_navigate_type.c
+++ b/source/blender/editors/space_view3d/view3d_manipulator_navigate_type.c
@@ -131,7 +131,7 @@ static void axis_geom_draw(
glDepthMask(GL_TRUE);
glDepthFunc(GL_LEQUAL);
glBlendFunc(GL_ONE, GL_ZERO);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_LINE_SMOOTH);
glEnable(GL_BLEND);
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index 28e15b3bfee..b352a2083a7 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -48,7 +48,7 @@
#include "MEM_guardedalloc.h"
#include "BLI_math.h"
-#include "BLI_lasso.h"
+#include "BLI_lasso_2d.h"
#include "BLI_rect.h"
#include "BLI_linklist.h"
#include "BLI_listbase.h"
@@ -209,6 +209,7 @@ static void edbm_backbuf_check_and_select_tfaces(Mesh *me, const bool select)
/* *********************** GESTURE AND LASSO ******************* */
typedef struct LassoSelectUserData {
+ const EvaluationContext *eval_ctx;
ViewContext *vc;
const rcti *rect;
const rctf *rect_fl;
@@ -251,14 +252,15 @@ static int view3d_selectable_data(bContext *C)
return 0;
if (ob) {
- if (ob->mode & OB_MODE_EDIT) {
+ const WorkSpace *workspace = CTX_wm_workspace(C);
+ if (workspace->object_mode & OB_MODE_EDIT) {
if (ob->type == OB_FONT) {
return 0;
}
}
else {
- if ((ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) &&
- !BKE_paint_select_elem_test(ob))
+ if ((workspace->object_mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) &&
+ !BKE_paint_select_elem_test(ob, workspace->object_mode))
{
return 0;
}
@@ -387,8 +389,10 @@ static void object_deselect_all_visible(ViewLayer *view_layer)
}
}
-static void do_lasso_select_objects(ViewContext *vc, const int mcords[][2], const short moves,
- const bool extend, const bool select)
+static void do_lasso_select_objects(
+ const EvaluationContext *eval_ctx,
+ ViewContext *vc, const int mcords[][2], const short moves,
+ const bool extend, const bool select)
{
Base *base;
@@ -403,7 +407,7 @@ static void do_lasso_select_objects(ViewContext *vc, const int mcords[][2], cons
ED_object_base_select(base, select ? BA_SELECT : BA_DESELECT);
}
}
- if (vc->obact == base->object && (base->object->mode & OB_MODE_POSE)) {
+ if (vc->obact == base->object && (eval_ctx->object_mode & OB_MODE_POSE)) {
do_lasso_select_pose(vc, base->object, mcords, moves, select);
}
}
@@ -810,20 +814,20 @@ static void view3d_lasso_select(bContext *C, ViewContext *vc,
CTX_data_eval_ctx(C, &eval_ctx);
if (vc->obedit == NULL) { /* Object Mode */
- if (BKE_paint_select_face_test(ob)) {
+ if (BKE_paint_select_face_test(ob, eval_ctx.object_mode)) {
do_lasso_select_paintface(&eval_ctx, vc, mcords, moves, extend, select);
}
- else if (BKE_paint_select_vert_test(ob)) {
+ else if (BKE_paint_select_vert_test(ob, eval_ctx.object_mode)) {
do_lasso_select_paintvert(&eval_ctx, vc, mcords, moves, extend, select);
}
- else if (ob && (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT))) {
+ else if (ob && (eval_ctx.object_mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT))) {
/* pass */
}
- else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT)) {
+ else if (ob && (eval_ctx.object_mode & OB_MODE_PARTICLE_EDIT)) {
PE_lasso_select(C, mcords, moves, extend, select);
}
else {
- do_lasso_select_objects(vc, mcords, moves, extend, select);
+ do_lasso_select_objects(&eval_ctx, vc, mcords, moves, extend, select);
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, vc->scene);
}
}
@@ -1544,7 +1548,10 @@ static bool ed_object_select_pick(
}
}
}
- else if (ED_do_pose_selectbuffer(scene, view_layer, basact, buffer, hits, extend, deselect, toggle, do_nearest)) {
+ else if (ED_do_pose_selectbuffer(
+ &eval_ctx, view_layer,
+ basact, buffer, hits, extend, deselect, toggle, do_nearest))
+ {
/* then bone is found */
/* we make the armature selected:
@@ -1557,7 +1564,7 @@ static bool ed_object_select_pick(
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_ACTIVE, basact->object);
/* in weightpaint, we use selected bone to select vertexgroup, so no switch to new active object */
- if (BASACT(view_layer) && (BASACT(view_layer)->object->mode & OB_MODE_WEIGHT_PAINT)) {
+ if (BASACT(view_layer) && (eval_ctx.object_mode & OB_MODE_WEIGHT_PAINT)) {
/* prevent activating */
basact = NULL;
}
@@ -2050,7 +2057,7 @@ static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, b
CTX_data_eval_ctx(C, &eval_ctx);
- if ((ob) && (ob->mode & OB_MODE_POSE))
+ if ((ob) && (eval_ctx.object_mode & OB_MODE_POSE))
bone_only = 1;
else
bone_only = 0;
@@ -2205,16 +2212,16 @@ static int view3d_borderselect_exec(bContext *C, wmOperator *op)
}
}
else { /* no editmode, unified for bones and objects */
- if (vc.obact && vc.obact->mode & OB_MODE_SCULPT) {
+ if (vc.obact && eval_ctx.object_mode & OB_MODE_SCULPT) {
ret = ED_sculpt_mask_box_select(C, &vc, &rect, select, extend);
}
- else if (vc.obact && BKE_paint_select_face_test(vc.obact)) {
+ else if (vc.obact && BKE_paint_select_face_test(vc.obact, eval_ctx.object_mode)) {
ret = do_paintface_box_select(&eval_ctx, &vc, &rect, select, extend);
}
- else if (vc.obact && BKE_paint_select_vert_test(vc.obact)) {
+ else if (vc.obact && BKE_paint_select_vert_test(vc.obact, eval_ctx.object_mode)) {
ret = do_paintvert_box_select(&eval_ctx, &vc, &rect, select, extend);
}
- else if (vc.obact && vc.obact->mode & OB_MODE_PARTICLE_EDIT) {
+ else if (vc.obact && eval_ctx.object_mode & OB_MODE_PARTICLE_EDIT) {
ret = PE_border_select(C, &rect, select, extend);
}
else { /* object mode with none active */
@@ -2300,6 +2307,7 @@ static bool ed_wpaint_vertex_select_pick(
static int view3d_select_exec(bContext *C, wmOperator *op)
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Object *obedit = CTX_data_edit_object(C);
Object *obact = CTX_data_active_object(C);
bool extend = RNA_boolean_get(op->ptr, "extend");
@@ -2311,9 +2319,9 @@ static int view3d_select_exec(bContext *C, wmOperator *op)
* or paint-select to allow pose bone select with vert/face select */
bool object = (RNA_boolean_get(op->ptr, "object") &&
(obedit ||
- BKE_paint_select_elem_test(obact) ||
+ BKE_paint_select_elem_test(obact, workspace->object_mode) ||
/* so its possible to select bones in weightpaint mode (LMB select) */
- (obact && (obact->mode & OB_MODE_WEIGHT_PAINT) && BKE_object_pose_armature_get(obact))));
+ (obact && (workspace->object_mode & OB_MODE_WEIGHT_PAINT) && BKE_object_pose_armature_get(obact))));
bool retval = false;
int location[2];
@@ -2347,11 +2355,11 @@ static int view3d_select_exec(bContext *C, wmOperator *op)
retval = ED_curve_editfont_select_pick(C, location, extend, deselect, toggle);
}
- else if (obact && obact->mode & OB_MODE_PARTICLE_EDIT)
+ else if (obact && workspace->object_mode & OB_MODE_PARTICLE_EDIT)
return PE_mouse_particles(C, location, extend, deselect, toggle);
- else if (obact && BKE_paint_select_face_test(obact))
+ else if (obact && BKE_paint_select_face_test(obact, workspace->object_mode))
retval = paintface_mouse_select(C, obact, location, extend, deselect, toggle);
- else if (BKE_paint_select_vert_test(obact))
+ else if (BKE_paint_select_vert_test(obact, workspace->object_mode))
retval = ed_wpaint_vertex_select_pick(C, location, extend, deselect, toggle, obact);
else
retval = ed_object_select_pick(C, location, extend, deselect, toggle, center, enumerate, object);
@@ -2856,6 +2864,8 @@ static bool object_circle_select(ViewContext *vc, const bool select, const int m
/* not a real operator, only for circle test */
static int view3d_circle_select_exec(bContext *C, wmOperator *op)
{
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
Scene *scene = CTX_data_scene(C);
Object *obact = CTX_data_active_object(C);
const int radius = RNA_int_get(op->ptr, "radius");
@@ -2863,35 +2873,33 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op)
const int mval[2] = {RNA_int_get(op->ptr, "x"),
RNA_int_get(op->ptr, "y")};
- if (CTX_data_edit_object(C) || BKE_paint_select_elem_test(obact) ||
- (obact && (obact->mode & (OB_MODE_PARTICLE_EDIT | OB_MODE_POSE))) )
+ if (CTX_data_edit_object(C) || BKE_paint_select_elem_test(obact, eval_ctx.object_mode) ||
+ (obact && (eval_ctx.object_mode & (OB_MODE_PARTICLE_EDIT | OB_MODE_POSE))) )
{
- EvaluationContext eval_ctx;
ViewContext vc;
-
+
view3d_operator_needs_opengl(C);
-
- CTX_data_eval_ctx(C, &eval_ctx);
+
view3d_set_viewcontext(C, &vc);
if (CTX_data_edit_object(C)) {
obedit_circle_select(&eval_ctx, &vc, select, mval, (float)radius);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obact->data);
}
- else if (BKE_paint_select_face_test(obact)) {
+ else if (BKE_paint_select_face_test(obact, eval_ctx.object_mode)) {
paint_facesel_circle_select(&eval_ctx, &vc, select, mval, (float)radius);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obact->data);
}
- else if (BKE_paint_select_vert_test(obact)) {
+ else if (BKE_paint_select_vert_test(obact, eval_ctx.object_mode)) {
paint_vertsel_circle_select(&eval_ctx, &vc, select, mval, (float)radius);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obact->data);
}
- else if (obact->mode & OB_MODE_POSE)
+ else if (eval_ctx.object_mode & OB_MODE_POSE)
pose_circle_select(&vc, select, mval, (float)radius);
else
return PE_circle_select(C, select, mval, (float)radius);
}
- else if (obact && obact->mode & OB_MODE_SCULPT) {
+ else if (obact && eval_ctx.object_mode & OB_MODE_SCULPT) {
return OPERATOR_CANCELLED;
}
else {
diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c
index 1df29201bf6..40dd2f0f428 100644
--- a/source/blender/editors/space_view3d/view3d_snap.c
+++ b/source/blender/editors/space_view3d/view3d_snap.c
@@ -113,7 +113,7 @@ static int snap_sel_to_grid_exec(bContext *C, wmOperator *UNUSED(op))
CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects)
{
- if (ob->mode & OB_MODE_POSE) {
+ if (eval_ctx.object_mode & OB_MODE_POSE) {
bPoseChannel *pchan;
bArmature *arm = ob->data;
@@ -272,7 +272,7 @@ static int snap_selected_to_location(bContext *C, const float snap_target_global
ED_transverts_update_obedit(&tvs, obedit);
ED_transverts_free(&tvs);
}
- else if (obact && (obact->mode & OB_MODE_POSE)) {
+ else if (obact && (eval_ctx.object_mode & OB_MODE_POSE)) {
struct KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_LOCATION_ID);
bPoseChannel *pchan;
@@ -554,6 +554,8 @@ static void bundle_midpoint(Scene *scene, Object *ob, float vec[3])
static bool snap_curs_to_sel_ex(bContext *C, float cursor[3])
{
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
Object *obedit = CTX_data_edit_object(C);
Scene *scene = CTX_data_scene(C);
View3D *v3d = CTX_wm_view3d(C);
@@ -599,7 +601,7 @@ static bool snap_curs_to_sel_ex(bContext *C, float cursor[3])
else {
Object *obact = CTX_data_active_object(C);
- if (obact && (obact->mode & OB_MODE_POSE)) {
+ if (obact && (eval_ctx.object_mode & OB_MODE_POSE)) {
bArmature *arm = obact->data;
bPoseChannel *pchan;
for (pchan = obact->pose->chanbase.first; pchan; pchan = pchan->next) {
@@ -701,7 +703,8 @@ static bool snap_calc_active_center(bContext *C, const bool select_only, float r
Object *ob = CTX_data_active_object(C);
if (ob) {
- if (ob->mode & OB_MODE_POSE) {
+ const WorkSpace *workspace = CTX_wm_workspace(C);
+ if (workspace->object_mode & OB_MODE_POSE) {
bPoseChannel *pchan = BKE_pose_channel_active(ob);
if (pchan) {
if (!select_only || (pchan->bone->flag & BONE_SELECTED)) {
diff --git a/source/blender/editors/space_view3d/view3d_utils.c b/source/blender/editors/space_view3d/view3d_utils.c
index 7bb3f443ac6..92b3ec19acb 100644
--- a/source/blender/editors/space_view3d/view3d_utils.c
+++ b/source/blender/editors/space_view3d/view3d_utils.c
@@ -161,7 +161,7 @@ void view3d_operator_needs_opengl(const bContext *C)
view3d_region_operator_needs_opengl(win, ar);
}
-void view3d_region_operator_needs_opengl(wmWindow *win, ARegion *ar)
+void view3d_region_operator_needs_opengl(wmWindow *UNUSED(win), ARegion *ar)
{
/* for debugging purpose, context should always be OK */
if ((ar == NULL) || (ar->regiontype != RGN_TYPE_WINDOW)) {
@@ -170,7 +170,7 @@ void view3d_region_operator_needs_opengl(wmWindow *win, ARegion *ar)
else {
RegionView3D *rv3d = ar->regiondata;
- wmSubWindowSet(win, ar->swinid);
+ wmViewport(&ar->winrct); // TODO: bad
gpuLoadProjectionMatrix(rv3d->winmat);
gpuLoadMatrix(rv3d->viewmat);
}
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index 0597f2806b3..4ccf86138e7 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -879,7 +879,7 @@ int view3d_opengl_select(
ARegion *ar = vc->ar;
rcti rect;
int hits;
- const bool use_obedit_skip = (scene->obedit != NULL) && (vc->obedit == NULL);
+ const bool use_obedit_skip = (OBEDIT_FROM_EVAL_CTX(eval_ctx) != NULL) && (vc->obedit == NULL);
const bool is_pick_select = (U.gpu_select_pick_deph != 0);
const bool do_passes = (
(is_pick_select == false) &&
@@ -954,7 +954,9 @@ int view3d_opengl_select(
else
#else
{
- DRW_draw_select_loop(graph, ar, v3d, use_obedit_skip, use_nearest, &rect);
+ DRW_draw_select_loop(
+ graph, ar, v3d, eval_ctx->object_mode,
+ use_obedit_skip, use_nearest, &rect);
}
#endif /* WITH_OPENGL_LEGACY */
@@ -971,7 +973,9 @@ int view3d_opengl_select(
else
#else
{
- DRW_draw_select_loop(graph, ar, v3d, use_obedit_skip, use_nearest, &rect);
+ DRW_draw_select_loop(
+ graph, ar, v3d, eval_ctx->object_mode,
+ use_obedit_skip, use_nearest, &rect);
}
#endif /* WITH_OPENGL_LEGACY */
@@ -1054,12 +1058,15 @@ int ED_view3d_view_layer_set(int lay, const int *values, int *active)
static ListBase queue_back;
static void game_engine_save_state(bContext *C, wmWindow *win)
{
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
Object *obact = CTX_data_active_object(C);
glPushAttrib(GL_ALL_ATTRIB_BITS);
- if (obact && obact->mode & OB_MODE_TEXTURE_PAINT)
+ if (obact && eval_ctx.object_mode & OB_MODE_TEXTURE_PAINT) {
GPU_paint_set_mipmap(1);
+ }
queue_back = win->queue;
@@ -1068,11 +1075,13 @@ static void game_engine_save_state(bContext *C, wmWindow *win)
static void game_engine_restore_state(bContext *C, wmWindow *win)
{
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
Object *obact = CTX_data_active_object(C);
- if (obact && obact->mode & OB_MODE_TEXTURE_PAINT)
+ if (obact && eval_ctx.object_mode & OB_MODE_TEXTURE_PAINT) {
GPU_paint_set_mipmap(0);
-
+ }
/* check because closing win can set to NULL */
if (win) {
win->queue = queue_back;
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 9f7b438e338..a4bce5b0f1d 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -1890,7 +1890,7 @@ static void drawAutoKeyWarning(TransInfo *UNUSED(t), ARegion *ar)
#endif
/* autokey recording icon... */
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
xco -= U.widget_unit;
@@ -2624,10 +2624,7 @@ static void constraintTransLim(TransInfo *t, TransData *td)
if (td->con) {
const bConstraintTypeInfo *ctiLoc = BKE_constraint_typeinfo_from_type(CONSTRAINT_TYPE_LOCLIMIT);
const bConstraintTypeInfo *ctiDist = BKE_constraint_typeinfo_from_type(CONSTRAINT_TYPE_DISTLIMIT);
- EvaluationContext eval_ctx;
- CTX_data_eval_ctx(t->context, &eval_ctx);
-
bConstraintOb cob = {NULL};
bConstraint *con;
float ctime = (float)(t->scene->r.cfra);
@@ -2676,7 +2673,7 @@ static void constraintTransLim(TransInfo *t, TransData *td)
}
/* get constraint targets if needed */
- BKE_constraint_targets_for_solving_get(&eval_ctx, con, &cob, &targets, ctime);
+ BKE_constraint_targets_for_solving_get(&t->eval_ctx, con, &cob, &targets, ctime);
/* do constraint */
cti->evaluate_constraint(con, &cob, &targets);
@@ -6883,7 +6880,7 @@ static void drawEdgeSlide(TransInfo *t)
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
gpuPushMatrix();
gpuMultMatrix(t->obedit->obmat);
@@ -7495,7 +7492,7 @@ static void drawVertSlide(TransInfo *t)
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
gpuPushMatrix();
gpuMultMatrix(t->obedit->obmat);
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index 4ad66c0a9a5..b198918b698 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -41,6 +41,8 @@
#include "DNA_listBase.h"
+#include "DEG_depsgraph.h"
+
/* ************************** Types ***************************** */
struct Depsgraph;
@@ -66,6 +68,8 @@ struct EditBone;
struct RenderEngineType;
struct SnapObjectContext;
+#include "DNA_object_enums.h"
+
/* transinfo->redraw */
typedef enum {
TREDRAW_NOTHING = 0,
@@ -465,6 +469,7 @@ typedef struct TransInfo {
bool remove_on_cancel; /* remove elements if operator is canceled */
+ EvaluationContext eval_ctx;
void *view;
struct bContext *context; /* Only valid (non null) during an operator called function. */
struct ScrArea *sa;
@@ -649,7 +654,8 @@ void restoreBones(TransInfo *t);
#define MANIPULATOR_AXIS_LINE_WIDTH 2.0f
-bool gimbal_axis(struct Object *ob, float gmat[3][3]); /* return 0 when no gimbal for selection */
+/* return 0 when no gimbal for selection */
+bool gimbal_axis(struct Object *ob, float gmat[3][3], const eObjectMode object_mode);
/*********************** TransData Creation and General Handling *********** */
void createTransData(struct bContext *C, TransInfo *t);
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 730ca70547b..96970fa8a0f 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -998,7 +998,7 @@ static short pose_grab_with_ik(Object *ob)
Bone *bonec;
short tot_ik = 0;
- if ((ob == NULL) || (ob->pose == NULL) || (ob->mode & OB_MODE_POSE) == 0)
+ if ((ob == NULL) || (ob->pose == NULL))
return 0;
arm = ob->data;
@@ -2049,9 +2049,7 @@ void flushTransParticles(TransInfo *t)
point->flag |= PEP_EDIT_RECALC;
}
- EvaluationContext eval_ctx;
- CTX_data_eval_ctx(t->context, &eval_ctx);
- PE_update_object(&eval_ctx, scene, view_layer, OBACT(view_layer), 1);
+ PE_update_object(&t->eval_ctx, scene, view_layer, OBACT(view_layer), 1);
}
/* ********************* mesh ****************** */
@@ -2463,7 +2461,6 @@ static void createTransEditVerts(TransInfo *t)
{
TransData *tob = NULL;
TransDataExtension *tx = NULL;
- EvaluationContext eval_ctx;
BMEditMesh *em = BKE_editmesh_from_object(t->obedit);
Mesh *me = t->obedit->data;
BMesh *bm = em->bm;
@@ -2482,10 +2479,6 @@ static void createTransEditVerts(TransInfo *t)
int island_info_tot;
int *island_vert_map = NULL;
- DEG_evaluation_context_init_from_scene(&eval_ctx,
- t->scene, t->view_layer, t->engine_type,
- DAG_EVAL_VIEWPORT);
-
/* Even for translation this is needed because of island-orientation, see: T51651. */
const bool is_island_center = (t->around == V3D_AROUND_LOCAL_ORIGINS);
/* Original index of our connected vertex when connected distances are calculated.
@@ -2566,10 +2559,10 @@ static void createTransEditVerts(TransInfo *t)
/* detect CrazySpace [tm] */
if (modifiers_getCageIndex(t->scene, t->obedit, NULL, 1) != -1) {
int totleft = -1;
- if (modifiers_isCorrectableDeformed(t->scene, t->obedit)) {
+ if (modifiers_isCorrectableDeformed(&t->eval_ctx, t->scene, t->obedit)) {
/* check if we can use deform matrices for modifier from the
* start up to stack, they are more accurate than quats */
- totleft = BKE_crazyspace_get_first_deform_matrices_editbmesh(&eval_ctx, t->scene, t->obedit, em, &defmats, &defcos);
+ totleft = BKE_crazyspace_get_first_deform_matrices_editbmesh(&t->eval_ctx, t->scene, t->obedit, em, &defmats, &defcos);
}
/* if we still have more modifiers, also do crazyspace
@@ -2582,7 +2575,7 @@ static void createTransEditVerts(TransInfo *t)
if (totleft > 0)
#endif
{
- mappedcos = BKE_crazyspace_get_mapped_editverts(&eval_ctx, t->scene, t->obedit);
+ mappedcos = BKE_crazyspace_get_mapped_editverts(&t->eval_ctx, t->scene, t->obedit);
quats = MEM_mallocN(em->bm->totvert * sizeof(*quats), "crazy quats");
BKE_crazyspace_set_quats_editmesh(em, defcos, mappedcos, quats, !prop_mode);
if (mappedcos)
@@ -2976,7 +2969,7 @@ static void createTransUVs(bContext *C, TransInfo *t)
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
BMLoop *l;
- if (!uvedit_face_visible_test(scene, ima, efa)) {
+ if (!uvedit_face_visible_test(scene, t->obedit, ima, efa)) {
BM_elem_flag_disable(efa, BM_ELEM_TAG);
continue;
}
@@ -5408,9 +5401,6 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob)
Scene *scene = t->scene;
bool constinv;
bool skip_invert = false;
- EvaluationContext eval_ctx;
-
- CTX_data_eval_ctx(t->context, &eval_ctx);
if (t->mode != TFM_DUMMY && ob->rigidbody_object) {
float rot[3][3], scale[3];
@@ -5458,11 +5448,11 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob)
if (skip_invert == false && constinv == false) {
ob->transflag |= OB_NO_CONSTRAINTS; /* BKE_object_where_is_calc_time checks this */
- BKE_object_where_is_calc(&eval_ctx, t->scene, ob);
+ BKE_object_where_is_calc(&t->eval_ctx, t->scene, ob);
ob->transflag &= ~OB_NO_CONSTRAINTS;
}
else
- BKE_object_where_is_calc(&eval_ctx, t->scene, ob);
+ BKE_object_where_is_calc(&t->eval_ctx, t->scene, ob);
td->ob = ob;
@@ -6103,14 +6093,11 @@ static void special_aftertrans_update__mesh(bContext *UNUSED(C), TransInfo *t)
* */
void special_aftertrans_update(bContext *C, TransInfo *t)
{
- EvaluationContext eval_ctx;
Object *ob;
// short redrawipo=0, resetslowpar=1;
const bool canceled = (t->state == TRANS_CANCEL);
const bool duplicate = (t->mode == TFM_TIME_DUPLICATE);
- CTX_data_eval_ctx(C, &eval_ctx);
-
/* early out when nothing happened */
if (t->total == 0 || t->mode == TFM_DUMMY)
return;
@@ -6449,7 +6436,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
* we need to update the pose otherwise no updates get called during
* transform and the auto-ik is not applied. see [#26164] */
struct Object *pose_ob = t->poseobj;
- BKE_pose_where_is(&eval_ctx, t->scene, pose_ob);
+ BKE_pose_where_is(&t->eval_ctx, t->scene, pose_ob);
}
/* set BONE_TRANSFORM flags for autokey, manipulator draw might have changed them */
@@ -6493,7 +6480,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
}
else if ((t->view_layer->basact) &&
(ob = t->view_layer->basact->object) &&
- (ob->mode & OB_MODE_PARTICLE_EDIT) &&
+ (t->eval_ctx.object_mode & OB_MODE_PARTICLE_EDIT) &&
PE_get_current(t->scene, t->view_layer, ob))
{
/* do nothing */
@@ -8231,26 +8218,28 @@ void createTransData(bContext *C, TransInfo *t)
t->poseobj = ob; /* <- tsk tsk, this is going to give issues one day */
}
}
- else if (ob && (ob->mode & OB_MODE_POSE)) {
+ else if (ob && (t->eval_ctx.object_mode & OB_MODE_POSE)) {
// XXX this is currently limited to active armature only...
// XXX active-layer checking isn't done as that should probably be checked through context instead
createTransPose(t, ob);
}
- else if (ob && (ob->mode & OB_MODE_WEIGHT_PAINT) && !(t->options & CTX_PAINT_CURVE)) {
+ else if (ob && (t->eval_ctx.object_mode & OB_MODE_WEIGHT_PAINT) && !(t->options & CTX_PAINT_CURVE)) {
/* important that ob_armature can be set even when its not selected [#23412]
* lines below just check is also visible */
Object *ob_armature = modifiers_isDeformedByArmature(ob);
- if (ob_armature && ob_armature->mode & OB_MODE_POSE) {
+ if (ob_armature) {
+// const bArmature *arm = ob_armature->data;
Base *base_arm = BKE_view_layer_base_find(t->view_layer, ob_armature);
if (base_arm) {
if (BASE_VISIBLE(base_arm)) {
createTransPose(t, ob_armature);
}
}
-
}
}
- else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT) && PE_start_edit(PE_get_current(scene, view_layer, ob))) {
+ else if (ob && (t->eval_ctx.object_mode & OB_MODE_PARTICLE_EDIT) &&
+ PE_start_edit(PE_get_current(scene, view_layer, ob)))
+ {
createTransParticleVerts(C, t);
t->flag |= T_POINTS;
@@ -8260,7 +8249,7 @@ void createTransData(bContext *C, TransInfo *t)
sort_trans_data_dist(t);
}
}
- else if (ob && (ob->mode & OB_MODE_ALL_PAINT)) {
+ else if (ob && (t->eval_ctx.object_mode & OB_MODE_ALL_PAINT)) {
if ((t->options & CTX_PAINT_CURVE) && !ELEM(t->mode, TFM_SHEAR, TFM_SHRINKFATTEN)) {
t->flag |= T_POINTS | T_2D_EDIT;
createTransPaintCurveVerts(C, t);
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index 1aa4513e99b..fdf5665b6d4 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -715,9 +715,6 @@ static void recalcData_spaceclip(TransInfo *t)
static void recalcData_objects(TransInfo *t)
{
Base *base = t->view_layer->basact;
- EvaluationContext eval_ctx;
-
- CTX_data_eval_ctx(t->context, &eval_ctx);
if (t->obedit) {
if (ELEM(t->obedit->type, OB_CURVE, OB_SURF)) {
@@ -902,9 +899,11 @@ static void recalcData_objects(TransInfo *t)
BIK_clear_data(ob->pose);
}
else
- BKE_pose_where_is(&eval_ctx, t->scene, ob);
+ BKE_pose_where_is(&t->eval_ctx, t->scene, ob);
}
- else if (base && (base->object->mode & OB_MODE_PARTICLE_EDIT) && PE_get_current(t->scene, t->view_layer, base->object)) {
+ else if (base && (t->eval_ctx.object_mode & OB_MODE_PARTICLE_EDIT) &&
+ PE_get_current(t->scene, t->view_layer, base->object))
+ {
if (t->state != TRANS_CANCEL) {
applyProject(t);
}
@@ -1115,6 +1114,7 @@ static int initTransInfo_edit_pet_to_flag(const int proportional)
*/
void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *event)
{
+ CTX_data_eval_ctx(C, &t->eval_ctx);
Depsgraph *depsgraph = CTX_data_depsgraph(C);
Scene *sce = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
@@ -1266,7 +1266,7 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
}
}
- if (ob && ob->mode & OB_MODE_ALL_PAINT) {
+ if (ob && t->eval_ctx.object_mode & OB_MODE_ALL_PAINT) {
Paint *p = BKE_paint_get_active_from_context(C);
if (p && p->brush && (p->brush->flag & BRUSH_CURVE)) {
t->options |= CTX_PAINT_CURVE;
@@ -1815,7 +1815,7 @@ bool calculateCenterActive(TransInfo *t, bool select_only, float r_center[3])
}
}
else if (t->options & CTX_PAINT_CURVE) {
- Paint *p = BKE_paint_get_active(t->scene, t->view_layer);
+ Paint *p = BKE_paint_get_active(t->scene, t->view_layer, t->eval_ctx.object_mode);
Brush *br = p->brush;
PaintCurve *pc = br->paint_curve;
copy_v3_v3(r_center, pc->points[pc->add_index - 1].bez.vec[1]);
diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c
index 0643687c29a..1839583015c 100644
--- a/source/blender/editors/transform/transform_manipulator.c
+++ b/source/blender/editors/transform/transform_manipulator.c
@@ -63,6 +63,8 @@
#include "BIF_gl.h"
+#include "DEG_depsgraph.h"
+
#include "WM_api.h"
#include "WM_types.h"
#include "WM_message.h"
@@ -518,9 +520,9 @@ static bool test_rotmode_euler(short rotmode)
return (ELEM(rotmode, ROT_MODE_AXISANGLE, ROT_MODE_QUAT)) ? 0 : 1;
}
-bool gimbal_axis(Object *ob, float gmat[3][3])
+bool gimbal_axis(Object *ob, float gmat[3][3], const eObjectMode object_mode)
{
- if (ob->mode & OB_MODE_POSE) {
+ if (object_mode & OB_MODE_POSE) {
bPoseChannel *pchan = BKE_pose_channel_active(ob);
if (pchan) {
@@ -589,6 +591,7 @@ static int calc_manipulator_stats(
const bContext *C, bool use_only_center,
struct TransformBounds *tbounds)
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = CTX_wm_region(C);
Scene *scene = CTX_data_scene(C);
@@ -626,7 +629,7 @@ static int calc_manipulator_stats(
case V3D_MANIP_GIMBAL:
{
float mat[3][3];
- if (gimbal_axis(ob, mat)) {
+ if (gimbal_axis(ob, mat, workspace->object_mode)) {
copy_m4_m3(rv3d->twmat, mat);
break;
}
@@ -635,7 +638,7 @@ static int calc_manipulator_stats(
}
case V3D_MANIP_NORMAL:
{
- if (obedit || ob->mode & OB_MODE_POSE) {
+ if (obedit || workspace->object_mode & OB_MODE_POSE) {
float mat[3][3];
ED_getTransformOrientationMatrix(C, mat, v3d->around);
copy_m4_m3(rv3d->twmat, mat);
@@ -646,7 +649,7 @@ static int calc_manipulator_stats(
}
case V3D_MANIP_LOCAL:
{
- if (ob->mode & OB_MODE_POSE) {
+ if (workspace->object_mode & OB_MODE_POSE) {
/* each bone moves on its own local axis, but to avoid confusion,
* use the active pones axis for display [#33575], this works as expected on a single bone
* and users who select many bones will understand whats going on and what local means
@@ -688,7 +691,7 @@ static int calc_manipulator_stats(
#ifdef USE_AXIS_BOUNDS
copy_m3_m4(tbounds->axis, rv3d->twmat);
- if (ob && ob->mode & OB_MODE_EDIT) {
+ if (ob && workspace->object_mode & OB_MODE_EDIT) {
float diff_mat[3][3];
copy_m3_m4(diff_mat, ob->obmat);
normalize_m3(diff_mat);
@@ -931,7 +934,7 @@ static int calc_manipulator_stats(
mul_m4_v3(obedit->obmat, tbounds->max);
}
}
- else if (ob && (ob->mode & OB_MODE_POSE)) {
+ else if (ob && (workspace->object_mode & OB_MODE_POSE)) {
bPoseChannel *pchan;
int mode = TFM_ROTATION; // mislead counting bones... bah. We don't know the manipulator mode, could be mixed
bool ok = false;
@@ -969,10 +972,10 @@ static int calc_manipulator_stats(
mul_m4_v3(ob->obmat, tbounds->max);
}
}
- else if (ob && (ob->mode & OB_MODE_ALL_PAINT)) {
+ else if (ob && (workspace->object_mode & OB_MODE_ALL_PAINT)) {
/* pass */
}
- else if (ob && ob->mode & OB_MODE_PARTICLE_EDIT) {
+ else if (ob && workspace->object_mode & OB_MODE_PARTICLE_EDIT) {
PTCacheEdit *edit = PE_get_current(scene, view_layer, ob);
PTCacheEditPoint *point;
PTCacheEditKey *ek;
@@ -1062,12 +1065,13 @@ static void manipulator_prepare_mat(
case V3D_AROUND_CENTER_BOUNDS:
case V3D_AROUND_ACTIVE:
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
bGPdata *gpd = CTX_data_gpencil_data(C);
Object *ob = OBACT(view_layer);
- if (((v3d->around == V3D_AROUND_ACTIVE) && (scene->obedit == NULL)) &&
+ if (((v3d->around == V3D_AROUND_ACTIVE) && ((workspace->object_mode & OB_MODE_EDIT) == 0)) &&
((gpd == NULL) || !(gpd->flag & GP_DATA_STROKE_EDITMODE)) &&
- (!(ob->mode & OB_MODE_POSE)))
+ (!(workspace->object_mode & OB_MODE_POSE)))
{
copy_v3_v3(rv3d->twmat[3], ob->obmat[3]);
}
@@ -1656,10 +1660,10 @@ static void WIDGETGROUP_xform_cage_draw_prepare(const bContext *C, wmManipulator
{
struct XFormCageWidgetGroup *xmgroup = mgroup->customdata;
wmManipulator *mpr = xmgroup->manipulator;
-
+ const WorkSpace *workspace = CTX_wm_workspace(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *ob = OBACT(view_layer);
- if (ob && ob->mode & OB_MODE_EDIT) {
+ if (ob && workspace->object_mode & OB_MODE_EDIT) {
copy_m4_m4(mpr->matrix_space, ob->obmat);
}
else {
diff --git a/source/blender/editors/transform/transform_manipulator2d.c b/source/blender/editors/transform/transform_manipulator2d.c
index 6e2d0d8c5c0..9b6dd187c15 100644
--- a/source/blender/editors/transform/transform_manipulator2d.c
+++ b/source/blender/editors/transform/transform_manipulator2d.c
@@ -368,7 +368,7 @@ bool ED_widgetgroup_manipulator2d_poll(const bContext *C, wmManipulatorGroupType
/* check if there's a selected poly */
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, ima, efa))
+ if (!uvedit_face_visible_test(scene, obedit, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c
index ab0e24671eb..d5d25888ec8 100644
--- a/source/blender/editors/transform/transform_ops.c
+++ b/source/blender/editors/transform/transform_ops.c
@@ -316,7 +316,8 @@ static void transformops_loopsel_hack(bContext *C, wmOperator *op)
/* still switch if we were originally in face select mode */
if ((ts->selectmode != selectmode_orig) && (selectmode_orig != SCE_SELECT_FACE)) {
- BMEditMesh *em = BKE_editmesh_from_object(scene->obedit);
+ Object *obedit = CTX_data_edit_object(C);
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
em->selectmode = ts->selectmode = selectmode_orig;
EDBM_selectmode_set(em);
}
diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c
index f8b11a0bcae..63eea11212c 100644
--- a/source/blender/editors/transform/transform_orientations.c
+++ b/source/blender/editors/transform/transform_orientations.c
@@ -55,6 +55,8 @@
#include "BKE_screen.h"
#include "BKE_workspace.h"
+#include "DEG_depsgraph.h"
+
#include "BLT_translation.h"
#include "ED_armature.h"
@@ -296,6 +298,7 @@ void BIF_createTransformOrientation(bContext *C, ReportList *reports,
ts = createViewSpace(C, reports, name, overwrite);
}
else {
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Object *obedit = CTX_data_edit_object(C);
Object *ob = CTX_data_active_object(C);
if (obedit) {
@@ -306,7 +309,7 @@ void BIF_createTransformOrientation(bContext *C, ReportList *reports,
else if (obedit->type == OB_CURVE)
ts = createCurveSpace(C, reports, name, overwrite);
}
- else if (ob && (ob->mode & OB_MODE_POSE)) {
+ else if (ob && (workspace->object_mode & OB_MODE_POSE)) {
ts = createBoneSpace(C, reports, name, overwrite);
}
else {
@@ -441,13 +444,13 @@ void initTransformOrientation(bContext *C, TransInfo *t)
case V3D_MANIP_GIMBAL:
unit_m3(t->spacemtx);
- if (ob && gimbal_axis(ob, t->spacemtx)) {
+ if (ob && gimbal_axis(ob, t->spacemtx, t->eval_ctx.object_mode)) {
BLI_strncpy(t->spacename, IFACE_("gimbal"), sizeof(t->spacename));
break;
}
ATTR_FALLTHROUGH; /* no gimbal fallthrough to normal */
case V3D_MANIP_NORMAL:
- if (obedit || (ob && ob->mode & OB_MODE_POSE)) {
+ if (obedit || (ob && t->eval_ctx.object_mode & OB_MODE_POSE)) {
BLI_strncpy(t->spacename, IFACE_("normal"), sizeof(t->spacename));
ED_getTransformOrientationMatrix(C, t->spacemtx, t->around);
break;
@@ -578,6 +581,7 @@ static unsigned int bm_mesh_faces_select_get_n(BMesh *bm, BMVert **elems, const
int getTransformOrientation_ex(const bContext *C, float normal[3], float plane[3], const short around)
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *obedit = CTX_data_edit_object(C);
Base *base;
@@ -1008,7 +1012,7 @@ int getTransformOrientation_ex(const bContext *C, float normal[3], float plane[3
mul_m3_v3(mat, plane);
}
}
- else if (ob && (ob->mode & OB_MODE_POSE)) {
+ else if (ob && (workspace->object_mode & OB_MODE_POSE)) {
bArmature *arm = ob->data;
bPoseChannel *pchan;
float imat[3][3], mat[3][3];
@@ -1048,7 +1052,7 @@ int getTransformOrientation_ex(const bContext *C, float normal[3], float plane[3
result = ORIENTATION_EDGE;
}
}
- else if (ob && (ob->mode & (OB_MODE_ALL_PAINT | OB_MODE_PARTICLE_EDIT))) {
+ else if (ob && (workspace->object_mode & (OB_MODE_ALL_PAINT | OB_MODE_PARTICLE_EDIT))) {
/* pass */
}
else {
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index 30aad46843d..9946f1ad546 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -70,6 +70,8 @@
#include "ED_view3d.h"
#include "ED_transform_snap_object_context.h"
+#include "DEG_depsgraph.h"
+
#include "UI_resources.h"
#include "UI_view2d.h"
@@ -542,7 +544,7 @@ static void initSnappingMode(TransInfo *t)
}
/* Particles edit mode*/
else if (t->tsnap.applySnap != NULL && // A snapping function actually exist
- (obedit == NULL && base_act && base_act->object && base_act->object->mode & OB_MODE_PARTICLE_EDIT))
+ (obedit == NULL && base_act && base_act->object && t->eval_ctx.object_mode & OB_MODE_PARTICLE_EDIT))
{
t->tsnap.modeSelect = SNAP_ALL;
}
diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c
index 8f0590eb5b9..14cd4bcc7ac 100644
--- a/source/blender/editors/transform/transform_snap_object.c
+++ b/source/blender/editors/transform/transform_snap_object.c
@@ -822,7 +822,7 @@ static bool raycastObjects(
Object **r_ob, float r_obmat[4][4],
ListBase *r_hit_list)
{
- Object *obedit = use_object_edit_cage ? sctx->scene->obedit : NULL;
+ Object *obedit = use_object_edit_cage ? OBEDIT_FROM_EVAL_CTX(&sctx->eval_ctx) : NULL;
struct RaycastObjUserData data = {
.ray_start = ray_start,
@@ -1358,7 +1358,7 @@ static bool snapArmature(
static bool snapCurve(
SnapData *snapdata,
- Object *ob, Curve *cu, float obmat[4][4],
+ Curve *cu, float obmat[4][4], bool use_obedit,
/* read/write args */
float *ray_depth, float *dist_px,
/* return args */
@@ -1376,12 +1376,12 @@ static bool snapCurve(
mul_m4_m4m4(lpmat, snapdata->pmat, obmat);
dist_px_sq = SQUARE(*dist_px);
- for (Nurb *nu = (ob->mode == OB_MODE_EDIT ? cu->editnurb->nurbs.first : cu->nurb.first); nu; nu = nu->next) {
+ for (Nurb *nu = (use_obedit ? cu->editnurb->nurbs.first : cu->nurb.first); nu; nu = nu->next) {
for (int u = 0; u < nu->pntsu; u++) {
switch (snapdata->snap_to) {
case SCE_SNAP_MODE_VERTEX:
{
- if (ob->mode == OB_MODE_EDIT) {
+ if (use_obedit) {
if (nu->bezt) {
/* don't snap to selected (moving) or hidden */
if (nu->bezt[u].f2 & SELECT || nu->bezt[u].hide != 0) {
@@ -1966,7 +1966,7 @@ static bool snapObject(
else if (ob->type == OB_CURVE) {
retval = snapCurve(
snapdata,
- ob, ob->data, obmat,
+ ob->data, obmat, use_obedit,
ray_depth, dist_px,
r_loc, r_no);
}
@@ -2060,7 +2060,7 @@ static bool snapObjectsRay(
float r_loc[3], float r_no[3],
Object **r_ob, float r_obmat[4][4])
{
- Object *obedit = use_object_edit_cage ? sctx->scene->obedit : NULL;
+ Object *obedit = use_object_edit_cage ? OBEDIT_FROM_EVAL_CTX(&sctx->eval_ctx) : NULL;
struct SnapObjUserData data = {
.snapdata = snapdata,
@@ -2096,7 +2096,8 @@ SnapObjectContext *ED_transform_snap_object_context_create(
sctx->bmain = bmain;
sctx->scene = scene;
- DEG_evaluation_context_init_from_scene(&sctx->eval_ctx, scene, view_layer, engine_type, DAG_EVAL_VIEWPORT);
+ DEG_evaluation_context_init_from_scene(
+ &sctx->eval_ctx, scene, view_layer, engine_type, OB_MODE_OBJECT, DAG_EVAL_VIEWPORT);
sctx->cache.object_map = BLI_ghash_ptr_new(__func__);
sctx->cache.mem_arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c
index b52cc20f71f..a5a26cf4d57 100644
--- a/source/blender/editors/util/ed_util.c
+++ b/source/blender/editors/util/ed_util.c
@@ -35,12 +35,14 @@
#include "MEM_guardedalloc.h"
+#include "DNA_armature_types.h"
#include "DNA_mesh_types.h"
#include "DNA_object_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
#include "DNA_scene_types.h"
#include "DNA_packedFile_types.h"
+#include "DNA_workspace_types.h"
#include "BLI_utildefines.h"
#include "BLI_string.h"
@@ -70,6 +72,8 @@
#include "ED_space_api.h"
#include "ED_util.h"
+#include "DEG_depsgraph.h"
+
#include "GPU_immediate.h"
#include "UI_interface.h"
@@ -86,11 +90,7 @@
void ED_editors_init(bContext *C)
{
wmWindowManager *wm = CTX_wm_manager(C);
- Main *bmain = CTX_data_main(C);
Scene *sce = CTX_data_scene(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Object *ob, *obact = (view_layer && view_layer->basact) ? view_layer->basact->object : NULL;
- ID *data;
/* This is called during initialization, so we don't want to store any reports */
ReportList *reports = CTX_wm_reports(C);
@@ -98,24 +98,6 @@ void ED_editors_init(bContext *C)
SWAP(int, reports->flag, reports_flag_prev);
- /* toggle on modes for objects that were saved with these enabled. for
- * e.g. linked objects we have to ensure that they are actually the
- * active object in this scene. */
- for (ob = bmain->object.first; ob; ob = ob->id.next) {
- int mode = ob->mode;
-
- if (mode == OB_MODE_OBJECT) {
- /* pass */
- }
- else {
- data = ob->data;
- ob->mode = OB_MODE_OBJECT;
- if ((ob == obact) && !ID_IS_LINKED(ob) && !(data && ID_IS_LINKED(data))) {
- ED_object_toggle_modes(C, mode);
- }
- }
- }
-
/* image editor paint mode */
if (sce) {
ED_space_image_paint_update(wm, sce);
@@ -128,7 +110,6 @@ void ED_editors_init(bContext *C)
void ED_editors_exit(bContext *C)
{
Main *bmain = CTX_data_main(C);
- Scene *sce;
if (!bmain)
return;
@@ -136,23 +117,20 @@ void ED_editors_exit(bContext *C)
/* frees all editmode undos */
undo_editmode_clear();
ED_undo_paint_free();
-
- for (sce = bmain->scene.first; sce; sce = sce->id.next) {
- if (sce->obedit) {
- Object *ob = sce->obedit;
-
- if (ob) {
- if (ob->type == OB_MESH) {
- Mesh *me = ob->data;
- if (me->edit_btmesh) {
- EDBM_mesh_free(me->edit_btmesh);
- MEM_freeN(me->edit_btmesh);
- me->edit_btmesh = NULL;
- }
- }
- else if (ob->type == OB_ARMATURE) {
- ED_armature_edit_free(ob->data);
- }
+
+ for (Object *ob = bmain->object.first; ob; ob = ob->id.next) {
+ if (ob->type == OB_MESH) {
+ Mesh *me = ob->data;
+ if (me->edit_btmesh) {
+ EDBM_mesh_free(me->edit_btmesh);
+ MEM_freeN(me->edit_btmesh);
+ me->edit_btmesh = NULL;
+ }
+ }
+ else if (ob->type == OB_ARMATURE) {
+ bArmature *arm = ob->data;
+ if (arm->edbo) {
+ ED_armature_edit_free(ob->data);
}
}
}
@@ -170,26 +148,35 @@ bool ED_editors_flush_edits(const bContext *C, bool for_render)
Object *ob;
Main *bmain = CTX_data_main(C);
+ eObjectMode object_mode = WM_windows_object_mode_get(bmain->wm.first);
+ if ((object_mode & (OB_MODE_SCULPT | OB_MODE_EDIT)) == 0) {
+ return has_edited;
+ }
+
/* loop through all data to find edit mode or object mode, because during
* exiting we might not have a context for edit object and multiple sculpt
* objects can exist at the same time */
for (ob = bmain->object.first; ob; ob = ob->id.next) {
- if (ob->mode & OB_MODE_SCULPT) {
- /* flush multires changes (for sculpt) */
- multires_force_update(ob);
- has_edited = true;
-
- if (for_render) {
- /* flush changes from dynamic topology sculpt */
- BKE_sculptsession_bm_to_me_for_render(ob);
- }
- else {
- /* Set reorder=false so that saving the file doesn't reorder
- * the BMesh's elements */
- BKE_sculptsession_bm_to_me(ob, false);
+ if (object_mode & OB_MODE_SCULPT) {
+ /* Don't allow flushing while in the middle of a stroke (frees data in use).
+ * Auto-save prevents this from happening but scripts may cause a flush on saving: T53986. */
+ if ((ob->sculpt && ob->sculpt->cache) == 0) {
+ /* flush multires changes (for sculpt) */
+ multires_force_update(ob);
+ has_edited = true;
+
+ if (for_render) {
+ /* flush changes from dynamic topology sculpt */
+ BKE_sculptsession_bm_to_me_for_render(ob);
+ }
+ else {
+ /* Set reorder=false so that saving the file doesn't reorder
+ * the BMesh's elements */
+ BKE_sculptsession_bm_to_me(ob, false);
+ }
}
}
- else if (ob->mode & OB_MODE_EDIT) {
+ else if (object_mode & OB_MODE_EDIT) {
/* get editmode results */
has_edited = true;
ED_object_editmode_load(ob);
diff --git a/source/blender/editors/util/undo.c b/source/blender/editors/util/undo.c
index dbf1cf46c61..8eaadb97888 100644
--- a/source/blender/editors/util/undo.c
+++ b/source/blender/editors/util/undo.c
@@ -49,6 +49,8 @@
#include "BKE_main.h"
#include "BKE_screen.h"
+#include "DEG_depsgraph.h"
+
#include "ED_armature.h"
#include "ED_particle.h"
#include "ED_curve.h"
@@ -77,6 +79,7 @@
void ED_undo_push(bContext *C, const char *str)
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Object *obedit = CTX_data_edit_object(C);
Object *obact = CTX_data_active_object(C);
@@ -102,24 +105,25 @@ void ED_undo_push(bContext *C, const char *str)
else if (obedit->type == OB_ARMATURE)
undo_push_armature(C, str);
}
- else if (obact && obact->mode & OB_MODE_PARTICLE_EDIT) {
+ else if (obact && workspace->object_mode & OB_MODE_PARTICLE_EDIT) {
if (U.undosteps == 0) return;
PE_undo_push(CTX_data_scene(C), CTX_data_view_layer(C), str);
}
- else if (obact && obact->mode & OB_MODE_SCULPT) {
+ else if (obact && workspace->object_mode & OB_MODE_SCULPT) {
/* do nothing for now */
}
else {
BKE_undo_write(C, str);
}
- WM_file_tag_modified(C);
+ WM_file_tag_modified();
}
/* note: also check undo_history_exec() in bottom if you change notifiers */
static int ed_undo_step(bContext *C, int step, const char *undoname)
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
wmWindowManager *wm = CTX_wm_manager(C);
wmWindow *win = CTX_wm_window(C);
Main *bmain = CTX_data_main(C);
@@ -143,7 +147,7 @@ static int ed_undo_step(bContext *C, int step, const char *undoname)
if (sa && (sa->spacetype == SPACE_IMAGE)) {
SpaceImage *sima = (SpaceImage *)sa->spacedata.first;
- if ((obact && (obact->mode & OB_MODE_TEXTURE_PAINT)) || (sima->mode == SI_MODE_PAINT)) {
+ if ((obact && (workspace->object_mode & OB_MODE_TEXTURE_PAINT)) || (sima->mode == SI_MODE_PAINT)) {
if (!ED_undo_paint_step(C, UNDO_PAINT_IMAGE, step, undoname) && undoname) {
if (U.uiflag & USER_GLOBALUNDO) {
ED_viewport_render_kill_jobs(wm, bmain, true);
@@ -177,13 +181,13 @@ static int ed_undo_step(bContext *C, int step, const char *undoname)
* That was inconsistent with editmode, and also makes for
* unecessarily tricky interaction with the other undo
* systems. */
- if (obact && obact->mode & OB_MODE_TEXTURE_PAINT) {
+ if (obact && workspace->object_mode & OB_MODE_TEXTURE_PAINT) {
ED_undo_paint_step(C, UNDO_PAINT_IMAGE, step, undoname);
}
- else if (obact && obact->mode & OB_MODE_SCULPT) {
+ else if (obact && workspace->object_mode & OB_MODE_SCULPT) {
ED_undo_paint_step(C, UNDO_PAINT_MESH, step, undoname);
}
- else if (obact && obact->mode & OB_MODE_PARTICLE_EDIT) {
+ else if (obact && workspace->object_mode & OB_MODE_PARTICLE_EDIT) {
if (step == 1)
PE_undo(scene, view_layer);
else
@@ -269,6 +273,7 @@ void ED_undo_pop_op(bContext *C, wmOperator *op)
/* name optionally, function used to check for operator redo panel */
bool ED_undo_is_valid(const bContext *C, const char *undoname)
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Object *obedit = CTX_data_edit_object(C);
Object *obact = CTX_data_active_object(C);
ScrArea *sa = CTX_wm_area(C);
@@ -276,7 +281,7 @@ bool ED_undo_is_valid(const bContext *C, const char *undoname)
if (sa && sa->spacetype == SPACE_IMAGE) {
SpaceImage *sima = (SpaceImage *)sa->spacedata.first;
- if ((obact && (obact->mode & OB_MODE_TEXTURE_PAINT)) || (sima->mode == SI_MODE_PAINT)) {
+ if ((obact && (workspace->object_mode & OB_MODE_TEXTURE_PAINT)) || (sima->mode == SI_MODE_PAINT)) {
return 1;
}
}
@@ -293,15 +298,15 @@ bool ED_undo_is_valid(const bContext *C, const char *undoname)
/* if below tests fail, global undo gets executed */
- if (obact && obact->mode & OB_MODE_TEXTURE_PAINT) {
+ if (obact && workspace->object_mode & OB_MODE_TEXTURE_PAINT) {
if (ED_undo_paint_is_valid(UNDO_PAINT_IMAGE, undoname))
return 1;
}
- else if (obact && obact->mode & OB_MODE_SCULPT) {
+ else if (obact && workspace->object_mode & OB_MODE_SCULPT) {
if (ED_undo_paint_is_valid(UNDO_PAINT_MESH, undoname))
return 1;
}
- else if (obact && obact->mode & OB_MODE_PARTICLE_EDIT) {
+ else if (obact && workspace->object_mode & OB_MODE_PARTICLE_EDIT) {
return PE_undo_is_valid(CTX_data_scene(C), CTX_data_view_layer(C));
}
@@ -522,6 +527,7 @@ enum {
static int get_undo_system(bContext *C)
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Object *obact = CTX_data_active_object(C);
Object *obedit = CTX_data_edit_object(C);
ScrArea *sa = CTX_wm_area(C);
@@ -530,7 +536,7 @@ static int get_undo_system(bContext *C)
if (sa && (sa->spacetype == SPACE_IMAGE)) {
SpaceImage *sima = (SpaceImage *)sa->spacedata.first;
- if ((obact && (obact->mode & OB_MODE_TEXTURE_PAINT)) || (sima->mode == SI_MODE_PAINT)) {
+ if ((obact && (workspace->object_mode & OB_MODE_TEXTURE_PAINT)) || (sima->mode == SI_MODE_PAINT)) {
if (!ED_undo_paint_empty(UNDO_PAINT_IMAGE))
return UNDOSYSTEM_IMAPAINT;
}
@@ -543,13 +549,13 @@ static int get_undo_system(bContext *C)
}
else {
if (obact) {
- if (obact->mode & OB_MODE_PARTICLE_EDIT)
+ if (workspace->object_mode & OB_MODE_PARTICLE_EDIT)
return UNDOSYSTEM_PARTICLE;
- else if (obact->mode & OB_MODE_TEXTURE_PAINT) {
+ else if (workspace->object_mode & OB_MODE_TEXTURE_PAINT) {
if (!ED_undo_paint_empty(UNDO_PAINT_IMAGE))
return UNDOSYSTEM_IMAPAINT;
}
- else if (obact->mode & OB_MODE_SCULPT) {
+ else if (workspace->object_mode & OB_MODE_SCULPT) {
if (!ED_undo_paint_empty(UNDO_PAINT_MESH))
return UNDOSYSTEM_SCULPT;
}
diff --git a/source/blender/editors/uvedit/uvedit_buttons.c b/source/blender/editors/uvedit/uvedit_buttons.c
index 6b4dd0f0210..f037783bd5e 100644
--- a/source/blender/editors/uvedit/uvedit_buttons.c
+++ b/source/blender/editors/uvedit/uvedit_buttons.c
@@ -61,7 +61,7 @@
/* UV Utilities */
-static int uvedit_center(Scene *scene, BMEditMesh *em, Image *ima, float center[2])
+static int uvedit_center(Scene *scene, Object *obedit, BMEditMesh *em, Image *ima, float center[2])
{
BMFace *f;
BMLoop *l;
@@ -73,7 +73,7 @@ static int uvedit_center(Scene *scene, BMEditMesh *em, Image *ima, float center[
zero_v2(center);
BM_ITER_MESH (f, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, ima, f))
+ if (!uvedit_face_visible_test(scene, obedit, ima, f))
continue;
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
@@ -93,7 +93,7 @@ static int uvedit_center(Scene *scene, BMEditMesh *em, Image *ima, float center[
return tot;
}
-static void uvedit_translate(Scene *scene, BMEditMesh *em, Image *ima, float delta[2])
+static void uvedit_translate(Scene *scene, Object *obedit, BMEditMesh *em, Image *ima, float delta[2])
{
BMFace *f;
BMLoop *l;
@@ -103,7 +103,7 @@ static void uvedit_translate(Scene *scene, BMEditMesh *em, Image *ima, float del
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
BM_ITER_MESH (f, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, ima, f))
+ if (!uvedit_face_visible_test(scene, obedit, ima, f))
continue;
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
@@ -134,7 +134,7 @@ static void uvedit_vertex_buttons(const bContext *C, uiBlock *block)
em = BKE_editmesh_from_object(obedit);
- if (uvedit_center(scene, em, ima, center)) {
+ if (uvedit_center(scene, obedit, em, ima, center)) {
float range_xy[2][2] = {
{-10.0f, 10.0f},
{-10.0f, 10.0f},
@@ -190,7 +190,7 @@ static void do_uvedit_vertex(bContext *C, void *UNUSED(arg), int event)
em = BKE_editmesh_from_object(obedit);
ED_space_image_get_size(sima, &imx, &imy);
- uvedit_center(scene, em, ima, center);
+ uvedit_center(scene, obedit, em, ima, center);
if (sima->flag & SI_COORDFLOATS) {
delta[0] = uvedit_old_center[0] - center[0];
@@ -201,7 +201,7 @@ static void do_uvedit_vertex(bContext *C, void *UNUSED(arg), int event)
delta[1] = uvedit_old_center[1] / imy - center[1];
}
- uvedit_translate(scene, em, ima, delta);
+ uvedit_translate(scene, obedit, em, ima, delta);
WM_event_add_notifier(C, NC_IMAGE, sima->image);
}
diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c
index 45fa35766f1..b4d32b3d03a 100644
--- a/source/blender/editors/uvedit/uvedit_draw.c
+++ b/source/blender/editors/uvedit/uvedit_draw.c
@@ -179,7 +179,7 @@ static void draw_uvs_shadow(Object *obedit)
immUnbindProgram();
}
-static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, const BMFace *efa_act)
+static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, Object *obedit, BMEditMesh *em, const BMFace *efa_act)
{
BMesh *bm = em->bm;
BMFace *efa;
@@ -217,7 +217,7 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, con
totarea += BM_face_calc_area(efa);
totuvarea += area_poly_v2(tf_uv, efa->len);
- if (uvedit_face_visible_test(scene, ima, efa)) {
+ if (uvedit_face_visible_test(scene, obedit, ima, efa)) {
BM_elem_flag_enable(efa, BM_ELEM_TAG);
}
else {
@@ -314,7 +314,7 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, con
immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
- if (uvedit_face_visible_test(scene, ima, efa)) {
+ if (uvedit_face_visible_test(scene, obedit, ima, efa)) {
const int efa_len = efa->len;
float (*tf_uv)[2] = (float (*)[2])BLI_buffer_reinit_data(&tf_uv_buf, vec2f, efa_len);
float (*tf_uvorig)[2] = (float (*)[2])BLI_buffer_reinit_data(&tf_uvorig_buf, vec2f, efa_len);
@@ -669,12 +669,12 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje
/* 2. draw colored faces */
if (sima->flag & SI_DRAW_STRETCH) {
- draw_uvs_stretch(sima, scene, em, efa_act);
+ draw_uvs_stretch(sima, scene, obedit, em, efa_act);
}
else {
unsigned int tri_count = 0;
BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) {
- if (uvedit_face_visible_test(scene, ima, efa)) {
+ if (uvedit_face_visible_test(scene, obedit, ima, efa)) {
BM_elem_flag_enable(efa, BM_ELEM_TAG);
tri_count += efa->len - 2;
}
@@ -687,7 +687,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje
/* draw transparent faces */
UI_GetThemeColor4ubv(TH_FACE, col1);
UI_GetThemeColor4ubv(TH_FACE_SELECT, col2);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
Gwn_VertFormat *format = immVertexFormat();
@@ -722,7 +722,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje
glDisable(GL_BLEND);
}
else {
- if (efa_act && !uvedit_face_visible_test(scene, ima, efa_act)) {
+ if (efa_act && !uvedit_face_visible_test(scene, obedit, ima, efa_act)) {
efa_act = NULL;
}
}
@@ -736,7 +736,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje
if (sima->flag & SI_SMOOTH_UV) {
glEnable(GL_LINE_SMOOTH);
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
}
glLineWidth(1);
@@ -1032,7 +1032,9 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje
}
-static void draw_uv_shadows_get(SpaceImage *sima, Object *ob, Object *obedit, bool *show_shadow, bool *show_texpaint)
+static void draw_uv_shadows_get(
+ SpaceImage *sima, const EvaluationContext *eval_ctx, Object *ob, Object *obedit,
+ bool *show_shadow, bool *show_texpaint)
{
*show_shadow = *show_texpaint = false;
@@ -1045,16 +1047,18 @@ static void draw_uv_shadows_get(SpaceImage *sima, Object *ob, Object *obedit, bo
*show_shadow = EDBM_uv_check(em);
}
- *show_texpaint = (ob && ob->type == OB_MESH && ob->mode == OB_MODE_TEXTURE_PAINT);
+ *show_texpaint = (ob && ob->type == OB_MESH && eval_ctx->object_mode == OB_MODE_TEXTURE_PAINT);
}
-void ED_uvedit_draw_main(SpaceImage *sima, ARegion *ar, Scene *scene, ViewLayer *view_layer, Object *obedit, Object *obact, Depsgraph *depsgraph)
+void ED_uvedit_draw_main(
+ SpaceImage *sima, const EvaluationContext *eval_ctx,
+ ARegion *ar, Scene *scene, ViewLayer *view_layer, Object *obedit, Object *obact, Depsgraph *depsgraph)
{
ToolSettings *toolsettings = scene->toolsettings;
bool show_uvedit, show_uvshadow, show_texpaint_uvshadow;
show_uvedit = ED_space_image_show_uvedit(sima, obedit);
- draw_uv_shadows_get(sima, obact, obedit, &show_uvshadow, &show_texpaint_uvshadow);
+ draw_uv_shadows_get(sima, eval_ctx, obact, obedit, &show_uvshadow, &show_texpaint_uvshadow);
if (show_uvedit || show_uvshadow || show_texpaint_uvshadow) {
if (show_uvshadow)
diff --git a/source/blender/editors/uvedit/uvedit_intern.h b/source/blender/editors/uvedit/uvedit_intern.h
index 6ca46941404..eb92f17544f 100644
--- a/source/blender/editors/uvedit/uvedit_intern.h
+++ b/source/blender/editors/uvedit/uvedit_intern.h
@@ -57,10 +57,12 @@ typedef struct NearestHit {
int lindex; /* index of loop within face */
} NearestHit;
-void uv_find_nearest_vert(struct Scene *scene, struct Image *ima, struct BMEditMesh *em,
- const float co[2], const float penalty[2], struct NearestHit *hit);
-void uv_find_nearest_edge(struct Scene *scene, struct Image *ima, struct BMEditMesh *em,
- const float co[2], struct NearestHit *hit);
+void uv_find_nearest_vert(
+ struct Scene *scene, struct Image *ima, struct Object *obedit, struct BMEditMesh *em,
+ const float co[2], const float penalty[2], struct NearestHit *hit);
+void uv_find_nearest_edge(
+ struct Scene *scene, struct Image *ima, struct Object *obedit, struct BMEditMesh *em,
+ const float co[2], struct NearestHit *hit);
/* utility tool functions */
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index 03a5f4dddc8..f66c9ee9951 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -49,7 +49,7 @@
#include "BLI_utildefines.h"
#include "BLI_alloca.h"
#include "BLI_math.h"
-#include "BLI_lasso.h"
+#include "BLI_lasso_2d.h"
#include "BLI_blenlib.h"
#include "BLI_array.h"
@@ -89,7 +89,7 @@
#include "uvedit_intern.h"
-static void uv_select_all_perform(Scene *scene, Image *ima, BMEditMesh *em, int action);
+static void uv_select_all_perform(Scene *scene, Image *ima, Object *obedit, BMEditMesh *em, int action);
static void uv_select_flush_from_tag_face(SpaceImage *sima, Scene *scene, Object *obedit, const bool select);
static void uv_select_flush_from_tag_loop(SpaceImage *sima, Scene *scene, Object *obedit, const bool select);
@@ -230,7 +230,7 @@ void ED_uvedit_assign_image(Main *UNUSED(bmain), Scene *scene, Object *obedit, I
/* now assign to all visible faces */
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (uvedit_face_visible_test(scene, previma, efa) &&
+ if (uvedit_face_visible_test(scene, obedit, previma, efa) &&
(selected == true || uvedit_face_select_test(scene, efa, cd_loop_uv_offset)))
{
#ifdef USE_SWITCH_ASPECT
@@ -296,12 +296,12 @@ bool uvedit_face_visible_nolocal(Scene *scene, BMFace *efa)
return (BM_elem_flag_test(efa, BM_ELEM_HIDDEN) == 0 && BM_elem_flag_test(efa, BM_ELEM_SELECT));
}
-bool uvedit_face_visible_test(Scene *scene, Image *ima, BMFace *efa)
+bool uvedit_face_visible_test(Scene *scene, Object *obedit, Image *ima, BMFace *efa)
{
ToolSettings *ts = scene->toolsettings;
if (ts->uv_flag & UV_SHOW_SAME_IMAGE) {
- const Image *face_image = BKE_object_material_edit_image_get(scene->obedit, efa->mat_nr);
+ const Image *face_image = BKE_object_material_edit_image_get(obedit, efa->mat_nr);
return (face_image == ima) ? uvedit_face_visible_nolocal(scene, efa) : false;
}
else {
@@ -607,7 +607,7 @@ bool ED_uvedit_minmax(Scene *scene, Image *ima, Object *obedit, float r_min[2],
INIT_MINMAX2(r_min, r_max);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, ima, efa))
+ if (!uvedit_face_visible_test(scene, obedit, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -653,7 +653,7 @@ static bool ED_uvedit_median(Scene *scene, Image *ima, Object *obedit, float co[
zero_v2(co);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, ima, efa))
+ if (!uvedit_face_visible_test(scene, obedit, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -692,7 +692,7 @@ bool ED_uvedit_center(Scene *scene, Image *ima, Object *obedit, float cent[2], c
/************************** find nearest ****************************/
-void uv_find_nearest_edge(Scene *scene, Image *ima, BMEditMesh *em, const float co[2], NearestHit *hit)
+void uv_find_nearest_edge(Scene *scene, Image *ima, Object *obedit, BMEditMesh *em, const float co[2], NearestHit *hit)
{
BMFace *efa;
BMLoop *l;
@@ -709,7 +709,7 @@ void uv_find_nearest_edge(Scene *scene, Image *ima, BMEditMesh *em, const float
BM_mesh_elem_index_ensure(em->bm, BM_VERT);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, ima, efa))
+ if (!uvedit_face_visible_test(scene, obedit, ima, efa))
continue;
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
@@ -732,7 +732,8 @@ void uv_find_nearest_edge(Scene *scene, Image *ima, BMEditMesh *em, const float
}
}
-static void uv_find_nearest_face(Scene *scene, Image *ima, BMEditMesh *em, const float co[2], NearestHit *hit)
+static void uv_find_nearest_face(
+ Scene *scene, Image *ima, Object *obedit, BMEditMesh *em, const float co[2], NearestHit *hit)
{
BMFace *efa;
BMIter iter;
@@ -744,12 +745,12 @@ static void uv_find_nearest_face(Scene *scene, Image *ima, BMEditMesh *em, const
memset(hit, 0, sizeof(*hit));
/*this will fill in hit.vert1 and hit.vert2*/
- uv_find_nearest_edge(scene, ima, em, co, hit);
+ uv_find_nearest_edge(scene, ima, obedit, em, co, hit);
hit->l = NULL;
hit->luv = hit->luv_next = NULL;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, ima, efa))
+ if (!uvedit_face_visible_test(scene, obedit, ima, efa))
continue;
uv_poly_center(efa, cent, cd_loop_uv_offset);
@@ -774,8 +775,9 @@ static bool uv_nearest_between(const BMLoop *l, const float co[2],
(line_point_side_v2(uv_next, uv_curr, co) <= 0.0f));
}
-void uv_find_nearest_vert(Scene *scene, Image *ima, BMEditMesh *em,
- float const co[2], const float penalty[2], NearestHit *hit)
+void uv_find_nearest_vert(
+ Scene *scene, Image *ima, Object *obedit, BMEditMesh *em,
+ float const co[2], const float penalty[2], NearestHit *hit)
{
BMFace *efa;
BMLoop *l;
@@ -787,7 +789,7 @@ void uv_find_nearest_vert(Scene *scene, Image *ima, BMEditMesh *em,
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
/*this will fill in hit.vert1 and hit.vert2*/
- uv_find_nearest_edge(scene, ima, em, co, hit);
+ uv_find_nearest_edge(scene, ima, obedit, em, co, hit);
hit->l = NULL;
hit->luv = hit->luv_next = NULL;
@@ -797,7 +799,7 @@ void uv_find_nearest_vert(Scene *scene, Image *ima, BMEditMesh *em,
BM_mesh_elem_index_ensure(em->bm, BM_VERT);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, ima, efa))
+ if (!uvedit_face_visible_test(scene, obedit, ima, efa))
continue;
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
@@ -842,7 +844,7 @@ bool ED_uvedit_nearest_uv(Scene *scene, Object *obedit, Image *ima, const float
copy_v2_v2(r_uv, co);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, ima, efa))
+ if (!uvedit_face_visible_test(scene, obedit, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -946,8 +948,9 @@ static bool uv_select_edgeloop_edge_tag_faces(BMEditMesh *em, UvMapVert *first1,
return true;
}
-static int uv_select_edgeloop(Scene *scene, Image *ima, BMEditMesh *em, NearestHit *hit,
- const float limit[2], const bool extend)
+static int uv_select_edgeloop(
+ Scene *scene, Image *ima, Object *obedit, BMEditMesh *em, NearestHit *hit,
+ const float limit[2], const bool extend)
{
BMFace *efa;
BMIter iter, liter;
@@ -967,7 +970,7 @@ static int uv_select_edgeloop(Scene *scene, Image *ima, BMEditMesh *em, NearestH
BM_mesh_elem_index_ensure(em->bm, BM_VERT | BM_FACE);
if (!extend) {
- uv_select_all_perform(scene, ima, em, SEL_DESELECT);
+ uv_select_all_perform(scene, ima, obedit, em, SEL_DESELECT);
}
BM_mesh_elem_hflag_disable_all(em->bm, BM_FACE, BM_ELEM_TAG, false);
@@ -991,7 +994,7 @@ static int uv_select_edgeloop(Scene *scene, Image *ima, BMEditMesh *em, NearestH
/* find correct valence edges which are not tagged yet, but connect to tagged one */
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!BM_elem_flag_test(efa, BM_ELEM_TAG) && uvedit_face_visible_test(scene, ima, efa)) {
+ if (!BM_elem_flag_test(efa, BM_ELEM_TAG) && uvedit_face_visible_test(scene, obedit, ima, efa)) {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
/* check face not hidden and not tagged */
if (!(iterv_curr = uv_select_edgeloop_vertex_map_get(vmap, efa, l)))
@@ -1046,7 +1049,9 @@ static int uv_select_edgeloop(Scene *scene, Image *ima, BMEditMesh *em, NearestH
/*********************** linked select ***********************/
-static void uv_select_linked(Scene *scene, Image *ima, BMEditMesh *em, const float limit[2], NearestHit *hit, bool extend, bool select_faces)
+static void uv_select_linked(
+ Scene *scene, Image *ima, Object *obedit, BMEditMesh *em,
+ const float limit[2], NearestHit *hit, bool extend, bool select_faces)
{
BMFace *efa;
BMLoop *l;
@@ -1078,7 +1083,7 @@ static void uv_select_linked(Scene *scene, Image *ima, BMEditMesh *em, const flo
if (!hit) {
BM_ITER_MESH_INDEX (efa, &iter, em->bm, BM_FACES_OF_MESH, a) {
- if (uvedit_face_visible_test(scene, ima, efa)) {
+ if (uvedit_face_visible_test(scene, obedit, ima, efa)) {
if (select_faces) {
if (BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
stack[stacksize] = a;
@@ -1236,7 +1241,7 @@ static void uv_select_linked(Scene *scene, Image *ima, BMEditMesh *em, const flo
/* WATCH IT: this returns first selected UV,
* not ideal in many cases since there could be multiple */
-static float *uv_sel_co_from_eve(Scene *scene, Image *ima, BMEditMesh *em, BMVert *eve)
+static float *uv_sel_co_from_eve(Scene *scene, Object *obedit, Image *ima, BMEditMesh *em, BMVert *eve)
{
BMIter liter;
BMLoop *l;
@@ -1244,7 +1249,7 @@ static float *uv_sel_co_from_eve(Scene *scene, Image *ima, BMEditMesh *em, BMVer
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
BM_ITER_ELEM (l, &liter, eve, BM_LOOPS_OF_VERT) {
- if (!uvedit_face_visible_test(scene, ima, l->f))
+ if (!uvedit_face_visible_test(scene, obedit, ima, l->f))
continue;
if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
@@ -1292,7 +1297,7 @@ static int uv_select_more_less(bContext *C, const bool select)
/* mark loops to be selected */
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (uvedit_face_visible_test(scene, ima, efa)) {
+ if (uvedit_face_visible_test(scene, obedit, ima, efa)) {
#define IS_SEL 1
#define IS_UNSEL 2
@@ -1335,7 +1340,7 @@ static int uv_select_more_less(bContext *C, const bool select)
/* mark loops to be selected */
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (uvedit_face_visible_test(scene, ima, efa)) {
+ if (uvedit_face_visible_test(scene, obedit, ima, efa)) {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
@@ -1418,7 +1423,7 @@ static void uv_weld_align(bContext *C, int tool)
BMLoop *l;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, ima, efa))
+ if (!uvedit_face_visible_test(scene, obedit, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -1440,7 +1445,7 @@ static void uv_weld_align(bContext *C, int tool)
BMLoop *l;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, ima, efa))
+ if (!uvedit_face_visible_test(scene, obedit, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -1459,7 +1464,7 @@ static void uv_weld_align(bContext *C, int tool)
BMLoop *l;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, ima, efa))
+ if (!uvedit_face_visible_test(scene, obedit, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -1487,7 +1492,7 @@ static void uv_weld_align(bContext *C, int tool)
/* tag verts with a selected UV */
BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
BM_ITER_ELEM (l, &liter, eve, BM_LOOPS_OF_VERT) {
- if (!uvedit_face_visible_test(scene, ima, l->f))
+ if (!uvedit_face_visible_test(scene, obedit, ima, l->f))
continue;
if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
@@ -1554,8 +1559,10 @@ static void uv_weld_align(bContext *C, int tool)
if (BLI_array_count(eve_line) > 2) {
/* we know the returns from these must be valid */
- const float *uv_start = uv_sel_co_from_eve(scene, ima, em, eve_line[0]);
- const float *uv_end = uv_sel_co_from_eve(scene, ima, em, eve_line[BLI_array_count(eve_line) - 1]);
+ const float *uv_start = uv_sel_co_from_eve(
+ scene, obedit, ima, em, eve_line[0]);
+ const float *uv_end = uv_sel_co_from_eve(
+ scene, obedit, ima, em, eve_line[BLI_array_count(eve_line) - 1]);
/* For t & u modes */
float a = 0.0f;
@@ -1575,7 +1582,7 @@ static void uv_weld_align(bContext *C, int tool)
/* go over all verts except for endpoints */
for (i = 0; i < BLI_array_count(eve_line); i++) {
BM_ITER_ELEM (l, &liter, eve_line[i], BM_LOOPS_OF_VERT) {
- if (!uvedit_face_visible_test(scene, ima, l->f))
+ if (!uvedit_face_visible_test(scene, obedit, ima, l->f))
continue;
if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
@@ -1684,7 +1691,7 @@ static int uv_remove_doubles_exec(bContext *C, wmOperator *op)
/* TODO, use qsort as with MESH_OT_remove_doubles, this isn't optimal */
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, ima, efa))
+ if (!uvedit_face_visible_test(scene, obedit, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -1704,7 +1711,7 @@ static int uv_remove_doubles_exec(bContext *C, wmOperator *op)
float uv_min[2];
float uv_max[2];
- BLI_array_empty(loop_arr);
+ BLI_array_clear(loop_arr);
BLI_array_append(loop_arr, vert_arr[uv_a_index].uv_loop);
uv_a = vert_arr[uv_a_index].uv_loop->uv;
@@ -1746,7 +1753,7 @@ static int uv_remove_doubles_exec(bContext *C, wmOperator *op)
BLI_array_declare(loop_arr_unselected);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, ima, efa))
+ if (!uvedit_face_visible_test(scene, obedit, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -1830,7 +1837,7 @@ static void UV_OT_weld(wmOperatorType *ot)
/* ******************** (de)select all operator **************** */
-static void uv_select_all_perform(Scene *scene, Image *ima, BMEditMesh *em, int action)
+static void uv_select_all_perform(Scene *scene, Image *ima, Object *obedit, BMEditMesh *em, int action)
{
ToolSettings *ts = scene->toolsettings;
BMFace *efa;
@@ -1862,7 +1869,7 @@ static void uv_select_all_perform(Scene *scene, Image *ima, BMEditMesh *em, int
if (action == SEL_TOGGLE) {
action = SEL_SELECT;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, ima, efa))
+ if (!uvedit_face_visible_test(scene, obedit, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -1878,7 +1885,7 @@ static void uv_select_all_perform(Scene *scene, Image *ima, BMEditMesh *em, int
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, ima, efa))
+ if (!uvedit_face_visible_test(scene, obedit, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -1909,7 +1916,7 @@ static int uv_select_all_exec(bContext *C, wmOperator *op)
int action = RNA_enum_get(op->ptr, "action");
- uv_select_all_perform(scene, ima, em, action);
+ uv_select_all_perform(scene, ima, obedit, em, action);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
@@ -2008,7 +2015,7 @@ static int uv_mouse_select(bContext *C, const float co[2], bool extend, bool loo
/* find nearest element */
if (loop) {
/* find edge */
- uv_find_nearest_edge(scene, ima, em, co, &hit);
+ uv_find_nearest_edge(scene, ima, obedit, em, co, &hit);
if (hit.efa == NULL) {
return OPERATOR_CANCELLED;
}
@@ -2017,7 +2024,7 @@ static int uv_mouse_select(bContext *C, const float co[2], bool extend, bool loo
}
else if (selectmode == UV_SELECT_VERTEX) {
/* find vertex */
- uv_find_nearest_vert(scene, ima, em, co, penalty, &hit);
+ uv_find_nearest_vert(scene, ima, obedit, em, co, penalty, &hit);
if (hit.efa == NULL) {
return OPERATOR_CANCELLED;
}
@@ -2034,7 +2041,7 @@ static int uv_mouse_select(bContext *C, const float co[2], bool extend, bool loo
}
else if (selectmode == UV_SELECT_EDGE) {
/* find edge */
- uv_find_nearest_edge(scene, ima, em, co, &hit);
+ uv_find_nearest_edge(scene, ima, obedit, em, co, &hit);
if (hit.efa == NULL) {
return OPERATOR_CANCELLED;
}
@@ -2053,7 +2060,7 @@ static int uv_mouse_select(bContext *C, const float co[2], bool extend, bool loo
}
else if (selectmode == UV_SELECT_FACE) {
/* find face */
- uv_find_nearest_face(scene, ima, em, co, &hit);
+ uv_find_nearest_face(scene, ima, obedit, em, co, &hit);
if (hit.efa == NULL) {
return OPERATOR_CANCELLED;
}
@@ -2074,7 +2081,7 @@ static int uv_mouse_select(bContext *C, const float co[2], bool extend, bool loo
hitlen = hit.efa->len;
}
else if (selectmode == UV_SELECT_ISLAND) {
- uv_find_nearest_edge(scene, ima, em, co, &hit);
+ uv_find_nearest_edge(scene, ima, obedit, em, co, &hit);
if (hit.efa == NULL) {
return OPERATOR_CANCELLED;
@@ -2089,10 +2096,10 @@ static int uv_mouse_select(bContext *C, const float co[2], bool extend, bool loo
/* do selection */
if (loop) {
- flush = uv_select_edgeloop(scene, ima, em, &hit, limit, extend);
+ flush = uv_select_edgeloop(scene, ima, obedit, em, &hit, limit, extend);
}
else if (selectmode == UV_SELECT_ISLAND) {
- uv_select_linked(scene, ima, em, limit, &hit, extend, false);
+ uv_select_linked(scene, ima, obedit, em, limit, &hit, extend, false);
}
else if (extend) {
if (selectmode == UV_SELECT_VERTEX) {
@@ -2127,7 +2134,7 @@ static int uv_mouse_select(bContext *C, const float co[2], bool extend, bool loo
BM_mesh_elem_index_ensure(em->bm, BM_VERT);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, ima, efa))
+ if (!uvedit_face_visible_test(scene, obedit, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -2142,7 +2149,7 @@ static int uv_mouse_select(bContext *C, const float co[2], bool extend, bool loo
}
else {
/* deselect all */
- uv_select_all_perform(scene, ima, em, SEL_DESELECT);
+ uv_select_all_perform(scene, ima, obedit, em, SEL_DESELECT);
if (selectmode == UV_SELECT_VERTEX) {
/* select vertex */
@@ -2162,7 +2169,7 @@ static int uv_mouse_select(bContext *C, const float co[2], bool extend, bool loo
/* select sticky uvs */
if (sticky != SI_STICKY_DISABLE) {
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, ima, efa))
+ if (!uvedit_face_visible_test(scene, obedit, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -2338,11 +2345,11 @@ static int uv_select_linked_internal(bContext *C, wmOperator *op, const wmEvent
RNA_float_get_array(op->ptr, "location", co);
}
- uv_find_nearest_edge(scene, ima, em, co, &hit);
+ uv_find_nearest_edge(scene, ima, obedit, em, co, &hit);
hit_p = &hit;
}
- uv_select_linked(scene, ima, em, limit, hit_p, extend, select_faces);
+ uv_select_linked(scene, ima, obedit, em, limit, hit_p, extend, select_faces);
DEG_id_tag_update(obedit->data, 0);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
@@ -2434,7 +2441,7 @@ static int uv_select_split_exec(bContext *C, wmOperator *op)
bool is_sel = false;
bool is_unsel = false;
- if (!uvedit_face_visible_test(scene, ima, efa))
+ if (!uvedit_face_visible_test(scene, obedit, ima, efa))
continue;
/* are we all selected? */
@@ -2765,7 +2772,7 @@ static int uv_border_select_exec(bContext *C, wmOperator *op)
pinned = RNA_boolean_get(op->ptr, "pinned");
if (!extend)
- uv_select_all_perform(scene, ima, em, SEL_DESELECT);
+ uv_select_all_perform(scene, ima, obedit, em, SEL_DESELECT);
/* do actual selection */
if (use_face_center && !pinned) {
@@ -2778,7 +2785,7 @@ static int uv_border_select_exec(bContext *C, wmOperator *op)
/* assume not touched */
BM_elem_flag_disable(efa, BM_ELEM_TAG);
- if (uvedit_face_visible_test(scene, ima, efa)) {
+ if (uvedit_face_visible_test(scene, obedit, ima, efa)) {
uv_poly_center(efa, cent, cd_loop_uv_offset);
if (BLI_rctf_isect_pt_v(&rectf, cent)) {
BM_elem_flag_enable(efa, BM_ELEM_TAG);
@@ -2797,7 +2804,7 @@ static int uv_border_select_exec(bContext *C, wmOperator *op)
changed = true;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, ima, efa))
+ if (!uvedit_face_visible_test(scene, obedit, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
@@ -3006,7 +3013,7 @@ static bool do_lasso_select_mesh_uv(bContext *C, const int mcords[][2], short mo
BLI_lasso_boundbox(&rect, mcords, moves);
if (!extend && select) {
- uv_select_all_perform(scene, ima, em, SEL_DESELECT);
+ uv_select_all_perform(scene, ima, obedit, em, SEL_DESELECT);
}
if (use_face_center) { /* Face Center Sel */
@@ -3034,7 +3041,7 @@ static bool do_lasso_select_mesh_uv(bContext *C, const int mcords[][2], short mo
}
else { /* Vert Sel */
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (uvedit_face_visible_test(scene, ima, efa)) {
+ if (uvedit_face_visible_test(scene, obedit, ima, efa)) {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if ((select) != (uvedit_uv_select_test(scene, l, cd_loop_uv_offset))) {
MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
@@ -3188,7 +3195,7 @@ static bool uv_snap_uvs_to_cursor(Scene *scene, Image *ima, Object *obedit, cons
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, ima, efa))
+ if (!uvedit_face_visible_test(scene, obedit, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -3215,7 +3222,7 @@ static bool uv_snap_uvs_offset(Scene *scene, Image *ima, Object *obedit, const f
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, ima, efa))
+ if (!uvedit_face_visible_test(scene, obedit, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -3244,7 +3251,7 @@ static bool uv_snap_uvs_to_adjacent_unselected(Scene *scene, Image *ima, Object
/* index every vert that has a selected UV using it, but only once so as to
* get unique indices and to count how much to malloc */
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
- if (uvedit_face_visible_test(scene, ima, f)) {
+ if (uvedit_face_visible_test(scene, obedit, ima, f)) {
BM_elem_flag_enable(f, BM_ELEM_TAG);
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
BM_elem_flag_set(l, BM_ELEM_TAG, uvedit_uv_select_test(scene, l, cd_loop_uv_offset));
@@ -3304,7 +3311,7 @@ static bool uv_snap_uvs_to_pixels(SpaceImage *sima, Scene *scene, Object *obedit
h = (float)height;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, ima, efa))
+ if (!uvedit_face_visible_test(scene, obedit, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -3400,7 +3407,7 @@ static int uv_pin_exec(bContext *C, wmOperator *op)
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, ima, efa))
+ if (!uvedit_face_visible_test(scene, obedit, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -3454,7 +3461,7 @@ static int uv_select_pinned_exec(bContext *C, wmOperator *UNUSED(op))
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, ima, efa))
+ if (!uvedit_face_visible_test(scene, obedit, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -3534,7 +3541,7 @@ static int uv_hide_exec(bContext *C, wmOperator *op)
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
int hide = 0;
- if (!uvedit_face_visible_test(scene, ima, efa)) {
+ if (!uvedit_face_visible_test(scene, obedit, ima, efa)) {
continue;
}
diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.c b/source/blender/editors/uvedit/uvedit_parametrizer.c
index 29c908ff900..c510c12ae53 100644
--- a/source/blender/editors/uvedit/uvedit_parametrizer.c
+++ b/source/blender/editors/uvedit/uvedit_parametrizer.c
@@ -32,8 +32,8 @@
#include "BLI_math.h"
#include "BLI_rand.h"
#include "BLI_heap.h"
-#include "BLI_boxpack2d.h"
-#include "BLI_convexhull2d.h"
+#include "BLI_boxpack_2d.h"
+#include "BLI_convexhull_2d.h"
#include "uvedit_parametrizer.h"
@@ -1291,7 +1291,7 @@ static void p_chart_fill_boundary(PChart *chart, PEdge *be, int nedges)
while (nedges > 2) {
PEdge *ne, *ne1, *ne2;
- e = (PEdge *)BLI_heap_popmin(heap);
+ e = (PEdge *)BLI_heap_pop_min(heap);
e1 = p_boundary_edge_prev(e);
e2 = p_boundary_edge_next(e);
@@ -2185,12 +2185,12 @@ static void p_chart_simplify_compute(PChart *chart)
e->u.nextcollapse = NULL;
/* pop edge collapse out of heap one by one */
- while (!BLI_heap_empty(heap)) {
+ while (!BLI_heap_is_empty(heap)) {
if (ncollapsed == NCOLLAPSE)
break;
HeapNode *link = BLI_heap_top(heap);
- PEdge *edge = (PEdge *)BLI_heap_popmin(heap), *pair = edge->pair;
+ PEdge *edge = (PEdge *)BLI_heap_pop_min(heap), *pair = edge->pair;
PVert *oldv, *keepv;
PEdge *wheele, *nexte;
diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c
index fa936e998fa..9cd34c46874 100644
--- a/source/blender/editors/uvedit/uvedit_smart_stitch.c
+++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c
@@ -157,6 +157,8 @@ typedef struct StitchState {
bool snap_islands;
/* stitch at midpoints or at islands */
bool midpoints;
+ /* object for editmesh */
+ Object *obedit;
/* editmesh, cached for use in modal handler */
BMEditMesh *em;
/* clear seams of stitched edges after stitch */
@@ -1719,6 +1721,7 @@ static int stitch_init(bContext *C, wmOperator *op)
/* initialize state */
state->use_limit = RNA_boolean_get(op->ptr, "use_limit");
state->limit_dist = RNA_float_get(op->ptr, "limit");
+ state->obedit = obedit;
state->em = em;
state->snap_islands = RNA_boolean_get(op->ptr, "snap_islands");
state->static_island = RNA_int_get(op->ptr, "static_island");
@@ -1848,7 +1851,7 @@ static int stitch_init(bContext *C, wmOperator *op)
}
}
- total_edges = BLI_ghash_size(edge_hash);
+ total_edges = BLI_ghash_len(edge_hash);
state->edges = edges = MEM_mallocN(sizeof(*edges) * total_edges, "stitch_edges");
/* I assume any system will be able to at least allocate an iterator :p */
@@ -2131,7 +2134,7 @@ static void stitch_select(bContext *C, Scene *scene, const wmEvent *event, Stitc
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &co[0], &co[1]);
if (state->mode == STITCH_VERT) {
- uv_find_nearest_vert(scene, ima, state->em, co, NULL, &hit);
+ uv_find_nearest_vert(scene, ima, state->obedit, state->em, co, NULL, &hit);
if (hit.efa) {
/* Add vertex to selection, deselect all common uv's of vert other
@@ -2145,7 +2148,7 @@ static void stitch_select(bContext *C, Scene *scene, const wmEvent *event, Stitc
}
}
else {
- uv_find_nearest_edge(scene, ima, state->em, co, &hit);
+ uv_find_nearest_edge(scene, ima, state->obedit, state->em, co, &hit);
if (hit.efa) {
UvEdge *edge = uv_edge_get(hit.l, state);
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
index 79f17756ca6..977bca66731 100644
--- a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
+++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
@@ -45,6 +45,7 @@ extern "C" {
#include "BKE_collection.h"
#include "BKE_customdata.h"
+#include "BKE_idprop.h"
#include "BKE_global.h"
#include "BKE_library.h" /* free_libblock */
#include "BKE_material.h"
@@ -117,9 +118,25 @@ BlenderStrokeRenderer::BlenderStrokeRenderer(Render *re, int render_count) : Str
freestyle_scene->r.gauss = old_scene->r.gauss;
freestyle_scene->r.dither_intensity = old_scene->r.dither_intensity;
BKE_viewrender_copy(&freestyle_scene->view_render, &old_scene->view_render);
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ cout << "Stroke rendering engine : " << freestyle_scene->view_render.engine_id << endl;
+ }
freestyle_scene->r.im_format.planes = R_IMF_PLANES_RGBA;
freestyle_scene->r.im_format.imtype = R_IMF_IMTYPE_PNG;
+ // Copy ID properties, including Cycles render properties
+ if (old_scene->id.properties) {
+ freestyle_scene->id.properties = IDP_CopyProperty_ex(old_scene->id.properties, 0);
+ }
+
+ if (STREQ(freestyle_scene->view_render.engine_id, RE_engine_id_CYCLES)) {
+ /* Render with transparent background. */
+ PointerRNA freestyle_scene_ptr;
+ RNA_id_pointer_create(&freestyle_scene->id, &freestyle_scene_ptr);
+ PointerRNA freestyle_cycles_ptr = RNA_pointer_get(&freestyle_scene_ptr, "cycles");
+ RNA_boolean_set(&freestyle_cycles_ptr, "film_transparent", 1);
+ }
+
if (G.debug & G_DEBUG_FREESTYLE) {
printf("%s: %d thread(s)\n", __func__, BKE_render_num_threads(&freestyle_scene->r));
}
@@ -478,28 +495,6 @@ void BlenderStrokeRenderer::RenderStrokeRepBasic(StrokeRep *iStrokeRep) const
ma = BlenderStrokeRenderer::GetStrokeShader(freestyle_bmain, nt, false);
BLI_ghash_insert(_nodetree_hash, nt, ma);
}
-
- if (STREQ(freestyle_scene->view_render.engine_id, RE_engine_id_CYCLES)) {
- PointerRNA scene_ptr, freestyle_scene_ptr;
- RNA_pointer_create(NULL, &RNA_Scene, old_scene, &scene_ptr);
- RNA_pointer_create(NULL, &RNA_Scene, freestyle_scene, &freestyle_scene_ptr);
-
- PointerRNA cycles_ptr = RNA_pointer_get(&scene_ptr, "cycles");
- PointerRNA freestyle_cycles_ptr = RNA_pointer_get(&freestyle_scene_ptr, "cycles");
-
- int flag;
- RNA_STRUCT_BEGIN(&freestyle_cycles_ptr, prop)
- {
- flag = RNA_property_flag(prop);
- if (flag & PROP_HIDDEN)
- continue;
- RNA_property_copy(&freestyle_cycles_ptr, &cycles_ptr, prop, -1);
- }
- RNA_STRUCT_END;
-
- RNA_boolean_set(&freestyle_cycles_ptr, "film_transparent", 1);
- }
-
iStrokeRep->setMaterial(ma);
}
else {
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 0ac842d90a0..189ca8e6a33 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -142,13 +142,13 @@ data_to_c_simple(shaders/gpu_shader_2D_line_dashed_geom.glsl SRC)
data_to_c_simple(shaders/gpu_shader_2D_smooth_color_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_2D_smooth_color_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_2D_image_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_image_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_image_linear_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_image_shuffle_color_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_image_mask_uniform_color_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_image_modulate_alpha_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_image_alpha_color_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_image_color_frag.glsl SRC)
-data_to_c_simple(shaders/gpu_shader_image_rect_modulate_alpha_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_image_depth_linear_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_image_interlace_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_image_vert.glsl SRC)
@@ -174,7 +174,7 @@ data_to_c_simple(shaders/gpu_shader_instance_edges_variying_color_geom.glsl SRC)
data_to_c_simple(shaders/gpu_shader_instance_edges_variying_color_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_instance_bone_envelope_solid_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_instance_bone_envelope_wire_vert.glsl SRC)
-data_to_c_simple(shaders/gpu_shader_instance_mball_helpers_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_instance_mball_handles_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_groundline_geom.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_groundpoint_vert.glsl SRC)
diff --git a/source/blender/gpu/GPU_draw.h b/source/blender/gpu/GPU_draw.h
index 8d29632fc71..e437b4e4f58 100644
--- a/source/blender/gpu/GPU_draw.h
+++ b/source/blender/gpu/GPU_draw.h
@@ -46,6 +46,9 @@ struct View3D;
struct RegionView3D;
struct SmokeModifierData;
struct DupliObject;
+struct EvaluationContext;
+
+#include "DNA_object_enums.h"
/* OpenGL drawing functions related to shading. These are also
* shared with the game engine, where there were previously
@@ -73,9 +76,10 @@ void GPU_disable_program_point_size(void);
* GPU_object_material_bind returns 0 if drawing should be skipped
* - after drawing, the material must be disabled again */
-void GPU_begin_object_materials(struct View3D *v3d, struct RegionView3D *rv3d,
- struct Scene *scene, struct ViewLayer *view_layer,
- struct Object *ob, bool glsl, bool *do_alpha_after);
+void GPU_begin_object_materials(
+ struct View3D *v3d, struct RegionView3D *rv3d,
+ struct Scene *scene, struct ViewLayer *view_layer,
+ struct Object *ob, bool glsl, const eObjectMode object_mode, bool *do_alpha_after);
void GPU_end_object_materials(void);
bool GPU_object_materials_check(void);
diff --git a/source/blender/gpu/GPU_extensions.h b/source/blender/gpu/GPU_extensions.h
index d860431b04f..d36b0ea15be 100644
--- a/source/blender/gpu/GPU_extensions.h
+++ b/source/blender/gpu/GPU_extensions.h
@@ -64,7 +64,6 @@ typedef enum GPUDeviceType {
GPU_DEVICE_INTEL = (1 << 2),
GPU_DEVICE_SOFTWARE = (1 << 3),
GPU_DEVICE_UNKNOWN = (1 << 4),
- GPU_DEVICE_AMD_VEGA = (1 << 5),
GPU_DEVICE_ANY = (0xff)
} GPUDeviceType;
diff --git a/source/blender/gpu/GPU_framebuffer.h b/source/blender/gpu/GPU_framebuffer.h
index c58d98c201e..31f24aa7c2e 100644
--- a/source/blender/gpu/GPU_framebuffer.h
+++ b/source/blender/gpu/GPU_framebuffer.h
@@ -83,14 +83,16 @@ void GPU_framebuffer_recursive_downsample(
* - wrapper around framebuffer and texture for simple offscreen drawing
* - changes size if graphics card can't support it */
-GPUOffScreen *GPU_offscreen_create(int width, int height, int samples, bool high_bitdepth, char err_out[256]);
+GPUOffScreen *GPU_offscreen_create(int width, int height, int samples,
+ bool depth, bool high_bitdepth, char err_out[256]);
void GPU_offscreen_free(GPUOffScreen *ofs);
void GPU_offscreen_bind(GPUOffScreen *ofs, bool save);
void GPU_offscreen_unbind(GPUOffScreen *ofs, bool restore);
void GPU_offscreen_read_pixels(GPUOffScreen *ofs, int type, void *pixels);
+void GPU_offscreen_blit(GPUOffScreen *ofs, int x, int y);
int GPU_offscreen_width(const GPUOffScreen *ofs);
int GPU_offscreen_height(const GPUOffScreen *ofs);
-int GPU_offscreen_color_texture(const GPUOffScreen *ofs);
+struct GPUTexture *GPU_offscreen_color_texture(const GPUOffScreen *ofs);
void GPU_offscreen_viewport_data_get(
GPUOffScreen *ofs,
diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h
index 698f3ada2a3..e2f40ff5c54 100644
--- a/source/blender/gpu/GPU_material.h
+++ b/source/blender/gpu/GPU_material.h
@@ -357,10 +357,9 @@ void GPU_zenith_update_color(float color[3]);
struct GPUParticleInfo
{
float scalprops[4];
- float location[3];
+ float location[4];
float velocity[3];
float angular_velocity[3];
- int random_id;
};
#ifdef WITH_OPENSUBDIV
diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h
index f2119a117e5..ca6e8343401 100644
--- a/source/blender/gpu/GPU_shader.h
+++ b/source/blender/gpu/GPU_shader.h
@@ -113,8 +113,10 @@ typedef enum GPUBuiltinShader {
GPU_SHADER_2D_UNIFORM_COLOR,
GPU_SHADER_2D_FLAT_COLOR,
GPU_SHADER_2D_SMOOTH_COLOR,
+ GPU_SHADER_2D_IMAGE,
GPU_SHADER_2D_IMAGE_COLOR,
GPU_SHADER_2D_IMAGE_ALPHA_COLOR,
+ GPU_SHADER_2D_IMAGE_ALPHA,
GPU_SHADER_2D_CHECKER,
GPU_SHADER_2D_DIAG_STRIPES,
/* for simple 3D drawing */
@@ -131,7 +133,6 @@ typedef enum GPUBuiltinShader {
GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR,
GPU_SHADER_2D_IMAGE_MASK_UNIFORM_COLOR,
GPU_SHADER_3D_IMAGE_MODULATE_ALPHA,
- GPU_SHADER_3D_IMAGE_RECT_MODULATE_ALPHA,
GPU_SHADER_3D_IMAGE_DEPTH,
/* stereo 3d */
GPU_SHADER_2D_IMAGE_INTERLACE,
@@ -173,7 +174,7 @@ typedef enum GPUBuiltinShader {
GPU_SHADER_3D_INSTANCE_BONE_ENVELOPE_SOLID,
GPU_SHADER_3D_INSTANCE_BONE_ENVELOPE_WIRE,
- GPU_SHADER_3D_INSTANCE_MBALL_HELPERS,
+ GPU_SHADER_3D_INSTANCE_MBALL_HANDLES,
GPU_NUM_BUILTIN_SHADERS /* (not an actual shader) */
} GPUBuiltinShader;
diff --git a/source/blender/gpu/GPU_viewport.h b/source/blender/gpu/GPU_viewport.h
index 580ff64befb..dff7e278ae1 100644
--- a/source/blender/gpu/GPU_viewport.h
+++ b/source/blender/gpu/GPU_viewport.h
@@ -98,6 +98,7 @@ typedef struct ViewportEngineData_Info {
GPUViewport *GPU_viewport_create(void);
void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect);
void GPU_viewport_unbind(GPUViewport *viewport);
+void GPU_viewport_draw_to_screen(GPUViewport *viewport, const rcti *rect);
void GPU_viewport_free(GPUViewport *viewport);
GPUViewport *GPU_viewport_create_from_offscreen(struct GPUOffScreen *ofs);
diff --git a/source/blender/gpu/intern/gpu_batch.c b/source/blender/gpu/intern/gpu_batch.c
index 0400fc1025b..332102aca46 100644
--- a/source/blender/gpu/intern/gpu_batch.c
+++ b/source/blender/gpu/intern/gpu_batch.c
@@ -34,7 +34,7 @@
#include "BLI_utildefines.h"
#include "BLI_rect.h"
#include "BLI_math.h"
-#include "BLI_polyfill2d.h"
+#include "BLI_polyfill_2d.h"
#include "BLI_sort_utils.h"
diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c
index d0efee79ab0..3043b3ab686 100644
--- a/source/blender/gpu/intern/gpu_buffers.c
+++ b/source/blender/gpu/intern/gpu_buffers.c
@@ -1901,7 +1901,7 @@ bool GPU_pbvh_buffers_diffuse_changed(GPU_PBVH_Buffers *buffers, GSet *bm_faces,
}
else if (buffers->use_bmesh) {
/* due to dynamic nature of dyntopo, only get first material */
- if (BLI_gset_size(bm_faces) > 0) {
+ if (BLI_gset_len(bm_faces) > 0) {
GSetIterator gs_iter;
BMFace *f;
diff --git a/source/blender/gpu/intern/gpu_compositing.c b/source/blender/gpu/intern/gpu_compositing.c
index 3de363cc76e..ca81ca72a32 100644
--- a/source/blender/gpu/intern/gpu_compositing.c
+++ b/source/blender/gpu/intern/gpu_compositing.c
@@ -1007,7 +1007,7 @@ bool GPU_fx_do_composite_pass(
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
/* the draw call we all waited for, draw a point per pixel, scaled per circle of confusion */
- GWN_batch_draw_stupid_instanced(fx->point_batch, 0, fx->dof_downsampled_w * fx->dof_downsampled_h, 0, 0, 0, NULL, NULL);
+ // GWN_batch_draw_stupid_instanced(fx->point_batch, 0, fx->dof_downsampled_w * fx->dof_downsampled_h, 0, 0, 0, NULL, NULL);
GPU_texture_unbind(fx->dof_half_downsampled_far);
GPU_framebuffer_texture_detach(fx->dof_far_blur);
@@ -1023,11 +1023,11 @@ bool GPU_fx_do_composite_pass(
/* have to clear the buffer unfortunately */
glClear(GL_COLOR_BUFFER_BIT);
/* the draw call we all waited for, draw a point per pixel, scaled per circle of confusion */
- GWN_batch_draw_stupid_instanced(fx->point_batch, 0, fx->dof_downsampled_w * fx->dof_downsampled_h, 0, 0, 0, NULL, NULL);
+ // GWN_batch_draw_stupid_instanced(fx->point_batch, 0, fx->dof_downsampled_w * fx->dof_downsampled_h, 0, 0, 0, NULL, NULL);
GWN_batch_program_use_end(fx->point_batch);
/* disable bindings */
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_BLEND);
GPU_framebuffer_texture_detach(fx->dof_near_blur);
diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c
index f9cf3235ac1..fdb5894e9ed 100644
--- a/source/blender/gpu/intern/gpu_draw.c
+++ b/source/blender/gpu/intern/gpu_draw.c
@@ -39,11 +39,11 @@
#include <string.h>
#include "BLI_blenlib.h"
+#include "BLI_hash.h"
#include "BLI_linklist.h"
#include "BLI_math.h"
#include "BLI_threads.h"
#include "BLI_utildefines.h"
-#include "BLI_hash.h"
#include "DNA_lamp_types.h"
#include "DNA_material_types.h"
@@ -398,7 +398,7 @@ static void gpu_set_alpha_blend(GPUBlendMode alphablend)
if (alphablend == GPU_BLEND_SOLID) {
glDisable(GL_BLEND);
glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
}
else if (alphablend == GPU_BLEND_ADD) {
glEnable(GL_BLEND);
@@ -1319,9 +1319,9 @@ static LinkNode *image_free_queue = NULL;
static void gpu_queue_image_for_free(Image *ima)
{
- BLI_lock_thread(LOCK_OPENGL);
+ BLI_thread_lock(LOCK_OPENGL);
BLI_linklist_prepend(&image_free_queue, ima);
- BLI_unlock_thread(LOCK_OPENGL);
+ BLI_thread_unlock(LOCK_OPENGL);
}
void GPU_free_unused_buffers(void)
@@ -1329,7 +1329,7 @@ void GPU_free_unused_buffers(void)
if (!BLI_thread_is_main())
return;
- BLI_lock_thread(LOCK_OPENGL);
+ BLI_thread_lock(LOCK_OPENGL);
/* images */
for (LinkNode *node = image_free_queue; node; node = node->next) {
@@ -1346,7 +1346,7 @@ void GPU_free_unused_buffers(void)
/* vbo buffers */
GPU_global_buffer_pool_free_unused();
- BLI_unlock_thread(LOCK_OPENGL);
+ BLI_thread_unlock(LOCK_OPENGL);
}
void GPU_free_image(Image *ima)
@@ -1460,6 +1460,7 @@ static struct GPUMaterialState {
Material *gmatbuf_fixed[FIXEDMAT];
Material *gboundmat;
Object *gob;
+ eObjectMode gob_object_mode;
DupliObject *dob;
Scene *gscene;
int glay;
@@ -1554,7 +1555,7 @@ void GPU_end_dupli_object(void)
void GPU_begin_object_materials(
View3D *v3d, RegionView3D *rv3d, Scene *scene, ViewLayer *view_layer, Object *ob,
- bool glsl, bool *do_alpha_after)
+ bool glsl, const eObjectMode object_mode, bool *do_alpha_after)
{
Material *ma;
GPUMaterial *gpumat;
@@ -1592,7 +1593,7 @@ void GPU_begin_object_materials(
#ifdef WITH_GAMEENGINE
if (rv3d->rflag & RV3D_IS_GAME_ENGINE) {
- ob = BKE_object_lod_matob_get(ob, view_layer);
+ ob = BKE_object_lod_matob_get(ob, view_layer, object_mode);
}
#else
UNUSED_VARS(view_layer);
@@ -1616,6 +1617,7 @@ void GPU_begin_object_materials(
GMS.two_sided_lighting = (((Mesh *)ob->data)->flag & ME_TWOSIDED) != 0;
GMS.gob = ob;
+ GMS.gob_object_mode = object_mode;
GMS.gscene = scene;
GMS.is_opensubdiv = use_opensubdiv;
GMS.totmat = use_matcap ? 1 : ob->totcol + 1; /* materials start from 1, default material is 0 */
@@ -1734,6 +1736,8 @@ static int gpu_get_particle_info(GPUParticleInfo *pi)
pi->scalprops[3] = p->size;
copy_v3_v3(pi->location, p->state.co);
+ pi->location[3] = BLI_hash_int_01(ind);
+
copy_v3_v3(pi->velocity, p->state.vel);
copy_v3_v3(pi->angular_velocity, p->state.ave);
return 1;
@@ -1834,7 +1838,7 @@ int GPU_object_material_bind(int nr, void *attribs)
}
GPU_material_bind(
- gpumat, GMS.gob->lay, GMS.glay, 1.0, !(GMS.gob->mode & OB_MODE_TEXTURE_PAINT),
+ gpumat, GMS.gob->lay, GMS.glay, 1.0, !(GMS.gob_object_mode & OB_MODE_TEXTURE_PAINT),
GMS.gviewmat, GMS.gviewinv, GMS.gviewcamtexcofac);
auto_bump_scale = GMS.gob->derivedFinal != NULL ? GMS.gob->derivedFinal->auto_bump_scale : 1.0f;
@@ -2093,7 +2097,7 @@ int GPU_scene_object_lights(ViewLayer *view_layer, float viewmat[4][4], int orth
return count;
}
-static void gpu_multisample(bool enable)
+static void gpu_disable_multisample(void)
{
#ifdef __linux__
/* changing multisample from the default (enabled) causes problems on some
@@ -2109,16 +2113,10 @@ static void gpu_multisample(bool enable)
}
if (toggle_ok) {
- if (enable)
- glEnable(GL_MULTISAMPLE);
- else
- glDisable(GL_MULTISAMPLE);
+ glDisable(GL_MULTISAMPLE);
}
#else
- if (enable)
- glEnable(GL_MULTISAMPLE);
- else
- glDisable(GL_MULTISAMPLE);
+ glDisable(GL_MULTISAMPLE);
#endif
}
@@ -2150,7 +2148,7 @@ void GPU_state_init(void)
glCullFace(GL_BACK);
glDisable(GL_CULL_FACE);
- gpu_multisample(false);
+ gpu_disable_multisample();
}
void GPU_enable_program_point_size(void)
diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c
index 57df877bf18..6bf330179d3 100644
--- a/source/blender/gpu/intern/gpu_extensions.c
+++ b/source/blender/gpu/intern/gpu_extensions.c
@@ -178,14 +178,6 @@ void gpu_extensions_init(void)
GG.device = GPU_DEVICE_ATI;
GG.driver = GPU_DRIVER_OFFICIAL;
}
- /* XXX : TODO : Remove this once this sampling mipmap problem is gone.
- * https://github.com/dfelinto/opengl-sandbox/blob/downsample/README.md */
- else if (strstr(renderer, "AMD VEGA") &&
- strstr(vendor, "X.Org"))
- {
- GG.device = GPU_DEVICE_AMD_VEGA;
- GG.driver = GPU_DRIVER_OPENSOURCE;
- }
else if (strstr(vendor, "NVIDIA")) {
GG.device = GPU_DEVICE_NVIDIA;
GG.driver = GPU_DRIVER_OFFICIAL;
diff --git a/source/blender/gpu/intern/gpu_framebuffer.c b/source/blender/gpu/intern/gpu_framebuffer.c
index 09013cd29bd..e83eeefe2c5 100644
--- a/source/blender/gpu/intern/gpu_framebuffer.c
+++ b/source/blender/gpu/intern/gpu_framebuffer.c
@@ -385,6 +385,13 @@ bool GPU_framebuffer_check_valid(GPUFrameBuffer *fb, char err_out[256])
glBindFramebuffer(GL_FRAMEBUFFER, fb->object);
GG.currentfb = fb->object;
+ /* On macOS glDrawBuffer must be set when checking completeness,
+ * otherwise it will return GL_FRAMEBUFFER_UNSUPPORTED when only a
+ * color buffer without depth is used. */
+ if (fb->colortex[0]) {
+ glDrawBuffer(GL_COLOR_ATTACHMENT0);
+ }
+
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE) {
@@ -602,18 +609,9 @@ void GPU_framebuffer_recursive_downsample(
current_dim[0] /= 2;
current_dim[1] /= 2;
- if (GPU_type_matches(GPU_DEVICE_AMD_VEGA, GPU_OS_UNIX, GPU_DRIVER_OPENSOURCE)) {
- /* NOTE : here 16 is because of a bug on AMD Vega GPU + non-pro drivers, that prevents us
- * from sampling mipmaps that are smaller or equal to 16px. (9) */
- if (current_dim[0] <= 16 && current_dim[1] <= 16) {
- break;
- }
- }
- else {
- if (current_dim[0] <= 2 && current_dim[1] <= 2) {
- /* Cannot reduce further. */
- break;
- }
+ if (current_dim[0] <= 2 && current_dim[1] <= 2) {
+ /* Cannot reduce further. */
+ break;
}
/* ensure that the viewport size is always at least 1x1 */
@@ -650,7 +648,7 @@ struct GPUOffScreen {
GPUTexture *depth;
};
-GPUOffScreen *GPU_offscreen_create(int width, int height, int samples, bool high_bitdepth, char err_out[256])
+GPUOffScreen *GPU_offscreen_create(int width, int height, int samples, bool depth, bool high_bitdepth, char err_out[256])
{
GPUOffScreen *ofs;
@@ -672,15 +670,17 @@ GPUOffScreen *GPU_offscreen_create(int width, int height, int samples, bool high
}
}
- ofs->depth = GPU_texture_create_depth_with_stencil_multisample(width, height, samples, err_out);
- if (!ofs->depth) {
- GPU_offscreen_free(ofs);
- return NULL;
- }
+ if (depth) {
+ ofs->depth = GPU_texture_create_depth_with_stencil_multisample(width, height, samples, err_out);
+ if (!ofs->depth) {
+ GPU_offscreen_free(ofs);
+ return NULL;
+ }
- if (!GPU_framebuffer_texture_attach(ofs->fb, ofs->depth, 0, 0)) {
- GPU_offscreen_free(ofs);
- return NULL;
+ if (!GPU_framebuffer_texture_attach(ofs->fb, ofs->depth, 0, 0)) {
+ GPU_offscreen_free(ofs);
+ return NULL;
+ }
}
if (high_bitdepth) {
@@ -740,6 +740,24 @@ void GPU_offscreen_unbind(GPUOffScreen *ofs, bool restore)
glEnable(GL_SCISSOR_TEST);
}
+void GPU_offscreen_blit(GPUOffScreen *ofs, int x, int y)
+{
+ const int w = GPU_texture_width(ofs->color);
+ const int h = GPU_texture_height(ofs->color);
+
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, ofs->fb->object);
+ GLenum status = glCheckFramebufferStatus(GL_READ_FRAMEBUFFER);
+
+ if (status == GL_FRAMEBUFFER_COMPLETE) {
+ glBlitFramebuffer(0, 0, w, h, x, y, x + w, y + h, GL_COLOR_BUFFER_BIT, GL_NEAREST);
+ }
+ else {
+ gpu_print_framebuffer_error(status, NULL);
+ }
+
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
+}
+
void GPU_offscreen_read_pixels(GPUOffScreen *ofs, int type, void *pixels)
{
const int w = GPU_texture_width(ofs->color);
@@ -827,9 +845,9 @@ int GPU_offscreen_height(const GPUOffScreen *ofs)
return GPU_texture_height(ofs->color);
}
-int GPU_offscreen_color_texture(const GPUOffScreen *ofs)
+GPUTexture *GPU_offscreen_color_texture(const GPUOffScreen *ofs)
{
- return GPU_texture_opengl_bindcode(ofs->color);
+ return ofs->color;
}
/* only to be used by viewport code! */
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index 2e6c1cbf9df..2d7b9415030 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -417,7 +417,7 @@ void GPU_material_bind_uniforms(
GPU_shader_uniform_vector(shader, material->partscalarpropsloc, 4, 1, pi->scalprops);
}
if (material->builtins & GPU_PARTICLE_LOCATION) {
- GPU_shader_uniform_vector(shader, material->partcoloc, 3, 1, pi->location);
+ GPU_shader_uniform_vector(shader, material->partcoloc, 4, 1, pi->location);
}
if (material->builtins & GPU_PARTICLE_VELOCITY) {
GPU_shader_uniform_vector(shader, material->partvel, 3, 1, pi->velocity);
@@ -557,7 +557,9 @@ static float eval_profile(float r, short falloff_type, float sharpness, float pa
{
r = fabsf(r);
- if (falloff_type == SHD_SUBSURFACE_BURLEY) {
+ if (falloff_type == SHD_SUBSURFACE_BURLEY ||
+ falloff_type == SHD_SUBSURFACE_RANDOM_WALK)
+ {
return burley_profile(r, param) / BURLEY_TRUNCATE_CDF;
}
else if (falloff_type == SHD_SUBSURFACE_CUBIC) {
@@ -598,7 +600,9 @@ static void compute_sss_kernel(
/* Christensen-Burley fitting */
float l[3], d[3];
- if (falloff_type == SHD_SUBSURFACE_BURLEY) {
+ if (falloff_type == SHD_SUBSURFACE_BURLEY ||
+ falloff_type == SHD_SUBSURFACE_RANDOM_WALK)
+ {
mul_v3_v3fl(l, rad, 0.25f * M_1_PI);
const float A = 1.0f;
const float s = 1.9f - A + 3.5f * (A - 0.8f) * (A - 0.8f);
diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c
index 598722d372b..c25d03dff2f 100644
--- a/source/blender/gpu/intern/gpu_shader.c
+++ b/source/blender/gpu/intern/gpu_shader.c
@@ -68,6 +68,7 @@ extern char datatoc_gpu_shader_2D_smooth_color_frag_glsl[];
extern char datatoc_gpu_shader_2D_image_vert_glsl[];
extern char datatoc_gpu_shader_3D_image_vert_glsl[];
+extern char datatoc_gpu_shader_image_frag_glsl[];
extern char datatoc_gpu_shader_image_linear_frag_glsl[];
extern char datatoc_gpu_shader_image_color_frag_glsl[];
extern char datatoc_gpu_shader_image_alpha_color_frag_glsl[];
@@ -75,7 +76,6 @@ extern char datatoc_gpu_shader_image_shuffle_color_frag_glsl[];
extern char datatoc_gpu_shader_image_interlace_frag_glsl[];
extern char datatoc_gpu_shader_image_mask_uniform_color_frag_glsl[];
extern char datatoc_gpu_shader_image_modulate_alpha_frag_glsl[];
-extern char datatoc_gpu_shader_image_rect_modulate_alpha_frag_glsl[];
extern char datatoc_gpu_shader_image_depth_linear_frag_glsl[];
extern char datatoc_gpu_shader_3D_vert_glsl[];
extern char datatoc_gpu_shader_3D_normal_vert_glsl[];
@@ -98,7 +98,7 @@ extern char datatoc_gpu_shader_instance_edges_variying_color_geom_glsl[];
extern char datatoc_gpu_shader_instance_edges_variying_color_vert_glsl[];
extern char datatoc_gpu_shader_instance_bone_envelope_solid_vert_glsl[];
extern char datatoc_gpu_shader_instance_bone_envelope_wire_vert_glsl[];
-extern char datatoc_gpu_shader_instance_mball_helpers_vert_glsl[];
+extern char datatoc_gpu_shader_instance_mball_handles_vert_glsl[];
extern char datatoc_gpu_shader_3D_groundpoint_vert_glsl[];
extern char datatoc_gpu_shader_3D_groundline_geom_glsl[];
@@ -710,8 +710,6 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)
datatoc_gpu_shader_image_mask_uniform_color_frag_glsl },
[GPU_SHADER_3D_IMAGE_MODULATE_ALPHA] = { datatoc_gpu_shader_3D_image_vert_glsl,
datatoc_gpu_shader_image_modulate_alpha_frag_glsl },
- [GPU_SHADER_3D_IMAGE_RECT_MODULATE_ALPHA] = { datatoc_gpu_shader_3D_image_vert_glsl,
- datatoc_gpu_shader_image_rect_modulate_alpha_frag_glsl },
[GPU_SHADER_3D_IMAGE_DEPTH] = { datatoc_gpu_shader_3D_image_vert_glsl,
datatoc_gpu_shader_image_depth_linear_frag_glsl },
@@ -728,10 +726,14 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)
datatoc_gpu_shader_2D_smooth_color_frag_glsl },
[GPU_SHADER_2D_IMAGE_LINEAR_TO_SRGB] = { datatoc_gpu_shader_2D_image_vert_glsl,
datatoc_gpu_shader_image_linear_frag_glsl },
+ [GPU_SHADER_2D_IMAGE] = { datatoc_gpu_shader_2D_image_vert_glsl,
+ datatoc_gpu_shader_image_frag_glsl },
[GPU_SHADER_2D_IMAGE_COLOR] = { datatoc_gpu_shader_2D_image_vert_glsl,
datatoc_gpu_shader_image_color_frag_glsl },
[GPU_SHADER_2D_IMAGE_ALPHA_COLOR] = { datatoc_gpu_shader_2D_image_vert_glsl,
datatoc_gpu_shader_image_alpha_color_frag_glsl },
+ [GPU_SHADER_2D_IMAGE_ALPHA] = { datatoc_gpu_shader_2D_image_vert_glsl,
+ datatoc_gpu_shader_image_modulate_alpha_frag_glsl },
[GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR] = { datatoc_gpu_shader_2D_image_vert_glsl,
datatoc_gpu_shader_image_shuffle_color_frag_glsl },
[GPU_SHADER_3D_UNIFORM_COLOR] = { datatoc_gpu_shader_3D_vert_glsl, datatoc_gpu_shader_uniform_color_frag_glsl },
@@ -821,7 +823,7 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)
[GPU_SHADER_3D_INSTANCE_BONE_ENVELOPE_WIRE] = { datatoc_gpu_shader_instance_bone_envelope_wire_vert_glsl,
datatoc_gpu_shader_flat_color_frag_glsl },
- [GPU_SHADER_3D_INSTANCE_MBALL_HELPERS] = { datatoc_gpu_shader_instance_mball_helpers_vert_glsl,
+ [GPU_SHADER_3D_INSTANCE_MBALL_HANDLES] = { datatoc_gpu_shader_instance_mball_handles_vert_glsl,
datatoc_gpu_shader_flat_color_frag_glsl },
};
diff --git a/source/blender/gpu/intern/gpu_viewport.c b/source/blender/gpu/intern/gpu_viewport.c
index 3ef53b3a6c3..fc045805874 100644
--- a/source/blender/gpu/intern/gpu_viewport.c
+++ b/source/blender/gpu/intern/gpu_viewport.c
@@ -474,7 +474,7 @@ cleanup:
GPU_framebuffer_slots_bind(dfbl->default_fb, 0);
}
-static void draw_ofs_to_screen(GPUViewport *viewport)
+static void draw_ofs_to_screen(GPUViewport *viewport, const rcti *rect)
{
DefaultTextureList *dtxl = viewport->txl;
@@ -483,6 +483,9 @@ static void draw_ofs_to_screen(GPUViewport *viewport)
const float w = (float)GPU_texture_width(color);
const float h = (float)GPU_texture_height(color);
+ BLI_assert(w == BLI_rcti_size_x(rect) + 1);
+ BLI_assert(h == BLI_rcti_size_y(rect) + 1);
+
Gwn_VertFormat *format = immVertexFormat();
unsigned int texcoord = GWN_vertformat_attr_add(format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
@@ -495,16 +498,16 @@ static void draw_ofs_to_screen(GPUViewport *viewport)
immBegin(GWN_PRIM_TRI_STRIP, 4);
immAttrib2f(texcoord, 0.0f, 0.0f);
- immVertex2f(pos, 0.0f, 0.0f);
+ immVertex2f(pos, rect->xmin, rect->ymin);
immAttrib2f(texcoord, 1.0f, 0.0f);
- immVertex2f(pos, w, 0.0f);
+ immVertex2f(pos, rect->xmin + w, rect->ymin);
immAttrib2f(texcoord, 0.0f, 1.0f);
- immVertex2f(pos, 0.0f, h);
+ immVertex2f(pos, rect->xmin, rect->ymin + h);
immAttrib2f(texcoord, 1.0f, 1.0f);
- immVertex2f(pos, w, h);
+ immVertex2f(pos, rect->xmin + w, rect->ymin + h);
immEnd();
@@ -523,9 +526,16 @@ void GPU_viewport_unbind(GPUViewport *viewport)
glEnable(GL_SCISSOR_TEST);
glDisable(GL_DEPTH_TEST);
+ }
+}
+void GPU_viewport_draw_to_screen(GPUViewport *viewport, const rcti *rect)
+{
+ DefaultFramebufferList *dfbl = viewport->fbl;
+
+ if (dfbl->default_fb) {
/* This might be bandwidth limiting */
- draw_ofs_to_screen(viewport);
+ draw_ofs_to_screen(viewport, rect);
}
}
diff --git a/source/blender/gpu/shaders/gpu_shader_image_rect_modulate_alpha_frag.glsl b/source/blender/gpu/shaders/gpu_shader_image_frag.glsl
index 7d9ce9d2003..6eeab8ca7e8 100644
--- a/source/blender/gpu/shaders/gpu_shader_image_rect_modulate_alpha_frag.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_image_frag.glsl
@@ -2,11 +2,9 @@
in vec2 texCoord_interp;
out vec4 fragColor;
-uniform float alpha;
-uniform sampler2DRect image;
+uniform sampler2D image;
void main()
{
fragColor = texture(image, texCoord_interp);
- fragColor.a *= alpha;
}
diff --git a/source/blender/gpu/shaders/gpu_shader_image_interlace_frag.glsl b/source/blender/gpu/shaders/gpu_shader_image_interlace_frag.glsl
index 7f3e7df40ac..d95645f58e5 100644
--- a/source/blender/gpu/shaders/gpu_shader_image_interlace_frag.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_image_interlace_frag.glsl
@@ -8,8 +8,8 @@ in vec2 texCoord_interp;
out vec4 fragColor;
uniform int interlace_id;
-uniform sampler2DRect image_a;
-uniform sampler2DRect image_b;
+uniform sampler2D image_a;
+uniform sampler2D image_b;
bool interlace()
{
diff --git a/source/blender/gpu/shaders/gpu_shader_instance_mball_helpers_vert.glsl b/source/blender/gpu/shaders/gpu_shader_instance_mball_handles_vert.glsl
index 819199c26c7..819199c26c7 100644
--- a/source/blender/gpu/shaders/gpu_shader_instance_mball_helpers_vert.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_instance_mball_handles_vert.glsl
diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl
index 780f4f59fb9..7acd9aa1fd5 100644
--- a/source/blender/gpu/shaders/gpu_shader_material.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material.glsl
@@ -238,16 +238,18 @@ void geom(
}
void particle_info(
- vec4 sprops, vec3 loc, vec3 vel, vec3 avel,
- out float index, out float age, out float life_time, out vec3 location,
+ vec4 sprops, vec4 loc, vec3 vel, vec3 avel,
+ out float index, out float random, out float age,
+ out float life_time, out vec3 location,
out float size, out vec3 velocity, out vec3 angular_velocity)
{
index = sprops.x;
+ random = loc.w;
age = sprops.y;
life_time = sprops.z;
size = sprops.w;
- location = loc;
+ location = loc.xyz;
velocity = vel;
angular_velocity = avel;
}
@@ -2533,8 +2535,7 @@ uint hash(int kx, int ky, int kz)
float bits_to_01(uint bits)
{
- float x = float(bits) * (1.0 / float(0xffffffffu));
- return x;
+ return (float(bits) / 4294967295.0);
}
float cellnoise(vec3 p)
@@ -2979,7 +2980,9 @@ void node_bsdf_refraction(vec4 color, float roughness, float ior, vec3 N, out Cl
color.rgb *= (refractionDepth > 0.0) ? color.rgb : vec3(1.0); /* Simulate 2 absorption event. */
roughness = sqrt(roughness);
eevee_closure_refraction(N, roughness, ior, out_refr);
+ vec3 vN = normalize(mat3(ViewMatrix) * N);
result = CLOSURE_DEFAULT;
+ result.ssr_normal = normal_encode(vN, viewCameraVec);
result.radiance = out_refr * color.rgb;
result.ssr_id = REFRACT_CLOSURE_FLAG;
#else
@@ -3004,7 +3007,7 @@ void node_ambient_occlusion(vec4 color, out Closure result)
/* emission */
-void node_emission(vec4 color, float strength, vec3 N, out Closure result)
+void node_emission(vec4 color, float strength, vec3 vN, out Closure result)
{
#ifndef VOLUMETRICS
color *= strength;
@@ -3012,7 +3015,7 @@ void node_emission(vec4 color, float strength, vec3 N, out Closure result)
result = CLOSURE_DEFAULT;
result.radiance = color.rgb;
result.opacity = color.a;
- result.ssr_normal = normal_encode(N, viewCameraVec);
+ result.ssr_normal = normal_encode(vN, viewCameraVec);
#else
result = Closure(color.rgb, color.a);
#endif
@@ -3657,17 +3660,29 @@ float noise_perlin(float x, float y, float z)
float v = noise_fade(fy);
float w = noise_fade(fz);
- float result;
+ float noise_u[2], noise_v[2];
+
+ noise_u[0] = noise_nerp(u,
+ noise_grad(hash(X, Y, Z), fx, fy, fz),
+ noise_grad(hash(X + 1, Y, Z), fx - 1.0, fy, fz));
+
+ noise_u[1] = noise_nerp(u,
+ noise_grad(hash(X, Y + 1, Z), fx, fy - 1.0, fz),
+ noise_grad(hash(X + 1, Y + 1, Z), fx - 1.0, fy - 1.0, fz));
- result = noise_nerp(w, noise_nerp(v, noise_nerp(u, noise_grad(hash(X, Y, Z), fx, fy, fz),
- noise_grad(hash(X + 1, Y, Z), fx - 1.0, fy, fz)),
- noise_nerp(u, noise_grad(hash(X, Y + 1, Z), fx, fy - 1.0, fz),
- noise_grad(hash(X + 1, Y + 1, Z), fx - 1.0, fy - 1.0, fz))),
- noise_nerp(v, noise_nerp(u, noise_grad(hash(X, Y, Z + 1), fx, fy, fz - 1.0),
- noise_grad(hash(X + 1, Y, Z + 1), fx - 1.0, fy, fz - 1.0)),
- noise_nerp(u, noise_grad(hash(X, Y + 1, Z + 1), fx, fy - 1.0, fz - 1.0),
- noise_grad(hash(X + 1, Y + 1, Z + 1), fx - 1.0, fy - 1.0, fz - 1.0))));
- return noise_scale3(result);
+ noise_v[0] = noise_nerp(v, noise_u[0], noise_u[1]);
+
+ noise_u[0] = noise_nerp(u,
+ noise_grad(hash(X, Y, Z + 1), fx, fy, fz - 1.0),
+ noise_grad(hash(X + 1, Y, Z + 1), fx - 1.0, fy, fz - 1.0));
+
+ noise_u[1] = noise_nerp(u,
+ noise_grad(hash(X, Y + 1, Z + 1), fx, fy - 1.0, fz - 1.0),
+ noise_grad(hash(X + 1, Y + 1, Z + 1), fx - 1.0, fy - 1.0, fz - 1.0));
+
+ noise_v[1] = noise_nerp(v, noise_u[0], noise_u[1]);
+
+ return noise_scale3(noise_nerp(w, noise_v[0], noise_v[1]));
}
float noise(vec3 p)
@@ -4135,9 +4150,38 @@ void node_bevel(float radius, vec3 N, out vec3 result)
result = N;
}
-void node_displacement(float height, float dist, vec3 N, out vec3 result)
+void node_displacement_object(float height, float midlevel, float scale, vec3 N, mat4 obmat, out vec3 result)
+{
+ N = (vec4(N, 0.0) * obmat).xyz;
+ result = (height - midlevel) * scale * normalize(N);
+ result = (obmat * vec4(result, 0.0)).xyz;
+}
+
+void node_displacement_world(float height, float midlevel, float scale, vec3 N, out vec3 result)
+{
+ result = (height - midlevel) * scale * normalize(N);
+}
+
+void node_vector_displacement_tangent(vec4 vector, float midlevel, float scale, vec4 tangent, vec3 normal, mat4 obmat, mat4 viewmat, out vec3 result)
+{
+ 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));
+
+ vec3 offset = (vector.xyz - vec3(midlevel)) * scale;
+ result = offset.x * T_object + offset.y * N_object + offset.z * B_object;
+ result = (obmat * vec4(result, 0.0)).xyz;
+}
+
+void node_vector_displacement_object(vec4 vector, float midlevel, float scale, mat4 obmat, out vec3 result)
+{
+ result = (vector.xyz - vec3(midlevel)) * scale;
+ result = (obmat * vec4(result, 0.0)).xyz;
+}
+
+void node_vector_displacement_world(vec4 vector, float midlevel, float scale, out vec3 result)
{
- result = height * dist * N;
+ result = (vector.xyz - vec3(midlevel)) * scale;
}
/* output */
diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c
index 863bce125c5..e28c8122006 100644
--- a/source/blender/imbuf/intern/colormanagement.c
+++ b/source/blender/imbuf/intern/colormanagement.c
@@ -2176,7 +2176,7 @@ unsigned char *IMB_display_buffer_acquire(ImBuf *ibuf, const ColorManagedViewSet
BLI_rcti_init(&ibuf->invalid_rect, 0, 0, 0, 0);
}
- BLI_lock_thread(LOCK_COLORMANAGE);
+ BLI_thread_lock(LOCK_COLORMANAGE);
/* ensure color management bit fields exists */
if (!ibuf->display_buffer_flags) {
@@ -2194,7 +2194,7 @@ unsigned char *IMB_display_buffer_acquire(ImBuf *ibuf, const ColorManagedViewSet
display_buffer = colormanage_cache_get(ibuf, &cache_view_settings, &cache_display_settings, cache_handle);
if (display_buffer) {
- BLI_unlock_thread(LOCK_COLORMANAGE);
+ BLI_thread_unlock(LOCK_COLORMANAGE);
return display_buffer;
}
@@ -2205,7 +2205,7 @@ unsigned char *IMB_display_buffer_acquire(ImBuf *ibuf, const ColorManagedViewSet
colormanage_cache_put(ibuf, &cache_view_settings, &cache_display_settings, display_buffer, cache_handle);
- BLI_unlock_thread(LOCK_COLORMANAGE);
+ BLI_thread_unlock(LOCK_COLORMANAGE);
return display_buffer;
}
@@ -2244,11 +2244,11 @@ void IMB_display_buffer_transform_apply(unsigned char *display_buffer, float *li
void IMB_display_buffer_release(void *cache_handle)
{
if (cache_handle) {
- BLI_lock_thread(LOCK_COLORMANAGE);
+ BLI_thread_lock(LOCK_COLORMANAGE);
colormanage_cache_handle_release(cache_handle);
- BLI_unlock_thread(LOCK_COLORMANAGE);
+ BLI_thread_unlock(LOCK_COLORMANAGE);
}
}
@@ -2964,7 +2964,7 @@ static void imb_partial_display_buffer_update_ex(ImBuf *ibuf,
view_flag = 1 << (cache_view_settings.view - 1);
display_index = cache_display_settings.display - 1;
- BLI_lock_thread(LOCK_COLORMANAGE);
+ BLI_thread_lock(LOCK_COLORMANAGE);
if ((ibuf->userflags & IB_DISPLAY_BUFFER_INVALID) == 0) {
display_buffer = colormanage_cache_get(ibuf,
@@ -2983,7 +2983,7 @@ static void imb_partial_display_buffer_update_ex(ImBuf *ibuf,
memset(ibuf->display_buffer_flags, 0, global_tot_display * sizeof(unsigned int));
ibuf->display_buffer_flags[display_index] |= view_flag;
- BLI_unlock_thread(LOCK_COLORMANAGE);
+ BLI_thread_unlock(LOCK_COLORMANAGE);
}
if (display_buffer == NULL) {
diff --git a/source/blender/imbuf/intern/moviecache.c b/source/blender/imbuf/intern/moviecache.c
index 89955711384..daf062f5499 100644
--- a/source/blender/imbuf/intern/moviecache.c
+++ b/source/blender/imbuf/intern/moviecache.c
@@ -513,7 +513,7 @@ void IMB_moviecache_get_cache_segments(MovieCache *cache, int proxy, int render_
*points_r = cache->points;
}
else {
- int totframe = BLI_ghash_size(cache->hash);
+ int totframe = BLI_ghash_len(cache->hash);
int *frames = MEM_callocN(totframe * sizeof(int), "movieclip cache frames");
int a, totseg = 0;
GHashIterator gh_iter;
diff --git a/source/blender/imbuf/intern/thumbs.c b/source/blender/imbuf/intern/thumbs.c
index 8c427dff4a3..ba72decf44d 100644
--- a/source/blender/imbuf/intern/thumbs.c
+++ b/source/blender/imbuf/intern/thumbs.c
@@ -652,7 +652,7 @@ static struct IMBThumbLocks {
void IMB_thumb_locks_acquire(void)
{
- BLI_lock_thread(LOCK_IMAGE);
+ BLI_thread_lock(LOCK_IMAGE);
if (thumb_locks.lock_counter == 0) {
BLI_assert(thumb_locks.locked_paths == NULL);
@@ -663,12 +663,12 @@ void IMB_thumb_locks_acquire(void)
BLI_assert(thumb_locks.locked_paths != NULL);
BLI_assert(thumb_locks.lock_counter > 0);
- BLI_unlock_thread(LOCK_IMAGE);
+ BLI_thread_unlock(LOCK_IMAGE);
}
void IMB_thumb_locks_release(void)
{
- BLI_lock_thread(LOCK_IMAGE);
+ BLI_thread_lock(LOCK_IMAGE);
BLI_assert((thumb_locks.locked_paths != NULL) && (thumb_locks.lock_counter > 0));
thumb_locks.lock_counter--;
@@ -678,14 +678,14 @@ void IMB_thumb_locks_release(void)
BLI_condition_end(&thumb_locks.cond);
}
- BLI_unlock_thread(LOCK_IMAGE);
+ BLI_thread_unlock(LOCK_IMAGE);
}
void IMB_thumb_path_lock(const char *path)
{
void *key = BLI_strdup(path);
- BLI_lock_thread(LOCK_IMAGE);
+ BLI_thread_lock(LOCK_IMAGE);
BLI_assert((thumb_locks.locked_paths != NULL) && (thumb_locks.lock_counter > 0));
if (thumb_locks.locked_paths) {
@@ -694,14 +694,14 @@ void IMB_thumb_path_lock(const char *path)
}
}
- BLI_unlock_thread(LOCK_IMAGE);
+ BLI_thread_unlock(LOCK_IMAGE);
}
void IMB_thumb_path_unlock(const char *path)
{
const void *key = path;
- BLI_lock_thread(LOCK_IMAGE);
+ BLI_thread_lock(LOCK_IMAGE);
BLI_assert((thumb_locks.locked_paths != NULL) && (thumb_locks.lock_counter > 0));
if (thumb_locks.locked_paths) {
@@ -711,5 +711,5 @@ void IMB_thumb_path_unlock(const char *path)
BLI_condition_notify_all(&thumb_locks.cond);
}
- BLI_unlock_thread(LOCK_IMAGE);
+ BLI_thread_unlock(LOCK_IMAGE);
}
diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h
index 407d59f09da..fc3b4afe18d 100644
--- a/source/blender/makesdna/DNA_brush_types.h
+++ b/source/blender/makesdna/DNA_brush_types.h
@@ -72,7 +72,7 @@ typedef struct Brush {
float rake_factor; /* rake actual data (not texture), used for sculpt */
short blend; /* blend mode */
- short ob_mode; /* & with ob->mode to see if the brush is compatible, use for display only. */
+ short ob_mode; /* eObjectMode: to see if the brush is compatible, use for display only. */
float weight; /* brush weight */
int size; /* brush diameter */
int flag; /* general purpose flag */
diff --git a/source/blender/makesdna/DNA_meta_types.h b/source/blender/makesdna/DNA_meta_types.h
index f9ba45efef8..d1f001fccc4 100644
--- a/source/blender/makesdna/DNA_meta_types.h
+++ b/source/blender/makesdna/DNA_meta_types.h
@@ -62,7 +62,7 @@ typedef struct MetaElem {
/* Draw_Data: stores pointers used for shader attributes */
float draw_scale_xform[3][4]; /* Matrix of Scale and Translation */
- float draw_stiffness_radius; /* stiffness circle radius (only in edit mode) */
+ float draw_stiffness_radius; /* radius of the stiffness circle (only in edit mode) */
float pad;
} MetaElem;
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 5df7e49c2f3..283e801ea7a 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -603,7 +603,7 @@ typedef struct ClothModifierData {
struct Cloth *clothObject; /* The internal data structure for cloth. */
struct ClothSimSettings *sim_parms; /* definition is in DNA_cloth_types.h */
struct ClothCollSettings *coll_parms; /* definition is in DNA_cloth_types.h */
- struct PointCache *point_cache; /* definition is in DNA_object_force.h */
+ struct PointCache *point_cache; /* definition is in DNA_object_force_types.h */
struct ListBase ptcaches;
/* XXX nasty hack, remove once hair can be separated from cloth modifier data */
struct ClothHairData *hairdata;
@@ -655,8 +655,7 @@ typedef struct BooleanModifierData {
struct Object *object;
char operation;
- char solver;
- char pad;
+ char pad[2];
char bm_flag;
float double_threshold;
} BooleanModifierData;
@@ -667,11 +666,6 @@ typedef enum {
eBooleanModifierOp_Difference = 2,
} BooleanModifierOp;
-typedef enum {
- eBooleanModifierSolver_Carve = 0,
- eBooleanModifierSolver_BMesh = 1,
-} BooleanSolver;
-
/* bm_flag (only used when G_DEBUG) */
enum {
eBooleanModifierBMeshFlag_BMesh_Separate = (1 << 0),
@@ -800,8 +794,8 @@ typedef enum {
typedef struct FluidsimModifierData {
ModifierData modifier;
- struct FluidsimSettings *fss; /* definition is in DNA_object_fluidsim.h */
- struct PointCache *point_cache; /* definition is in DNA_object_force.h */
+ struct FluidsimSettings *fss; /* definition is in DNA_object_fluidsim_types.h */
+ struct PointCache *point_cache; /* definition is in DNA_object_force_types.h */
} FluidsimModifierData;
typedef struct ShrinkwrapModifierData {
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 0bd36244ffb..63eecebf44a 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -1032,12 +1032,12 @@ typedef struct NodeSunBeams {
#define SHD_TANGENT_AXIS_Y 1
#define SHD_TANGENT_AXIS_Z 2
-/* normal map space */
-#define SHD_NORMAL_MAP_TANGENT 0
-#define SHD_NORMAL_MAP_OBJECT 1
-#define SHD_NORMAL_MAP_WORLD 2
-#define SHD_NORMAL_MAP_BLENDER_OBJECT 3
-#define SHD_NORMAL_MAP_BLENDER_WORLD 4
+/* normal map, displacement space */
+#define SHD_SPACE_TANGENT 0
+#define SHD_SPACE_OBJECT 1
+#define SHD_SPACE_WORLD 2
+#define SHD_SPACE_BLENDER_OBJECT 3
+#define SHD_SPACE_BLENDER_WORLD 4
/* math node clamp */
#define SHD_MATH_CLAMP 1
@@ -1077,6 +1077,7 @@ enum {
SHD_SUBSURFACE_CUBIC = 1,
SHD_SUBSURFACE_GAUSSIAN = 2,
SHD_SUBSURFACE_BURLEY = 3,
+ SHD_SUBSURFACE_RANDOM_WALK = 4,
};
/* blur node */
diff --git a/source/blender/makesdna/DNA_object_enums.h b/source/blender/makesdna/DNA_object_enums.h
new file mode 100644
index 00000000000..58f9e29297f
--- /dev/null
+++ b/source/blender/makesdna/DNA_object_enums.h
@@ -0,0 +1,49 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file DNA_object_enums.h
+ * \ingroup DNA
+ *
+ * Enums typedef's for use in public headers.
+ */
+
+#ifndef __DNA_OBJECT_ENUMS_H__
+#define __DNA_OBJECT_ENUMS_H__
+
+/* Object.mode */
+typedef enum eObjectMode {
+ OB_MODE_OBJECT = 0,
+ OB_MODE_EDIT = 1 << 0,
+ OB_MODE_SCULPT = 1 << 1,
+ OB_MODE_VERTEX_PAINT = 1 << 2,
+ OB_MODE_WEIGHT_PAINT = 1 << 3,
+ OB_MODE_TEXTURE_PAINT = 1 << 4,
+ OB_MODE_PARTICLE_EDIT = 1 << 5,
+ OB_MODE_POSE = 1 << 6,
+ OB_MODE_GPENCIL = 1 << 7, /* NOTE: Just a dummy to make the UI nicer */
+} eObjectMode;
+
+/* Any mode where the brush system is used. */
+#define OB_MODE_ALL_PAINT (OB_MODE_SCULPT | OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)
+
+/* Any mode that uses Object.sculpt. */
+#define OB_MODE_ALL_SCULPT (OB_MODE_SCULPT | OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT)
+
+#endif /* __DNA_OBJECT_ENUMS_H__ */
diff --git a/source/blender/makesdna/DNA_object_fluidsim.h b/source/blender/makesdna/DNA_object_fluidsim_types.h
index 846d5788d63..b305235083a 100644
--- a/source/blender/makesdna/DNA_object_fluidsim.h
+++ b/source/blender/makesdna/DNA_object_fluidsim_types.h
@@ -25,12 +25,12 @@
* ***** END GPL LICENSE BLOCK *****
*/
-/** \file DNA_object_fluidsim.h
+/** \file DNA_object_fluidsim_types.h
* \ingroup DNA
*/
-#ifndef __DNA_OBJECT_FLUIDSIM_H__
-#define __DNA_OBJECT_FLUIDSIM_H__
+#ifndef __DNA_OBJECT_FLUIDSIM_TYPES_H__
+#define __DNA_OBJECT_FLUIDSIM_TYPES_H__
#include "DNA_ID.h"
#include "DNA_defs.h"
@@ -189,6 +189,5 @@ typedef struct FluidsimSettings {
}
#endif
-#endif
-
+#endif /* __DNA_OBJECT_FLUIDSIM_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_object_force.h b/source/blender/makesdna/DNA_object_force_types.h
index 63e1da4f90e..e7ebd3b72d7 100644
--- a/source/blender/makesdna/DNA_object_force.h
+++ b/source/blender/makesdna/DNA_object_force_types.h
@@ -25,12 +25,12 @@
* ***** END GPL LICENSE BLOCK *****
*/
-/** \file DNA_object_force.h
+/** \file DNA_object_force_types.h
* \ingroup DNA
*/
-#ifndef __DNA_OBJECT_FORCE_H__
-#define __DNA_OBJECT_FORCE_H__
+#ifndef __DNA_OBJECT_FORCE_TYPES_H__
+#define __DNA_OBJECT_FORCE_TYPES_H__
#ifdef __cplusplus
extern "C" {
@@ -459,5 +459,5 @@ typedef struct SoftBody {
}
#endif
-#endif
+#endif /* __DNA_OBJECT_FORCE_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h
index 7c3ef5e72be..0b7dccee9ab 100644
--- a/source/blender/makesdna/DNA_object_types.h
+++ b/source/blender/makesdna/DNA_object_types.h
@@ -33,6 +33,8 @@
#ifndef __DNA_OBJECT_TYPES_H__
#define __DNA_OBJECT_TYPES_H__
+#include "DNA_object_enums.h"
+
#include "DNA_defs.h"
#include "DNA_listBase.h"
#include "DNA_ID.h"
@@ -169,9 +171,6 @@ typedef struct Object {
ListBase defbase; /* list of bDeformGroup (vertex groups) names and flag only */
ListBase modifiers; /* list of ModifierData structures */
ListBase fmaps; /* list of facemaps */
-
- int mode; /* Local object mode */
- int restore_mode; /* Keep track of what mode to return to after toggling a mode */
/* materials */
struct Material **mat; /* material slots */
@@ -711,25 +710,6 @@ enum {
OB_DUPLI_FLAG_RENDER = 1 << 1,
};
-/* ob->mode */
-typedef enum eObjectMode {
- OB_MODE_OBJECT = 0,
- OB_MODE_EDIT = 1 << 0,
- OB_MODE_SCULPT = 1 << 1,
- OB_MODE_VERTEX_PAINT = 1 << 2,
- OB_MODE_WEIGHT_PAINT = 1 << 3,
- OB_MODE_TEXTURE_PAINT = 1 << 4,
- OB_MODE_PARTICLE_EDIT = 1 << 5,
- OB_MODE_POSE = 1 << 6,
- OB_MODE_GPENCIL = 1 << 7, /* NOTE: Just a dummy to make the UI nicer */
-} eObjectMode;
-
-/* any mode where the brush system is used */
-#define OB_MODE_ALL_PAINT (OB_MODE_SCULPT | OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)
-
-/* any mode that uses ob->sculpt */
-#define OB_MODE_ALL_SCULPT (OB_MODE_SCULPT | OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT)
-
#define MAX_DUPLI_RECUR 8
#ifdef __cplusplus
diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h
index ea7905eb2ad..a7be2e37c4b 100644
--- a/source/blender/makesdna/DNA_particle_types.h
+++ b/source/blender/makesdna/DNA_particle_types.h
@@ -263,6 +263,11 @@ typedef struct ParticleSettings {
short pad5;
int recalc;
+
+ float twist;
+ float pad6;
+ struct CurveMapping *twistcurve;
+ void *pad7;
} ParticleSettings;
typedef struct ParticleSystem {
@@ -305,7 +310,8 @@ typedef struct ParticleSystem {
char bb_uvname[3][64]; /* billboard uv name, MAX_CUSTOMDATA_LAYER_NAME */
/* if you change these remember to update array lengths to PSYS_TOT_VG! */
- short vgroup[12], vg_neg, rt3; /* vertex groups, 0==disable, 1==starting index */
+ short vgroup[13], vg_neg, rt3; /* vertex groups, 0==disable, 1==starting index */
+ char pad[6];
/* temporary storage during render */
struct ParticleRenderData *renderdata;
@@ -439,6 +445,7 @@ typedef enum eParticleChildFlag {
PART_CHILD_USE_CLUMP_NOISE = (1<<0),
PART_CHILD_USE_CLUMP_CURVE = (1<<1),
PART_CHILD_USE_ROUGH_CURVE = (1<<2),
+ PART_CHILD_USE_TWIST_CURVE = (1<<3),
} eParticleChildFlag;
/* part->draw_col */
@@ -566,7 +573,7 @@ typedef enum eParticleChildFlag {
#define PART_DUPLIW_CURRENT 1
/* psys->vg */
-#define PSYS_TOT_VG 12
+#define PSYS_TOT_VG 13
#define PSYS_VG_DENSITY 0
#define PSYS_VG_VEL 1
@@ -580,6 +587,7 @@ typedef enum eParticleChildFlag {
#define PSYS_VG_TAN 9
#define PSYS_VG_ROT 10
#define PSYS_VG_EFFECTOR 11
+#define PSYS_VG_TWIST 12
/* ParticleTarget->flag */
#define PTARGET_CURRENT 1
@@ -611,7 +619,8 @@ typedef enum eParticleTextureInfluence {
PAMAP_KINK_AMP = (1<<12),
PAMAP_ROUGH = (1<<9),
PAMAP_LENGTH = (1<<4),
- PAMAP_CHILD = (PAMAP_CLUMP | PAMAP_KINK_FREQ | PAMAP_KINK_AMP | PAMAP_ROUGH | PAMAP_LENGTH),
+ PAMAP_TWIST = (1<<13),
+ PAMAP_CHILD = (PAMAP_CLUMP | PAMAP_KINK_FREQ | PAMAP_KINK_AMP | PAMAP_ROUGH | PAMAP_LENGTH | PAMAP_TWIST),
} eParticleTextureInfluence;
#endif
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 671ad1bc954..1642da25481 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -1623,7 +1623,7 @@ typedef struct Scene {
ListBase base DNA_DEPRECATED;
struct Base *basact DNA_DEPRECATED; /* active base */
- struct Object *obedit; /* name replaces old G.obedit */
+ void *_pad1;
float cursor[3]; /* 3d cursor location */
char _pad[4];
@@ -1944,6 +1944,14 @@ extern const char *RE_engine_id_CYCLES;
#define BASACT(_view_layer) ((_view_layer)->basact)
#define OBACT(_view_layer) (BASACT(_view_layer) ? BASACT(_view_layer)->object: NULL)
+#define OBEDIT_FROM_WORKSPACE(workspace, _view_layer) \
+ (((workspace)->object_mode & OD_MODE_EDIT) ? OBACT(_view_layer) : NULL)
+#define OBEDIT_FROM_EVAL_CTX(eval_ctx) \
+ (((eval_ctx)->object_mode & OB_MODE_EDIT) ? OBACT((eval_ctx)->view_layer) : NULL)
+
+#define OBEDIT_FROM_WINDOW(window) \
+ BKE_workspace_edit_object(WM_window_get_active_workspace(window), WM_window_get_active_scene(window))
+
#define V3D_CAMERA_LOCAL(v3d) ((!(v3d)->scenelock && (v3d)->camera) ? (v3d)->camera : NULL)
#define V3D_CAMERA_SCENE(scene, v3d) ((!(v3d)->scenelock && (v3d)->camera) ? (v3d)->camera : (scene)->camera)
diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h
index fff3ec10292..939ff9eb075 100644
--- a/source/blender/makesdna/DNA_screen_types.h
+++ b/source/blender/makesdna/DNA_screen_types.h
@@ -71,11 +71,9 @@ typedef struct bScreen {
char swap; /* indicator to survive swap-exchange systems */
char skip_handling; /* set to delay screen handling after switching back from maximized area */
char scrubbing; /* set when scrubbing to avoid some costly updates */
- char pad[6];
-
- /* XXX mainwin is actually entire window content now, including global bars. Should be moved out of bScreen. */
- short mainwin; /* screensize subwindow, for screenedges and global menus */
- short subwinactive; /* active subwindow */
+ char pad[2];
+
+ struct ARegion *active_region; /* active region that has mouse focus */
struct wmTimer *animtimer; /* if set, screen has timer handler added in window */
void *context; /* context callback */
@@ -258,7 +256,7 @@ typedef struct ARegion {
rcti drawrct; /* runtime for partial redraw, same or smaller than winrct */
short winx, winy; /* size */
- short swinid;
+ short visible; /* region is currently visible on screen */
short regiontype; /* window, header, etc. identifier for drawing */
short alignment; /* how it should split */
short flag; /* hide, ... */
diff --git a/source/blender/makesdna/DNA_smoke_types.h b/source/blender/makesdna/DNA_smoke_types.h
index c95e0a1f54a..9932e16e988 100644
--- a/source/blender/makesdna/DNA_smoke_types.h
+++ b/source/blender/makesdna/DNA_smoke_types.h
@@ -189,7 +189,7 @@ typedef struct SmokeDomainSettings {
char pad[2];
/* Smoke uses only one cache from now on (index [0]), but keeping the array for now for reading old files. */
- struct PointCache *point_cache[2]; /* definition is in DNA_object_force.h */
+ struct PointCache *point_cache[2]; /* definition is in DNA_object_force_types.h */
struct ListBase ptcaches[2];
struct EffectorWeights *effector_weights;
int border_collisions; /* How domain border collisions are handled */
diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h
index 995d7645dc0..0eb54a9b5b3 100644
--- a/source/blender/makesdna/DNA_texture_types.h
+++ b/source/blender/makesdna/DNA_texture_types.h
@@ -86,7 +86,7 @@ typedef struct MTex {
float timefac, lengthfac, clumpfac, dampfac;
float kinkfac, kinkampfac, roughfac, padensfac, gravityfac;
float lifefac, sizefac, ivelfac, fieldfac;
- int pad2;
+ float twistfac;
/* lamp */
float shadowfac;
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index 38a1c3ae01c..bc7a484cef6 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -413,7 +413,6 @@ typedef struct bTheme {
#define UI_THEMESPACE_START(btheme) (CHECK_TYPE_INLINE(btheme, bTheme *), &((btheme)->tbuts))
#define UI_THEMESPACE_END(btheme) (CHECK_TYPE_INLINE(btheme, bTheme *), (&((btheme)->tclip) + 1))
-/* for the moment only the name. may want to store options with this later */
typedef struct bAddon {
struct bAddon *next, *prev;
char module[64];
diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h
index 4332959bd9a..003e7eb6e46 100644
--- a/source/blender/makesdna/DNA_windowmanager_types.h
+++ b/source/blender/makesdna/DNA_windowmanager_types.h
@@ -197,8 +197,7 @@ typedef struct wmWindow {
short modalcursor; /* the current modal cursor */
short grabcursor; /* cursor grab mode */
short addmousemove; /* internal: tag this for extra mousemove event, makes cursors/buttons active on UI switching */
- short multisamples; /* amount of samples for OpenGL FSA the ghost window was created with, if zero no FSA */
- short pad[3];
+ short pad[4];
int winid; /* winid also in screens, is for retrieving this window after read */
@@ -208,8 +207,6 @@ typedef struct wmWindow {
struct wmEvent *eventstate; /* storage for event system */
- struct wmSubWindow *curswin; /* internal for wm_subwindow.c only */
-
struct wmGesture *tweak; /* internal for wm_operators.c */
/* Input Method Editor data - complex character input (esp. for asian character input)
@@ -223,7 +220,6 @@ typedef struct wmWindow {
ListBase handlers; /* window+screen handlers, handled last */
ListBase modalhandlers; /* priority handlers, handled first */
- ListBase subwindows; /* opengl stuff for sub windows, see notes in wm_subwindow.c */
ListBase gesture; /* gesture stuff */
/** Global areas aren't part of the screen, but part of the window directly.
diff --git a/source/blender/makesdna/DNA_workspace_types.h b/source/blender/makesdna/DNA_workspace_types.h
index adc3c1fef2b..dbcc278ea15 100644
--- a/source/blender/makesdna/DNA_workspace_types.h
+++ b/source/blender/makesdna/DNA_workspace_types.h
@@ -92,6 +92,9 @@ typedef struct WorkSpace {
int pad;
int flags DNA_PRIVATE_WORKSPACE; /* enum eWorkSpaceFlags */
+ short object_mode, object_mode_restore;
+ char _pad[4];
+
/* should be: '#ifdef USE_WORKSPACE_TOOL'. */
bToolDef tool;
diff --git a/source/blender/makesdna/DNA_world_types.h b/source/blender/makesdna/DNA_world_types.h
index 2ab99617ee8..3361e50e257 100644
--- a/source/blender/makesdna/DNA_world_types.h
+++ b/source/blender/makesdna/DNA_world_types.h
@@ -163,6 +163,12 @@ enum {
WO_AOMUL = 3,
};
+enum {
+ WO_MIST_QUADRATIC = 0,
+ WO_MIST_LINEAR = 1,
+ WO_MIST_INVERSE_QUADRATIC = 2,
+};
+
/* ao_samp_method - methods for sampling the AO hemi */
#define WO_AOSAMP_CONSTANT 0
#define WO_AOSAMP_HALTON 1
diff --git a/source/blender/makesdna/intern/CMakeLists.txt b/source/blender/makesdna/intern/CMakeLists.txt
index 8c758c33dc5..5b8dcd97108 100644
--- a/source/blender/makesdna/intern/CMakeLists.txt
+++ b/source/blender/makesdna/intern/CMakeLists.txt
@@ -107,6 +107,7 @@ set(INC_SYS
set(SRC
../../blenlib/intern/BLI_ghash.c
+ ../../blenlib/intern/BLI_ghash_utils.c
../../blenlib/intern/BLI_mempool.c
../../blenlib/intern/endian_switch.c
../../blenlib/intern/hash_mm2a.c
diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c
index 593d93b5615..f0f1c2210f0 100644
--- a/source/blender/makesdna/intern/makesdna.c
+++ b/source/blender/makesdna/intern/makesdna.c
@@ -86,8 +86,8 @@ static const char *includefiles[] = {
"DNA_modifier_types.h",
"DNA_lattice_types.h",
"DNA_object_types.h",
- "DNA_object_force.h",
- "DNA_object_fluidsim.h",
+ "DNA_object_force_types.h",
+ "DNA_object_fluidsim_types.h",
"DNA_world_types.h",
"DNA_scene_types.h",
"DNA_view3d_types.h",
@@ -1313,8 +1313,8 @@ int main(int argc, char **argv)
#include "DNA_modifier_types.h"
#include "DNA_lattice_types.h"
#include "DNA_object_types.h"
-#include "DNA_object_force.h"
-#include "DNA_object_fluidsim.h"
+#include "DNA_object_force_types.h"
+#include "DNA_object_fluidsim_types.h"
#include "DNA_world_types.h"
#include "DNA_scene_types.h"
#include "DNA_view3d_types.h"
diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h
index e0824281656..2a9b9ebe376 100644
--- a/source/blender/makesrna/RNA_types.h
+++ b/source/blender/makesrna/RNA_types.h
@@ -411,22 +411,46 @@ typedef struct ParameterDynAlloc {
/* Function */
typedef enum FunctionFlag {
- FUNC_NO_SELF = (1 << 0), /* for static functions */
- FUNC_USE_SELF_TYPE = (1 << 1), /* for class methods, only used when FUNC_NO_SELF is set */
+ /***** Options affecting callback signature. *****/
+ /* Those add additionnal parameters at the beginning of the C callback, like that:
+ * rna_my_func([ID *_selfid],
+ * [<DNA_STRUCT> *self|StructRNA *type],
+ * [Main *bmain],
+ * [bContext *C],
+ * [ReportList *reports],
+ * <other RNA-defined parameters>);
+ */
+ /* Pass ID owning 'self' data (i.e. ptr->id.data, might be same as self in case data is an ID...). */
+ FUNC_USE_SELF_ID = (1 << 11),
+
+ /* Do not pass the object (DNA struct pointer) from which it is called, used to define static or class functions. */
+ FUNC_NO_SELF = (1 << 0),
+ /* Pass RNA type, used to define class functions, only valid when FUNC_NO_SELF is set. */
+ FUNC_USE_SELF_TYPE = (1 << 1),
+
+ /* Pass Main, bContext and/or ReportList. */
FUNC_USE_MAIN = (1 << 2),
FUNC_USE_CONTEXT = (1 << 3),
FUNC_USE_REPORTS = (1 << 4),
- FUNC_USE_SELF_ID = (1 << 11),
- FUNC_ALLOW_WRITE = (1 << 12),
- /* registering */
+
+ /***** Registering of python subclasses. *****/
+ /* This function is part of the registerable class' interface, and can be implemented/redefined in python. */
FUNC_REGISTER = (1 << 5),
+ /* Subclasses can choose not to implement this function. */
FUNC_REGISTER_OPTIONAL = FUNC_REGISTER | (1 << 6),
+ /* If not set, the python function implementing this call is not allowed to write into data-blocks.
+ * Except for WindowManager and Screen currently, see rna_id_write_error() in bpy_rna.c */
+ FUNC_ALLOW_WRITE = (1 << 12),
- /* internal flags */
+ /***** Internal flags. *****/
+ /* UNUSED CURRENTLY? ??? */
FUNC_BUILTIN = (1 << 7),
+ /* UNUSED CURRENTLY. ??? */
FUNC_EXPORT = (1 << 8),
+ /* Function has been defined at runtime, not statically in RNA source code. */
FUNC_RUNTIME = (1 << 9),
+ /* UNUSED CURRENTLY? Function owns its identifier and description strings, and has to free them when deleted. */
FUNC_FREE_POINTERS = (1 << 10),
} FunctionFlag;
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index b8dbc69f352..1750c50b9da 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -7053,8 +7053,21 @@ bool RNA_property_copy(PointerRNA *ptr, PointerRNA *fromptr, PropertyRNA *prop,
prop_dst = rna_ensure_property_realdata(&prop_dst, ptr);
prop_src = rna_ensure_property_realdata(&prop_src, fromptr);
+ /* IDprops: destination may not exist, if source does and is set, try to create it. */
+ /* Note: this is sort of quick hack/bandage to fix the issue, we need to rethink how IDProps are handled
+ * in 'diff' RNA code completely, imho... */
+ if (prop_src != NULL && prop_dst == NULL && RNA_property_is_set(fromptr, prop)) {
+ BLI_assert(prop_src->magic != RNA_MAGIC);
+ IDProperty *idp_dst = RNA_struct_idprops(ptr, true);
+ IDProperty *prop_idp_dst = IDP_CopyProperty((IDProperty *)prop_src);
+ IDP_AddToGroup(idp_dst, prop_idp_dst);
+ rna_idproperty_touch(prop_idp_dst);
+ /* Nothing else to do here... */
+ return true;
+ }
+
if (ELEM(NULL, prop_dst, prop_src)) {
- false;
+ return false;
}
IDOverrideStaticPropertyOperation opop = {
diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c
index 5336a63fb76..aa37c9ffa88 100644
--- a/source/blender/makesrna/intern/rna_brush.c
+++ b/source/blender/makesrna/intern/rna_brush.c
@@ -31,6 +31,7 @@
#include "DNA_texture_types.h"
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
+#include "DNA_workspace_types.h"
#include "BLI_math.h"
@@ -43,6 +44,8 @@
#include "WM_types.h"
+#include "DEG_depsgraph.h"
+
static const EnumPropertyItem prop_direction_items[] = {
{0, "ADD", 0, "Add", "Add effect of brush"},
{BRUSH_DIR_IN, "SUBTRACT", 0, "Subtract", "Subtract effect of brush"},
@@ -373,21 +376,23 @@ static void rna_Brush_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerR
static void rna_Brush_main_tex_update(bContext *C, PointerRNA *ptr)
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Brush *br = (Brush *)ptr->data;
- BKE_paint_invalidate_overlay_tex(scene, view_layer, br->mtex.tex);
+ BKE_paint_invalidate_overlay_tex(scene, view_layer, br->mtex.tex, workspace->object_mode);
rna_Brush_update(bmain, scene, ptr);
}
static void rna_Brush_secondary_tex_update(bContext *C, PointerRNA *ptr)
{
Main *bmain = CTX_data_main(C);
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Brush *br = (Brush *)ptr->data;
- BKE_paint_invalidate_overlay_tex(scene, view_layer, br->mask_mtex.tex);
+ BKE_paint_invalidate_overlay_tex(scene, view_layer, br->mask_mtex.tex, workspace->object_mode);
rna_Brush_update(bmain, scene, ptr);
}
@@ -449,8 +454,9 @@ static void rna_TextureSlot_brush_angle_update(bContext *C, PointerRNA *ptr)
MTex *mtex = ptr->data;
/* skip invalidation of overlay for stencil mode */
if (mtex->mapping != MTEX_MAP_MODE_STENCIL) {
+ const WorkSpace *workspace = CTX_wm_workspace(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
- BKE_paint_invalidate_overlay_tex(scene, view_layer, mtex->tex);
+ BKE_paint_invalidate_overlay_tex(scene, view_layer, mtex->tex, workspace->object_mode);
}
rna_TextureSlot_update(C, ptr);
diff --git a/source/blender/makesrna/intern/rna_dynamicpaint.c b/source/blender/makesrna/intern/rna_dynamicpaint.c
index 596aff6de8f..b973e0f27ee 100644
--- a/source/blender/makesrna/intern/rna_dynamicpaint.c
+++ b/source/blender/makesrna/intern/rna_dynamicpaint.c
@@ -34,7 +34,7 @@
#include "DNA_dynamicpaint_types.h"
#include "DNA_modifier_types.h"
-#include "DNA_object_force.h"
+#include "DNA_object_force_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
diff --git a/source/blender/makesrna/intern/rna_fluidsim.c b/source/blender/makesrna/intern/rna_fluidsim.c
index 271ead13197..a75aceb6f7e 100644
--- a/source/blender/makesrna/intern/rna_fluidsim.c
+++ b/source/blender/makesrna/intern/rna_fluidsim.c
@@ -26,7 +26,7 @@
#include <stdlib.h>
-#include "DNA_object_fluidsim.h"
+#include "DNA_object_fluidsim_types.h"
#include "BLI_threads.h"
#include "BLI_utildefines.h"
diff --git a/source/blender/makesrna/intern/rna_layer.c b/source/blender/makesrna/intern/rna_layer.c
index 131378b5c49..7a1c1710a87 100644
--- a/source/blender/makesrna/intern/rna_layer.c
+++ b/source/blender/makesrna/intern/rna_layer.c
@@ -64,6 +64,7 @@ const EnumPropertyItem rna_enum_collection_type_items[] = {
#include "DNA_group_types.h"
#include "DNA_object_types.h"
+#include "DNA_workspace_types.h"
#include "RNA_access.h"
@@ -72,6 +73,8 @@ const EnumPropertyItem rna_enum_collection_type_items[] = {
#include "BKE_node.h"
#include "BKE_scene.h"
#include "BKE_mesh.h"
+#include "BKE_object.h"
+#include "BKE_workspace.h"
#include "DEG_depsgraph_build.h"
#include "DEG_depsgraph_query.h"
@@ -94,7 +97,7 @@ static void rna_SceneCollection_name_set(PointerRNA *ptr, const char *value)
{
Scene *scene = (Scene *)ptr->id.data;
SceneCollection *sc = (SceneCollection *)ptr->data;
- BKE_collection_rename(scene, sc, value);
+ BKE_collection_rename(&scene->id, sc, value);
}
static PointerRNA rna_SceneCollection_objects_get(CollectionPropertyIterator *iter)
@@ -141,6 +144,23 @@ static int rna_SceneCollection_move_into(ID *id, SceneCollection *sc_src, Main *
return 1;
}
+static SceneCollection *rna_SceneCollection_duplicate(
+ ID *id, SceneCollection *scene_collection, Main *bmain, bContext *C, ReportList *reports)
+{
+ if (scene_collection == BKE_collection_master(id)) {
+ BKE_report(reports, RPT_ERROR, "The master collection can't be duplicated");
+ return NULL;
+ }
+
+ SceneCollection *scene_collection_new = BKE_collection_duplicate(id, scene_collection);
+
+ DEG_relations_tag_update(bmain);
+ /* Don't use id here, since the layer collection may come from a group. */
+ WM_event_add_notifier(C, NC_SCENE | ND_LAYER, CTX_data_scene(C));
+
+ return scene_collection_new;
+}
+
static SceneCollection *rna_SceneCollection_new(
ID *id, SceneCollection *sc_parent, Main *bmain, const char *name)
{
@@ -635,9 +655,9 @@ static int rna_LayerCollection_name_length(PointerRNA *ptr)
static void rna_LayerCollection_name_set(PointerRNA *ptr, const char *value)
{
- Scene *scene = (Scene *)ptr->id.data;
+ ID *owner_id = (ID *)ptr->id.data;
SceneCollection *sc = ((LayerCollection *)ptr->data)->scene_collection;
- BKE_collection_rename(scene, sc, value);
+ BKE_collection_rename(owner_id, sc, value);
}
static PointerRNA rna_LayerCollection_objects_get(CollectionPropertyIterator *iter)
@@ -717,6 +737,23 @@ static Group *rna_LayerCollection_create_group(
return group;
}
+static LayerCollection *rna_LayerCollection_duplicate(
+ ID *id, LayerCollection *layer_collection, Main *bmain, bContext *C, ReportList *reports)
+{
+ if (layer_collection->scene_collection == BKE_collection_master(id)) {
+ BKE_report(reports, RPT_ERROR, "The master collection can't be duplicated");
+ return NULL;
+ }
+
+ LayerCollection *layer_collection_new = BKE_layer_collection_duplicate(id, layer_collection);
+
+ DEG_relations_tag_update(bmain);
+ /* Don't use id here, since the layer collection may come from a group. */
+ WM_event_add_notifier(C, NC_SCENE | ND_LAYER, CTX_data_scene(C));
+
+ return layer_collection_new;
+}
+
static int rna_LayerCollections_active_collection_index_get(PointerRNA *ptr)
{
ViewLayer *view_layer = (ViewLayer *)ptr->data;
@@ -801,6 +838,18 @@ static void rna_LayerObjects_active_object_set(PointerRNA *ptr, PointerRNA value
view_layer->basact = NULL;
}
+static void rna_LayerObjects_active_object_update(struct bContext *C, PointerRNA *ptr)
+{
+ wmWindow *win = CTX_wm_window(C);
+ Scene *scene = WM_window_get_active_scene(win);
+
+ if (scene != ptr->id.data) {
+ return;
+ }
+ ViewLayer *view_layer = (ViewLayer *)ptr->data;
+ ED_object_base_activate(C, view_layer->basact);
+}
+
static IDProperty *rna_ViewLayer_idprops(PointerRNA *ptr, bool create)
{
ViewLayer *view_layer = (ViewLayer *)ptr->data;
@@ -843,10 +892,14 @@ static int rna_ViewLayer_objects_selected_skip(CollectionPropertyIterator *iter,
static PointerRNA rna_ViewLayer_depsgraph_get(PointerRNA *ptr)
{
- Scene *scene = (Scene *)ptr->id.data;
- ViewLayer *view_layer = (ViewLayer *)ptr->data;
- Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene, view_layer, false);
- return rna_pointer_inherit_refine(ptr, &RNA_Depsgraph, depsgraph);
+ ID *id = ptr->id.data;
+ if (GS(id->name) == ID_SCE) {
+ Scene *scene = (Scene *)id;
+ ViewLayer *view_layer = (ViewLayer *)ptr->data;
+ Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene, view_layer, false);
+ return rna_pointer_inherit_refine(ptr, &RNA_Depsgraph, depsgraph);
+ }
+ return PointerRNA_NULL;
}
static void rna_LayerObjects_selected_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
@@ -881,7 +934,7 @@ static void rna_ObjectBase_select_update(Main *UNUSED(bmain), Scene *UNUSED(scen
static char *rna_ViewRenderSettings_path(PointerRNA *UNUSED(ptr))
{
- return BLI_sprintfN("viewport_render");
+ return BLI_sprintfN("view_render");
}
static void rna_ViewRenderSettings_engine_set(PointerRNA *ptr, int value)
@@ -1080,6 +1133,12 @@ static void rna_def_scene_collection(BlenderRNA *brna)
parm = RNA_def_pointer(func, "sc_dst", "SceneCollection", "Collection", "Collection to insert into");
parm = RNA_def_boolean(func, "result", false, "Result", "Whether the operation succeded");
RNA_def_function_return(func, parm);
+
+ func = RNA_def_function(srna, "duplicate", "rna_SceneCollection_duplicate");
+ RNA_def_function_ui_description(func, "Create a copy of the collection");
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN | FUNC_USE_CONTEXT | FUNC_USE_REPORTS);
+ parm = RNA_def_pointer(func, "result", "SceneCollection", "", "Newly created collection");
+ RNA_def_function_return(func, parm);
}
static void rna_def_layer_collection_override(BlenderRNA *brna)
@@ -1994,6 +2053,12 @@ static void rna_def_layer_collection(BlenderRNA *brna)
parm = RNA_def_pointer(func, "result", "Group", "", "Newly created Group");
RNA_def_function_return(func, parm);
+ func = RNA_def_function(srna, "duplicate", "rna_LayerCollection_duplicate");
+ RNA_def_function_ui_description(func, "Create a copy of the collection");
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN | FUNC_USE_CONTEXT | FUNC_USE_REPORTS);
+ parm = RNA_def_pointer(func, "result", "LayerCollection", "", "Newly created collection");
+ RNA_def_function_return(func, parm);
+
/* Flags */
prop = RNA_def_property(srna, "selectable", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", COLLECTION_SELECTABLE);
@@ -2079,11 +2144,11 @@ static void rna_def_layer_objects(BlenderRNA *brna, PropertyRNA *cprop)
prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "Object");
RNA_def_property_pointer_funcs(prop, "rna_LayerObjects_active_object_get", "rna_LayerObjects_active_object_set", NULL, NULL);
- RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_UNLINK);
+ RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_UNLINK | PROP_CONTEXT_UPDATE);
RNA_def_property_ui_text(prop, "Active Object", "Active object for this layer");
/* Could call: ED_object_base_activate(C, rl->basact);
* but would be a bad level call and it seems the notifier is enough */
- RNA_def_property_update(prop, NC_SCENE | ND_OB_ACTIVE, NULL);
+ RNA_def_property_update(prop, NC_SCENE | ND_OB_ACTIVE, "rna_LayerObjects_active_object_update");
prop = RNA_def_property(srna, "selected", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "object_bases", NULL);
diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c
index 440af0d0e8e..6f23b0fd281 100644
--- a/source/blender/makesrna/intern/rna_material.c
+++ b/source/blender/makesrna/intern/rna_material.c
@@ -92,13 +92,15 @@ const EnumPropertyItem rna_enum_ramp_blend_items[] = {
#include "BKE_texture.h"
#include "BKE_node.h"
#include "BKE_paint.h"
+#include "BKE_scene.h"
+#include "BKE_workspace.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
#include "ED_node.h"
#include "ED_image.h"
-#include "BKE_scene.h"
+#include "ED_screen.h"
static void rna_Material_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
@@ -201,6 +203,11 @@ static void rna_Material_active_paint_texture_index_update(Main *bmain, Scene *s
if (ma->texpaintslot) {
Image *image = ma->texpaintslot[ma->paint_active_slot].ima;
for (sc = bmain->screen.first; sc; sc = sc->id.next) {
+ wmWindow *win = ED_screen_window_find(sc, bmain->wm.first);
+ if (win == NULL) {
+ continue;
+ }
+ Object *obedit = OBEDIT_FROM_WINDOW(win);
ScrArea *sa;
for (sa = sc->areabase.first; sa; sa = sa->next) {
SpaceLink *sl;
@@ -209,7 +216,7 @@ static void rna_Material_active_paint_texture_index_update(Main *bmain, Scene *s
SpaceImage *sima = (SpaceImage *)sl;
if (!sima->pin)
- ED_space_image_set(sima, scene, scene->obedit, image);
+ ED_space_image_set(sima, scene, obedit, image);
}
}
}
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index e721a04bd2a..99417ee7b1b 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -34,7 +34,7 @@
#include "DNA_mesh_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
-#include "DNA_object_force.h"
+#include "DNA_object_force_types.h"
#include "DNA_scene_types.h"
#include "MEM_guardedalloc.h"
@@ -1960,12 +1960,6 @@ static void rna_def_modifier_boolean(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL}
};
- static const EnumPropertyItem prop_solver_items[] = {
- {eBooleanModifierSolver_BMesh, "BMESH", 0, "BMesh", "Use the BMesh boolean solver"},
- {eBooleanModifierSolver_Carve, "CARVE", 0, "Carve", "Use the Carve boolean solver"},
- {0, NULL, 0, NULL, NULL}
- };
-
srna = RNA_def_struct(brna, "BooleanModifier", "Modifier");
RNA_def_struct_ui_text(srna, "Boolean Modifier", "Boolean operations modifier");
RNA_def_struct_sdna(srna, "BooleanModifierData");
@@ -1982,11 +1976,6 @@ static void rna_def_modifier_boolean(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Operation", "");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
- prop = RNA_def_property(srna, "solver", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, prop_solver_items);
- RNA_def_property_ui_text(prop, "Solver", "");
- RNA_def_property_update(prop, 0, "rna_Modifier_update");
-
prop = RNA_def_property(srna, "double_threshold", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "double_threshold");
RNA_def_property_range(prop, 0, 1.0f);
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 2b2c6998eb4..a148efb859d 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -3312,11 +3312,18 @@ static const EnumPropertyItem node_script_mode_items[] = {
};
static const EnumPropertyItem node_principled_distribution_items[] = {
- { SHD_GLOSSY_GGX, "GGX", 0, "GGX", "" },
- { SHD_GLOSSY_MULTI_GGX, "MULTI_GGX", 0, "Multiscatter GGX", "" },
+ {SHD_GLOSSY_GGX, "GGX", 0, "GGX", ""},
+ {SHD_GLOSSY_MULTI_GGX, "MULTI_GGX", 0, "Multiscatter GGX", ""},
+ {0, NULL, 0, NULL, NULL}
+};
+
+static const EnumPropertyItem node_subsurface_method_items[] = {
+ {SHD_SUBSURFACE_BURLEY, "BURLEY", 0, "Christensen-Burley", "Approximation to physically based volume scattering"},
+ {SHD_SUBSURFACE_RANDOM_WALK, "RANDOM_WALK", 0, "Random Walk", "Volumetric approximation to physically based volume scattering"},
{ 0, NULL, 0, NULL, NULL }
};
+
/* -- Common nodes ---------------------------------------------------------- */
static void def_group_input(StructRNA *srna)
@@ -4263,6 +4270,12 @@ static void def_principled(StructRNA *srna)
RNA_def_property_enum_items(prop, node_principled_distribution_items);
RNA_def_property_ui_text(prop, "Distribution", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_ShaderNodePrincipled_update");
+
+ prop = RNA_def_property(srna, "subsurface_method", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "custom2");
+ RNA_def_property_enum_items(prop, node_subsurface_method_items);
+ RNA_def_property_ui_text(prop, "Subsurface Method", "Method for rendering subsurface scattering");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_ShaderNodePrincipled_update");
}
static void def_refraction(StructRNA *srna)
@@ -4350,11 +4363,11 @@ static void def_sh_uvalongstroke(StructRNA *srna)
static void def_sh_normal_map(StructRNA *srna)
{
static const EnumPropertyItem prop_space_items[] = {
- {SHD_NORMAL_MAP_TANGENT, "TANGENT", 0, "Tangent Space", "Tangent space normal mapping"},
- {SHD_NORMAL_MAP_OBJECT, "OBJECT", 0, "Object Space", "Object space normal mapping"},
- {SHD_NORMAL_MAP_WORLD, "WORLD", 0, "World Space", "World space normal mapping"},
- {SHD_NORMAL_MAP_BLENDER_OBJECT, "BLENDER_OBJECT", 0, "Blender Object Space", "Object space normal mapping, compatible with Blender render baking"},
- {SHD_NORMAL_MAP_BLENDER_WORLD, "BLENDER_WORLD", 0, "Blender World Space", "World space normal mapping, compatible with Blender render baking"},
+ {SHD_SPACE_TANGENT, "TANGENT", 0, "Tangent Space", "Tangent space normal mapping"},
+ {SHD_SPACE_OBJECT, "OBJECT", 0, "Object Space", "Object space normal mapping"},
+ {SHD_SPACE_WORLD, "WORLD", 0, "World Space", "World space normal mapping"},
+ {SHD_SPACE_BLENDER_OBJECT, "BLENDER_OBJECT", 0, "Blender Object Space", "Object space normal mapping, compatible with Blender render baking"},
+ {SHD_SPACE_BLENDER_WORLD, "BLENDER_WORLD", 0, "Blender World Space", "World space normal mapping, compatible with Blender render baking"},
{0, NULL, 0, NULL, NULL}
};
@@ -4374,6 +4387,45 @@ static void def_sh_normal_map(StructRNA *srna)
RNA_def_struct_sdna_from(srna, "bNode", NULL);
}
+static void def_sh_displacement(StructRNA *srna)
+{
+ static const EnumPropertyItem prop_space_items[] = {
+ {SHD_SPACE_OBJECT, "OBJECT", 0, "Object Space", "Displacement is in object space, affected by object scale"},
+ {SHD_SPACE_WORLD, "WORLD", 0, "World Space", "Displacement is in world space, not affected by object scale"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ PropertyRNA *prop;
+
+ prop = RNA_def_property(srna, "space", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "custom1");
+ RNA_def_property_enum_items(prop, prop_space_items);
+ RNA_def_property_ui_text(prop, "Space", "Space of the input height");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
+
+ RNA_def_struct_sdna_from(srna, "bNode", NULL);
+}
+
+static void def_sh_vector_displacement(StructRNA *srna)
+{
+ static const EnumPropertyItem prop_space_items[] = {
+ {SHD_SPACE_TANGENT, "TANGENT", 0, "Tangent Space", "Tagent space vector displacement mapping"},
+ {SHD_SPACE_OBJECT, "OBJECT", 0, "Object Space", "Object space vector displacement mapping"},
+ {SHD_SPACE_WORLD, "WORLD", 0, "World Space", "World space vector displacement mapping"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ PropertyRNA *prop;
+
+ prop = RNA_def_property(srna, "space", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "custom1");
+ RNA_def_property_enum_items(prop, prop_space_items);
+ RNA_def_property_ui_text(prop, "Space", "Space of the input height");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
+
+ RNA_def_struct_sdna_from(srna, "bNode", NULL);
+}
+
static void def_sh_tangent(StructRNA *srna)
{
static const EnumPropertyItem prop_direction_type_items[] = {
@@ -4427,6 +4479,7 @@ static void def_sh_subsurface(StructRNA *srna)
{SHD_SUBSURFACE_CUBIC, "CUBIC", 0, "Cubic", "Simple cubic falloff function"},
{SHD_SUBSURFACE_GAUSSIAN, "GAUSSIAN", 0, "Gaussian", "Normal distribution, multiple can be combined to fit more complex profiles"},
{SHD_SUBSURFACE_BURLEY, "BURLEY", 0, "Christensen-Burley", "Approximation to physically based volume scattering"},
+ {SHD_SUBSURFACE_RANDOM_WALK, "RANDOM_WALK", 0, "Random Walk", "Volumetric approximation to physically based volume scattering"},
{0, NULL, 0, NULL, NULL}
};
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index f2b2e95d21e..e37446028be 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -33,11 +33,12 @@
#include "DNA_group_types.h"
#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
-#include "DNA_object_force.h"
+#include "DNA_object_force_types.h"
#include "DNA_object_types.h"
#include "DNA_property_types.h"
#include "DNA_scene_types.h"
#include "DNA_meta_types.h"
+#include "DNA_workspace_types.h"
#include "BLI_utildefines.h"
#include "BLI_listbase.h"
@@ -217,6 +218,12 @@ static void rna_Object_internal_update(Main *UNUSED(bmain), Scene *UNUSED(scene)
DEG_id_tag_update(ptr->id.data, OB_RECALC_OB);
}
+static void rna_Object_internal_update_draw(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
+{
+ DEG_id_tag_update(ptr->id.data, OB_RECALC_OB);
+ WM_main_add_notifier(NC_OBJECT | ND_DRAW, ptr->id.data);
+}
+
static void rna_Object_matrix_world_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
/* don't use compat so we get predictable rotation */
@@ -294,11 +301,11 @@ void rna_Object_internal_update_data(Main *UNUSED(bmain), Scene *UNUSED(scene),
WM_main_add_notifier(NC_OBJECT | ND_DRAW, ptr->id.data);
}
-static void rna_Object_active_shape_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_Object_active_shape_update(bContext *C, Main *bmain, Scene *scene, PointerRNA *ptr)
{
Object *ob = ptr->id.data;
- if (scene->obedit == ob) {
+ if (CTX_data_edit_object(C) == ob) {
/* exit/enter editmode to get new shape */
switch (ob->type) {
case OB_MESH:
@@ -337,7 +344,7 @@ static void rna_Object_data_set(PointerRNA *ptr, PointerRNA value)
Object *ob = (Object *)ptr->data;
ID *id = value.data;
- if (ob->mode & OB_MODE_EDIT) {
+ if (BKE_object_is_in_editmode(ob)) {
return;
}
@@ -1394,7 +1401,9 @@ static void rna_Object_constraints_clear(Object *object)
static ModifierData *rna_Object_modifier_new(Object *object, bContext *C, ReportList *reports,
const char *name, int type)
{
- return ED_object_modifier_add(reports, CTX_data_main(C), CTX_data_scene(C), object, name, type);
+ Main *bmain = CTX_data_main(C);
+ const WorkSpace *workspace = CTX_wm_workspace(C);
+ return ED_object_modifier_add(reports, bmain, CTX_data_scene(C), object, workspace->object_mode, name, type);
}
static void rna_Object_modifier_remove(Object *object, bContext *C, ReportList *reports, PointerRNA *md_ptr)
@@ -2419,12 +2428,6 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Type", "Type of Object");
- prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_sdna(prop, NULL, "mode");
- RNA_def_property_enum_items(prop, rna_enum_object_mode_items);
- RNA_def_property_clear_flag(prop, PROP_EDITABLE);
- RNA_def_property_ui_text(prop, "Mode", "Object interaction mode");
-
prop = RNA_def_property(srna, "layers_local_view", PROP_BOOLEAN, PROP_LAYER_MEMBER);
RNA_def_property_boolean_sdna(prop, NULL, "lay", 0x01000000);
RNA_def_property_array(prop, 8);
@@ -2754,7 +2757,7 @@ static void rna_def_object(BlenderRNA *brna)
prop = RNA_def_property(srna, "pass_index", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "index");
RNA_def_property_ui_text(prop, "Pass Index", "Index number for the \"Object Index\" render pass");
- RNA_def_property_update(prop, NC_OBJECT, "rna_Object_internal_update");
+ RNA_def_property_update(prop, NC_OBJECT, "rna_Object_internal_update_draw");
prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR);
RNA_def_property_float_sdna(prop, NULL, "col");
@@ -3021,6 +3024,7 @@ static void rna_def_object(BlenderRNA *brna)
prop = RNA_def_property(srna, "active_shape_key_index", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "shapenr");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); /* XXX this is really unpredictable... */
RNA_def_property_int_funcs(prop, "rna_Object_active_shape_key_index_get", "rna_Object_active_shape_key_index_set",
"rna_Object_active_shape_key_index_range");
diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c
index 74528a2c0e8..17f19bfc38c 100644
--- a/source/blender/makesrna/intern/rna_object_api.c
+++ b/source/blender/makesrna/intern/rna_object_api.c
@@ -526,10 +526,8 @@ void rna_Object_dm_info(struct Object *ob, int type, char *result)
static int rna_Object_update_from_editmode(Object *ob)
{
- if (ob->mode & OB_MODE_EDIT) {
- return ED_object_editmode_load(ob);
- }
- return false;
+ /* fail gracefully if we aren't in edit-mode. */
+ return ED_object_editmode_load(ob);
}
#else /* RNA_RUNTIME */
diff --git a/source/blender/makesrna/intern/rna_object_force.c b/source/blender/makesrna/intern/rna_object_force.c
index 9265c7b62cf..8fc6b2b1a58 100644
--- a/source/blender/makesrna/intern/rna_object_force.c
+++ b/source/blender/makesrna/intern/rna_object_force.c
@@ -28,7 +28,7 @@
#include "DNA_cloth_types.h"
#include "DNA_object_types.h"
-#include "DNA_object_force.h"
+#include "DNA_object_force_types.h"
#include "DNA_particle_types.h"
#include "DNA_scene_types.h"
#include "DNA_smoke_types.h"
@@ -53,6 +53,7 @@ static const EnumPropertyItem effector_shape_items[] = {
#include "BLI_math_base.h"
+#include "BKE_main.h"
/* type specific return values only used from functions */
static const EnumPropertyItem curve_shape_items[] = {
@@ -523,7 +524,7 @@ static void rna_FieldSettings_shape_update(Main *bmain, Scene *scene, PointerRNA
{
if (!particle_id_check(ptr)) {
Object *ob = (Object *)ptr->id.data;
- ED_object_check_force_modifiers(bmain, scene, ob);
+ ED_object_check_force_modifiers(bmain, scene, ob, bmain->eval_ctx->object_mode);
WM_main_add_notifier(NC_OBJECT | ND_DRAW, ob);
WM_main_add_notifier(NC_OBJECT | ND_MODIFIER, ob);
}
@@ -710,7 +711,7 @@ static void rna_CollisionSettings_dependency_update(Main *bmain, Scene *scene, P
/* add/remove modifier as needed */
if (ob->pd->deflect && !md)
- ED_object_modifier_add(NULL, bmain, scene, ob, NULL, eModifierType_Collision);
+ ED_object_modifier_add(NULL, bmain, scene, ob, bmain->eval_ctx->object_mode, NULL, eModifierType_Collision);
else if (!ob->pd->deflect && md)
ED_object_modifier_remove(NULL, bmain, ob, md);
diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c
index 12e56b8e926..14bf612f467 100644
--- a/source/blender/makesrna/intern/rna_particle.c
+++ b/source/blender/makesrna/intern/rna_particle.c
@@ -36,7 +36,7 @@
#include "DNA_modifier_types.h"
#include "DNA_cloth_types.h"
#include "DNA_particle_types.h"
-#include "DNA_object_force.h"
+#include "DNA_object_force_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_boid_types.h"
@@ -953,6 +953,19 @@ static void rna_ParticleSettings_use_roughness_curve_update(Main *bmain, Scene *
rna_Particle_redo_child(bmain, scene, ptr);
}
+static void rna_ParticleSettings_use_twist_curve_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+ ParticleSettings *part = ptr->data;
+
+ if (part->child_flag & PART_CHILD_USE_TWIST_CURVE) {
+ if (!part->twistcurve) {
+ BKE_particlesettings_twist_curve_init(part);
+ }
+ }
+
+ rna_Particle_redo_child(bmain, scene, ptr);
+}
+
static void rna_ParticleSystem_name_set(PointerRNA *ptr, const char *value)
{
Object *ob = ptr->id.data;
@@ -1309,6 +1322,7 @@ static void rna_ParticleVGroup_name_get_8(PointerRNA *ptr, char *value) { psys_v
static void rna_ParticleVGroup_name_get_9(PointerRNA *ptr, char *value) { psys_vg_name_get__internal(ptr, value, 9); }
static void rna_ParticleVGroup_name_get_10(PointerRNA *ptr, char *value) { psys_vg_name_get__internal(ptr, value, 10); }
static void rna_ParticleVGroup_name_get_11(PointerRNA *ptr, char *value) { psys_vg_name_get__internal(ptr, value, 11); }
+static void rna_ParticleVGroup_name_get_12(PointerRNA *ptr, char *value) { psys_vg_name_get__internal(ptr, value, 12); }
static int rna_ParticleVGroup_name_len_0(PointerRNA *ptr) { return psys_vg_name_len__internal(ptr, 0); }
static int rna_ParticleVGroup_name_len_1(PointerRNA *ptr) { return psys_vg_name_len__internal(ptr, 1); }
@@ -1322,6 +1336,7 @@ static int rna_ParticleVGroup_name_len_8(PointerRNA *ptr) { return psys_vg_name_
static int rna_ParticleVGroup_name_len_9(PointerRNA *ptr) { return psys_vg_name_len__internal(ptr, 9); }
static int rna_ParticleVGroup_name_len_10(PointerRNA *ptr) { return psys_vg_name_len__internal(ptr, 10); }
static int rna_ParticleVGroup_name_len_11(PointerRNA *ptr) { return psys_vg_name_len__internal(ptr, 11); }
+static int rna_ParticleVGroup_name_len_12(PointerRNA *ptr) { return psys_vg_name_len__internal(ptr, 12); }
static void rna_ParticleVGroup_name_set_0(PointerRNA *ptr, const char *value) { psys_vg_name_set__internal(ptr, value, 0); }
static void rna_ParticleVGroup_name_set_1(PointerRNA *ptr, const char *value) { psys_vg_name_set__internal(ptr, value, 1); }
@@ -1335,6 +1350,7 @@ static void rna_ParticleVGroup_name_set_8(PointerRNA *ptr, const char *value) {
static void rna_ParticleVGroup_name_set_9(PointerRNA *ptr, const char *value) { psys_vg_name_set__internal(ptr, value, 9); }
static void rna_ParticleVGroup_name_set_10(PointerRNA *ptr, const char *value) { psys_vg_name_set__internal(ptr, value, 10); }
static void rna_ParticleVGroup_name_set_11(PointerRNA *ptr, const char *value) { psys_vg_name_set__internal(ptr, value, 11); }
+static void rna_ParticleVGroup_name_set_12(PointerRNA *ptr, const char *value) { psys_vg_name_set__internal(ptr, value, 12); }
#else
@@ -1887,6 +1903,10 @@ static void rna_def_particle_settings_mtex(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Length", "Affect the child hair length");
RNA_def_property_update(prop, 0, "rna_Particle_redo_child");
+ prop = RNA_def_property(srna, "use_map_twist", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "mapto", PAMAP_TWIST);
+ RNA_def_property_ui_text(prop, "Twist", "Affect the child twist");
+ RNA_def_property_update(prop, 0, "rna_Particle_redo_child");
/* influence factors */
prop = RNA_def_property(srna, "time_factor", PROP_FLOAT, PROP_NONE);
@@ -1968,6 +1988,12 @@ static void rna_def_particle_settings_mtex(BlenderRNA *brna)
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
RNA_def_property_ui_text(prop, "Rough Factor", "Amount texture affects child roughness");
RNA_def_property_update(prop, 0, "rna_Particle_redo_child");
+
+ prop = RNA_def_property(srna, "twist_factor", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "twistfac");
+ RNA_def_property_ui_range(prop, 0, 1, 10, 3);
+ RNA_def_property_ui_text(prop, "Twist Factor", "Amount texture affects child twist");
+ RNA_def_property_update(prop, 0, "rna_Particle_redo_child");
}
static void rna_def_particle_settings(BlenderRNA *brna)
@@ -2382,7 +2408,7 @@ static void rna_def_particle_settings(BlenderRNA *brna)
prop = RNA_def_property(srna, "draw_size", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 0, 1000);
RNA_def_property_ui_range(prop, 0, 100, 1, -1);
- RNA_def_property_ui_text(prop, "Draw Size", "Size of particles on viewport in BU (0.1 = default)");
+ RNA_def_property_ui_text(prop, "Draw Size", "Size of particles on viewport in BU");
RNA_def_property_update(prop, 0, "rna_Particle_redo");
prop = RNA_def_property(srna, "child_type", PROP_ENUM, PROP_NONE);
@@ -3174,6 +3200,25 @@ static void rna_def_particle_settings(BlenderRNA *brna)
RNA_def_property_struct_type(prop, "FieldSettings");
RNA_def_property_pointer_funcs(prop, "rna_Particle_field2_get", NULL, NULL, NULL);
RNA_def_property_ui_text(prop, "Force Field 2", "");
+
+ /* twist */
+ prop = RNA_def_property(srna, "twist", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_range(prop, -100000.0f, 100000.0f);
+ RNA_def_property_ui_range(prop, -10.0f, 10.0f, 0.1, 3);
+ RNA_def_property_ui_text(prop, "Twist", "Number of turns around parent allong the strand");
+ RNA_def_property_update(prop, 0, "rna_Particle_redo_child");
+
+ prop = RNA_def_property(srna, "use_twist_curve", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "child_flag", PART_CHILD_USE_TWIST_CURVE);
+ RNA_def_property_ui_text(prop, "Use Twist Curve", "Use a curve to define twist");
+ RNA_def_property_update(prop, 0, "rna_ParticleSettings_use_twist_curve_update");
+
+ prop = RNA_def_property(srna, "twist_curve", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "twistcurve");
+ RNA_def_property_struct_type(prop, "CurveMapping");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Twist Curve", "Curve defining twist");
+ RNA_def_property_update(prop, 0, "rna_Particle_redo_child");
}
static void rna_def_particle_target(BlenderRNA *brna)
@@ -3507,6 +3552,18 @@ static void rna_def_particle_system(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Vertex Group Field Negate", "Negate the effect of the field vertex group");
RNA_def_property_update(prop, 0, "rna_Particle_reset");
+ prop = RNA_def_property(srna, "vertex_group_twist", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_funcs(prop, "rna_ParticleVGroup_name_get_12", "rna_ParticleVGroup_name_len_12",
+ "rna_ParticleVGroup_name_set_12");
+ RNA_def_property_ui_text(prop, "Vertex Group Twist", "Vertex group to control twist");
+ RNA_def_property_update(prop, 0, "rna_Particle_redo_child");
+
+ prop = RNA_def_property(srna, "invert_vertex_group_twist", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "vg_neg", (1 << PSYS_VG_TWIST));
+ RNA_def_property_ui_text(prop, "Vertex Group Twist Negate",
+ "Negate the effect of the twist vertex group");
+ RNA_def_property_update(prop, 0, "rna_Particle_redo_child");
+
/* pointcache */
prop = RNA_def_property(srna, "point_cache", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c
index 38149734bc2..8cf9bc7d39c 100644
--- a/source/blender/makesrna/intern/rna_rna.c
+++ b/source/blender/makesrna/intern/rna_rna.c
@@ -1444,6 +1444,12 @@ int rna_property_override_diff_default(PointerRNA *ptr_a, PointerRNA *ptr_b,
equals = false;
continue;
}
+ else if (iter_a.ptr.type == NULL) {
+ /* NULL RNA pointer... */
+ BLI_assert(iter_a.ptr.data == NULL);
+ BLI_assert(iter_b.ptr.data == NULL);
+ continue;
+ }
PropertyRNA *propname = RNA_struct_name_property(iter_a.ptr.type);
char propname_buff_a[256], propname_buff_b[256];
@@ -1475,10 +1481,10 @@ int rna_property_override_diff_default(PointerRNA *ptr_a, PointerRNA *ptr_b,
}
if (propname_a != propname_buff_a) {
- MEM_freeN(propname_a);
+ MEM_SAFE_FREE(propname_a);
}
if (propname_b != propname_buff_b) {
- MEM_freeN(propname_b);
+ MEM_SAFE_FREE(propname_b);
}
MEM_SAFE_FREE(extended_rna_path);
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 5518b296e22..2c3f90d718b 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -1703,9 +1703,10 @@ static KeyingSet *rna_Scene_keying_set_new(Scene *sce, ReportList *reports, cons
static void rna_UnifiedPaintSettings_update(bContext *C, PointerRNA *UNUSED(ptr))
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
- Brush *br = BKE_paint_brush(BKE_paint_get_active(scene, view_layer));
+ Brush *br = BKE_paint_brush(BKE_paint_get_active(scene, view_layer, workspace->object_mode));
WM_main_add_notifier(NC_BRUSH | NA_EDITED, br);
}
@@ -5720,7 +5721,8 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
prop = RNA_def_property(srna, "filter_size", PROP_FLOAT, PROP_PIXEL);
RNA_def_property_float_sdna(prop, NULL, "gauss");
- RNA_def_property_range(prop, 0.5f, 1.5f);
+ RNA_def_property_range(prop, 0.0f, 500.0f);
+ RNA_def_property_ui_range(prop, 0.01f, 10.0f, 1, 2);
RNA_def_property_ui_text(prop, "Filter Size", "Width over which the reconstruction filter combines samples");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
@@ -6961,6 +6963,7 @@ void RNA_def_scene(BlenderRNA *brna)
/* Statistics */
func = RNA_def_function(srna, "statistics", "ED_info_stats_string");
+ parm = RNA_def_pointer(func, "workspace", "WorkSpace", "", "Active workspace");
parm = RNA_def_pointer(func, "view_layer", "ViewLayer", "", "Active layer");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
parm = RNA_def_string(func, "statistics", NULL, 0, "Statistics", "");
diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c
index 7d8bf4949d5..f99803a1d99 100644
--- a/source/blender/makesrna/intern/rna_scene_api.c
+++ b/source/blender/makesrna/intern/rna_scene_api.c
@@ -117,9 +117,9 @@ static void rna_Scene_frame_set(Scene *scene, Main *bmain, int frame, float subf
static void rna_Scene_uvedit_aspect(Scene *scene, Object *ob, float *aspect)
{
- if ((ob->type == OB_MESH) && (ob->mode == OB_MODE_EDIT)) {
- BMEditMesh *em;
- em = BKE_editmesh_from_object(ob);
+ if (ob->type == OB_MESH) {
+ /* Will be NULL when not in editmode */
+ BMEditMesh *em = BKE_editmesh_from_object(ob);
if (EDBM_uv_check(em)) {
ED_uvedit_get_aspect(scene, ob, em->bm, aspect, aspect + 1);
return;
diff --git a/source/blender/makesrna/intern/rna_screen.c b/source/blender/makesrna/intern/rna_screen.c
index 21a77019f32..593f5aa669d 100644
--- a/source/blender/makesrna/intern/rna_screen.c
+++ b/source/blender/makesrna/intern/rna_screen.c
@@ -352,11 +352,6 @@ static void rna_def_region(BlenderRNA *brna)
RNA_def_struct_ui_text(srna, "Region", "Region in a subdivided screen area");
RNA_def_struct_sdna(srna, "ARegion");
- prop = RNA_def_property(srna, "id", PROP_INT, PROP_NONE);
- RNA_def_property_int_sdna(prop, NULL, "swinid");
- RNA_def_property_clear_flag(prop, PROP_EDITABLE);
- RNA_def_property_ui_text(prop, "Region ID", "Unique ID for this region");
-
prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "regiontype");
RNA_def_property_enum_items(prop, rna_enum_region_type_items);
diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c
index cc447f2a028..06c0260d08f 100644
--- a/source/blender/makesrna/intern/rna_sculpt_paint.c
+++ b/source/blender/makesrna/intern/rna_sculpt_paint.c
@@ -39,6 +39,7 @@
#include "DNA_brush_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
+#include "DNA_workspace_types.h"
#include "BKE_paint.h"
#include "BKE_material.h"
@@ -107,6 +108,7 @@ const EnumPropertyItem rna_enum_symmetrize_direction_items[] = {
#include "BKE_pointcache.h"
#include "BKE_particle.h"
#include "BKE_pbvh.h"
+#include "BKE_object.h"
#include "DEG_depsgraph.h"
@@ -391,10 +393,12 @@ static void rna_ImaPaint_stencil_update(bContext *C, PointerRNA *UNUSED(ptr))
static void rna_ImaPaint_canvas_update(bContext *C, PointerRNA *UNUSED(ptr))
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *ob = OBACT(view_layer);
+ Object *obedit = ((workspace->object_mode & OB_MODE_EDIT) && BKE_object_is_in_editmode(ob)) ? ob : NULL;
bScreen *sc;
Image *ima = scene->toolsettings->imapaint.canvas;
@@ -407,7 +411,7 @@ static void rna_ImaPaint_canvas_update(bContext *C, PointerRNA *UNUSED(ptr))
SpaceImage *sima = (SpaceImage *)slink;
if (!sima->pin)
- ED_space_image_set(sima, scene, scene->obedit, ima);
+ ED_space_image_set(sima, scene, obedit, ima);
}
}
}
diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c
index 61ac81a6d1c..1d0fa7a311c 100644
--- a/source/blender/makesrna/intern/rna_sequencer.c
+++ b/source/blender/makesrna/intern/rna_sequencer.c
@@ -2160,6 +2160,7 @@ static void rna_def_wipe(StructRNA *srna)
prop = RNA_def_property(srna, "transition_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "wipetype");
RNA_def_property_enum_items(prop, wipe_type_items);
+ RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_SEQUENCE);
RNA_def_property_ui_text(prop, "Transition Type", "");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
}
diff --git a/source/blender/makesrna/intern/rna_smoke.c b/source/blender/makesrna/intern/rna_smoke.c
index ac13f9d8294..4c5c584b16b 100644
--- a/source/blender/makesrna/intern/rna_smoke.c
+++ b/source/blender/makesrna/intern/rna_smoke.c
@@ -42,7 +42,7 @@
#include "BKE_pointcache.h"
#include "DNA_modifier_types.h"
-#include "DNA_object_force.h"
+#include "DNA_object_force_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_smoke_types.h"
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index e748299a635..a34f11f11c8 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -575,12 +575,12 @@ static void rna_SpaceView3D_layer_update(Main *bmain, Scene *UNUSED(scene), Poin
DEG_on_visible_update(bmain, false);
}
-static void rna_SpaceView3D_viewport_shade_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_SpaceView3D_viewport_shade_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
{
View3D *v3d = (View3D *)(ptr->data);
ScrArea *sa = rna_area_from_space(ptr);
- ED_view3d_shade_update(bmain, scene, v3d, sa);
+ ED_view3d_shade_update(bmain, v3d, sa);
}
static void rna_SpaceView3D_matcap_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
@@ -859,28 +859,31 @@ static int rna_SpaceImageEditor_show_uvedit_get(PointerRNA *ptr)
{
SpaceImage *sima = (SpaceImage *)(ptr->data);
bScreen *sc = (bScreen *)ptr->id.data;
- Scene *scene = ED_screen_scene_find(sc, G.main->wm.first);
+ wmWindow *win = ED_screen_window_find(sc, G.main->wm.first);
+ Object *obedit = OBEDIT_FROM_WINDOW(win);
- return ED_space_image_show_uvedit(sima, scene->obedit);
+ return ED_space_image_show_uvedit(sima, obedit);
}
static int rna_SpaceImageEditor_show_maskedit_get(PointerRNA *ptr)
{
SpaceImage *sima = (SpaceImage *)(ptr->data);
bScreen *sc = (bScreen *)ptr->id.data;
- Scene *scene = ED_screen_scene_find(sc, G.main->wm.first);
+ wmWindow *window = NULL;
+ Scene *scene = ED_screen_scene_find_with_window(sc, G.main->wm.first, &window);
ViewLayer *view_layer = BKE_view_layer_context_active_PLACEHOLDER(scene);
-
- return ED_space_image_check_show_maskedit(view_layer, sima);
+ const WorkSpace *workspace = WM_window_get_active_workspace(window);
+ return ED_space_image_check_show_maskedit(sima, workspace, view_layer);
}
static void rna_SpaceImageEditor_image_set(PointerRNA *ptr, PointerRNA value)
{
SpaceImage *sima = (SpaceImage *)(ptr->data);
bScreen *sc = (bScreen *)ptr->id.data;
- Scene *scene = ED_screen_scene_find(sc, G.main->wm.first);
-
- ED_space_image_set(sima, scene, scene->obedit, (Image *)value.data);
+ wmWindow *win;
+ Scene *scene = ED_screen_scene_find_with_window(sc, G.main->wm.first, &win);
+ Object *obedit = OBEDIT_FROM_WINDOW(win);
+ ED_space_image_set(sima, scene, obedit, (Image *)value.data);
}
static void rna_SpaceImageEditor_mask_set(PointerRNA *ptr, PointerRNA value)
diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c
index 42e3e2c83fb..e2e44a8ac5c 100644
--- a/source/blender/makesrna/intern/rna_texture.c
+++ b/source/blender/makesrna/intern/rna_texture.c
@@ -37,6 +37,7 @@
#include "DNA_node_types.h"
#include "DNA_particle_types.h"
#include "DNA_scene_types.h" /* MAXFRAME only */
+#include "DNA_workspace_types.h"
#include "BLI_utildefines.h"
@@ -247,10 +248,11 @@ void rna_TextureSlot_update(bContext *C, PointerRNA *ptr)
break;
case ID_BR:
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
Scene *scene = CTX_data_scene(C);
MTex *mtex = ptr->data;
ViewLayer *view_layer = CTX_data_view_layer(C);
- BKE_paint_invalidate_overlay_tex(scene, view_layer, mtex->tex);
+ BKE_paint_invalidate_overlay_tex(scene, view_layer, mtex->tex, workspace->object_mode);
WM_main_add_notifier(NC_BRUSH, id);
break;
}
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index 7bd1e4bb3b2..8ef70c4d108 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -364,8 +364,11 @@ static void rna_UserDef_weight_color_update(Main *bmain, Scene *scene, PointerRN
vDM_ColorBand_store((U.flag & USER_CUSTOM_RANGE) ? (&U.coba_weight) : NULL, btheme->tv3d.vertex_unreferenced);
for (ob = bmain->object.first; ob; ob = ob->id.next) {
- if (ob->mode & OB_MODE_WEIGHT_PAINT)
+ /* TODO/OBMODE (not urgent) */
+ // if (ob->mode & OB_MODE_WEIGHT_PAINT)
+ {
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ }
}
rna_userdef_update(bmain, scene, ptr);
@@ -395,26 +398,23 @@ static void rna_userdef_autosave_update(Main *bmain, Scene *scene, PointerRNA *p
static bAddon *rna_userdef_addon_new(void)
{
- bAddon *bext = MEM_callocN(sizeof(bAddon), "bAddon");
- BLI_addtail(&U.addons, bext);
- return bext;
+ ListBase *addons_list = &U.addons;
+ bAddon *addon = BKE_addon_new();
+ BLI_addtail(addons_list, addon);
+ return addon;
}
-static void rna_userdef_addon_remove(ReportList *reports, PointerRNA *path_cmp_ptr)
+static void rna_userdef_addon_remove(ReportList *reports, PointerRNA *addon_ptr)
{
- bAddon *bext = path_cmp_ptr->data;
- if (BLI_findindex(&U.addons, bext) == -1) {
+ ListBase *addons_list = &U.addons;
+ bAddon *addon = addon_ptr->data;
+ if (BLI_findindex(addons_list, addon) == -1) {
BKE_report(reports, RPT_ERROR, "Add-on is no longer valid");
return;
}
-
- if (bext->prop) {
- IDP_FreeProperty(bext->prop);
- MEM_freeN(bext->prop);
- }
-
- BLI_freelinkN(&U.addons, bext);
- RNA_POINTER_INVALIDATE(path_cmp_ptr);
+ BLI_remlink(addons_list, addon);
+ BKE_addon_free(addon);
+ RNA_POINTER_INVALIDATE(addon_ptr);
}
static bPathCompare *rna_userdef_pathcompare_new(void)
diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c
index bcb5bb524f0..dca4fa3822d 100644
--- a/source/blender/makesrna/intern/rna_wm.c
+++ b/source/blender/makesrna/intern/rna_wm.c
@@ -473,6 +473,7 @@ const EnumPropertyItem rna_enum_wm_report_items[] = {
#include "DNA_workspace_types.h"
#include "ED_screen.h"
+#include "ED_object.h"
#include "UI_interface.h"
@@ -778,28 +779,22 @@ static void rna_Window_view_layer_set(PointerRNA *ptr, PointerRNA value)
BKE_workspace_view_layer_set(workspace, value.data, scene);
}
-#ifdef USE_WORKSPACE_MODE
-
-static int rna_Window_object_mode_get(PointerRNA *ptr)
-{
- wmWindow *win = ptr->data;
- Scene *scene = WM_window_get_active_scene(win);
- WorkSpace *workspace = WM_window_get_active_workspace(win);
-
- return (int)BKE_workspace_object_mode_get(workspace, scene);
-}
-
-static void rna_Window_object_mode_set(PointerRNA *ptr, int value)
+static void rna_Window_view_layer_update(struct bContext *C, PointerRNA *ptr)
{
wmWindow *win = ptr->data;
Scene *scene = WM_window_get_active_scene(win);
WorkSpace *workspace = WM_window_get_active_workspace(win);
+ ViewLayer *view_layer = BKE_workspace_view_layer_get(workspace, scene);
+ Object *obedit = CTX_data_edit_object(C);
- BKE_workspace_object_mode_set(workspace, scene, value);
+ eObjectMode object_mode = workspace->object_mode;
+ if (obedit) {
+ ED_object_editmode_exit(C, EM_FREEDATA);
+ }
+ workspace->object_mode = object_mode;
+ ED_object_base_activate(C, view_layer->basact);
}
-#endif /* USE_WORKSPACE_MODE */
-
static PointerRNA rna_KeyMapItem_properties_get(PointerRNA *ptr)
{
wmKeyMapItem *kmi = ptr->data;
@@ -2083,15 +2078,8 @@ static void rna_def_window(BlenderRNA *brna)
RNA_def_property_struct_type(prop, "ViewLayer");
RNA_def_property_pointer_funcs(prop, "rna_Window_view_layer_get", "rna_Window_view_layer_set", NULL, NULL);
RNA_def_property_ui_text(prop, "Active View Layer", "The active workspace view layer showing in the window");
- RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_NULL);
- RNA_def_property_update(prop, NC_SCREEN | ND_LAYER, NULL);
-
-#ifdef USE_WORKSPACE_MODE
- prop = RNA_def_property(srna, "object_mode", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, rna_enum_object_mode_items);
- RNA_def_property_enum_funcs(prop, "rna_Window_object_mode_get", "rna_Window_object_mode_set", NULL);
- RNA_def_property_ui_text(prop, "Mode", "Object interaction mode used in this window");
-#endif
+ RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_NULL | PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCREEN | ND_LAYER, "rna_Window_view_layer_update");
prop = RNA_def_property(srna, "x", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "posx");
diff --git a/source/blender/makesrna/intern/rna_workspace.c b/source/blender/makesrna/intern/rna_workspace.c
index 0bed91f2807..5e0a4b97981 100644
--- a/source/blender/makesrna/intern/rna_workspace.c
+++ b/source/blender/makesrna/intern/rna_workspace.c
@@ -121,6 +121,10 @@ static void rna_def_workspace(BlenderRNA *brna)
"rna_workspace_transform_orientations_item_get", NULL, NULL, NULL, NULL);
RNA_def_property_ui_text(prop, "Transform Orientations", "");
+ prop = RNA_def_property(srna, "object_mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, rna_enum_object_mode_items);
+ RNA_def_property_ui_text(prop, "Mode", "Object interaction mode used in this window");
+
/* View Render */
prop = RNA_def_property(srna, "view_render", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
diff --git a/source/blender/makesrna/intern/rna_world.c b/source/blender/makesrna/intern/rna_world.c
index 15fa686a40a..e78355ee426 100644
--- a/source/blender/makesrna/intern/rna_world.c
+++ b/source/blender/makesrna/intern/rna_world.c
@@ -396,9 +396,9 @@ static void rna_def_world_mist(BlenderRNA *brna)
PropertyRNA *prop;
static const EnumPropertyItem falloff_items[] = {
- {0, "QUADRATIC", 0, "Quadratic", "Use quadratic progression"},
- {1, "LINEAR", 0, "Linear", "Use linear progression"},
- {2, "INVERSE_QUADRATIC", 0, "Inverse Quadratic", "Use inverse quadratic progression"},
+ {WO_MIST_QUADRATIC, "QUADRATIC", 0, "Quadratic", "Use quadratic progression"},
+ {WO_MIST_LINEAR, "LINEAR", 0, "Linear", "Use linear progression"},
+ {WO_MIST_INVERSE_QUADRATIC, "INVERSE_QUADRATIC", 0, "Inverse Quadratic", "Use inverse quadratic progression"},
{0, NULL, 0, NULL, NULL}
};
diff --git a/source/blender/modifiers/CMakeLists.txt b/source/blender/modifiers/CMakeLists.txt
index d6a7b94505f..397a3263e22 100644
--- a/source/blender/modifiers/CMakeLists.txt
+++ b/source/blender/modifiers/CMakeLists.txt
@@ -107,7 +107,6 @@ set(SRC
intern/MOD_wireframe.c
MOD_modifiertypes.h
- intern/MOD_boolean_util.h
intern/MOD_fluidsim_util.h
intern/MOD_meshcache_util.h
intern/MOD_util.h
@@ -121,16 +120,6 @@ if(WITH_ALEMBIC)
)
endif()
-if(WITH_MOD_BOOLEAN)
- add_definitions(-DWITH_MOD_BOOLEAN)
- list(APPEND SRC
- intern/MOD_boolean_util.c
- )
- list(APPEND INC
- ../../../extern/carve
- )
-endif()
-
if(WITH_MOD_REMESH)
add_definitions(-DWITH_MOD_REMESH)
list(APPEND INC
diff --git a/source/blender/modifiers/intern/MOD_boolean.c b/source/blender/modifiers/intern/MOD_boolean.c
index 0554fbb0317..7f79c941770 100644
--- a/source/blender/modifiers/intern/MOD_boolean.c
+++ b/source/blender/modifiers/intern/MOD_boolean.c
@@ -33,10 +33,6 @@
*/
// #ifdef DEBUG_TIME
-#define USE_BMESH
-#ifdef WITH_MOD_BOOLEAN
-# define USE_CARVE WITH_MOD_BOOLEAN
-#endif
#include <stdio.h>
@@ -49,11 +45,9 @@
#include "BKE_library_query.h"
#include "BKE_modifier.h"
-#include "MOD_boolean_util.h"
#include "MOD_util.h"
-#ifdef USE_BMESH
#include "BLI_alloca.h"
#include "BLI_math_geom.h"
#include "BKE_material.h"
@@ -63,18 +57,16 @@
#include "bmesh.h"
#include "bmesh_tools.h"
#include "tools/bmesh_intersect.h"
-#endif
#ifdef DEBUG_TIME
-#include "PIL_time.h"
-#include "PIL_time_utildefines.h"
+# include "PIL_time.h"
+# include "PIL_time_utildefines.h"
#endif
static void initData(ModifierData *md)
{
BooleanModifierData *bmd = (BooleanModifierData *)md;
- bmd->solver = eBooleanModifierSolver_BMesh;
bmd->double_threshold = 1e-6f;
}
@@ -118,8 +110,6 @@ static void updateDepsgraph(ModifierData *md,
DEG_add_object_relation(node, ob, DEG_OB_COMP_TRANSFORM, "Boolean Modifier");
}
-#if defined(USE_CARVE) || defined(USE_BMESH)
-
static DerivedMesh *get_quick_derivedMesh(
Object *ob_self, DerivedMesh *dm_self,
Object *ob_other, DerivedMesh *dm_other,
@@ -166,13 +156,7 @@ static DerivedMesh *get_quick_derivedMesh(
return result;
}
-#endif /* defined(USE_CARVE) || defined(USE_BMESH) */
-
-/* -------------------------------------------------------------------- */
-/* BMESH */
-
-#ifdef USE_BMESH
/* has no meaning for faces, do this so we can tell which face is which */
#define BM_FACE_TAG BM_ELEM_DRAW
@@ -185,8 +169,8 @@ static int bm_face_isect_pair(BMFace *f, void *UNUSED(user_data))
return BM_elem_flag_test(f, BM_FACE_TAG) ? 1 : 0;
}
-static DerivedMesh *applyModifier_bmesh(
- ModifierData *md, Object *ob,
+static DerivedMesh *applyModifier(
+ ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx), Object *ob,
DerivedMesh *dm,
ModifierApplyFlag flag)
{
@@ -354,66 +338,6 @@ static DerivedMesh *applyModifier_bmesh(
return dm;
}
-#endif /* USE_BMESH */
-
-
-/* -------------------------------------------------------------------- */
-/* CARVE */
-
-#ifdef USE_CARVE
-static DerivedMesh *applyModifier_carve(
- ModifierData *md, Object *ob,
- DerivedMesh *derivedData,
- ModifierApplyFlag flag)
-{
- BooleanModifierData *bmd = (BooleanModifierData *) md;
- DerivedMesh *dm;
-
- if (!bmd->object)
- return derivedData;
-
- dm = get_dm_for_modifier(bmd->object, flag);
-
- if (dm) {
- DerivedMesh *result;
-
- /* when one of objects is empty (has got no faces) we could speed up
- * calculation a bit returning one of objects' derived meshes (or empty one)
- * Returning mesh is depended on modifiers operation (sergey) */
- result = get_quick_derivedMesh(ob, derivedData, bmd->object, dm, bmd->operation);
-
- if (result == NULL) {
-#ifdef DEBUG_TIME
- TIMEIT_START(boolean_carve);
-#endif
-
- result = NewBooleanDerivedMesh(dm, bmd->object, derivedData, ob,
- 1 + bmd->operation);
-#ifdef DEBUG_TIME
- TIMEIT_END(boolean_carve);
-#endif
- }
-
- /* if new mesh returned, return it; otherwise there was
- * an error, so delete the modifier object */
- if (result)
- return result;
- else
- modifier_setError(md, "Cannot execute boolean operation");
- }
-
- return derivedData;
-}
-#endif /* USE_CARVE */
-
-
-static DerivedMesh *applyModifier_nop(
- ModifierData *UNUSED(md), Object *UNUSED(ob),
- DerivedMesh *derivedData,
- ModifierApplyFlag UNUSED(flag))
-{
- return derivedData;
-}
static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *UNUSED(md))
{
@@ -424,28 +348,6 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *UNUSED(
return dataMask;
}
-static DerivedMesh *applyModifier(
- ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx),
- Object *ob, DerivedMesh *derivedData,
- ModifierApplyFlag flag)
-{
- BooleanModifierData *bmd = (BooleanModifierData *)md;
-
- switch (bmd->solver) {
-#ifdef USE_CARVE
- case eBooleanModifierSolver_Carve:
- return applyModifier_carve(md, ob, derivedData, flag);
-#endif
-#ifdef USE_BMESH
- case eBooleanModifierSolver_BMesh:
- return applyModifier_bmesh(md, ob, derivedData, flag);
-#endif
- default:
- return applyModifier_nop(md, ob, derivedData, flag);
- }
-}
-
-
ModifierTypeInfo modifierType_Boolean = {
/* name */ "Boolean",
/* structName */ "BooleanModifierData",
diff --git a/source/blender/modifiers/intern/MOD_boolean_util.c b/source/blender/modifiers/intern/MOD_boolean_util.c
deleted file mode 100644
index 49010664aa8..00000000000
--- a/source/blender/modifiers/intern/MOD_boolean_util.c
+++ /dev/null
@@ -1,790 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) Blender Foundation
- * All rights reserved.
- *
- * Contributor(s): Sergey Sharybin.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file blender/modifiers/intern/MOD_boolean_util.c
- * \ingroup modifiers
- */
-
-#include "MEM_guardedalloc.h"
-
-#include "DNA_material_types.h"
-#include "DNA_meshdata_types.h"
-#include "DNA_object_types.h"
-
-#include "BLI_utildefines.h"
-#include "BLI_alloca.h"
-#include "BLI_ghash.h"
-#include "BLI_math.h"
-
-#include "BKE_cdderivedmesh.h"
-#include "BKE_material.h"
-
-#include "MOD_boolean_util.h"
-
-#include "carve-capi.h"
-
-/* Adopted from BM_loop_interp_from_face(),
- *
- * Transform matrix is used in cases when target coordinate needs
- * to be converted to source space (namely when interpolating
- * boolean result loops from second operand).
- *
- * TODO(sergey): Consider making it a generic function in DerivedMesh.c.
- */
-static void DM_loop_interp_from_poly(DerivedMesh *source_dm,
- MVert *source_mverts,
- MLoop *source_mloops,
- MPoly *source_poly,
- DerivedMesh *target_dm,
- MVert *target_mverts,
- MLoop *target_mloop,
- float transform[4][4],
- int target_loop_index)
-{
- float (*cos_3d)[3] = BLI_array_alloca(cos_3d, source_poly->totloop);
- int *source_indices = BLI_array_alloca(source_indices, source_poly->totloop);
- float *weights = BLI_array_alloca(weights, source_poly->totloop);
- int i;
- int target_vert_index = target_mloop[target_loop_index].v;
- float coord[3];
-
- for (i = 0; i < source_poly->totloop; ++i) {
- MLoop *mloop = &source_mloops[source_poly->loopstart + i];
- source_indices[i] = source_poly->loopstart + i;
- copy_v3_v3(cos_3d[i], source_mverts[mloop->v].co);
- }
-
- if (transform) {
- mul_v3_m4v3(coord, transform, target_mverts[target_vert_index].co);
- }
- else {
- copy_v3_v3(coord, target_mverts[target_vert_index].co);
- }
-
- interp_weights_poly_v3(weights, cos_3d, source_poly->totloop, coord);
-
- DM_interp_loop_data(source_dm, target_dm, source_indices, weights,
- source_poly->totloop, target_loop_index);
-}
-
-typedef struct DMArrays {
- MVert *mvert;
- MEdge *medge;
- MLoop *mloop;
- MPoly *mpoly;
- bool mvert_allocated;
- bool medge_allocated;
- bool mloop_allocated;
- bool mpoly_allocated;
-} DMArrays;
-
-static void dm_arrays_get(DerivedMesh *dm, DMArrays *arrays)
-{
- arrays->mvert = DM_get_vert_array(dm, &arrays->mvert_allocated);
- arrays->medge = DM_get_edge_array(dm, &arrays->medge_allocated);
- arrays->mloop = DM_get_loop_array(dm, &arrays->mloop_allocated);
- arrays->mpoly = DM_get_poly_array(dm, &arrays->mpoly_allocated);
-}
-
-static void dm_arrays_free(DMArrays *arrays)
-{
- if (arrays->mvert_allocated) {
- MEM_freeN(arrays->mvert);
- }
- if (arrays->medge_allocated) {
- MEM_freeN(arrays->medge);
- }
- if (arrays->mloop_allocated) {
- MEM_freeN(arrays->mloop);
- }
- if (arrays->mpoly_allocated) {
- MEM_freeN(arrays->mpoly);
- }
-}
-
-/* **** Importer from derived mesh to Carve **** */
-
-typedef struct ImportMeshData {
- DerivedMesh *dm;
- float obmat[4][4];
- MVert *mvert;
- MEdge *medge;
- MLoop *mloop;
- MPoly *mpoly;
-} ImportMeshData;
-
-/* Get number of vertices. */
-static int importer_GetNumVerts(ImportMeshData *import_data)
-{
- DerivedMesh *dm = import_data->dm;
- return dm->getNumVerts(dm);
-}
-
-/* Get number of edges. */
-static int importer_GetNumEdges(ImportMeshData *import_data)
-{
- DerivedMesh *dm = import_data->dm;
- return dm->getNumEdges(dm);
-}
-
-/* Get number of loops. */
-static int importer_GetNumLoops(ImportMeshData *import_data)
-{
- DerivedMesh *dm = import_data->dm;
- return dm->getNumLoops(dm);
-}
-
-/* Get number of polys. */
-static int importer_GetNumPolys(ImportMeshData *import_data)
-{
- DerivedMesh *dm = import_data->dm;
- return dm->getNumPolys(dm);
-}
-
-/* Get 3D coordinate of vertex with given index. */
-static void importer_GetVertCoord(ImportMeshData *import_data, int vert_index, float coord[3])
-{
- MVert *mvert = import_data->mvert;
-
- BLI_assert(vert_index >= 0 && vert_index < import_data->dm->getNumVerts(import_data->dm));
-
- mul_v3_m4v3(coord, import_data->obmat, mvert[vert_index].co);
-}
-
-/* Get index of vertices which are adjucent to edge specified by it's index. */
-static void importer_GetEdgeVerts(ImportMeshData *import_data, int edge_index, int *v1, int *v2)
-{
- MEdge *medge = &import_data->medge[edge_index];
-
- BLI_assert(edge_index >= 0 && edge_index < import_data->dm->getNumEdges(import_data->dm));
-
- *v1 = medge->v1;
- *v2 = medge->v2;
-}
-
-/* Get number of adjucent vertices to the poly specified by it's index. */
-static int importer_GetPolyNumVerts(ImportMeshData *import_data, int poly_index)
-{
- MPoly *mpoly = import_data->mpoly;
-
- BLI_assert(poly_index >= 0 && poly_index < import_data->dm->getNumPolys(import_data->dm));
-
- return mpoly[poly_index].totloop;
-}
-
-/* Get list of adjucent vertices to the poly specified by it's index. */
-static void importer_GetPolyVerts(ImportMeshData *import_data, int poly_index, int *verts)
-{
- MPoly *mpoly = &import_data->mpoly[poly_index];
- MLoop *mloop = import_data->mloop + mpoly->loopstart;
- int i;
- BLI_assert(poly_index >= 0 && poly_index < import_data->dm->getNumPolys(import_data->dm));
- for (i = 0; i < mpoly->totloop; i++, mloop++) {
- verts[i] = mloop->v;
- }
-}
-
-// Triangulate 2D polygon.
-#if 0
-static int importer_triangulate2DPoly(ImportMeshData *UNUSED(import_data),
- const float (*vertices)[2], int num_vertices,
- unsigned int (*triangles)[3])
-{
- // TODO(sergey): Currently import_data is unused but in the future we could
- // put memory arena there which will reduce amount of allocations happening
- // over the triangulation period.
- //
- // However that's not so much straighforward to do it right now because we
- // also are tu consider threaded import/export.
-
- BLI_assert(num_vertices > 3);
-
- BLI_polyfill_calc(vertices, num_vertices, triangles);
-
- return num_vertices - 2;
-}
-#endif
-
-static CarveMeshImporter MeshImporter = {
- importer_GetNumVerts,
- importer_GetNumEdges,
- importer_GetNumLoops,
- importer_GetNumPolys,
- importer_GetVertCoord,
- importer_GetEdgeVerts,
- importer_GetPolyNumVerts,
- importer_GetPolyVerts,
-
- /* TODO(sergey): We don't use BLI_polyfill_calc() because it tends
- * to generate degenerated geometry which is fatal for booleans.
- *
- * For now we stick to Carve's triangulation.
- */
- NULL, /* importer_triangulate2DPoly */
-};
-
-/* **** Exporter from Carve to derived mesh **** */
-
-typedef struct ExportMeshData {
- DerivedMesh *dm;
- float obimat[4][4];
- MVert *mvert;
- MEdge *medge;
- MLoop *mloop;
- MPoly *mpoly;
- int *vert_origindex;
- int *edge_origindex;
- int *poly_origindex;
- int *loop_origindex;
-
- /* Objects and derived meshes of left and right operands.
- * Used for custom data merge and interpolation.
- */
- Object *ob_left;
- Object *ob_right;
- DerivedMesh *dm_left;
- DerivedMesh *dm_right;
- MVert *mvert_left;
- MEdge *medge_left;
- MLoop *mloop_left;
- MPoly *mpoly_left;
- MVert *mvert_right;
- MEdge *medge_right;
- MLoop *mloop_right;
- MPoly *mpoly_right;
-
- float left_to_right_mat[4][4];
-
- /* Hash to map materials from right object to result. */
- GHash *material_hash;
-} ExportMeshData;
-
-BLI_INLINE Object *which_object(ExportMeshData *export_data, int which_mesh)
-{
- Object *object = NULL;
- switch (which_mesh) {
- case CARVE_MESH_LEFT:
- object = export_data->ob_left;
- break;
- case CARVE_MESH_RIGHT:
- object = export_data->ob_right;
- break;
- }
- return object;
-}
-
-BLI_INLINE DerivedMesh *which_dm(ExportMeshData *export_data, int which_mesh)
-{
- DerivedMesh *dm = NULL;
- switch (which_mesh) {
- case CARVE_MESH_LEFT:
- dm = export_data->dm_left;
- break;
- case CARVE_MESH_RIGHT:
- dm = export_data->dm_right;
- break;
- }
- return dm;
-}
-
-BLI_INLINE MVert *which_mvert(ExportMeshData *export_data, int which_mesh)
-{
- MVert *mvert = NULL;
- switch (which_mesh) {
- case CARVE_MESH_LEFT:
- mvert = export_data->mvert_left;
- break;
- case CARVE_MESH_RIGHT:
- mvert = export_data->mvert_right;
- break;
- }
- return mvert;
-}
-
-BLI_INLINE MEdge *which_medge(ExportMeshData *export_data, int which_mesh)
-{
- MEdge *medge = NULL;
- switch (which_mesh) {
- case CARVE_MESH_LEFT:
- medge = export_data->medge_left;
- break;
- case CARVE_MESH_RIGHT:
- medge = export_data->medge_right;
- break;
- }
- return medge;
-}
-
-BLI_INLINE MLoop *which_mloop(ExportMeshData *export_data, int which_mesh)
-{
- MLoop *mloop = NULL;
- switch (which_mesh) {
- case CARVE_MESH_LEFT:
- mloop = export_data->mloop_left;
- break;
- case CARVE_MESH_RIGHT:
- mloop = export_data->mloop_right;
- break;
- }
- return mloop;
-}
-
-BLI_INLINE MPoly *which_mpoly(ExportMeshData *export_data, int which_mesh)
-{
- MPoly *mpoly = NULL;
- switch (which_mesh) {
- case CARVE_MESH_LEFT:
- mpoly = export_data->mpoly_left;
- break;
- case CARVE_MESH_RIGHT:
- mpoly = export_data->mpoly_right;
- break;
- }
- return mpoly;
-}
-
-/* Create new external mesh */
-static void exporter_InitGeomArrays(ExportMeshData *export_data,
- int num_verts, int num_edges,
- int num_loops, int num_polys)
-{
- DerivedMesh *dm = CDDM_new(num_verts, num_edges, 0,
- num_loops, num_polys);
- DerivedMesh *dm_left = export_data->dm_left,
- *dm_right = export_data->dm_right;
-
- /* Mask for custom data layers to be merged from operands. */
- CustomDataMask merge_mask = CD_MASK_DERIVEDMESH & ~CD_MASK_ORIGINDEX;
-
- export_data->dm = dm;
- export_data->mvert = dm->getVertArray(dm);
- export_data->medge = dm->getEdgeArray(dm);
- export_data->mloop = dm->getLoopArray(dm);
- export_data->mpoly = dm->getPolyArray(dm);
-
- /* Merge custom data layers from operands.
- *
- * Will only create custom data layers for all the layers which appears in
- * the operand. Data for those layers will not be allocated or initialized.
- */
-
- CustomData_merge(&dm_left->vertData, &dm->vertData, merge_mask, CD_DEFAULT, num_verts);
- CustomData_merge(&dm_right->vertData, &dm->vertData, merge_mask, CD_DEFAULT, num_verts);
-
- CustomData_merge(&dm_left->loopData, &dm->loopData, merge_mask, CD_DEFAULT, num_loops);
- CustomData_merge(&dm_right->loopData, &dm->loopData, merge_mask, CD_DEFAULT, num_loops);
-
- CustomData_merge(&dm_left->polyData, &dm->polyData, merge_mask, CD_DEFAULT, num_polys);
- CustomData_merge(&dm_right->polyData, &dm->polyData, merge_mask, CD_DEFAULT, num_polys);
-
- CustomData_merge(&dm_left->edgeData, &dm->edgeData, merge_mask, CD_DEFAULT, num_edges);
- CustomData_merge(&dm_right->edgeData, &dm->edgeData, merge_mask, CD_DEFAULT, num_edges);
-
- export_data->vert_origindex = dm->getVertDataArray(dm, CD_ORIGINDEX);
- export_data->edge_origindex = dm->getEdgeDataArray(dm, CD_ORIGINDEX);
- export_data->poly_origindex = dm->getPolyDataArray(dm, CD_ORIGINDEX);
- export_data->loop_origindex = dm->getLoopDataArray(dm, CD_ORIGINDEX);
-}
-
-/* Set coordinate of vertex with given index. */
-static void exporter_SetVert(ExportMeshData *export_data,
- int vert_index, float coord[3],
- int which_orig_mesh, int orig_vert_index)
-{
- DerivedMesh *dm = export_data->dm;
- DerivedMesh *dm_orig;
- MVert *mvert = export_data->mvert;
-
- BLI_assert(vert_index >= 0 && vert_index <= dm->getNumVerts(dm));
-
- dm_orig = which_dm(export_data, which_orig_mesh);
- if (dm_orig) {
- BLI_assert(orig_vert_index >= 0 && orig_vert_index < dm_orig->getNumVerts(dm_orig));
- mvert[vert_index] = which_mvert(export_data, which_orig_mesh)[orig_vert_index];
- CustomData_copy_data(&dm_orig->vertData, &dm->vertData, orig_vert_index, vert_index, 1);
- }
-
- /* Set original index of the vertex. */
- if (export_data->vert_origindex) {
- if (which_orig_mesh == CARVE_MESH_LEFT) {
- export_data->vert_origindex[vert_index] = orig_vert_index;
- }
- else {
- export_data->vert_origindex[vert_index] = ORIGINDEX_NONE;
- }
- }
-
- mul_v3_m4v3(mvert[vert_index].co, export_data->obimat, coord);
-}
-
-/* Set vertices which are adjucent to the edge specified by it's index. */
-static void exporter_SetEdge(ExportMeshData *export_data,
- int edge_index, int v1, int v2,
- int which_orig_mesh, int orig_edge_index)
-{
- DerivedMesh *dm = export_data->dm;
- MEdge *medge = &export_data->medge[edge_index];
- DerivedMesh *dm_orig;
-
- BLI_assert(edge_index >= 0 && edge_index < dm->getNumEdges(dm));
- BLI_assert(v1 >= 0 && v1 < dm->getNumVerts(dm));
- BLI_assert(v2 >= 0 && v2 < dm->getNumVerts(dm));
-
- dm_orig = which_dm(export_data, which_orig_mesh);
- if (dm_orig) {
- BLI_assert(orig_edge_index >= 0 && orig_edge_index < dm_orig->getNumEdges(dm_orig));
-
- *medge = which_medge(export_data, which_orig_mesh)[orig_edge_index];
-
- /* Copy all edge layers, including medge. */
- CustomData_copy_data(&dm_orig->edgeData, &dm->edgeData, orig_edge_index, edge_index, 1);
- }
-
- /* Set original index of the edge. */
- if (export_data->edge_origindex) {
- if (which_orig_mesh == CARVE_MESH_LEFT) {
- export_data->edge_origindex[edge_index] = orig_edge_index;
- }
- else {
- export_data->edge_origindex[edge_index] = ORIGINDEX_NONE;
- }
- }
-
- medge->v1 = v1;
- medge->v2 = v2;
-
- medge->flag |= ME_EDGEDRAW | ME_EDGERENDER;
-}
-
-static void setMPolyMaterial(ExportMeshData *export_data,
- MPoly *mpoly,
- int which_orig_mesh)
-{
- Object *orig_object;
- GHash *material_hash;
- Material *orig_mat;
-
- if (which_orig_mesh == CARVE_MESH_LEFT) {
- /* No need to change materian index for faces from left operand */
- return;
- }
-
- material_hash = export_data->material_hash;
- orig_object = which_object(export_data, which_orig_mesh);
-
- /* Set material, based on lookup in hash table. */
- orig_mat = give_current_material(orig_object, mpoly->mat_nr + 1);
-
- if (orig_mat) {
- /* For faces from right operand check if there's requested material
- * in the left operand. And if it is, use index of that material,
- * otherwise fallback to first material (material with index=0).
- */
- if (!BLI_ghash_haskey(material_hash, orig_mat)) {
- int a, mat_nr;
-
- mat_nr = 0;
- for (a = 0; a < export_data->ob_left->totcol; a++) {
- if (give_current_material(export_data->ob_left, a + 1) == orig_mat) {
- mat_nr = a;
- break;
- }
- }
-
- BLI_ghash_insert(material_hash, orig_mat, SET_INT_IN_POINTER(mat_nr));
-
- mpoly->mat_nr = mat_nr;
- }
- else
- mpoly->mat_nr = GET_INT_FROM_POINTER(BLI_ghash_lookup(material_hash, orig_mat));
- }
- else {
- mpoly->mat_nr = 0;
- }
-}
-
-/* Set list of adjucent loops to the poly specified by it's index. */
-static void exporter_SetPoly(ExportMeshData *export_data,
- int poly_index, int start_loop, int num_loops,
- int which_orig_mesh, int orig_poly_index)
-{
- DerivedMesh *dm = export_data->dm;
- MPoly *mpoly = &export_data->mpoly[poly_index];
- DerivedMesh *dm_orig;
- int i;
-
- /* Poly is always to be either from left or right operand. */
- dm_orig = which_dm(export_data, which_orig_mesh);
-
- BLI_assert(poly_index >= 0 && poly_index < dm->getNumPolys(dm));
- BLI_assert(start_loop >= 0 && start_loop <= dm->getNumLoops(dm) - num_loops);
- BLI_assert(num_loops >= 3);
- BLI_assert(dm_orig != NULL);
- BLI_assert(orig_poly_index >= 0 && orig_poly_index < dm_orig->getNumPolys(dm_orig));
-
- /* Copy all poly layers, including mpoly. */
- *mpoly = which_mpoly(export_data, which_orig_mesh)[orig_poly_index];
- CustomData_copy_data(&dm_orig->polyData, &dm->polyData, orig_poly_index, poly_index, 1);
-
- /* Set material of the curren poly.
- * This would re-map materials from right operand to materials from the
- * left one as well.
- */
- setMPolyMaterial(export_data, mpoly, which_orig_mesh);
-
- /* Set original index of the poly. */
- if (export_data->poly_origindex) {
- if (which_orig_mesh == CARVE_MESH_LEFT) {
- export_data->poly_origindex[poly_index] = orig_poly_index;
- }
- else {
- export_data->poly_origindex[poly_index] = ORIGINDEX_NONE;
- }
- }
-
- /* Set poly data itself. */
- mpoly->loopstart = start_loop;
- mpoly->totloop = num_loops;
-
- /* Interpolate data for poly loops. */
- {
- MVert *source_mverts = which_mvert(export_data, which_orig_mesh);
- MLoop *source_mloops = which_mloop(export_data, which_orig_mesh);
- MPoly *source_mpolys = which_mpoly(export_data, which_orig_mesh);
- MPoly *source_poly = &source_mpolys[orig_poly_index];
- MVert *target_mverts = export_data->mvert;
- MLoop *target_mloops = export_data->mloop;
- float (*transform)[4] = NULL;
-
- if (which_orig_mesh == CARVE_MESH_RIGHT) {
- transform = export_data->left_to_right_mat;
- }
-
- for (i = 0; i < mpoly->totloop; i++) {
- DM_loop_interp_from_poly(dm_orig,
- source_mverts,
- source_mloops,
- source_poly,
- dm,
- target_mverts,
- target_mloops,
- transform,
- i + mpoly->loopstart);
- }
- }
-}
-
-/* Set list vertex and edge which are adjucent to loop with given index. */
-static void exporter_SetLoop(ExportMeshData *export_data,
- int loop_index, int vertex, int edge,
- int which_orig_mesh, int orig_loop_index)
-{
- DerivedMesh *dm = export_data->dm;
- MLoop *mloop = &export_data->mloop[loop_index];
- DerivedMesh *dm_orig;
-
- BLI_assert(loop_index >= 0 && loop_index < dm->getNumLoops(dm));
- BLI_assert(vertex >= 0 && vertex < dm->getNumVerts(dm));
- BLI_assert(edge >= 0 && vertex < dm->getNumEdges(dm));
-
- dm_orig = which_dm(export_data, which_orig_mesh);
- if (dm_orig) {
- BLI_assert(orig_loop_index >= 0 && orig_loop_index < dm_orig->getNumLoops(dm_orig));
-
- /* Copy all loop layers, including mloop. */
- *mloop = which_mloop(export_data, which_orig_mesh)[orig_loop_index];
- CustomData_copy_data(&dm_orig->loopData, &dm->loopData, orig_loop_index, loop_index, 1);
- }
-
- /* Set original index of the loop. */
- if (export_data->loop_origindex) {
- if (which_orig_mesh == CARVE_MESH_LEFT) {
- export_data->loop_origindex[loop_index] = orig_loop_index;
- }
- else {
- export_data->loop_origindex[loop_index] = ORIGINDEX_NONE;
- }
- }
-
- mloop->v = vertex;
- mloop->e = edge;
-}
-
-/* Edge index from a loop index for a given original mesh. */
-static int exporter_MapLoopToEdge(ExportMeshData *export_data,
- int which_mesh, int loop_index)
-{
- DerivedMesh *dm = which_dm(export_data, which_mesh);
- MLoop *mloop = which_mloop(export_data, which_mesh);
-
- (void) dm; /* Unused in release builds. */
-
- BLI_assert(dm != NULL);
- BLI_assert(loop_index >= 0 && loop_index < dm->getNumLoops(dm));
-
- return mloop[loop_index].e;
-}
-
-static CarveMeshExporter MeshExporter = {
- exporter_InitGeomArrays,
- exporter_SetVert,
- exporter_SetEdge,
- exporter_SetPoly,
- exporter_SetLoop,
- exporter_MapLoopToEdge
-};
-
-static int operation_from_optype(int int_op_type)
-{
- int operation;
-
- switch (int_op_type) {
- case 1:
- operation = CARVE_OP_INTERSECTION;
- break;
- case 2:
- operation = CARVE_OP_UNION;
- break;
- case 3:
- operation = CARVE_OP_A_MINUS_B;
- break;
- default:
- BLI_assert(!"Should not happen");
- operation = -1;
- break;
- }
-
- return operation;
-}
-
-static void prepare_import_data(Object *object,
- DerivedMesh *dm,
- const DMArrays *dm_arrays,
- ImportMeshData *import_data)
-{
- import_data->dm = dm;
- copy_m4_m4(import_data->obmat, object->obmat);
- import_data->mvert = dm_arrays->mvert;
- import_data->medge = dm_arrays->medge;
- import_data->mloop = dm_arrays->mloop;
- import_data->mpoly = dm_arrays->mpoly;
-}
-
-static struct CarveMeshDescr *carve_mesh_from_dm(Object *object,
- DerivedMesh *dm,
- const DMArrays *dm_arrays)
-{
- ImportMeshData import_data;
- prepare_import_data(object, dm, dm_arrays, &import_data);
- return carve_addMesh(&import_data, &MeshImporter);
-}
-
-static void prepare_export_data(Object *object_left, DerivedMesh *dm_left, const DMArrays *dm_left_arrays,
- Object *object_right, DerivedMesh *dm_right, const DMArrays *dm_right_arrays,
- ExportMeshData *export_data)
-{
- float object_right_imat[4][4];
-
- invert_m4_m4(export_data->obimat, object_left->obmat);
-
- export_data->ob_left = object_left;
- export_data->ob_right = object_right;
-
- export_data->dm_left = dm_left;
- export_data->dm_right = dm_right;
-
- export_data->mvert_left = dm_left_arrays->mvert;
- export_data->medge_left = dm_left_arrays->medge;
- export_data->mloop_left = dm_left_arrays->mloop;
- export_data->mpoly_left = dm_left_arrays->mpoly;
- export_data->mvert_right = dm_right_arrays->mvert;
- export_data->medge_right = dm_right_arrays->medge;
- export_data->mloop_right = dm_right_arrays->mloop;
- export_data->mpoly_right = dm_right_arrays->mpoly;
-
- export_data->material_hash = BLI_ghash_ptr_new("CSG_mat gh");
-
- /* Matrix to convert coord from left object's loca; space to
- * right object's local space.
- */
- invert_m4_m4(object_right_imat, object_right->obmat);
- mul_m4_m4m4(export_data->left_to_right_mat, object_left->obmat,
- object_right_imat);
-}
-
-DerivedMesh *NewBooleanDerivedMesh(DerivedMesh *dm, struct Object *ob,
- DerivedMesh *dm_select, struct Object *ob_select,
- int int_op_type)
-{
-
- struct CarveMeshDescr *left, *right, *output = NULL;
- DerivedMesh *output_dm = NULL;
- int operation;
- bool result;
- DMArrays dm_left_arrays, dm_right_arrays;
-
- if (dm == NULL || dm_select == NULL) {
- return NULL;
- }
-
- operation = operation_from_optype(int_op_type);
- if (operation == -1) {
- return NULL;
- }
-
- dm_arrays_get(dm_select, &dm_left_arrays);
- dm_arrays_get(dm, &dm_right_arrays);
-
- left = carve_mesh_from_dm(ob_select, dm_select, &dm_left_arrays);
- right = carve_mesh_from_dm(ob, dm, &dm_right_arrays);
-
- result = carve_performBooleanOperation(left, right, operation, &output);
-
- carve_deleteMesh(left);
- carve_deleteMesh(right);
-
- if (result) {
- ExportMeshData export_data;
-
- prepare_export_data(ob_select, dm_select, &dm_left_arrays,
- ob, dm, &dm_right_arrays,
- &export_data);
-
- carve_exportMesh(output, &MeshExporter, &export_data);
- output_dm = export_data.dm;
-
- /* Free memory used by export mesh. */
- BLI_ghash_free(export_data.material_hash, NULL, NULL);
-
- output_dm->cd_flag |= dm->cd_flag | dm_select->cd_flag;
- output_dm->dirty |= DM_DIRTY_NORMALS;
- carve_deleteMesh(output);
- }
-
- dm_arrays_free(&dm_left_arrays);
- dm_arrays_free(&dm_right_arrays);
-
- return output_dm;
-}
diff --git a/source/blender/modifiers/intern/MOD_boolean_util.h b/source/blender/modifiers/intern/MOD_boolean_util.h
deleted file mode 100644
index 00d7c37b266..00000000000
--- a/source/blender/modifiers/intern/MOD_boolean_util.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) Blender Foundation.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file blender/modifiers/intern/MOD_boolean_util.h
- * \ingroup modifiers
- */
-
-
-#ifndef __MOD_BOOLEAN_UTIL_H__
-#define __MOD_BOOLEAN_UTIL_H__
-
-struct Object;
-struct DerivedMesh;
-
-/* Performs a boolean between two mesh objects, it is assumed that both objects
- * are in fact mesh object. On success returns a DerivedMesh. On failure
- * returns NULL and reports an error. */
-
-struct DerivedMesh *NewBooleanDerivedMesh(struct DerivedMesh *dm, struct Object *ob,
- struct DerivedMesh *dm_select, struct Object *ob_select, int int_op_type);
-
-#endif /* MOD_BOOLEAN_UTILS */
diff --git a/source/blender/modifiers/intern/MOD_build.c b/source/blender/modifiers/intern/MOD_build.c
index 7a52ede8838..2e0b13b0603 100644
--- a/source/blender/modifiers/intern/MOD_build.c
+++ b/source/blender/modifiers/intern/MOD_build.c
@@ -154,7 +154,7 @@ static DerivedMesh *applyModifier(ModifierData *md, const struct EvaluationConte
numLoops_dst += mp->totloop;
}
- BLI_assert(hash_num == BLI_ghash_size(vertHash));
+ BLI_assert(hash_num == BLI_ghash_len(vertHash));
/* get the set of edges that will be in the new mesh (i.e. all edges
* that have both verts in the new mesh)
@@ -187,7 +187,7 @@ static DerivedMesh *applyModifier(ModifierData *md, const struct EvaluationConte
*/
medge = medge_src;
hash_num = 0;
- BLI_assert(hash_num == BLI_ghash_size(vertHash));
+ BLI_assert(hash_num == BLI_ghash_len(vertHash));
for (i = 0; i < numEdges_dst; i++) {
void **val_p;
me = medge + edgeMap[i];
@@ -201,11 +201,11 @@ static DerivedMesh *applyModifier(ModifierData *md, const struct EvaluationConte
hash_num++;
}
}
- BLI_assert(hash_num == BLI_ghash_size(vertHash));
+ BLI_assert(hash_num == BLI_ghash_len(vertHash));
/* get the set of edges that will be in the new mesh */
for (i = 0; i < numEdges_dst; i++) {
- j = BLI_ghash_size(edgeHash);
+ j = BLI_ghash_len(edgeHash);
BLI_ghash_insert(edgeHash, SET_INT_IN_POINTER(j),
SET_INT_IN_POINTER(edgeMap[i]));
@@ -232,8 +232,8 @@ static DerivedMesh *applyModifier(ModifierData *md, const struct EvaluationConte
/* now we know the number of verts, edges and faces, we can create
* the mesh
*/
- result = CDDM_from_template(dm, BLI_ghash_size(vertHash),
- BLI_ghash_size(edgeHash), 0, numLoops_dst, numFaces_dst);
+ result = CDDM_from_template(dm, BLI_ghash_len(vertHash),
+ BLI_ghash_len(edgeHash), 0, numLoops_dst, numFaces_dst);
/* copy the vertices across */
GHASH_ITER (gh_iter, vertHash) {
@@ -250,7 +250,7 @@ static DerivedMesh *applyModifier(ModifierData *md, const struct EvaluationConte
}
/* copy the edges across, remapping indices */
- for (i = 0; i < BLI_ghash_size(edgeHash); i++) {
+ for (i = 0; i < BLI_ghash_len(edgeHash); i++) {
MEdge source;
MEdge *dest;
int oldIndex = GET_INT_FROM_POINTER(BLI_ghash_lookup(edgeHash, SET_INT_IN_POINTER(i)));
diff --git a/source/blender/modifiers/intern/MOD_dynamicpaint.c b/source/blender/modifiers/intern/MOD_dynamicpaint.c
index cf3f84364ea..da5d9a29be5 100644
--- a/source/blender/modifiers/intern/MOD_dynamicpaint.c
+++ b/source/blender/modifiers/intern/MOD_dynamicpaint.c
@@ -29,7 +29,7 @@
#include "DNA_dynamicpaint_types.h"
#include "DNA_object_types.h"
-#include "DNA_object_force.h"
+#include "DNA_object_force_types.h"
#include "DNA_scene_types.h"
#include "BLI_utildefines.h"
diff --git a/source/blender/modifiers/intern/MOD_fluidsim.c b/source/blender/modifiers/intern/MOD_fluidsim.c
index f9e7f10653b..75f57de2a37 100644
--- a/source/blender/modifiers/intern/MOD_fluidsim.c
+++ b/source/blender/modifiers/intern/MOD_fluidsim.c
@@ -34,7 +34,7 @@
#include "DNA_scene_types.h"
-#include "DNA_object_fluidsim.h"
+#include "DNA_object_fluidsim_types.h"
#include "DNA_object_types.h"
#include "BLI_utildefines.h"
diff --git a/source/blender/modifiers/intern/MOD_fluidsim_util.c b/source/blender/modifiers/intern/MOD_fluidsim_util.c
index c9f475ad228..65f45c9af64 100644
--- a/source/blender/modifiers/intern/MOD_fluidsim_util.c
+++ b/source/blender/modifiers/intern/MOD_fluidsim_util.c
@@ -40,7 +40,7 @@
#include "DNA_scene_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
-#include "DNA_object_fluidsim.h"
+#include "DNA_object_fluidsim_types.h"
#include "BLI_blenlib.h"
#include "BLI_math.h"
diff --git a/source/blender/modifiers/intern/MOD_meshdeform.c b/source/blender/modifiers/intern/MOD_meshdeform.c
index da233a18d0a..e8fc832b597 100644
--- a/source/blender/modifiers/intern/MOD_meshdeform.c
+++ b/source/blender/modifiers/intern/MOD_meshdeform.c
@@ -49,6 +49,8 @@
#include "MEM_guardedalloc.h"
+#include "DEG_depsgraph.h"
+
#include "MOD_util.h"
#ifdef __SSE2__
@@ -300,7 +302,7 @@ static void meshdeformModifier_do(
*
* We'll support this case once granular dependency graph is landed.
*/
- if (mmd->object == md->scene->obedit) {
+ if (mmd->object == OBEDIT_FROM_EVAL_CTX(eval_ctx)) {
BMEditMesh *em = BKE_editmesh_from_object(mmd->object);
tmpdm = editbmesh_get_derived_cage_and_final(eval_ctx, md->scene, mmd->object, em, 0, &cagedm);
if (tmpdm)
diff --git a/source/blender/modifiers/intern/MOD_multires.c b/source/blender/modifiers/intern/MOD_multires.c
index 2b675d36140..6704526ea03 100644
--- a/source/blender/modifiers/intern/MOD_multires.c
+++ b/source/blender/modifiers/intern/MOD_multires.c
@@ -48,6 +48,8 @@
#include "MOD_modifiertypes.h"
+#include "DEG_depsgraph.h"
+
static void initData(ModifierData *md)
{
MultiresModifierData *mmd = (MultiresModifierData *)md;
@@ -67,7 +69,7 @@ static void copyData(ModifierData *md, ModifierData *target)
modifier_copyData_generic(md, target);
}
-static DerivedMesh *applyModifier(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx), Object *ob,
+static DerivedMesh *applyModifier(ModifierData *md, const struct EvaluationContext *eval_ctx, Object *ob,
DerivedMesh *dm, ModifierApplyFlag flag)
{
MultiresModifierData *mmd = (MultiresModifierData *)md;
@@ -94,7 +96,7 @@ static DerivedMesh *applyModifier(ModifierData *md, const struct EvaluationConte
if (ignore_simplify)
flags |= MULTIRES_IGNORE_SIMPLIFY;
- result = multires_make_derived_from_derived(dm, mmd, ob, flags);
+ result = multires_make_derived_from_derived(dm, mmd, ob, flags, eval_ctx->object_mode);
if (result == dm)
return dm;
diff --git a/source/blender/modifiers/intern/MOD_shrinkwrap.c b/source/blender/modifiers/intern/MOD_shrinkwrap.c
index c87fdd321ab..8b9a7c42eb2 100644
--- a/source/blender/modifiers/intern/MOD_shrinkwrap.c
+++ b/source/blender/modifiers/intern/MOD_shrinkwrap.c
@@ -103,7 +103,7 @@ static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk,
walk(userData, ob, &smd->auxTarget, IDWALK_CB_NOP);
}
-static void deformVerts(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx),
+static void deformVerts(ModifierData *md, const struct EvaluationContext *eval_ctx,
Object *ob, DerivedMesh *derivedData,
float (*vertexCos)[3],
int numVerts,
@@ -118,13 +118,13 @@ static void deformVerts(ModifierData *md, const struct EvaluationContext *UNUSED
dm = get_cddm(ob, NULL, dm, vertexCos, dependsOnNormals(md));
}
- shrinkwrapModifier_deform((ShrinkwrapModifierData *)md, ob, dm, vertexCos, numVerts, forRender);
+ shrinkwrapModifier_deform(eval_ctx, (ShrinkwrapModifierData *)md, ob, dm, vertexCos, numVerts, forRender);
if (dm != derivedData)
dm->release(dm);
}
-static void deformVertsEM(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx), Object *ob,
+static void deformVertsEM(ModifierData *md, const struct EvaluationContext *eval_ctx, Object *ob,
struct BMEditMesh *editData, DerivedMesh *derivedData,
float (*vertexCos)[3], int numVerts)
{
@@ -136,7 +136,7 @@ static void deformVertsEM(ModifierData *md, const struct EvaluationContext *UNUS
dm = get_cddm(ob, editData, dm, vertexCos, dependsOnNormals(md));
}
- shrinkwrapModifier_deform((ShrinkwrapModifierData *)md, ob, dm, vertexCos, numVerts, false);
+ shrinkwrapModifier_deform(eval_ctx, (ShrinkwrapModifierData *)md, ob, dm, vertexCos, numVerts, false);
if (dm != derivedData)
dm->release(dm);
diff --git a/source/blender/modifiers/intern/MOD_skin.c b/source/blender/modifiers/intern/MOD_skin.c
index 97afe6d5e87..d2d8da289b7 100644
--- a/source/blender/modifiers/intern/MOD_skin.c
+++ b/source/blender/modifiers/intern/MOD_skin.c
@@ -1470,7 +1470,7 @@ static void hull_merge_triangles(SkinOutput *so, const SkinModifierData *smd)
while (!BLI_heap_is_empty(heap)) {
BMFace *adj[2];
- e = BLI_heap_popmin(heap);
+ e = BLI_heap_pop_min(heap);
if (BM_edge_face_pair(e, &adj[0], &adj[1])) {
/* If both triangles still free, and if they don't already
diff --git a/source/blender/modifiers/intern/MOD_smoke.c b/source/blender/modifiers/intern/MOD_smoke.c
index e66afe07841..9881d7ee9b9 100644
--- a/source/blender/modifiers/intern/MOD_smoke.c
+++ b/source/blender/modifiers/intern/MOD_smoke.c
@@ -41,7 +41,7 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_smoke_types.h"
-#include "DNA_object_force.h"
+#include "DNA_object_force_types.h"
#include "BLI_utildefines.h"
diff --git a/source/blender/modifiers/intern/MOD_softbody.c b/source/blender/modifiers/intern/MOD_softbody.c
index 020dd3da6a5..d0b1d7361cc 100644
--- a/source/blender/modifiers/intern/MOD_softbody.c
+++ b/source/blender/modifiers/intern/MOD_softbody.c
@@ -35,7 +35,7 @@
#include <stdio.h>
#include "DNA_scene_types.h"
-#include "DNA_object_force.h"
+#include "DNA_object_force_types.h"
#include "BLI_utildefines.h"
diff --git a/source/blender/modifiers/intern/MOD_subsurf.c b/source/blender/modifiers/intern/MOD_subsurf.c
index a09923d6dfe..8fd510a6662 100644
--- a/source/blender/modifiers/intern/MOD_subsurf.c
+++ b/source/blender/modifiers/intern/MOD_subsurf.c
@@ -117,7 +117,7 @@ static DerivedMesh *applyModifier(ModifierData *md, const EvaluationContext *eva
subsurf_flags |= SUBSURF_USE_RENDER_PARAMS;
if (isFinalCalc)
subsurf_flags |= SUBSURF_IS_FINAL_CALC;
- if (ob->mode & OB_MODE_EDIT)
+ if (eval_ctx->object_mode & OB_MODE_EDIT)
subsurf_flags |= SUBSURF_IN_EDIT_MODE;
#ifdef WITH_OPENSUBDIV
@@ -132,7 +132,7 @@ static DerivedMesh *applyModifier(ModifierData *md, const EvaluationContext *eva
if (U.opensubdiv_compute_type == USER_OPENSUBDIV_COMPUTE_NONE) {
modifier_setError(md, "OpenSubdiv is disabled in User Preferences");
}
- else if ((ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) != 0) {
+ else if ((eval_ctx->object_mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) != 0) {
modifier_setError(md, "OpenSubdiv is not supported in paint modes");
}
else if ((DEG_get_eval_flags_for_id(eval_ctx->depsgraph, &ob->id) & DAG_EVAL_NEED_CPU) == 0) {
@@ -143,6 +143,8 @@ static DerivedMesh *applyModifier(ModifierData *md, const EvaluationContext *eva
modifier_setError(md, "OpenSubdiv is disabled due to dependencies");
}
}
+#else
+ UNUSED_VARS(ob);
#endif
result = subsurf_make_derived_from_derived(derivedData, smd, NULL, subsurf_flags);
diff --git a/source/blender/modifiers/intern/MOD_surfacedeform.c b/source/blender/modifiers/intern/MOD_surfacedeform.c
index 046a0ab27bf..85347288872 100644
--- a/source/blender/modifiers/intern/MOD_surfacedeform.c
+++ b/source/blender/modifiers/intern/MOD_surfacedeform.c
@@ -11,6 +11,8 @@
#include "BKE_library_query.h"
#include "BKE_modifier.h"
+#include "DEG_depsgraph.h"
+
#include "MEM_guardedalloc.h"
#include "MOD_util.h"
@@ -1097,7 +1099,9 @@ static void deformVert(
}
}
-static void surfacedeformModifier_do(ModifierData *md, float (*vertexCos)[3], unsigned int numverts, Object *ob)
+static void surfacedeformModifier_do(
+ ModifierData *md, const EvaluationContext *eval_ctx,
+ float (*vertexCos)[3], unsigned int numverts, Object *ob)
{
SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
DerivedMesh *tdm;
@@ -1110,7 +1114,7 @@ static void surfacedeformModifier_do(ModifierData *md, float (*vertexCos)[3], un
}
/* Handle target mesh both in and out of edit mode */
- if (smd->target == md->scene->obedit) {
+ if (smd->target == OBEDIT_FROM_EVAL_CTX(eval_ctx)) {
BMEditMesh *em = BKE_editmesh_from_object(smd->target);
tdm = em->derivedFinal;
}
@@ -1180,20 +1184,22 @@ static void surfacedeformModifier_do(ModifierData *md, float (*vertexCos)[3], un
}
}
-static void deformVerts(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx),
- Object *ob, DerivedMesh *UNUSED(derivedData),
- float (*vertexCos)[3], int numVerts,
- ModifierApplyFlag UNUSED(flag))
+static void deformVerts(
+ ModifierData *md, const struct EvaluationContext *eval_ctx,
+ Object *ob, DerivedMesh *UNUSED(derivedData),
+ float (*vertexCos)[3], int numVerts,
+ ModifierApplyFlag UNUSED(flag))
{
- surfacedeformModifier_do(md, vertexCos, numVerts, ob);
+ surfacedeformModifier_do(md, eval_ctx, vertexCos, numVerts, ob);
}
-static void deformVertsEM(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx),
- Object *ob, struct BMEditMesh *UNUSED(editData),
- DerivedMesh *UNUSED(derivedData),
- float (*vertexCos)[3], int numVerts)
+static void deformVertsEM(
+ ModifierData *md, const struct EvaluationContext *eval_ctx,
+ Object *ob, struct BMEditMesh *UNUSED(editData),
+ DerivedMesh *UNUSED(derivedData),
+ float (*vertexCos)[3], int numVerts)
{
- surfacedeformModifier_do(md, vertexCos, numVerts, ob);
+ surfacedeformModifier_do(md, eval_ctx, vertexCos, numVerts, ob);
}
static bool isDisabled(ModifierData *md, int UNUSED(useRenderParams))
diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt
index c83daa185a8..230918776dc 100644
--- a/source/blender/nodes/CMakeLists.txt
+++ b/source/blender/nodes/CMakeLists.txt
@@ -32,6 +32,7 @@ set(INC
../blenkernel
../blenlib
../blentranslation
+ ../depsgraph
../gpu
../imbuf
../makesdna
@@ -195,6 +196,7 @@ set(SRC
shader/nodes/node_shader_tangent.c
shader/nodes/node_shader_bevel.c
shader/nodes/node_shader_displacement.c
+ shader/nodes/node_shader_vector_displacement.c
shader/nodes/node_shader_tex_brick.c
shader/nodes/node_shader_tex_checker.c
shader/nodes/node_shader_tex_coord.c
diff --git a/source/blender/nodes/NOD_shader.h b/source/blender/nodes/NOD_shader.h
index cbdfd8d3dbf..bb9f9881e33 100644
--- a/source/blender/nodes/NOD_shader.h
+++ b/source/blender/nodes/NOD_shader.h
@@ -80,6 +80,7 @@ void register_node_type_sh_tex_pointdensity(void);
void register_node_type_sh_attribute(void);
void register_node_type_sh_bevel(void);
void register_node_type_sh_displacement(void);
+void register_node_type_sh_vector_displacement(void);
void register_node_type_sh_geometry(void);
void register_node_type_sh_light_path(void);
void register_node_type_sh_light_falloff(void);
diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h
index e2c1fae1bde..394e141647e 100644
--- a/source/blender/nodes/NOD_static_types.h
+++ b/source/blender/nodes/NOD_static_types.h
@@ -128,7 +128,8 @@ DefNode( ShaderNode, SH_NODE_UVALONGSTROKE, def_sh_uvalongstroke, "UV
DefNode( ShaderNode, SH_NODE_SEPXYZ, 0, "SEPXYZ", SeparateXYZ, "Separate XYZ", "" )
DefNode( ShaderNode, SH_NODE_COMBXYZ, 0, "COMBXYZ", CombineXYZ, "Combine XYZ", "" )
DefNode( ShaderNode, SH_NODE_BEVEL, def_sh_bevel, "BEVEL", Bevel, "Bevel", "" )
-DefNode( ShaderNode, SH_NODE_DISPLACEMENT, 0, "DISPLACEMENT", Displacement, "Displacement", "" )
+DefNode( ShaderNode, SH_NODE_DISPLACEMENT, def_sh_displacement, "DISPLACEMENT", Displacement, "Displacement", "" )
+DefNode( ShaderNode, SH_NODE_VECTOR_DISPLACEMENT,def_sh_vector_displacement,"VECTOR_DISPLACEMENT",VectorDisplacement,"Vector Displacement","" )
DefNode( CompositorNode, CMP_NODE_VIEWER, def_cmp_viewer, "VIEWER", Viewer, "Viewer", "" )
DefNode( CompositorNode, CMP_NODE_RGB, 0, "RGB", RGB, "RGB", "" )
diff --git a/source/blender/nodes/shader/node_shader_tree.c b/source/blender/nodes/shader/node_shader_tree.c
index 2f65188841e..fd30df4293e 100644
--- a/source/blender/nodes/shader/node_shader_tree.c
+++ b/source/blender/nodes/shader/node_shader_tree.c
@@ -736,10 +736,10 @@ bool ntreeShaderExecTree(bNodeTree *ntree, ShadeInput *shi, ShadeResult *shr)
/* ensure execdata is only initialized once */
if (!exec) {
- BLI_lock_thread(LOCK_NODES);
+ BLI_thread_lock(LOCK_NODES);
if (!ntree->execdata)
ntree->execdata = ntreeShaderBeginExecTree(ntree);
- BLI_unlock_thread(LOCK_NODES);
+ BLI_thread_unlock(LOCK_NODES);
exec = ntree->execdata;
}
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 b0ca4128d19..1c291cb5b83 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c
@@ -61,6 +61,7 @@ static bNodeSocketTemplate sh_node_bsdf_principled_out[] = {
static void node_shader_init_principled(bNodeTree *UNUSED(ntree), bNode *node)
{
node->custom1 = SHD_GLOSSY_MULTI_GGX;
+ node->custom2 = SHD_SUBSURFACE_BURLEY;
}
static int node_shader_gpu_bsdf_principled(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
diff --git a/source/blender/nodes/shader/nodes/node_shader_displacement.c b/source/blender/nodes/shader/nodes/node_shader_displacement.c
index d5c191b3966..c26968e8d14 100644
--- a/source/blender/nodes/shader/nodes/node_shader_displacement.c
+++ b/source/blender/nodes/shader/nodes/node_shader_displacement.c
@@ -31,6 +31,7 @@
static bNodeSocketTemplate sh_node_displacement_in[] = {
{ SOCK_FLOAT, 0, N_("Height"), 0.00f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f},
+ { SOCK_FLOAT, 0, N_("Midlevel"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f},
{ SOCK_FLOAT, 0, N_("Scale"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f},
{ SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
{ -1, 0, "" }
@@ -41,13 +42,30 @@ static bNodeSocketTemplate sh_node_displacement_out[] = {
{ -1, 0, "" }
};
+static void node_shader_init_displacement(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ node->custom1 = SHD_SPACE_OBJECT; /* space */
+
+ /* Set default value here for backwards compatibility. */
+ for (bNodeSocket *sock = node->inputs.first; sock; sock = sock->next) {
+ if (STREQ(sock->name, "Midlevel")) {
+ ((bNodeSocketValueFloat *)sock->default_value)->value = 0.5f;
+ }
+ }
+}
+
static int gpu_shader_displacement(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
{
- if (!in[2].link) {
- GPU_link(mat, "direction_transform_m4v3", GPU_builtin(GPU_VIEW_NORMAL), GPU_builtin(GPU_INVERSE_VIEW_MATRIX), &in[2].link);
+ if (!in[3].link) {
+ GPU_link(mat, "direction_transform_m4v3", GPU_builtin(GPU_VIEW_NORMAL), GPU_builtin(GPU_INVERSE_VIEW_MATRIX), &in[3].link);
}
- return GPU_stack_link(mat, node, "node_displacement", in, out);
+ if (node->custom1 == SHD_SPACE_OBJECT) {
+ return GPU_stack_link(mat, node, "node_displacement_object", in, out, GPU_builtin(GPU_OBJECT_MATRIX));
+ }
+ else {
+ return GPU_stack_link(mat, node, "node_displacement_world", in, out, GPU_builtin(GPU_OBJECT_MATRIX));
+ }
}
/* node type definition */
@@ -59,6 +77,7 @@ void register_node_type_sh_displacement(void)
node_type_compatibility(&ntype, NODE_NEW_SHADING);
node_type_socket_templates(&ntype, sh_node_displacement_in, sh_node_displacement_out);
node_type_storage(&ntype, "", NULL, NULL);
+ node_type_init(&ntype, node_shader_init_displacement);
node_type_gpu(&ntype, gpu_shader_displacement);
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/shader/nodes/node_shader_hair_info.c b/source/blender/nodes/shader/nodes/node_shader_hair_info.c
index 63adba750cf..6a15c59aa5b 100644
--- a/source/blender/nodes/shader/nodes/node_shader_hair_info.c
+++ b/source/blender/nodes/shader/nodes/node_shader_hair_info.c
@@ -33,6 +33,7 @@ static bNodeSocketTemplate outputs[] = {
{ SOCK_FLOAT, 0, N_("Thickness"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
{ SOCK_VECTOR, 0, N_("Tangent Normal"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
/*{ SOCK_FLOAT, 0, N_("Fade"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},*/
+ { SOCK_FLOAT, 0, N_("Random") },
{ -1, 0, "" }
};
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 36d7522e3e6..7584b5eba4d 100644
--- a/source/blender/nodes/shader/nodes/node_shader_normal_map.c
+++ b/source/blender/nodes/shader/nodes/node_shader_normal_map.c
@@ -68,7 +68,7 @@ static void node_shader_exec_normal_map(
float *N = shi->nmapnorm;
int uv_index = 0;
switch (nm->space) {
- case SHD_NORMAL_MAP_TANGENT:
+ case SHD_SPACE_TANGENT:
if (nm->uv_map[0]) {
/* find uv map by name */
for (int i = 0; i < shi->totuv; i++) {
@@ -96,8 +96,8 @@ static void node_shader_exec_normal_map(
}
break;
- case SHD_NORMAL_MAP_OBJECT:
- case SHD_NORMAL_MAP_BLENDER_OBJECT:
+ case SHD_SPACE_OBJECT:
+ case SHD_SPACE_BLENDER_OBJECT:
if (shi->use_world_space_shading) {
mul_mat3_m4_v3((float (*)[4])RE_object_instance_get_matrix(shi->obi, RE_OBJECT_INSTANCE_MATRIX_OB), vecIn);
mul_mat3_m4_v3((float (*)[4])RE_render_current_get_matrix(RE_VIEWINV_MATRIX), N);
@@ -107,8 +107,8 @@ static void node_shader_exec_normal_map(
interp_v3_v3v3(out[0]->vec, N, vecIn, strength);
break;
- case SHD_NORMAL_MAP_WORLD:
- case SHD_NORMAL_MAP_BLENDER_WORLD:
+ case SHD_SPACE_WORLD:
+ case SHD_SPACE_BLENDER_WORLD:
if (shi->use_world_space_shading)
mul_mat3_m4_v3((float (*)[4])RE_render_current_get_matrix(RE_VIEWINV_MATRIX), N);
else
@@ -150,10 +150,10 @@ static int gpu_shader_normal_map(GPUMaterial *mat, bNode *node, bNodeExecData *U
/* ******* CYCLES or BLENDER INTERNAL with world space shading flag ******* */
const char *color_to_normal_fnc_name = "color_to_normal_new_shading";
- if (nm->space == SHD_NORMAL_MAP_BLENDER_OBJECT || nm->space == SHD_NORMAL_MAP_BLENDER_WORLD || !GPU_material_use_new_shading_nodes(mat))
+ if (nm->space == SHD_SPACE_BLENDER_OBJECT || nm->space == SHD_SPACE_BLENDER_WORLD || !GPU_material_use_new_shading_nodes(mat))
color_to_normal_fnc_name = "color_to_blender_normal_new_shading";
switch (nm->space) {
- case SHD_NORMAL_MAP_TANGENT:
+ case SHD_SPACE_TANGENT:
GPU_link(mat, "color_to_normal_new_shading", realnorm, &realnorm);
GPU_link(mat, "node_normal_map", GPU_attribute(CD_TANGENT, nm->uv_map), negnorm, realnorm, &realnorm);
GPU_link(mat, "vec_math_mix", strength, realnorm, GPU_builtin(GPU_VIEW_NORMAL), &out[0].link);
@@ -161,14 +161,14 @@ static int gpu_shader_normal_map(GPUMaterial *mat, bNode *node, bNodeExecData *U
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;
- case SHD_NORMAL_MAP_OBJECT:
- case SHD_NORMAL_MAP_BLENDER_OBJECT:
+ 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_NORMAL_MAP_WORLD:
- case SHD_NORMAL_MAP_BLENDER_WORLD:
+ 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);
break;
@@ -184,15 +184,15 @@ static int gpu_shader_normal_map(GPUMaterial *mat, bNode *node, bNodeExecData *U
GPU_link(mat, "vec_math_negate", negnorm, &negnorm);
switch (nm->space) {
- case SHD_NORMAL_MAP_TANGENT:
+ case SHD_SPACE_TANGENT:
GPU_link(mat, "node_normal_map", GPU_attribute(CD_TANGENT, nm->uv_map), negnorm, realnorm, &realnorm);
break;
- case SHD_NORMAL_MAP_OBJECT:
- case SHD_NORMAL_MAP_BLENDER_OBJECT:
+ case SHD_SPACE_OBJECT:
+ case SHD_SPACE_BLENDER_OBJECT:
GPU_link(mat, "direction_transform_m4v3", realnorm, GPU_builtin(GPU_LOC_TO_VIEW_MATRIX), &realnorm);
break;
- case SHD_NORMAL_MAP_WORLD:
- case SHD_NORMAL_MAP_BLENDER_WORLD:
+ case SHD_SPACE_WORLD:
+ case SHD_SPACE_BLENDER_WORLD:
GPU_link(mat, "direction_transform_m4v3", realnorm, GPU_builtin(GPU_VIEW_MATRIX), &realnorm);
break;
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_particle_info.c b/source/blender/nodes/shader/nodes/node_shader_particle_info.c
index 8bdc88292e7..69fcbba8f88 100644
--- a/source/blender/nodes/shader/nodes/node_shader_particle_info.c
+++ b/source/blender/nodes/shader/nodes/node_shader_particle_info.c
@@ -30,6 +30,7 @@
static bNodeSocketTemplate outputs[] = {
{ SOCK_FLOAT, 0, "Index" },
+ { SOCK_FLOAT, 0, "Random" },
{ SOCK_FLOAT, 0, "Age" },
{ SOCK_FLOAT, 0, "Lifetime" },
{ SOCK_VECTOR, 0, "Location" },
@@ -45,7 +46,7 @@ static void node_shader_exec_particle_info(void *data, int UNUSED(thread), bNode
{
ShadeInput *shi = ((ShaderCallData *)data)->shi;
- RE_instance_get_particle_info(shi->obi, out[0]->vec, out[1]->vec, out[2]->vec, out[3]->vec, out[4]->vec, out[5]->vec, out[6]->vec);
+ RE_instance_get_particle_info(shi->obi, out[0]->vec, out[1]->vec, out[2]->vec, out[3]->vec, out[4]->vec, out[5]->vec, out[6]->vec, out[7]->vec);
}
static int gpu_shader_particle_info(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
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 4d98b142f37..8a65ee89ffc 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
@@ -102,6 +102,7 @@ void register_node_type_sh_tex_environment(void)
node_type_init(&ntype, node_shader_init_tex_environment);
node_type_storage(&ntype, "NodeTexEnvironment", node_free_standard_storage, node_copy_standard_storage);
node_type_gpu(&ntype, node_shader_gpu_tex_environment);
+ node_type_label(&ntype, node_image_label);
nodeRegisterType(&ntype);
}
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 c86a502b666..22f302a9c59 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_image.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_image.c
@@ -126,6 +126,7 @@ void register_node_type_sh_tex_image(void)
node_type_init(&ntype, node_shader_init_tex_image);
node_type_storage(&ntype, "NodeTexImage", node_free_standard_storage, node_copy_standard_storage);
node_type_gpu(&ntype, node_shader_gpu_tex_image);
+ node_type_label(&ntype, node_image_label);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_vector_displacement.c b/source/blender/nodes/shader/nodes/node_shader_vector_displacement.c
new file mode 100644
index 00000000000..79b41509fcc
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_vector_displacement.c
@@ -0,0 +1,83 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "../node_shader_util.h"
+
+/* **************** OUTPUT ******************** */
+
+static bNodeSocketTemplate sh_node_vector_displacement_in[] = {
+ { SOCK_RGBA, 0, N_("Vector"), 0.00f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f, PROP_NONE, SOCK_HIDE_VALUE},
+ { SOCK_FLOAT, 0, N_("Midlevel"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f},
+ { SOCK_FLOAT, 0, N_("Scale"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f},
+ { -1, 0, "" }
+};
+
+static bNodeSocketTemplate sh_node_vector_displacement_out[] = {
+ { SOCK_VECTOR, 0, N_("Displacement"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { -1, 0, "" }
+};
+
+static void node_shader_init_vector_displacement(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ node->custom1 = SHD_SPACE_TANGENT; /* space */
+}
+
+static int gpu_shader_vector_displacement(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
+{
+ if (node->custom1 == SHD_SPACE_TANGENT) {
+ return GPU_stack_link(mat,
+ node,
+ "node_vector_displacement_tangent",
+ in,
+ out,
+ GPU_attribute(CD_TANGENT, ""),
+ GPU_builtin(GPU_VIEW_NORMAL),
+ GPU_builtin(GPU_OBJECT_MATRIX),
+ GPU_builtin(GPU_VIEW_MATRIX));
+ }
+ else if (node->custom1 == SHD_SPACE_OBJECT) {
+ return GPU_stack_link(mat, node, "node_vector_displacement_object", in, out, GPU_builtin(GPU_OBJECT_MATRIX));
+ }
+ else {
+ return GPU_stack_link(mat, node, "node_vector_displacement_world", in, out);
+ }
+}
+
+/* node type definition */
+void register_node_type_sh_vector_displacement(void)
+{
+ static bNodeType ntype;
+
+ sh_node_type_base(&ntype, SH_NODE_VECTOR_DISPLACEMENT, "Vector Displacement", NODE_CLASS_OP_VECTOR, 0);
+ node_type_compatibility(&ntype, NODE_NEW_SHADING);
+ node_type_socket_templates(&ntype, sh_node_vector_displacement_in, sh_node_vector_displacement_out);
+ node_type_storage(&ntype, "", NULL, NULL);
+ node_type_init(&ntype, node_shader_init_vector_displacement);
+ node_type_gpu(&ntype, gpu_shader_vector_displacement);
+
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/texture/node_texture_tree.c b/source/blender/nodes/texture/node_texture_tree.c
index dcae9d2345f..fab28bacff8 100644
--- a/source/blender/nodes/texture/node_texture_tree.c
+++ b/source/blender/nodes/texture/node_texture_tree.c
@@ -35,6 +35,7 @@
#include "DNA_texture_types.h"
#include "DNA_node_types.h"
#include "DNA_space_types.h"
+#include "DNA_workspace_types.h"
#include "BLI_listbase.h"
#include "BLI_threads.h"
@@ -53,13 +54,16 @@
#include "NOD_texture.h"
#include "node_texture_util.h"
+#include "DEG_depsgraph.h"
+
#include "RNA_access.h"
#include "RE_shader_ext.h"
-
-static void texture_get_from_context(const bContext *C, bNodeTreeType *UNUSED(treetype), bNodeTree **r_ntree, ID **r_id, ID **r_from)
+static void texture_get_from_context(
+ const bContext *C, bNodeTreeType *UNUSED(treetype), bNodeTree **r_ntree, ID **r_id, ID **r_from)
{
+ const WorkSpace *workspace = CTX_wm_workspace(C);
SpaceNode *snode = CTX_wm_space_node(C);
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
@@ -94,7 +98,7 @@ static void texture_get_from_context(const bContext *C, bNodeTreeType *UNUSED(tr
else if (snode->texfrom == SNODE_TEX_BRUSH) {
struct Brush *brush = NULL;
- if (ob && (ob->mode & OB_MODE_SCULPT))
+ if (ob && (workspace->object_mode & OB_MODE_SCULPT))
brush = BKE_paint_brush(&scene->toolsettings->sculpt->paint);
else
brush = BKE_paint_brush(&scene->toolsettings->imapaint.paint);
@@ -346,10 +350,10 @@ int ntreeTexExecTree(
/* ensure execdata is only initialized once */
if (!exec) {
- BLI_lock_thread(LOCK_NODES);
+ BLI_thread_lock(LOCK_NODES);
if (!nodes->execdata)
ntreeTexBeginExecTree(nodes);
- BLI_unlock_thread(LOCK_NODES);
+ BLI_thread_unlock(LOCK_NODES);
exec = nodes->execdata;
}
diff --git a/source/blender/nodes/texture/nodes/node_texture_image.c b/source/blender/nodes/texture/nodes/node_texture_image.c
index 8e9821c0fcb..69c8f4b7262 100644
--- a/source/blender/nodes/texture/nodes/node_texture_image.c
+++ b/source/blender/nodes/texture/nodes/node_texture_image.c
@@ -64,10 +64,10 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **UNUSED(i
if ( (!xsize) || (!ysize) ) return;
if (!ibuf->rect_float) {
- BLI_lock_thread(LOCK_IMAGE);
+ BLI_thread_lock(LOCK_IMAGE);
if (!ibuf->rect_float)
IMB_float_from_rect(ibuf);
- BLI_unlock_thread(LOCK_IMAGE);
+ BLI_thread_unlock(LOCK_IMAGE);
}
while (px < 0) px += ibuf->x;
diff --git a/source/blender/physics/intern/BPH_mass_spring.cpp b/source/blender/physics/intern/BPH_mass_spring.cpp
index b694b6e994d..5b5639495da 100644
--- a/source/blender/physics/intern/BPH_mass_spring.cpp
+++ b/source/blender/physics/intern/BPH_mass_spring.cpp
@@ -34,7 +34,7 @@ extern "C" {
#include "DNA_cloth_types.h"
#include "DNA_scene_types.h"
-#include "DNA_object_force.h"
+#include "DNA_object_force_types.h"
#include "DNA_object_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
diff --git a/source/blender/physics/intern/implicit_blender.c b/source/blender/physics/intern/implicit_blender.c
index 16cd335dc0c..d676b1a1521 100644
--- a/source/blender/physics/intern/implicit_blender.c
+++ b/source/blender/physics/intern/implicit_blender.c
@@ -37,7 +37,7 @@
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
-#include "DNA_object_force.h"
+#include "DNA_object_force_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_texture_types.h"
diff --git a/source/blender/physics/intern/implicit_eigen.cpp b/source/blender/physics/intern/implicit_eigen.cpp
index afe1b441632..c36fabcffb0 100644
--- a/source/blender/physics/intern/implicit_eigen.cpp
+++ b/source/blender/physics/intern/implicit_eigen.cpp
@@ -73,7 +73,7 @@
extern "C" {
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
-#include "DNA_object_force.h"
+#include "DNA_object_force_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_texture_types.h"
diff --git a/source/blender/python/bmesh/bmesh_py_ops_call.c b/source/blender/python/bmesh/bmesh_py_ops_call.c
index 6598d402f72..4dce0dc2a22 100644
--- a/source/blender/python/bmesh/bmesh_py_ops_call.c
+++ b/source/blender/python/bmesh/bmesh_py_ops_call.c
@@ -566,7 +566,7 @@ static PyObject *bpy_slot_to_py(BMesh *bm, BMOpSlot *slot)
switch (slot->slot_subtype.map) {
case BMO_OP_SLOT_SUBTYPE_MAP_ELEM:
{
- item = _PyDict_NewPresized(slot_hash ? BLI_ghash_size(slot_hash) : 0);
+ item = _PyDict_NewPresized(slot_hash ? BLI_ghash_len(slot_hash) : 0);
if (slot_hash) {
GHASH_ITER (hash_iter, slot_hash) {
BMHeader *ele_key = BLI_ghashIterator_getKey(&hash_iter);
@@ -584,7 +584,7 @@ static PyObject *bpy_slot_to_py(BMesh *bm, BMOpSlot *slot)
}
case BMO_OP_SLOT_SUBTYPE_MAP_FLT:
{
- item = _PyDict_NewPresized(slot_hash ? BLI_ghash_size(slot_hash) : 0);
+ item = _PyDict_NewPresized(slot_hash ? BLI_ghash_len(slot_hash) : 0);
if (slot_hash) {
GHASH_ITER (hash_iter, slot_hash) {
BMHeader *ele_key = BLI_ghashIterator_getKey(&hash_iter);
@@ -602,7 +602,7 @@ static PyObject *bpy_slot_to_py(BMesh *bm, BMOpSlot *slot)
}
case BMO_OP_SLOT_SUBTYPE_MAP_INT:
{
- item = _PyDict_NewPresized(slot_hash ? BLI_ghash_size(slot_hash) : 0);
+ item = _PyDict_NewPresized(slot_hash ? BLI_ghash_len(slot_hash) : 0);
if (slot_hash) {
GHASH_ITER (hash_iter, slot_hash) {
BMHeader *ele_key = BLI_ghashIterator_getKey(&hash_iter);
@@ -620,7 +620,7 @@ static PyObject *bpy_slot_to_py(BMesh *bm, BMOpSlot *slot)
}
case BMO_OP_SLOT_SUBTYPE_MAP_BOOL:
{
- item = _PyDict_NewPresized(slot_hash ? BLI_ghash_size(slot_hash) : 0);
+ item = _PyDict_NewPresized(slot_hash ? BLI_ghash_len(slot_hash) : 0);
if (slot_hash) {
GHASH_ITER (hash_iter, slot_hash) {
BMHeader *ele_key = BLI_ghashIterator_getKey(&hash_iter);
diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c
index 629c3a3c7a3..ec787768a57 100644
--- a/source/blender/python/bmesh/bmesh_py_types.c
+++ b/source/blender/python/bmesh/bmesh_py_types.c
@@ -902,7 +902,11 @@ static PyObject *bpy_bmesh_to_mesh(BPy_BMesh *self, PyObject *args)
bm = self->bm;
- BM_mesh_bm_to_me(bm, me, (&(struct BMeshToMeshParams){0}));
+ BM_mesh_bm_to_me(
+ bm, me,
+ (&(struct BMeshToMeshParams){
+ .calc_object_remap = true,
+ }));
/* we could have the user do this but if they forget blender can easy crash
* since the references arrays for the objects derived meshes are now invalid */
diff --git a/source/blender/python/intern/CMakeLists.txt b/source/blender/python/intern/CMakeLists.txt
index 41018468695..a71478cdb15 100644
--- a/source/blender/python/intern/CMakeLists.txt
+++ b/source/blender/python/intern/CMakeLists.txt
@@ -248,10 +248,6 @@ if(WITH_LIBMV)
add_definitions(-DWITH_LIBMV)
endif()
-if(WITH_MOD_BOOLEAN)
- add_definitions(-DWITH_MOD_BOOLEAN)
-endif()
-
if(WITH_MOD_FLUID)
add_definitions(-DWITH_MOD_FLUID)
endif()
diff --git a/source/blender/python/intern/bpy_app_build_options.c b/source/blender/python/intern/bpy_app_build_options.c
index 501e09dd6ad..d5c325e4317 100644
--- a/source/blender/python/intern/bpy_app_build_options.c
+++ b/source/blender/python/intern/bpy_app_build_options.c
@@ -58,7 +58,6 @@ static PyStructSequence_Field app_builtopts_info_fields[] = {
{(char *)"sdl_dynload", NULL},
{(char *)"jack", NULL},
{(char *)"libmv", NULL},
- {(char *)"mod_boolean", NULL},
{(char *)"mod_fluid", NULL},
{(char *)"mod_oceansim", NULL},
{(char *)"mod_remesh", NULL},
@@ -237,12 +236,6 @@ static PyObject *make_builtopts_info(void)
SetObjIncref(Py_False);
#endif
-#ifdef WITH_MOD_BOOLEAN
- SetObjIncref(Py_True);
-#else
- SetObjIncref(Py_False);
-#endif
-
#ifdef WITH_MOD_FLUID
SetObjIncref(Py_True);
#else
diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c
index 5b84a7cf73c..0cadbc30a9f 100644
--- a/source/blender/python/intern/bpy_operator.c
+++ b/source/blender/python/intern/bpy_operator.c
@@ -384,7 +384,7 @@ static PyObject *pyop_dir(PyObject *UNUSED(self))
int i;
WM_operatortype_iter(&iter);
- list = PyList_New(BLI_ghash_size(iter.gh));
+ list = PyList_New(BLI_ghash_len(iter.gh));
for (i = 0; !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter), i++) {
wmOperatorType *ot = BLI_ghashIterator_getValue(&iter);
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index e220e6559a6..4ce9ba59a0b 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -223,7 +223,7 @@ static PyObject *id_free_weakref_cb(PyObject *weakinfo_capsule, PyObject *weakre
GHash *weakinfo_hash = PyCapsule_GetPointer(weakinfo_capsule, NULL);
- if (BLI_ghash_size(weakinfo_hash) > 1) {
+ if (BLI_ghash_len(weakinfo_hash) > 1) {
BLI_ghash_remove(weakinfo_hash, weakref, NULL, NULL);
}
else { /* get the last id and free it */
@@ -243,7 +243,7 @@ static void id_release_weakref_list(struct ID *id, GHash *weakinfo_hash)
BLI_ghashIterator_init(&weakinfo_hash_iter, weakinfo_hash);
#ifdef DEBUG_RNA_WEAKREF
- fprintf(stdout, "id_release_weakref: '%s', %d items\n", id->name, BLI_ghash_size(weakinfo_hash));
+ fprintf(stdout, "id_release_weakref: '%s', %d items\n", id->name, BLI_ghash_len(weakinfo_hash));
#endif
while (!BLI_ghashIterator_done(&weakinfo_hash_iter)) {
@@ -266,7 +266,7 @@ static void id_release_weakref_list(struct ID *id, GHash *weakinfo_hash)
BLI_ghash_remove(id_weakref_pool, (void *)id, NULL, NULL);
BLI_ghash_free(weakinfo_hash, NULL, NULL);
- if (BLI_ghash_size(id_weakref_pool) == 0) {
+ if (BLI_ghash_len(id_weakref_pool) == 0) {
BLI_ghash_free(id_weakref_pool, NULL, NULL);
id_weakref_pool = NULL;
#ifdef DEBUG_RNA_WEAKREF
diff --git a/source/blender/python/intern/gpu_offscreen.c b/source/blender/python/intern/gpu_offscreen.c
index 91d407d18a8..2da0227cdca 100644
--- a/source/blender/python/intern/gpu_offscreen.c
+++ b/source/blender/python/intern/gpu_offscreen.c
@@ -39,6 +39,7 @@
#include "GPU_compositing.h"
#include "GPU_framebuffer.h"
+#include "GPU_texture.h"
#include "../mathutils/mathutils.h"
@@ -89,7 +90,8 @@ PyDoc_STRVAR(pygpu_offscreen_color_texture_doc, "Color texture.\n\n:type: int");
static PyObject *pygpu_offscreen_color_texture_get(BPy_GPUOffScreen *self, void *UNUSED(type))
{
BPY_GPU_OFFSCREEN_CHECK_OBJ(self);
- return PyLong_FromLong(GPU_offscreen_color_texture(self->ofs));
+ GPUTexture *texture = GPU_offscreen_color_texture(self->ofs);
+ return PyLong_FromLong(GPU_texture_opengl_bindcode(texture));
}
PyDoc_STRVAR(pygpu_offscreen_bind_doc,
@@ -354,7 +356,7 @@ static PyObject *pygpu_offscreen_new(PyObject *UNUSED(self), PyObject *args, PyO
return NULL;
}
- ofs = GPU_offscreen_create(width, height, samples, false, err_out);
+ ofs = GPU_offscreen_create(width, height, samples, true, false, err_out);
if (ofs == NULL) {
PyErr_Format(PyExc_RuntimeError,
diff --git a/source/blender/python/mathutils/mathutils_bvhtree.c b/source/blender/python/mathutils/mathutils_bvhtree.c
index ba0b6eb11a5..88195700a50 100644
--- a/source/blender/python/mathutils/mathutils_bvhtree.c
+++ b/source/blender/python/mathutils/mathutils_bvhtree.c
@@ -33,7 +33,7 @@
#include "BLI_utildefines.h"
#include "BLI_kdopbvh.h"
-#include "BLI_polyfill2d.h"
+#include "BLI_polyfill_2d.h"
#include "BLI_math.h"
#include "BLI_ghash.h"
#include "BLI_memarena.h"
diff --git a/source/blender/python/mathutils/mathutils_geometry.c b/source/blender/python/mathutils/mathutils_geometry.c
index 72f92d210d7..fa0d271f7d3 100644
--- a/source/blender/python/mathutils/mathutils_geometry.c
+++ b/source/blender/python/mathutils/mathutils_geometry.c
@@ -34,8 +34,8 @@
#ifndef MATH_STANDALONE /* define when building outside blender */
# include "MEM_guardedalloc.h"
# include "BLI_blenlib.h"
-# include "BLI_boxpack2d.h"
-# include "BLI_convexhull2d.h"
+# include "BLI_boxpack_2d.h"
+# include "BLI_convexhull_2d.h"
# include "BKE_displist.h"
# include "BKE_curve.h"
#endif
diff --git a/source/blender/render/extern/include/RE_shader_ext.h b/source/blender/render/extern/include/RE_shader_ext.h
index 0b392c122db..281f0082d7f 100644
--- a/source/blender/render/extern/include/RE_shader_ext.h
+++ b/source/blender/render/extern/include/RE_shader_ext.h
@@ -215,7 +215,7 @@ int multitex_nodes(struct Tex *tex, float texvec[3], float dxt[3], float dyt[3],
const short thread, short which_output, struct ShadeInput *shi, struct MTex *mtex,
struct ImagePool *pool);
float RE_lamp_get_data(struct ShadeInput *shi, struct Object *lamp_obj, float col[4], float lv[3], float *dist, float shadow[4]);
-void RE_instance_get_particle_info(struct ObjectInstanceRen *obi, float *index, float *age, float *lifetime, float co[3], float *size, float vel[3], float angvel[3]);
+void RE_instance_get_particle_info(struct ObjectInstanceRen *obi, float *index, float *random, float *age, float *lifetime, float co[3], float *size, float vel[3], float angvel[3]);
float RE_fresnel_dielectric(float incoming[3], float normal[3], float eta);
diff --git a/source/blender/render/intern/source/bake.c b/source/blender/render/intern/source/bake.c
index 71a595d6a8b..48f5f494e58 100644
--- a/source/blender/render/intern/source/bake.c
+++ b/source/blender/render/intern/source/bake.c
@@ -609,7 +609,7 @@ static int get_next_bake_face(BakeShade *bs)
return 0;
}
- BLI_lock_thread(LOCK_CUSTOM1);
+ BLI_thread_lock(LOCK_CUSTOM1);
for (; obi; obi = obi->next, v = 0) {
obr = obi->obr;
@@ -725,13 +725,13 @@ static int get_next_bake_face(BakeShade *bs)
bs->vlr = vlr;
bs->vdone++; /* only for error message if nothing was rendered */
v++;
- BLI_unlock_thread(LOCK_CUSTOM1);
+ BLI_thread_unlock(LOCK_CUSTOM1);
return 1;
}
}
}
- BLI_unlock_thread(LOCK_CUSTOM1);
+ BLI_thread_unlock(LOCK_CUSTOM1);
return 0;
}
@@ -846,7 +846,7 @@ static void shade_tface(BakeShade *bs)
if (bs->use_mask || bs->use_displacement_buffer) {
BakeImBufuserData *userdata = bs->ibuf->userdata;
if (userdata == NULL) {
- BLI_lock_thread(LOCK_CUSTOM1);
+ BLI_thread_lock(LOCK_CUSTOM1);
userdata = bs->ibuf->userdata;
if (userdata == NULL) /* since the thread was locked, its possible another thread alloced the value */
userdata = MEM_callocN(sizeof(BakeImBufuserData), "BakeImBufuserData");
@@ -865,7 +865,7 @@ static void shade_tface(BakeShade *bs)
bs->ibuf->userdata = userdata;
- BLI_unlock_thread(LOCK_CUSTOM1);
+ BLI_thread_unlock(LOCK_CUSTOM1);
}
bs->rect_mask = userdata->mask_buffer;
@@ -1041,7 +1041,7 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up
BKE_main_id_tag_listbase(&G.main->mesh, LIB_TAG_DOIT, false);
}
- BLI_init_threads(&threads, do_bake_thread, re->r.threads);
+ BLI_threadpool_init(&threads, do_bake_thread, re->r.threads);
handles = MEM_callocN(sizeof(BakeShade) * re->r.threads, "BakeShade");
@@ -1078,7 +1078,7 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up
handles[a].displacement_min = FLT_MAX;
handles[a].displacement_max = -FLT_MAX;
- BLI_insert_thread(&threads, &handles[a]);
+ BLI_threadpool_insert(&threads, &handles[a]);
}
/* wait for everything to be done */
@@ -1152,7 +1152,7 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up
MEM_freeN(handles);
- BLI_end_threads(&threads);
+ BLI_threadpool_end(&threads);
if (vdone == 0) {
result = BAKE_RESULT_NO_OBJECTS;
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index 19a87784ad4..503748236f6 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -56,7 +56,7 @@
#include "DNA_modifier_types.h"
#include "DNA_node_types.h"
#include "DNA_object_types.h"
-#include "DNA_object_fluidsim.h"
+#include "DNA_object_fluidsim_types.h"
#include "DNA_particle_types.h"
#include "DNA_scene_types.h"
#include "DNA_texture_types.h"
@@ -1293,6 +1293,7 @@ static void get_particle_uvco_mcol(short from, DerivedMesh *dm, float *fuv, int
}
static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem *psys, int timeoffset)
{
+ const EvaluationContext *eval_ctx = RE_GetEvalCtx(re);
Object *ob= obr->ob;
// Object *tob=0;
Material *ma = NULL;
@@ -1339,7 +1340,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
if (part->ren_as==PART_DRAW_OB || part->ren_as==PART_DRAW_GR || part->ren_as==PART_DRAW_NOT)
return 1;
- if ((re->r.scemode & R_VIEWPORT_PREVIEW) && (ob->mode & OB_MODE_PARTICLE_EDIT))
+ if ((re->r.scemode & R_VIEWPORT_PREVIEW) && (eval_ctx->object_mode & OB_MODE_PARTICLE_EDIT))
return 0;
if (part->ren_as == PART_DRAW_BB && part->bb_ob == NULL && RE_GetCamera(re) == NULL)
diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c
index 2a7aab58980..f666bbd2b95 100644
--- a/source/blender/render/intern/source/envmap.c
+++ b/source/blender/render/intern/source/envmap.c
@@ -71,7 +71,7 @@ static void envmap_split_ima(EnvMap *env, ImBuf *ibuf)
int dx, part;
/* after lock we test cube[1], if set the other thread has done it fine */
- BLI_lock_thread(LOCK_IMAGE);
+ BLI_thread_lock(LOCK_IMAGE);
if (env->cube[1] == NULL) {
BKE_texture_envmap_free_data(env);
@@ -119,7 +119,7 @@ static void envmap_split_ima(EnvMap *env, ImBuf *ibuf)
}
}
}
- BLI_unlock_thread(LOCK_IMAGE);
+ BLI_thread_unlock(LOCK_IMAGE);
}
/* ------------------------------------------------------------------------- */
diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c
index 2714e8b7685..ddf128c0fbc 100644
--- a/source/blender/render/intern/source/external_engine.c
+++ b/source/blender/render/intern/source/external_engine.c
@@ -177,7 +177,7 @@ RenderEngine *RE_engine_create_ex(RenderEngineType *type, bool use_for_viewport)
if (use_for_viewport) {
engine->flag |= RE_ENGINE_USED_FOR_VIEWPORT;
- BLI_begin_threaded_malloc();
+ BLI_threaded_malloc_begin();
}
return engine;
@@ -192,7 +192,7 @@ void RE_engine_free(RenderEngine *engine)
#endif
if (engine->flag & RE_ENGINE_USED_FOR_VIEWPORT) {
- BLI_end_threaded_malloc();
+ BLI_threaded_malloc_end();
}
MEM_freeN(engine);
diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c
index ae02cf56b88..6e5d10fcc84 100644
--- a/source/blender/render/intern/source/imagetexture.c
+++ b/source/blender/render/intern/source/imagetexture.c
@@ -890,18 +890,18 @@ static void image_mipmap_test(Tex *tex, ImBuf *ibuf)
if ((ibuf->flags & IB_fields) == 0) {
if (ibuf->mipmap[0] && (ibuf->userflags & IB_MIPMAP_INVALID)) {
- BLI_lock_thread(LOCK_IMAGE);
+ BLI_thread_lock(LOCK_IMAGE);
if (ibuf->userflags & IB_MIPMAP_INVALID) {
IMB_remakemipmap(ibuf, tex->imaflag & TEX_GAUSS_MIP);
ibuf->userflags &= ~IB_MIPMAP_INVALID;
}
- BLI_unlock_thread(LOCK_IMAGE);
+ BLI_thread_unlock(LOCK_IMAGE);
}
if (ibuf->mipmap[0] == NULL) {
- BLI_lock_thread(LOCK_IMAGE);
+ BLI_thread_lock(LOCK_IMAGE);
if (ibuf->mipmap[0] == NULL)
IMB_makemipmap(ibuf, tex->imaflag & TEX_GAUSS_MIP);
- BLI_unlock_thread(LOCK_IMAGE);
+ BLI_thread_unlock(LOCK_IMAGE);
}
/* if no mipmap could be made, fall back on non-mipmap render */
if (ibuf->mipmap[0] == NULL) {
diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c
index 731a5ec4e22..9182d545089 100644
--- a/source/blender/render/intern/source/initrender.c
+++ b/source/blender/render/intern/source/initrender.c
@@ -38,7 +38,7 @@
#include "BLI_math.h"
#include "BLI_blenlib.h"
-#include "BLI_jitter.h"
+#include "BLI_jitter_2d.h"
#include "BLI_utildefines.h"
#include "DNA_camera_types.h"
diff --git a/source/blender/render/intern/source/multires_bake.c b/source/blender/render/intern/source/multires_bake.c
index 4c0355ef604..ddab8b23b59 100644
--- a/source/blender/render/intern/source/multires_bake.c
+++ b/source/blender/render/intern/source/multires_bake.c
@@ -470,7 +470,7 @@ static void do_multires_bake(MultiresBakeRender *bkr, Image *ima, bool require_t
bake_data = initBakeData(bkr, ima);
if (tot_thread > 1)
- BLI_init_threads(&threads, do_multires_bake_thread, tot_thread);
+ BLI_threadpool_init(&threads, do_multires_bake_thread, tot_thread);
handles = MEM_callocN(tot_thread * sizeof(MultiresBakeThread), "do_multires_bake handles");
@@ -512,12 +512,12 @@ static void do_multires_bake(MultiresBakeRender *bkr, Image *ima, bool require_t
init_bake_rast(&handle->bake_rast, ibuf, &handle->data, flush_pixel, bkr->do_update);
if (tot_thread > 1)
- BLI_insert_thread(&threads, handle);
+ BLI_threadpool_insert(&threads, handle);
}
/* run threads */
if (tot_thread > 1)
- BLI_end_threads(&threads);
+ BLI_threadpool_end(&threads);
else
do_multires_bake_thread(&handles[0]);
diff --git a/source/blender/render/intern/source/occlusion.c b/source/blender/render/intern/source/occlusion.c
index cd93898d846..42200a8278c 100644
--- a/source/blender/render/intern/source/occlusion.c
+++ b/source/blender/render/intern/source/occlusion.c
@@ -553,7 +553,7 @@ static void occ_build_recursive(OcclusionTree *tree, OccNode *node, int begin, i
occ_build_8_split(tree, begin, end, offset, count);
if (depth == 1 && tree->dothreadedbuild)
- BLI_init_threads(&threads, exec_occ_build, tree->totbuildthread);
+ BLI_threadpool_init(&threads, exec_occ_build, tree->totbuildthread);
for (b = 0; b < TOTCHILD; b++) {
if (count[b] == 0) {
@@ -566,7 +566,7 @@ static void occ_build_recursive(OcclusionTree *tree, OccNode *node, int begin, i
}
else {
if (tree->dothreadedbuild)
- BLI_lock_thread(LOCK_CUSTOM1);
+ BLI_thread_lock(LOCK_CUSTOM1);
child = BLI_memarena_alloc(tree->arena, sizeof(OccNode));
node->child[b].node = child;
@@ -576,7 +576,7 @@ static void occ_build_recursive(OcclusionTree *tree, OccNode *node, int begin, i
tree->maxdepth = depth + 1;
if (tree->dothreadedbuild)
- BLI_unlock_thread(LOCK_CUSTOM1);
+ BLI_thread_unlock(LOCK_CUSTOM1);
if (depth == 1 && tree->dothreadedbuild) {
othreads[totthread].tree = tree;
@@ -584,7 +584,7 @@ static void occ_build_recursive(OcclusionTree *tree, OccNode *node, int begin, i
othreads[totthread].begin = offset[b];
othreads[totthread].end = offset[b] + count[b];
othreads[totthread].depth = depth + 1;
- BLI_insert_thread(&threads, &othreads[totthread]);
+ BLI_threadpool_insert(&threads, &othreads[totthread]);
totthread++;
}
else
@@ -593,7 +593,7 @@ static void occ_build_recursive(OcclusionTree *tree, OccNode *node, int begin, i
}
if (depth == 1 && tree->dothreadedbuild)
- BLI_end_threads(&threads);
+ BLI_threadpool_end(&threads);
}
/* combine area, position and sh */
@@ -1313,12 +1313,12 @@ void make_occ_tree(Render *re)
exec_strandsurface_sample(&othreads[0]);
}
else {
- BLI_init_threads(&threads, exec_strandsurface_sample, totthread);
+ BLI_threadpool_init(&threads, exec_strandsurface_sample, totthread);
for (a = 0; a < totthread; a++)
- BLI_insert_thread(&threads, &othreads[a]);
+ BLI_threadpool_insert(&threads, &othreads[a]);
- BLI_end_threads(&threads);
+ BLI_threadpool_end(&threads);
}
for (a = 0; a < mesh->totface; a++) {
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index 5a5c99724fe..e5426384c6f 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -41,6 +41,7 @@
#include "DNA_image_types.h"
#include "DNA_node_types.h"
#include "DNA_object_types.h"
+#include "DNA_particle_types.h"
#include "DNA_scene_types.h"
#include "DNA_sequence_types.h"
#include "DNA_userdef_types.h"
@@ -1427,7 +1428,7 @@ static void threaded_tile_processor(Render *re)
BLI_thread_queue_nowait(workqueue);
/* start all threads */
- BLI_init_threads(&threads, do_render_thread, re->r.threads);
+ BLI_threadpool_init(&threads, do_render_thread, re->r.threads);
for (a = 0; a < re->r.threads; a++) {
thread[a].workqueue = workqueue;
@@ -1443,7 +1444,7 @@ static void threaded_tile_processor(Render *re)
thread[a].duh = NULL;
}
- BLI_insert_thread(&threads, &thread[a]);
+ BLI_threadpool_insert(&threads, &thread[a]);
}
/* wait for results to come back */
@@ -1487,7 +1488,7 @@ static void threaded_tile_processor(Render *re)
}
}
- BLI_end_threads(&threads);
+ BLI_threadpool_end(&threads);
if ((g_break=re->test_break(re->tbh)))
break;
@@ -2104,6 +2105,28 @@ static void tag_dependend_objects_for_render(Scene *scene, int UNUSED(renderlay)
DEG_id_tag_update(&smd->target->id, OB_RECALC_DATA);
}
}
+ else if (md->type == eModifierType_ParticleSystem) {
+ ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md;
+ ParticleSystem *psys = psmd->psys;
+ ParticleSettings *part = psys->part;
+ switch (part->ren_as) {
+ case PART_DRAW_OB:
+ if (part->dup_ob != NULL) {
+ DEG_id_tag_update(&part->dup_ob->id, OB_RECALC_DATA);
+ }
+ break;
+ case PART_DRAW_GR:
+ if (part->dup_group != NULL) {
+ for (GroupObject *go = part->dup_group->gobject.first;
+ go != NULL;
+ go = go->next)
+ {
+ DEG_id_tag_update(&go->ob->id, OB_RECALC_DATA);
+ }
+ }
+ break;
+ }
+ }
}
}
}
diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c
index 6749fedb16e..f97c8fb0b06 100644
--- a/source/blender/render/intern/source/render_result.c
+++ b/source/blender/render/intern/source/render_result.c
@@ -1037,7 +1037,7 @@ static void save_render_result_tile(RenderResult *rr, RenderResult *rrpart, cons
RenderPass *rpassp;
int offs, partx, party;
- BLI_lock_thread(LOCK_IMAGE);
+ BLI_thread_lock(LOCK_IMAGE);
for (rlp = rrpart->layers.first; rlp; rlp = rlp->next) {
rl = RE_GetRenderLayer(rr, rlp->name);
@@ -1086,7 +1086,7 @@ static void save_render_result_tile(RenderResult *rr, RenderResult *rrpart, cons
IMB_exrtile_write_channels(rl->exrhandle, partx, party, 0, viewname, false);
}
- BLI_unlock_thread(LOCK_IMAGE);
+ BLI_thread_unlock(LOCK_IMAGE);
}
void render_result_save_empty_result_tiles(Render *re)
diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c
index 4241dff96de..e66dd86a75a 100644
--- a/source/blender/render/intern/source/render_texture.c
+++ b/source/blender/render/intern/source/render_texture.c
@@ -3675,7 +3675,7 @@ void render_realtime_texture(ShadeInput *shi, Image *ima)
if (R.r.scemode & R_NO_TEX) return;
if (firsttime) {
- BLI_lock_thread(LOCK_IMAGE);
+ BLI_thread_lock(LOCK_IMAGE);
if (firsttime) {
const int num_threads = BLI_system_thread_count();
for (a = 0; a < num_threads; a++) {
@@ -3686,7 +3686,7 @@ void render_realtime_texture(ShadeInput *shi, Image *ima)
firsttime= 0;
}
- BLI_unlock_thread(LOCK_IMAGE);
+ BLI_thread_unlock(LOCK_IMAGE);
}
tex= &imatex[shi->thread];
diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c
index 199322795f3..2fbfcc64c8f 100644
--- a/source/blender/render/intern/source/renderdatabase.c
+++ b/source/blender/render/intern/source/renderdatabase.c
@@ -1482,9 +1482,10 @@ ObjectInstanceRen *RE_addRenderInstance(
return obi;
}
-void RE_instance_get_particle_info(struct ObjectInstanceRen *obi, float *index, float *age, float *lifetime, float co[3], float *size, float vel[3], float angvel[3])
+void RE_instance_get_particle_info(struct ObjectInstanceRen *obi, float *index, float *random, float *age, float *lifetime, float co[3], float *size, float vel[3], float angvel[3])
{
*index = obi->part_index;
+ *random = BLI_hash_int_01(obi->part_index);
*age = obi->part_age;
*lifetime = obi->part_lifetime;
copy_v3_v3(co, obi->part_co);
diff --git a/source/blender/render/intern/source/shadbuf.c b/source/blender/render/intern/source/shadbuf.c
index 6dd7e2c152d..fb441662829 100644
--- a/source/blender/render/intern/source/shadbuf.c
+++ b/source/blender/render/intern/source/shadbuf.c
@@ -40,7 +40,7 @@
#include "BLI_math.h"
#include "BLI_blenlib.h"
-#include "BLI_jitter.h"
+#include "BLI_jitter_2d.h"
#include "BLI_memarena.h"
#include "BLI_rand.h"
#include "BLI_utildefines.h"
@@ -787,10 +787,10 @@ void makeshadowbuf(Render *re, LampRen *lar)
shb->totbuf= lar->buffers;
/* jitter, weights - not threadsafe! */
- BLI_lock_thread(LOCK_CUSTOM1);
+ BLI_thread_lock(LOCK_CUSTOM1);
shb->jit= give_jitter_tab(get_render_shadow_samples(&re->r, shb->samp));
make_jitter_weight_tab(re, shb, lar->filtertype);
- BLI_unlock_thread(LOCK_CUSTOM1);
+ BLI_thread_unlock(LOCK_CUSTOM1);
if (shb->totbuf==4) jitbuf= give_jitter_tab(2);
else if (shb->totbuf==9) jitbuf= give_jitter_tab(3);
@@ -814,21 +814,21 @@ static void *do_shadow_thread(void *re_v)
LampRen *lar;
do {
- BLI_lock_thread(LOCK_CUSTOM1);
+ BLI_thread_lock(LOCK_CUSTOM1);
for (lar=re->lampren.first; lar; lar=lar->next) {
if (lar->shb && !lar->thread_assigned) {
lar->thread_assigned= 1;
break;
}
}
- BLI_unlock_thread(LOCK_CUSTOM1);
+ BLI_thread_unlock(LOCK_CUSTOM1);
/* if type is irregular, this only sets the perspective matrix and autoclips */
if (lar) {
makeshadowbuf(re, lar);
- BLI_lock_thread(LOCK_CUSTOM1);
+ BLI_thread_lock(LOCK_CUSTOM1);
lar->thread_ready= 1;
- BLI_unlock_thread(LOCK_CUSTOM1);
+ BLI_thread_unlock(LOCK_CUSTOM1);
}
} while (lar && !re->test_break(re->tbh));
@@ -878,10 +878,10 @@ void threaded_makeshadowbufs(Render *re)
lar->thread_ready= 0;
}
- BLI_init_threads(&threads, do_shadow_thread, totthread);
+ BLI_threadpool_init(&threads, do_shadow_thread, totthread);
for (a=0; a<totthread; a++)
- BLI_insert_thread(&threads, re);
+ BLI_threadpool_insert(&threads, re);
/* keep rendering as long as there are shadow buffers not ready */
do {
@@ -890,14 +890,14 @@ void threaded_makeshadowbufs(Render *re)
PIL_sleep_ms(50);
- BLI_lock_thread(LOCK_CUSTOM1);
+ BLI_thread_lock(LOCK_CUSTOM1);
for (lar=re->lampren.first; lar; lar= lar->next)
if (lar->shb && !lar->thread_ready)
break;
- BLI_unlock_thread(LOCK_CUSTOM1);
+ BLI_thread_unlock(LOCK_CUSTOM1);
} while (lar);
- BLI_end_threads(&threads);
+ BLI_threadpool_end(&threads);
/* unset threadsafety */
re->test_break= test_break;
diff --git a/source/blender/render/intern/source/sss.c b/source/blender/render/intern/source/sss.c
index 26ca3ad50e0..c29da9b17c6 100644
--- a/source/blender/render/intern/source/sss.c
+++ b/source/blender/render/intern/source/sss.c
@@ -973,9 +973,9 @@ void sss_add_points(Render *re, float (*co)[3], float (*color)[3], float *area,
p->area= area;
p->totpoint= totpoint;
- BLI_lock_thread(LOCK_CUSTOM1);
+ BLI_thread_lock(LOCK_CUSTOM1);
BLI_addtail(re->sss_points, p);
- BLI_unlock_thread(LOCK_CUSTOM1);
+ BLI_thread_unlock(LOCK_CUSTOM1);
}
}
diff --git a/source/blender/render/intern/source/voxeldata.c b/source/blender/render/intern/source/voxeldata.c
index 1022aeeec66..c45bde300e7 100644
--- a/source/blender/render/intern/source/voxeldata.c
+++ b/source/blender/render/intern/source/voxeldata.c
@@ -61,7 +61,7 @@
#include "BPH_mass_spring.h"
#include "DNA_texture_types.h"
-#include "DNA_object_force.h"
+#include "DNA_object_force_types.h"
#include "DNA_object_types.h"
#include "DNA_particle_types.h"
#include "DNA_modifier_types.h"
diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c
index f39936dc01f..770a270592c 100644
--- a/source/blender/render/intern/source/zbuf.c
+++ b/source/blender/render/intern/source/zbuf.c
@@ -42,7 +42,7 @@
#include "BLI_math.h"
#include "BLI_blenlib.h"
-#include "BLI_jitter.h"
+#include "BLI_jitter_2d.h"
#include "BLI_threads.h"
#include "BLI_utildefines.h"
diff --git a/source/blender/windowmanager/CMakeLists.txt b/source/blender/windowmanager/CMakeLists.txt
index 059055daea9..0da45202730 100644
--- a/source/blender/windowmanager/CMakeLists.txt
+++ b/source/blender/windowmanager/CMakeLists.txt
@@ -93,7 +93,6 @@ set(SRC
wm_event_system.h
wm_event_types.h
wm_files.h
- wm_subwindow.h
wm_window.h
manipulators/WM_manipulator_api.h
manipulators/WM_manipulator_types.h
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 16c376888df..aaf1a11a416 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -68,6 +68,8 @@ struct ScrArea;
struct Main;
struct bToolDef;
+#include "DNA_object_enums.h"
+
#ifdef WITH_INPUT_NDOF
struct wmNDOFMotionData;
#endif
@@ -105,6 +107,7 @@ bool WM_window_is_fullscreen(struct wmWindow *win);
void WM_windows_scene_data_sync(const ListBase *win_lb, struct Scene *scene) ATTR_NONNULL();
struct Scene *WM_windows_scene_get_from_screen(const struct wmWindowManager *wm, const struct bScreen *screen) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT;
struct WorkSpace *WM_windows_workspace_get_from_screen(const wmWindowManager *wm, const struct bScreen *screen) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT;
+eObjectMode WM_windows_object_mode_get(const struct wmWindowManager *wm) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT;
struct Scene *WM_window_get_active_scene(const struct wmWindow *win) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT;
void WM_window_change_active_scene(struct Main *bmain, struct bContext *C, struct wmWindow *win,
@@ -140,7 +143,7 @@ void WM_file_autoexec_init(const char *filepath);
bool WM_file_read(struct bContext *C, const char *filepath, struct ReportList *reports);
void WM_autosave_init(struct wmWindowManager *wm);
void WM_recover_last_session(struct bContext *C, struct ReportList *reports);
-void WM_file_tag_modified(const struct bContext *C);
+void WM_file_tag_modified(void);
void WM_lib_reload(struct Library *lib, struct bContext *C, struct ReportList *reports);
@@ -456,15 +459,17 @@ struct wmDropBox *WM_dropbox_add(ListBase *lb, const char *idname, int (*poll)(s
void (*copy)(struct wmDrag *, struct wmDropBox *));
ListBase *WM_dropboxmap_find(const char *idname, int spaceid, int regionid);
- /* Set a subwindow active in pixelspace view, with optional scissor subset */
-void wmSubWindowSet (struct wmWindow *win, int swinid);
-void wmSubWindowScissorSet (struct wmWindow *win, int swinid, const struct rcti *srct, bool srct_pad);
+ /* Set OpenGL viewport and scissor */
+void wmViewport(const struct rcti *rect);
+void wmPartialViewport(rcti *drawrct, const rcti *winrct, const rcti *partialrct);
+void wmWindowViewport(struct wmWindow *win);
/* OpenGL utilities with safety check */
void wmOrtho2 (float x1, float x2, float y1, float y2);
/* use for conventions (avoid hard-coded offsets all over) */
void wmOrtho2_region_pixelspace(const struct ARegion *ar);
void wmOrtho2_pixelspace(const float x, const float y);
+void wmGetProjectionMatrix(float mat[4][4], const struct rcti *winrct);
/* threaded Jobs Manager */
enum {
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index cb90029a5e7..50062a04ae9 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -115,6 +115,7 @@ struct ImBuf;
#include "RNA_types.h"
#include "DNA_listBase.h"
+#include "DNA_vec_types.h"
#include "BLI_compiler_attrs.h"
/* exported types for WM */
@@ -214,7 +215,6 @@ typedef struct wmNotifier {
struct wmWindowManager *wm;
struct wmWindow *window;
- int swinid; /* can't rely on this, notifiers can be added without context, swinid of 0 */
unsigned int category, data, subtype, action;
void *reference;
@@ -423,7 +423,7 @@ typedef struct wmGesture {
struct wmGesture *next, *prev;
int event_type; /* event->type */
int type; /* gesture type define */
- int swinid; /* initial subwindow id where it started */
+ rcti winrct; /* bounds of region to draw gesture within */
int points; /* optional, amount of points stored */
int points_alloc; /* optional, maximum amount of points stored */
int modal_state;
@@ -521,6 +521,10 @@ typedef struct wmNDOFMotionData {
} wmNDOFMotionData;
#endif /* WITH_INPUT_NDOF */
+typedef enum { /* Timer flags */
+ WM_TIMER_NO_FREE_CUSTOM_DATA = 1 << 0, /* Do not attempt to free customdata pointer even if non-NULL. */
+} wmTimerFlags;
+
typedef struct wmTimer {
struct wmTimer *next, *prev;
@@ -528,6 +532,7 @@ typedef struct wmTimer {
double timestep; /* set by timer user */
int event_type; /* set by timer user, goes to event system */
+ wmTimerFlags flags; /* Various flags controlling timer options, see below. */
void *customdata; /* set by timer user, to allow custom values */
double duration; /* total running time in seconds */
@@ -536,7 +541,7 @@ typedef struct wmTimer {
double ltime; /* internal, last time timer was activated */
double ntime; /* internal, next time we want to activate the timer */
double stime; /* internal, when the timer started */
- int sleep; /* internal, put timers to sleep when needed */
+ bool sleep; /* internal, put timers to sleep when needed */
} wmTimer;
typedef struct wmOperatorType {
diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c
index 30197537e14..70cff8465fc 100644
--- a/source/blender/windowmanager/intern/wm_draw.c
+++ b/source/blender/windowmanager/intern/wm_draw.c
@@ -95,7 +95,7 @@ static void wm_paintcursor_draw(bContext *C, ARegion *ar)
bScreen *screen = WM_window_get_active_screen(win);
wmPaintCursor *pc;
- if (ar->swinid && screen->subwinactive == ar->swinid) {
+ if (ar->visible && ar == screen->active_region) {
for (pc = wm->paintcursors.first; pc; pc = pc->next) {
if (pc->poll == NULL || pc->poll(C)) {
ARegion *ar_other = CTX_wm_region(C);
@@ -223,7 +223,7 @@ static void wm_method_draw_full(bContext *C, wmWindow *win)
CTX_wm_area_set(C, sa);
for (ar = sa->regionbase.first; ar; ar = ar->next) {
- if (ar->swinid) {
+ if (ar->visible) {
CTX_wm_region_set(C, ar);
ED_region_do_draw(C, ar);
ar->do_draw = false;
@@ -242,7 +242,7 @@ static void wm_method_draw_full(bContext *C, wmWindow *win)
/* draw overlapping regions */
for (ar = screen->regionbase.first; ar; ar = ar->next) {
- if (ar->swinid) {
+ if (ar->visible) {
CTX_wm_menu_set(C, ar);
ED_region_do_draw(C, ar);
ar->do_draw = false;
@@ -300,7 +300,7 @@ static void wm_method_draw_overlap_all(bContext *C, wmWindow *win, int exchange)
/* after backbuffer selection draw, we need to redraw */
ED_screen_areas_iter(win, screen, sa) {
for (ar = sa->regionbase.first; ar; ar = ar->next)
- if (ar->swinid && !wm_area_test_invalid_backbuf(sa))
+ if (ar->visible && !wm_area_test_invalid_backbuf(sa))
ED_region_tag_redraw(ar);
}
@@ -309,18 +309,18 @@ static void wm_method_draw_overlap_all(bContext *C, wmWindow *win, int exchange)
/* flush redraws of area regions up to overlapping regions */
ED_screen_areas_iter(win, screen, sa) {
for (ar = sa->regionbase.first; ar; ar = ar->next)
- if (ar->swinid && ar->do_draw)
+ if (ar->visible && ar->do_draw)
wm_flush_regions_up(screen, &ar->winrct);
}
/* flush between overlapping regions */
for (ar = screen->regionbase.last; ar; ar = ar->prev)
- if (ar->swinid && ar->do_draw)
+ if (ar->visible && ar->do_draw)
wm_flush_regions_up(screen, &ar->winrct);
/* flush redraws of overlapping regions down to area regions */
for (ar = screen->regionbase.last; ar; ar = ar->prev)
- if (ar->swinid && ar->do_draw)
+ if (ar->visible && ar->do_draw)
wm_flush_regions_down(win, screen, &ar->winrct);
}
@@ -339,7 +339,7 @@ static void wm_method_draw_overlap_all(bContext *C, wmWindow *win, int exchange)
CTX_wm_area_set(C, sa);
for (ar = sa->regionbase.first; ar; ar = ar->next) {
- if (ar->swinid) {
+ if (ar->visible) {
if (ar->do_draw) {
CTX_wm_region_set(C, ar);
ED_region_do_draw(C, ar);
@@ -396,7 +396,7 @@ static void wm_method_draw_overlap_all(bContext *C, wmWindow *win, int exchange)
/* draw marked overlapping regions */
for (ar = screen->regionbase.first; ar; ar = ar->next) {
- if (ar->swinid && ar->do_draw) {
+ if (ar->visible && ar->do_draw) {
CTX_wm_menu_set(C, ar);
ED_region_do_draw(C, ar);
ar->do_draw = false;
@@ -437,15 +437,8 @@ static void wm_draw_triple_fail(bContext *C, wmWindow *win)
static bool wm_triple_gen_textures(wmWindow *win, wmDrawTriple *triple)
{
/* compute texture sizes */
- triple->x = WM_window_pixels_x(win);
- triple->y = WM_window_pixels_y(win);
-
-#if USE_TEXTURE_RECTANGLE
- /* GL_TEXTURE_RECTANGLE is part of GL 3.1 so we can use it soon without runtime checks */
- triple->target = GL_TEXTURE_RECTANGLE;
-#else
- triple->target = GL_TEXTURE_2D;
-#endif
+ const int sizex = WM_window_pixels_x(win);
+ const int sizey = WM_window_pixels_y(win);
/* generate texture names */
glGenTextures(1, &triple->bind);
@@ -454,29 +447,25 @@ static bool wm_triple_gen_textures(wmWindow *win, wmDrawTriple *triple)
* there is only one texture in use, which may not be the case */
const GLint maxsize = GPU_max_texture_size();
- if (triple->x > maxsize || triple->y > maxsize) {
+ if (sizex > maxsize || sizey > maxsize) {
printf("WM: failed to allocate texture for triple buffer drawing "
"(texture too large for graphics card).\n");
return false;
}
/* setup actual texture */
- glBindTexture(triple->target, triple->bind);
+ glBindTexture(GL_TEXTURE_2D, triple->bind);
/* no mipmaps */
-#if USE_TEXTURE_RECTANGLE
- /* already has no mipmaps */
-#else
- glTexParameteri(triple->target, GL_TEXTURE_MAX_LEVEL, 0);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
/* GL_TEXTURE_BASE_LEVEL = 0 by default */
-#endif
- glTexParameteri(triple->target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(triple->target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexImage2D(triple->target, 0, GL_RGB8, triple->x, triple->y, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, sizex, sizey, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
- glBindTexture(triple->target, 0);
+ glBindTexture(GL_TEXTURE_2D, 0);
return true;
}
@@ -487,19 +476,10 @@ void wm_triple_draw_textures(wmWindow *win, wmDrawTriple *triple, float alpha)
const int sizey = WM_window_pixels_y(win);
/* wmOrtho for the screen has this same offset */
- float ratiox = sizex;
- float ratioy = sizey;
- float halfx = GLA_PIXEL_OFS;
- float halfy = GLA_PIXEL_OFS;
-
-#if USE_TEXTURE_RECTANGLE
- /* texture rectangle has unnormalized coordinates */
-#else
- ratiox /= triple->x;
- ratioy /= triple->y;
- halfx /= triple->x;
- halfy /= triple->y;
-#endif
+ const float ratiox = 1.0f;
+ const float ratioy = 1.0f;
+ const float halfx = GLA_PIXEL_OFS / sizex;
+ const float halfy = GLA_PIXEL_OFS / sizey;
Gwn_VertFormat *format = immVertexFormat();
unsigned int texcoord = GWN_vertformat_attr_add(format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
@@ -507,16 +487,10 @@ void wm_triple_draw_textures(wmWindow *win, wmDrawTriple *triple, float alpha)
const int activeTex = 7; /* arbitrary */
glActiveTexture(GL_TEXTURE0 + activeTex);
- glBindTexture(triple->target, triple->bind);
-
-#if USE_TEXTURE_RECTANGLE
- immBindBuiltinProgram(GPU_SHADER_3D_IMAGE_RECT_MODULATE_ALPHA);
-#else
- immBindBuiltinProgram(GPU_SHADER_3D_IMAGE_MODULATE_ALPHA);
- /* TODO: make pure 2D version
- * and a 2D_IMAGE (replace, not modulate) version for when alpha = 1.0
- */
-#endif
+ glBindTexture(GL_TEXTURE_2D, triple->bind);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_ALPHA);
+
immUniform1f("alpha", alpha);
immUniform1i("image", activeTex);
@@ -537,7 +511,7 @@ void wm_triple_draw_textures(wmWindow *win, wmDrawTriple *triple, float alpha)
immEnd();
immUnbindProgram();
- glBindTexture(triple->target, 0);
+ glBindTexture(GL_TEXTURE_2D, 0);
if (activeTex != 0)
glActiveTexture(GL_TEXTURE0);
}
@@ -547,10 +521,10 @@ static void wm_triple_copy_textures(wmWindow *win, wmDrawTriple *triple)
const int sizex = WM_window_pixels_x(win);
const int sizey = WM_window_pixels_y(win);
- glBindTexture(triple->target, triple->bind);
+ glBindTexture(GL_TEXTURE_2D, triple->bind);
/* what is GL_READ_BUFFER right now? */
- glCopyTexSubImage2D(triple->target, 0, 0, 0, 0, 0, sizex, sizey);
- glBindTexture(triple->target, 0);
+ glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, sizex, sizey);
+ glBindTexture(GL_TEXTURE_2D, 0);
}
static void wm_draw_region_blend(wmWindow *win, ARegion *ar, wmDrawTriple *triple)
@@ -559,9 +533,7 @@ static void wm_draw_region_blend(wmWindow *win, ARegion *ar, wmDrawTriple *tripl
/* region blend always is 1, except when blend timer is running */
if (fac < 1.0f) {
- bScreen *screen = WM_window_get_active_screen(win);
-
- wmSubWindowScissorSet(win, screen->mainwin, &ar->winrct, true);
+ wmViewport(&ar->winrct);
glEnable(GL_BLEND);
wm_triple_draw_textures(win, triple, 1.0f - fac);
@@ -583,7 +555,7 @@ static void wm_method_draw_triple(bContext *C, wmWindow *win)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
#endif
- wmSubWindowSet(win, screen->mainwin);
+ wmWindowViewport(win);
wm_triple_draw_textures(win, drawdata->triple, 1.0f);
}
@@ -619,7 +591,7 @@ static void wm_method_draw_triple(bContext *C, wmWindow *win)
CTX_wm_area_set(C, sa);
for (ar = sa->regionbase.first; ar; ar = ar->next) {
- if (ar->swinid && ar->do_draw) {
+ if (ar->visible && ar->do_draw) {
if (ar->overlap == false) {
wm_draw_region(C, ar);
copytex = true;
@@ -632,7 +604,7 @@ static void wm_method_draw_triple(bContext *C, wmWindow *win)
}
if (copytex) {
- wmSubWindowSet(win, screen->mainwin);
+ wmWindowViewport(win);
wm_triple_copy_textures(win, triple);
}
@@ -640,12 +612,12 @@ static void wm_method_draw_triple(bContext *C, wmWindow *win)
if (wm->paintcursors.first) {
ED_screen_areas_iter(win, screen, sa) {
for (ar = sa->regionbase.first; ar; ar = ar->next) {
- if (ar->swinid && ar->swinid == screen->subwinactive) {
+ if (ar->visible && ar == screen->active_region) {
CTX_wm_area_set(C, sa);
CTX_wm_region_set(C, ar);
/* make region ready for draw, scissor, pixelspace */
- ED_region_set(C, ar);
+ wmViewport(&ar->winrct);
wm_paintcursor_draw(C, ar);
CTX_wm_region_set(C, NULL);
@@ -654,7 +626,7 @@ static void wm_method_draw_triple(bContext *C, wmWindow *win)
}
}
- wmSubWindowSet(win, screen->mainwin);
+ wmWindowViewport(win);
}
/* draw overlapping area regions (always like popups) */
@@ -662,7 +634,7 @@ static void wm_method_draw_triple(bContext *C, wmWindow *win)
CTX_wm_area_set(C, sa);
for (ar = sa->regionbase.first; ar; ar = ar->next) {
- if (ar->swinid && ar->overlap) {
+ if (ar->visible && ar->overlap) {
wm_draw_region(C, ar);
wm_draw_region_blend(win, ar, triple);
}
@@ -678,7 +650,7 @@ static void wm_method_draw_triple(bContext *C, wmWindow *win)
/* draw floating regions (menus) */
for (ar = screen->regionbase.first; ar; ar = ar->next) {
- if (ar->swinid) {
+ if (ar->visible) {
CTX_wm_menu_set(C, ar);
ED_region_do_draw(C, ar);
ar->do_draw = false;
@@ -717,7 +689,7 @@ static void wm_method_draw_triple_multiview(bContext *C, wmWindow *win, eStereoV
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
#endif
- wmSubWindowSet(win, screen->mainwin);
+ wmWindowViewport(win);
wm_triple_draw_textures(win, drawdata->triple, 1.0f);
}
@@ -782,7 +754,7 @@ static void wm_method_draw_triple_multiview(bContext *C, wmWindow *win, eStereoV
/* draw marked area regions */
for (ar = sa->regionbase.first; ar; ar = ar->next) {
- if (ar->swinid && ar->do_draw) {
+ if (ar->visible && ar->do_draw) {
if (ar->overlap == false) {
CTX_wm_region_set(C, ar);
@@ -802,7 +774,7 @@ static void wm_method_draw_triple_multiview(bContext *C, wmWindow *win, eStereoV
}
if (copytex) {
- wmSubWindowSet(win, screen->mainwin);
+ wmWindowViewport(win);
wm_triple_copy_textures(win, triple_data);
}
@@ -810,12 +782,12 @@ static void wm_method_draw_triple_multiview(bContext *C, wmWindow *win, eStereoV
if (wm->paintcursors.first) {
ED_screen_areas_iter(win, screen, sa) {
for (ar = sa->regionbase.first; ar; ar = ar->next) {
- if (ar->swinid && ar->swinid == screen->subwinactive) {
+ if (ar->visible && ar == screen->active_region) {
CTX_wm_area_set(C, sa);
CTX_wm_region_set(C, ar);
/* make region ready for draw, scissor, pixelspace */
- ED_region_set(C, ar);
+ wmViewport(&ar->winrct);
wm_paintcursor_draw(C, ar);
CTX_wm_region_set(C, NULL);
@@ -824,7 +796,7 @@ static void wm_method_draw_triple_multiview(bContext *C, wmWindow *win, eStereoV
}
}
- wmSubWindowSet(win, screen->mainwin);
+ wmWindowViewport(win);
}
/* draw overlapping area regions (always like popups) */
@@ -832,7 +804,7 @@ static void wm_method_draw_triple_multiview(bContext *C, wmWindow *win, eStereoV
CTX_wm_area_set(C, sa);
for (ar = sa->regionbase.first; ar; ar = ar->next) {
- if (ar->swinid && ar->overlap) {
+ if (ar->visible && ar->overlap) {
CTX_wm_region_set(C, ar);
ED_region_do_draw(C, ar);
if (sview == STEREO_RIGHT_ID)
@@ -855,7 +827,7 @@ static void wm_method_draw_triple_multiview(bContext *C, wmWindow *win, eStereoV
/* draw floating regions (menus) */
for (ar = screen->regionbase.first; ar; ar = ar->next) {
- if (ar->swinid) {
+ if (ar->visible) {
CTX_wm_menu_set(C, ar);
ED_region_do_draw(C, ar);
if (sview == STEREO_RIGHT_ID)
@@ -874,7 +846,7 @@ static void wm_method_draw_triple_multiview(bContext *C, wmWindow *win, eStereoV
}
/* copy the ui + overlays */
- wmSubWindowSet(win, screen->mainwin);
+ wmWindowViewport(win);
wm_triple_copy_textures(win, triple_all);
}
@@ -896,7 +868,7 @@ static bool wm_draw_update_test_window(wmWindow *win)
wm_tag_redraw_overlay(win, ar);
ar->do_draw_overlay = false;
}
- if (ar->swinid && ar->do_draw)
+ if (ar->visible && ar->do_draw)
do_draw = true;
}
@@ -904,7 +876,7 @@ static bool wm_draw_update_test_window(wmWindow *win)
for (ar = sa->regionbase.first; ar; ar = ar->next) {
wm_region_test_render_do_draw(scene, depsgraph, sa, ar);
- if (ar->swinid && ar->do_draw)
+ if (ar->visible && ar->do_draw)
do_draw = true;
}
}
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index e66e7728d31..040ecc63bec 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -182,7 +182,6 @@ static bool wm_test_duplicate_notifier(wmWindowManager *wm, unsigned int type, v
/* XXX: in future, which notifiers to send to other windows? */
void WM_event_add_notifier(const bContext *C, unsigned int type, void *reference)
{
- ARegion *ar;
wmWindowManager *wm = CTX_wm_manager(C);
wmNotifier *note;
@@ -196,10 +195,6 @@ void WM_event_add_notifier(const bContext *C, unsigned int type, void *reference
note->window = CTX_wm_window(C);
- ar = CTX_wm_region(C);
- if (ar)
- note->swinid = ar->swinid;
-
note->category = type & NOTE_CATEGORY;
note->data = type & NOTE_DATA;
note->subtype = type & NOTE_SUBTYPE;
@@ -339,6 +334,9 @@ void wm_event_do_refresh_wm_and_depsgraph(bContext *C)
scene->customdata_mask |= scene->customdata_mask_modal;
WorkSpace *workspace = WM_window_get_active_workspace(win);
+
+ BKE_workspace_update_object_mode(bmain->eval_ctx, workspace);
+
BKE_workspace_update_tagged(bmain->eval_ctx, bmain, workspace, scene);
}
}
@@ -383,7 +381,7 @@ void wm_event_do_notifiers(bContext *C)
UI_popup_handlers_remove_all(C, &win->modalhandlers);
- ED_workspace_change(ref_ws, C, wm, win);
+ ED_workspace_change(ref_ws, C, win);
if (G.debug & G_DEBUG_EVENTS)
printf("%s: Workspace set %p\n", __func__, note->reference);
}
@@ -1219,8 +1217,8 @@ static int wm_operator_invoke(
}
if ((G.debug & G_DEBUG_HANDLERS) && ((event == NULL) || (event->type != MOUSEMOVE))) {
- printf("%s: handle evt %d win %d op %s\n",
- __func__, event ? event->type : 0, CTX_wm_screen(C)->subwinactive, ot->idname);
+ printf("%s: handle evt %d region %p op %s\n",
+ __func__, event ? event->type : 0, CTX_wm_screen(C)->active_region, ot->idname);
}
if (op->type->invoke && event) {
@@ -1357,6 +1355,8 @@ static int wm_operator_call_internal(
switch (context) {
case WM_OP_INVOKE_DEFAULT:
case WM_OP_INVOKE_REGION_WIN:
+ case WM_OP_INVOKE_REGION_PREVIEW:
+ case WM_OP_INVOKE_REGION_CHANNELS:
case WM_OP_INVOKE_AREA:
case WM_OP_INVOKE_SCREEN:
/* window is needed for invoke, cancel operator */
@@ -2783,7 +2783,7 @@ void wm_event_do_handlers(bContext *C)
/* Note: setting subwin active should be done here, after modal handlers have been done */
if (event->type == MOUSEMOVE) {
/* state variables in screen, cursors. Also used in wm_draw.c, fails for modal handlers though */
- ED_screen_set_subwinactive(C, event);
+ ED_screen_set_active_region(C, event);
/* for regions having custom cursors */
wm_paintcursor_test(C, event);
}
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index 6a86644da17..98606379a61 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -182,7 +182,6 @@ static void wm_window_match_init(bContext *C, ListBase *wmlist)
static void wm_window_substitute_old(wmWindowManager *wm, wmWindow *oldwin, wmWindow *win)
{
win->ghostwin = oldwin->ghostwin;
- win->multisamples = oldwin->multisamples;
win->active = oldwin->active;
if (win->active)
wm->winactive = win;
@@ -191,7 +190,6 @@ static void wm_window_substitute_old(wmWindowManager *wm, wmWindow *oldwin, wmWi
GHOST_SetWindowUserData(win->ghostwin, win); /* pointer back */
oldwin->ghostwin = NULL;
- oldwin->multisamples = 0;
win->eventstate = oldwin->eventstate;
oldwin->eventstate = NULL;
@@ -1365,13 +1363,13 @@ void wm_open_init_use_scripts(wmOperator *op, bool use_prefs)
/** \} */
-void WM_file_tag_modified(const bContext *C)
+void WM_file_tag_modified(void)
{
- wmWindowManager *wm = CTX_wm_manager(C);
+ wmWindowManager *wm = G.main->wm.first;
if (wm->file_saved) {
wm->file_saved = 0;
/* notifier that data changed, for save-over warning or header */
- WM_event_add_notifier(C, NC_WM | ND_DATACHANGED, NULL);
+ WM_main_add_notifier(NC_WM | ND_DATACHANGED, NULL);
}
}
diff --git a/source/blender/windowmanager/intern/wm_files_link.c b/source/blender/windowmanager/intern/wm_files_link.c
index cd6a38cb9a8..a33df1bc1f2 100644
--- a/source/blender/windowmanager/intern/wm_files_link.c
+++ b/source/blender/windowmanager/intern/wm_files_link.c
@@ -320,9 +320,6 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
char path[FILE_MAX_LIBEXTRA], root[FILE_MAXDIR], libname[FILE_MAX_LIBEXTRA], relname[FILE_MAX];
char *group, *name;
int totfiles = 0;
- short flag;
- bool has_item = false;
- bool do_append;
RNA_string_get(op->ptr, "filename", relname);
RNA_string_get(op->ptr, "directory", root);
@@ -359,8 +356,8 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- flag = wm_link_append_flag(op);
- do_append = (flag & FILE_LINK) == 0;
+ short flag = wm_link_append_flag(op);
+ const bool do_append = (flag & FILE_LINK) == 0;
/* sanity checks for flag */
if (scene && scene->id.lib) {
@@ -406,7 +403,6 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
BLI_ghash_insert(libraries, BLI_strdup(libname), SET_INT_IN_POINTER(lib_idx));
lib_idx++;
wm_link_append_data_library_add(lapp_data, libname);
- has_item = true;
}
}
}
@@ -429,7 +425,6 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
item = wm_link_append_data_item_add(lapp_data, name, BKE_idcode_from_name(group), NULL);
BLI_BITMAP_ENABLE(item->libraries, lib_idx);
- has_item = true;
}
}
RNA_END;
@@ -442,10 +437,10 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
wm_link_append_data_library_add(lapp_data, libname);
item = wm_link_append_data_item_add(lapp_data, name, BKE_idcode_from_name(group), NULL);
BLI_BITMAP_ENABLE(item->libraries, 0);
- has_item = true;
}
- if (!has_item) {
+ if (lapp_data->num_items == 0) {
+ /* Early out in case there is nothing to link. */
wm_link_append_data_free(lapp_data);
return OPERATOR_CANCELLED;
}
@@ -614,7 +609,6 @@ static void lib_relocate_do(
LinkNode *itemlink;
int item_idx;
- bool has_item = false;
/* Remove all IDs to be reloaded from Main. */
lba_idx = set_listbasepointers(bmain, lbarray);
@@ -636,7 +630,6 @@ static void lib_relocate_do(
BLI_remlink(lbarray[lba_idx], id);
item = wm_link_append_data_item_add(lapp_data, id->name + 2, idcode, id);
BLI_BITMAP_SET_ALL(item->libraries, true, lapp_data->num_libraries);
- has_item = true;
#ifdef PRINT_DEBUG
printf("\tdatablock to seek for: %s\n", id->name);
@@ -645,8 +638,8 @@ static void lib_relocate_do(
}
}
- if (!has_item) {
- /* nothing to relocate */
+ if (lapp_data->num_items == 0) {
+ /* Early out in case there is nothing to do. */
return;
}
diff --git a/source/blender/windowmanager/intern/wm_gesture.c b/source/blender/windowmanager/intern/wm_gesture.c
index fa5fd38b7b2..6da9101156a 100644
--- a/source/blender/windowmanager/intern/wm_gesture.c
+++ b/source/blender/windowmanager/intern/wm_gesture.c
@@ -41,7 +41,7 @@
#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
-#include "BLI_lasso.h"
+#include "BLI_lasso_2d.h"
#include "BKE_context.h"
@@ -49,7 +49,6 @@
#include "WM_types.h"
#include "wm.h"
-#include "wm_subwindow.h"
#include "wm_draw.h"
#include "GPU_immediate.h"
@@ -64,40 +63,37 @@ wmGesture *WM_gesture_new(bContext *C, const wmEvent *event, int type)
wmGesture *gesture = MEM_callocN(sizeof(wmGesture), "new gesture");
wmWindow *window = CTX_wm_window(C);
ARegion *ar = CTX_wm_region(C);
- int sx, sy;
BLI_addtail(&window->gesture, gesture);
gesture->type = type;
gesture->event_type = event->type;
- gesture->swinid = ar->swinid; /* means only in area-region context! */
+ gesture->winrct = ar->winrct;
gesture->userdata_free = true; /* Free if userdata is set. */
gesture->modal_state = GESTURE_MODAL_NOP;
- wm_subwindow_origin_get(window, gesture->swinid, &sx, &sy);
-
if (ELEM(type, WM_GESTURE_RECT, WM_GESTURE_CROSS_RECT, WM_GESTURE_TWEAK,
WM_GESTURE_CIRCLE, WM_GESTURE_STRAIGHTLINE))
{
rcti *rect = MEM_callocN(sizeof(rcti), "gesture rect new");
gesture->customdata = rect;
- rect->xmin = event->x - sx;
- rect->ymin = event->y - sy;
+ rect->xmin = event->x - gesture->winrct.xmin;
+ rect->ymin = event->y - gesture->winrct.ymin;
if (type == WM_GESTURE_CIRCLE) {
/* caller is responsible for initializing 'xmax' to radius. */
}
else {
- rect->xmax = event->x - sx;
- rect->ymax = event->y - sy;
+ rect->xmax = event->x - gesture->winrct.xmin;
+ rect->ymax = event->y - gesture->winrct.ymin;
}
}
else if (ELEM(type, WM_GESTURE_LINES, WM_GESTURE_LASSO)) {
short *lasso;
gesture->points_alloc = 1024;
gesture->customdata = lasso = MEM_mallocN(sizeof(short[2]) * gesture->points_alloc, "lasso points");
- lasso[0] = event->x - sx;
- lasso[1] = event->y - sy;
+ lasso[0] = event->x - gesture->winrct.xmin;
+ lasso[1] = event->y - gesture->winrct.ymin;
gesture->points = 1;
}
@@ -273,14 +269,13 @@ static void draw_filled_lasso_px_cb(int x, int x_end, int y, void *user_data)
memset(col, 0x10, x_end - x);
}
-static void draw_filled_lasso(wmWindow *win, wmGesture *gt)
+static void draw_filled_lasso(wmGesture *gt)
{
const short *lasso = (short *)gt->customdata;
const int tot = gt->points;
int (*moves)[2] = MEM_mallocN(sizeof(*moves) * (tot + 1), __func__);
int i;
rcti rect;
- rcti rect_win;
float red[4] = {1.0f, 0.0f, 0.0f, 0.0f};
for (i = 0; i < tot; i++, lasso += 2) {
@@ -290,10 +285,9 @@ static void draw_filled_lasso(wmWindow *win, wmGesture *gt)
BLI_lasso_boundbox(&rect, (const int (*)[2])moves, tot);
- wm_subwindow_rect_get(win, gt->swinid, &rect_win);
- BLI_rcti_translate(&rect, rect_win.xmin, rect_win.ymin);
- BLI_rcti_isect(&rect_win, &rect, &rect);
- BLI_rcti_translate(&rect, -rect_win.xmin, -rect_win.ymin);
+ BLI_rcti_translate(&rect, gt->winrct.xmin, gt->winrct.ymin);
+ BLI_rcti_isect(&gt->winrct, &rect, &rect);
+ BLI_rcti_translate(&rect, -gt->winrct.xmin, -gt->winrct.ymin);
/* highly unlikely this will fail, but could crash if (tot == 0) */
if (BLI_rcti_is_empty(&rect) == false) {
@@ -335,13 +329,13 @@ static void draw_filled_lasso(wmWindow *win, wmGesture *gt)
}
-static void wm_gesture_draw_lasso(wmWindow *win, wmGesture *gt, bool filled)
+static void wm_gesture_draw_lasso(wmGesture *gt, bool filled)
{
const short *lasso = (short *)gt->customdata;
int i;
if (filled) {
- draw_filled_lasso(win, gt);
+ draw_filled_lasso(gt);
}
const int numverts = gt->points;
@@ -425,7 +419,7 @@ void wm_gesture_draw(wmWindow *win)
glLineWidth(1.0f);
for (; gt; gt = gt->next) {
/* all in subwindow space */
- wmSubWindowSet(win, gt->swinid);
+ wmViewport(&gt->winrct);
if (gt->type == WM_GESTURE_RECT)
wm_gesture_draw_rect(gt);
@@ -442,9 +436,9 @@ void wm_gesture_draw(wmWindow *win)
}
}
else if (gt->type == WM_GESTURE_LINES)
- wm_gesture_draw_lasso(win, gt, false);
+ wm_gesture_draw_lasso(gt, false);
else if (gt->type == WM_GESTURE_LASSO)
- wm_gesture_draw_lasso(win, gt, true);
+ wm_gesture_draw_lasso(gt, true);
else if (gt->type == WM_GESTURE_STRAIGHTLINE)
wm_gesture_draw_line(gt);
}
diff --git a/source/blender/windowmanager/intern/wm_gesture_ops.c b/source/blender/windowmanager/intern/wm_gesture_ops.c
index a554727cacd..01184f47920 100644
--- a/source/blender/windowmanager/intern/wm_gesture_ops.c
+++ b/source/blender/windowmanager/intern/wm_gesture_ops.c
@@ -47,7 +47,6 @@
#include "wm.h"
#include "wm_event_types.h"
#include "wm_event_system.h"
-#include "wm_subwindow.h"
#include "ED_screen.h"
@@ -198,18 +197,15 @@ int WM_gesture_border_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
wmGesture *gesture = op->customdata;
rcti *rect = gesture->customdata;
- int sx, sy;
if (event->type == MOUSEMOVE) {
- wm_subwindow_origin_get(CTX_wm_window(C), gesture->swinid, &sx, &sy);
-
if (gesture->type == WM_GESTURE_CROSS_RECT && gesture->is_active == false) {
- rect->xmin = rect->xmax = event->x - sx;
- rect->ymin = rect->ymax = event->y - sy;
+ rect->xmin = rect->xmax = event->x - gesture->winrct.xmin;
+ rect->ymin = rect->ymax = event->y - gesture->winrct.ymin;
}
else {
- rect->xmax = event->x - sx;
- rect->ymax = event->y - sy;
+ rect->xmax = event->x - gesture->winrct.xmin;
+ rect->ymax = event->y - gesture->winrct.ymin;
}
gesture_border_apply_rect(op);
@@ -333,13 +329,11 @@ int WM_gesture_circle_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
wmGesture *gesture = op->customdata;
rcti *rect = gesture->customdata;
- int sx, sy;
if (event->type == MOUSEMOVE) {
- wm_subwindow_origin_get(CTX_wm_window(C), gesture->swinid, &sx, &sy);
- rect->xmin = event->x - sx;
- rect->ymin = event->y - sy;
+ rect->xmin = event->x - gesture->winrct.xmin;
+ rect->ymin = event->y - gesture->winrct.ymin;
wm_gesture_tag_redraw(C);
@@ -464,24 +458,22 @@ static void gesture_tweak_modal(bContext *C, const wmEvent *event)
wmWindow *window = CTX_wm_window(C);
wmGesture *gesture = window->tweak;
rcti *rect = gesture->customdata;
- int sx, sy, val;
+ int val;
switch (event->type) {
case MOUSEMOVE:
case INBETWEEN_MOUSEMOVE:
- wm_subwindow_origin_get(window, gesture->swinid, &sx, &sy);
-
- rect->xmax = event->x - sx;
- rect->ymax = event->y - sy;
+ rect->xmax = event->x - gesture->winrct.xmin;
+ rect->ymax = event->y - gesture->winrct.ymin;
if ((val = wm_gesture_evaluate(gesture))) {
wmEvent tevent;
wm_event_init_from_window(window, &tevent);
/* We want to get coord from start of drag, not from point where it becomes a tweak event, see T40549 */
- tevent.x = rect->xmin + sx;
- tevent.y = rect->ymin + sy;
+ tevent.x = rect->xmin + gesture->winrct.xmin;
+ tevent.y = rect->ymin + gesture->winrct.ymin;
if (gesture->event_type == LEFTMOUSE)
tevent.type = EVT_TWEAK_L;
else if (gesture->event_type == RIGHTMOUSE)
@@ -617,7 +609,6 @@ static void gesture_lasso_apply(bContext *C, wmOperator *op)
int WM_gesture_lasso_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
wmGesture *gesture = op->customdata;
- int sx, sy;
switch (event->type) {
case MOUSEMOVE:
@@ -625,8 +616,6 @@ int WM_gesture_lasso_modal(bContext *C, wmOperator *op, const wmEvent *event)
wm_gesture_tag_redraw(C);
- wm_subwindow_origin_get(CTX_wm_window(C), gesture->swinid, &sx, &sy);
-
if (gesture->points == gesture->points_alloc) {
gesture->points_alloc *= 2;
gesture->customdata = MEM_reallocN(gesture->customdata, sizeof(short[2]) * gesture->points_alloc);
@@ -637,15 +626,15 @@ int WM_gesture_lasso_modal(bContext *C, wmOperator *op, const wmEvent *event)
short *lasso = gesture->customdata;
lasso += (2 * gesture->points - 2);
- x = (event->x - sx - lasso[0]);
- y = (event->y - sy - lasso[1]);
+ x = (event->x - gesture->winrct.xmin - lasso[0]);
+ y = (event->y - gesture->winrct.ymin - lasso[1]);
/* make a simple distance check to get a smoother lasso
* add only when at least 2 pixels between this and previous location */
if ((x * x + y * y) > 4) {
lasso += 2;
- lasso[0] = event->x - sx;
- lasso[1] = event->y - sy;
+ lasso[0] = event->x - gesture->winrct.xmin;
+ lasso[1] = event->y - gesture->winrct.ymin;
gesture->points++;
}
}
@@ -813,18 +802,15 @@ int WM_gesture_straightline_modal(bContext *C, wmOperator *op, const wmEvent *ev
{
wmGesture *gesture = op->customdata;
rcti *rect = gesture->customdata;
- int sx, sy;
if (event->type == MOUSEMOVE) {
- wm_subwindow_origin_get(CTX_wm_window(C), gesture->swinid, &sx, &sy);
-
if (gesture->is_active == false) {
- rect->xmin = rect->xmax = event->x - sx;
- rect->ymin = rect->ymax = event->y - sy;
+ rect->xmin = rect->xmax = event->x - gesture->winrct.xmin;
+ rect->ymin = rect->ymax = event->y - gesture->winrct.ymin;
}
else {
- rect->xmax = event->x - sx;
- rect->ymax = event->y - sy;
+ rect->xmax = event->x - gesture->winrct.xmin;
+ rect->ymax = event->y - gesture->winrct.ymin;
gesture_straightline_apply(C, op);
}
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index 55ed8b2a091..adb03de4612 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -256,7 +256,7 @@ void WM_init(bContext *C, int argc, const char **argv)
clear_matcopybuf();
ED_render_clear_mtex_copybuf();
- // glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ // glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
wm_history_file_read();
diff --git a/source/blender/windowmanager/intern/wm_jobs.c b/source/blender/windowmanager/intern/wm_jobs.c
index 528b9e2b3d9..f9fe787ed2d 100644
--- a/source/blender/windowmanager/intern/wm_jobs.c
+++ b/source/blender/windowmanager/intern/wm_jobs.c
@@ -418,8 +418,8 @@ void WM_jobs_start(wmWindowManager *wm, wmJob *wm_job)
// printf("job started: %s\n", wm_job->name);
- BLI_init_threads(&wm_job->threads, do_job_thread, 1);
- BLI_insert_thread(&wm_job->threads, wm_job);
+ BLI_threadpool_init(&wm_job->threads, do_job_thread, 1);
+ BLI_threadpool_insert(&wm_job->threads, wm_job);
}
/* restarted job has timer already */
@@ -450,7 +450,7 @@ static void wm_jobs_kill_job(wmWindowManager *wm, wmJob *wm_job)
wm_job->stop = true;
WM_job_main_thread_lock_release(wm_job);
- BLI_end_threads(&wm_job->threads);
+ BLI_threadpool_end(&wm_job->threads);
WM_job_main_thread_lock_acquire(wm_job);
if (wm_job->endjob)
@@ -601,7 +601,7 @@ void wm_jobs_timer(const bContext *C, wmWindowManager *wm, wmTimer *wt)
wm_job->running = false;
WM_job_main_thread_lock_release(wm_job);
- BLI_end_threads(&wm_job->threads);
+ BLI_threadpool_end(&wm_job->threads);
WM_job_main_thread_lock_acquire(wm_job);
if (wm_job->endnote)
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 8980c4acf26..579892734db 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -59,7 +59,7 @@
#include "PIL_time.h"
#include "BLI_blenlib.h"
-#include "BLI_dial.h"
+#include "BLI_dial_2d.h"
#include "BLI_dynstr.h" /*for WM_operator_pystring */
#include "BLI_math.h"
#include "BLI_utildefines.h"
@@ -3313,7 +3313,7 @@ static void redraw_timer_step(
CTX_wm_area_set(C, sa_iter);
for (ar_iter = sa_iter->regionbase.first; ar_iter; ar_iter = ar_iter->next) {
- if (ar_iter->swinid) {
+ if (ar_iter->visible) {
CTX_wm_region_set(C, ar_iter);
ED_region_do_draw(C, ar_iter);
ar_iter->do_draw = false;
diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c
index fcb471530e0..d6a1eb81981 100644
--- a/source/blender/windowmanager/intern/wm_playanim.c
+++ b/source/blender/windowmanager/intern/wm_playanim.c
@@ -317,7 +317,7 @@ static void playanim_toscreen(PlayState *ps, PlayAnimPict *picture, struct ImBuf
/* checkerboard for case alpha */
if (ibuf->planes == 32) {
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
imm_draw_box_checker_2d(offs_x, offs_y, offs_x + span_x, offs_y + span_y);
}
diff --git a/source/blender/windowmanager/intern/wm_stereo.c b/source/blender/windowmanager/intern/wm_stereo.c
index 84b739a692e..b70769b2d51 100644
--- a/source/blender/windowmanager/intern/wm_stereo.c
+++ b/source/blender/windowmanager/intern/wm_stereo.c
@@ -110,10 +110,10 @@ static void wm_method_draw_stereo3d_interlace(wmWindow *win)
const int sizey = WM_window_pixels_y(win);
/* wmOrtho for the screen has this same offset */
- float ratiox = sizex;
- float ratioy = sizey;
- float halfx = GLA_PIXEL_OFS;
- float halfy = GLA_PIXEL_OFS;
+ float ratiox = 1.0f;
+ float ratioy = 1.0f;
+ float halfx = GLA_PIXEL_OFS / sizex;
+ float halfy = GLA_PIXEL_OFS / sizex;
Gwn_VertFormat *format = immVertexFormat();
unsigned int texcoord = GWN_vertformat_attr_add(format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
@@ -124,7 +124,7 @@ static void wm_method_draw_stereo3d_interlace(wmWindow *win)
/* leave GL_TEXTURE0 as the latest bind texture */
for (int eye = 1; eye >= 0; eye--) {
glActiveTexture(GL_TEXTURE0 + eye);
- glBindTexture(drawdata[eye]->triple->target, drawdata[eye]->triple->bind);
+ glBindTexture(GL_TEXTURE_2D, drawdata[eye]->triple->bind);
}
immUniform1i("image_a", 0);
@@ -149,8 +149,9 @@ static void wm_method_draw_stereo3d_interlace(wmWindow *win)
immEnd();
immUnbindProgram();
- for (int eye = 0; eye < 2; eye++) {
- glBindTexture(drawdata[eye]->triple->target, 0);
+ for (int eye = 1; eye >= 0; eye--) {
+ glActiveTexture(GL_TEXTURE0 + eye);
+ glBindTexture(GL_TEXTURE_2D, 0);
}
}
@@ -194,7 +195,6 @@ static void wm_method_draw_stereo3d_sidebyside(wmWindow *win)
{
wmDrawData *drawdata;
wmDrawTriple *triple;
- float halfx, halfy, ratiox, ratioy;
int view;
int soffx;
bool cross_eyed = (win->stereo3d_format->flag & S3D_SIDEBYSIDE_CROSSEYED) != 0;
@@ -203,6 +203,8 @@ static void wm_method_draw_stereo3d_sidebyside(wmWindow *win)
unsigned int texcoord = GWN_vertformat_attr_add(format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_ALPHA);
+
for (view = 0; view < 2; view ++) {
drawdata = BLI_findlink(&win->drawdata, (view * 2) + 1);
triple = drawdata->triple;
@@ -217,27 +219,16 @@ static void wm_method_draw_stereo3d_sidebyside(wmWindow *win)
soffx = 0;
}
- const int sizex = triple->x;
- const int sizey = triple->y;
+ const int sizex = WM_window_pixels_x(win);
+ const int sizey = WM_window_pixels_y(win);
/* wmOrtho for the screen has this same offset */
- ratiox = sizex;
- ratioy = sizey;
- halfx = GLA_PIXEL_OFS;
- halfy = GLA_PIXEL_OFS;
-
- /* texture rectangle has unnormalized coordinates */
- if (triple->target == GL_TEXTURE_2D) {
- ratiox /= triple->x;
- ratioy /= triple->y;
- halfx /= triple->x;
- halfy /= triple->y;
- }
-
- /* TODO: if target is always same for both eyes, bind program & set uniform before loop */
- immBindBuiltinProgram((triple->target == GL_TEXTURE_2D) ? GPU_SHADER_3D_IMAGE_MODULATE_ALPHA : GPU_SHADER_3D_IMAGE_RECT_MODULATE_ALPHA);
+ const float ratiox = 1.0f;
+ const float ratioy = 1.0f;
+ const float halfx = GLA_PIXEL_OFS / sizex;
+ const float halfy = GLA_PIXEL_OFS / sizey;
- glBindTexture(triple->target, triple->bind);
+ glBindTexture(GL_TEXTURE_2D, triple->bind);
immUniform1f("alpha", 1.0f);
immUniform1i("image", 0); /* default GL_TEXTURE0 unit */
@@ -257,18 +248,16 @@ static void wm_method_draw_stereo3d_sidebyside(wmWindow *win)
immVertex2f(pos, soffx, sizey);
immEnd();
-
- /* TODO: if target is always same for both eyes, unbind program & texture target after loop */
- glBindTexture(triple->target, 0);
- immUnbindProgram();
}
+
+ glBindTexture(GL_TEXTURE_2D, 0);
+ immUnbindProgram();
}
static void wm_method_draw_stereo3d_topbottom(wmWindow *win)
{
wmDrawData *drawdata;
wmDrawTriple *triple;
- float halfx, halfy, ratiox, ratioy;
int view;
int soffy;
@@ -276,6 +265,8 @@ static void wm_method_draw_stereo3d_topbottom(wmWindow *win)
unsigned int texcoord = GWN_vertformat_attr_add(format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_ALPHA);
+
for (view = 0; view < 2; view ++) {
drawdata = BLI_findlink(&win->drawdata, (view * 2) + 1);
triple = drawdata->triple;
@@ -287,27 +278,16 @@ static void wm_method_draw_stereo3d_topbottom(wmWindow *win)
soffy = 0;
}
- const int sizex = triple->x;
- const int sizey = triple->y;
+ const int sizex = WM_window_pixels_x(win);
+ const int sizey = WM_window_pixels_y(win);
/* wmOrtho for the screen has this same offset */
- ratiox = sizex;
- ratioy = sizey;
- halfx = GLA_PIXEL_OFS;
- halfy = GLA_PIXEL_OFS;
-
- /* texture rectangle has unnormalized coordinates */
- if (triple->target == GL_TEXTURE_2D) {
- ratiox /= triple->x;
- ratioy /= triple->y;
- halfx /= triple->x;
- halfy /= triple->y;
- }
-
- /* TODO: if target is always same for both eyes, bind program & set uniforms before loop */
- immBindBuiltinProgram((triple->target == GL_TEXTURE_2D) ? GPU_SHADER_3D_IMAGE_MODULATE_ALPHA : GPU_SHADER_3D_IMAGE_RECT_MODULATE_ALPHA);
+ const float ratiox = 1.0f;
+ const float ratioy = 1.0f;
+ const float halfx = GLA_PIXEL_OFS / sizex;
+ const float halfy = GLA_PIXEL_OFS / sizey;
- glBindTexture(triple->target, triple->bind);
+ glBindTexture(GL_TEXTURE_2D, triple->bind);
immUniform1f("alpha", 1.0f);
immUniform1i("image", 0); /* default GL_TEXTURE0 unit */
@@ -327,11 +307,10 @@ static void wm_method_draw_stereo3d_topbottom(wmWindow *win)
immVertex2f(pos, 0.0f, soffy + (sizey * 0.5f));
immEnd();
-
- /* TODO: if target is always same for both eyes, unbind program & texture target after loop */
- immUnbindProgram();
- glBindTexture(triple->target, 0);
}
+
+ immUnbindProgram();
+ glBindTexture(GL_TEXTURE_2D, 0);
}
void wm_method_draw_stereo3d(const bContext *UNUSED(C), wmWindow *win)
diff --git a/source/blender/windowmanager/intern/wm_subwindow.c b/source/blender/windowmanager/intern/wm_subwindow.c
index 57085d4f4bd..5ca34880743 100644
--- a/source/blender/windowmanager/intern/wm_subwindow.c
+++ b/source/blender/windowmanager/intern/wm_subwindow.c
@@ -21,317 +21,87 @@
* Contributor(s): 2007 Blender Foundation (refactor)
*
* ***** END GPL LICENSE BLOCK *****
- *
- *
- * Subwindow opengl handling.
- * BTW: subwindows open/close in X11 are way too slow, tried it, and choose for my own system... (ton)
- *
*/
/** \file blender/windowmanager/intern/wm_subwindow.c
* \ingroup wm
*
- * Internal subwindows used for OpenGL state, used for regions and screens.
+ * OpenGL utilities for setting up 2D viewport for window and regions.
*/
-#include <string.h>
-
-#include "MEM_guardedalloc.h"
+#include "BLI_math.h"
+#include "BLI_rect.h"
-#include "DNA_windowmanager_types.h"
#include "DNA_screen_types.h"
-
-#include "BLI_blenlib.h"
-#include "BLI_math.h"
-#include "BLI_utildefines.h"
+#include "DNA_windowmanager_types.h"
#include "BIF_gl.h"
#include "GPU_matrix.h"
#include "WM_api.h"
-#include "wm_subwindow.h"
-
-/**
- * \note #wmSubWindow stored in #wmWindow but not exposed outside this C file,
- * it seems a bit redundant (area regions can store it too, but we keep it
- * because we can store all kind of future opengl fanciness here.
- *
- * We use indices and array because:
- * - index has safety, no pointers from this C file hanging around
- * - fast lookups of indices with array, list would give overhead
- * - old code used it this way...
- * - keep option open to have 2 screens using same window
- */
-
-typedef struct wmSubWindow {
- struct wmSubWindow *next, *prev;
-
- rcti winrct;
- int swinid;
-} wmSubWindow;
-
-
-/* ******************* open, free, set, get data ******************** */
-
-/* not subwindow itself */
-static void wm_subwindow_free(wmSubWindow *UNUSED(swin))
-{
- /* future fancy stuff */
-}
-
-void wm_subwindows_free(wmWindow *win)
-{
- wmSubWindow *swin;
-
- for (swin = win->subwindows.first; swin; swin = swin->next)
- wm_subwindow_free(swin);
-
- BLI_freelistN(&win->subwindows);
-}
-
-
-int wm_subwindow_get_id(wmWindow *win)
-{
- if (win->curswin)
- return win->curswin->swinid;
- return 0;
-}
-
-static wmSubWindow *swin_from_swinid(wmWindow *win, int swinid)
-{
- wmSubWindow *swin;
-
- for (swin = win->subwindows.first; swin; swin = swin->next)
- if (swin->swinid == swinid)
- break;
- return swin;
-}
-
-static void wm_swin_size_get(wmSubWindow *swin, int *x, int *y)
-{
- *x = BLI_rcti_size_x(&swin->winrct) + 1;
- *y = BLI_rcti_size_y(&swin->winrct) + 1;
-}
-void wm_subwindow_size_get(wmWindow *win, int swinid, int *x, int *y)
+void wmViewport(const rcti *winrct)
{
- wmSubWindow *swin = swin_from_swinid(win, swinid);
-
- if (swin) {
- wm_swin_size_get(swin, x, y);
- }
-}
+ int width = BLI_rcti_size_x(winrct) + 1;
+ int height = BLI_rcti_size_y(winrct) + 1;
+ glViewport(winrct->xmin, winrct->ymin, width, height);
+ glScissor(winrct->xmin, winrct->ymin, width, height);
-static void wm_swin_origin_get(wmSubWindow *swin, int *x, int *y)
-{
- *x = swin->winrct.xmin;
- *y = swin->winrct.ymin;
-}
-void wm_subwindow_origin_get(wmWindow *win, int swinid, int *x, int *y)
-{
- wmSubWindow *swin = swin_from_swinid(win, swinid);
-
- if (swin) {
- wm_swin_origin_get(swin, x, y);
- }
+ wmOrtho2_pixelspace(width, height);
+ gpuLoadIdentity();
}
-
-static void wm_swin_matrix_get(wmWindow *win, wmSubWindow *swin, float mat[4][4])
+void wmPartialViewport(rcti *drawrct, const rcti *winrct, const rcti *partialrct)
{
- const bScreen *screen = WM_window_get_active_screen(win);
+ /* Setup part of the viewport for partial redraw. */
+ bool scissor_pad;
- /* used by UI, should find a better way to get the matrix there */
- if (swin->swinid == screen->mainwin) {
- int width, height;
-
- wm_swin_size_get(swin, &width, &height);
- orthographic_m4(mat, -GLA_PIXEL_OFS, (float)width - GLA_PIXEL_OFS, -GLA_PIXEL_OFS, (float)height - GLA_PIXEL_OFS, -100, 100);
+ if (partialrct->xmin == partialrct->xmax) {
+ /* Full region. */
+ *drawrct = *winrct;
+ scissor_pad = true;
}
else {
- gpuGetProjectionMatrix(mat);
- }
-}
-void wm_subwindow_matrix_get(wmWindow *win, int swinid, float mat[4][4])
-{
- wmSubWindow *swin = swin_from_swinid(win, swinid);
-
- if (swin) {
- wm_swin_matrix_get(win, swin, mat);
- }
-}
-
-
-static void wm_swin_rect_get(wmSubWindow *swin, rcti *r_rect)
-{
- *r_rect = swin->winrct;
-}
-void wm_subwindow_rect_get(wmWindow *win, int swinid, rcti *r_rect)
-{
- wmSubWindow *swin = swin_from_swinid(win, swinid);
-
- if (swin) {
- wm_swin_rect_get(swin, r_rect);
- }
-}
-
-
-static void wm_swin_rect_set(wmSubWindow *swin, const rcti *rect)
-{
- swin->winrct = *rect;
-}
-void wm_subwindow_rect_set(wmWindow *win, int swinid, const rcti *rect)
-{
- wmSubWindow *swin = swin_from_swinid(win, swinid);
-
- if (swin) {
- wm_swin_rect_set(swin, rect);
- }
-}
-
-
-/* always sets pixel-precise 2D window/view matrices */
-/* coords is in whole pixels. xmin = 15, xmax = 16: means window is 2 pix big */
-int wm_subwindow_open(wmWindow *win, const rcti *winrct, bool activate)
-{
- wmSubWindow *swin;
- int width, height;
- int freewinid = 1;
-
- for (swin = win->subwindows.first; swin; swin = swin->next)
- if (freewinid <= swin->swinid)
- freewinid = swin->swinid + 1;
-
- win->curswin = swin = MEM_callocN(sizeof(wmSubWindow), "swinopen");
- BLI_addtail(&win->subwindows, swin);
-
- swin->swinid = freewinid;
- swin->winrct = *winrct;
-
- if (activate) {
- /* and we appy it all right away */
- wmSubWindowSet(win, swin->swinid);
-
- /* extra service */
- wm_swin_size_get(swin, &width, &height);
- wmOrtho2_pixelspace(width, height);
- gpuLoadIdentity();
+ /* Partial redraw, clipped to region. */
+ BLI_rcti_isect(winrct, partialrct, drawrct);
+ scissor_pad = false;
}
- return swin->swinid;
-}
+ int x = drawrct->xmin;
+ int y = drawrct->ymin;
+ int width = BLI_rcti_size_x(winrct) + 1;
+ int height = BLI_rcti_size_y(winrct) + 1;
-void wm_subwindow_close(wmWindow *win, int swinid)
-{
- wmSubWindow *swin = swin_from_swinid(win, swinid);
+ int scissor_width = BLI_rcti_size_x(drawrct);
+ int scissor_height = BLI_rcti_size_y(drawrct);
- if (swin) {
- if (swin == win->curswin)
- win->curswin = NULL;
- wm_subwindow_free(swin);
- BLI_remlink(&win->subwindows, swin);
- MEM_freeN(swin);
+ /* Partial redraw rect uses different convention than region rect,
+ * so compensate for that here. One pixel offset is noticeable with
+ * viewport border render. */
+ if (scissor_pad) {
+ scissor_width += 1;
+ scissor_height += 1;
}
- else {
- printf("%s: Internal error, bad winid: %d\n", __func__, swinid);
- }
-}
-/* pixels go from 0-99 for a 100 pixel window */
-void wm_subwindow_position(wmWindow *win, int swinid, const rcti *winrct, bool activate)
-{
- wmSubWindow *swin = swin_from_swinid(win, swinid);
-
- if (swin) {
- const int window_size_x = WM_window_pixels_x(win);
- const int window_size_y = WM_window_pixels_y(win);
+ glViewport(x, y, width, height);
+ glScissor(x, y, scissor_width, scissor_height);
- int width, height;
-
- swin->winrct = *winrct;
-
- /* CRITICAL, this clamping ensures that
- * the viewport never goes outside the screen
- * edges (assuming the x, y coords aren't
- * outside). This caused a hardware lock
- * on Matrox cards if it happens.
- *
- * Really Blender should never _ever_ try
- * to do such a thing, but just to be safe
- * clamp it anyway (or fix the bScreen
- * scaling routine, and be damn sure you
- * fixed it). - zr (2001!)
- */
-
- if (swin->winrct.xmax > window_size_x)
- swin->winrct.xmax = window_size_x;
- if (swin->winrct.ymax > window_size_y)
- swin->winrct.ymax = window_size_y;
-
- if (activate) {
- /* extra service */
- wmSubWindowSet(win, swinid);
- wm_swin_size_get(swin, &width, &height);
- wmOrtho2_pixelspace(width, height);
- }
- }
- else {
- printf("%s: Internal error, bad winid: %d\n", __func__, swinid);
- }
+ wmOrtho2_pixelspace(width, height);
+ gpuLoadIdentity();
}
-/* ---------------- WM versions of OpenGL style API calls ------------------------ */
-/* ----------------- exported in WM_api.h ------------------------------------------------------ */
-
-/* internal state, no threaded opengl! XXX */
-static wmWindow *_curwindow = NULL;
-static wmSubWindow *_curswin = NULL;
-
-void wmSubWindowScissorSet(wmWindow *win, int swinid, const rcti *srct, bool srct_pad)
+void wmWindowViewport(wmWindow *win)
{
- int width, height;
- _curswin = swin_from_swinid(win, swinid);
-
- if (_curswin == NULL) {
- printf("%s %d: doesn't exist\n", __func__, swinid);
- return;
- }
-
- win->curswin = _curswin;
- _curwindow = win;
-
- width = BLI_rcti_size_x(&_curswin->winrct) + 1;
- height = BLI_rcti_size_y(&_curswin->winrct) + 1;
- glViewport(_curswin->winrct.xmin, _curswin->winrct.ymin, width, height);
-
- if (srct) {
- int scissor_width = BLI_rcti_size_x(srct);
- int scissor_height = BLI_rcti_size_y(srct);
+ int width = WM_window_pixels_x(win);
+ int height = WM_window_pixels_y(win);
- /* typically a single pixel doesn't matter,
- * but one pixel offset is noticeable with viewport border render */
- if (srct_pad) {
- scissor_width += 1;
- scissor_height += 1;
- }
+ glViewport(0, 0, width, height);
+ glScissor(0, 0, width, height);
- glScissor(srct->xmin, srct->ymin, scissor_width, scissor_height);
- }
- else
- glScissor(_curswin->winrct.xmin, _curswin->winrct.ymin, width, height);
-
wmOrtho2_pixelspace(width, height);
gpuLoadIdentity();
-
- glFlush();
-}
-
-/* enable the WM versions of opengl calls */
-void wmSubWindowSet(wmWindow *win, int swinid)
-{
- wmSubWindowScissorSet(win, swinid, NULL, true);
}
void wmOrtho2(float x1, float x2, float y1, float y2)
@@ -348,9 +118,7 @@ static void wmOrtho2_offset(const float x, const float y, const float ofs)
wmOrtho2(ofs, x + ofs, ofs, y + ofs);
}
-/**
- * default pixel alignment.
- */
+/* Default pixel alignment for regions. */
void wmOrtho2_region_pixelspace(const ARegion *ar)
{
wmOrtho2_offset(ar->winx, ar->winy, -0.01f);
@@ -361,5 +129,9 @@ void wmOrtho2_pixelspace(const float x, const float y)
wmOrtho2_offset(x, y, -GLA_PIXEL_OFS);
}
-/* ********** END MY WINDOW ************** */
-
+void wmGetProjectionMatrix(float mat[4][4], const rcti *winrct)
+{
+ int width = BLI_rcti_size_x(winrct) + 1;
+ int height = BLI_rcti_size_y(winrct) + 1;
+ orthographic_m4(mat, -GLA_PIXEL_OFS, (float)width - GLA_PIXEL_OFS, -GLA_PIXEL_OFS, (float)height - GLA_PIXEL_OFS, -100, 100);
+}
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index a1d9edd2e96..60e67bb2129 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -68,7 +68,6 @@
#include "wm.h"
#include "wm_draw.h"
#include "wm_window.h"
-#include "wm_subwindow.h"
#include "wm_event_system.h"
#include "ED_scene.h"
@@ -175,7 +174,6 @@ static void wm_ghostwindow_destroy(wmWindow *win)
if (win->ghostwin) {
GHOST_DisposeWindow(g_system, win->ghostwin);
win->ghostwin = NULL;
- win->multisamples = 0;
}
}
@@ -228,7 +226,6 @@ void wm_window_free(bContext *C, wmWindowManager *wm, wmWindow *win)
if (win->eventstate) MEM_freeN(win->eventstate);
wm_event_free_all(win);
- wm_subwindows_free(win);
wm_draw_data_free(win);
@@ -474,16 +471,8 @@ static void wm_window_ghostwindow_add(wmWindowManager *wm, const char *title, wm
{
GHOST_WindowHandle ghostwin;
GHOST_GLSettings glSettings = {0};
- static int multisamples = -1;
int scr_w, scr_h, posy;
- /* force setting multisamples only once, it requires restart - and you cannot
- * mix it, either all windows have it, or none (tested in OSX opengl) */
- if (multisamples == -1)
- multisamples = U.ogl_multisamples;
-
- glSettings.numOfAASamples = multisamples;
-
/* a new window is created when pageflip mode is required for a window */
if (win->stereo3d_format->display_mode == S3D_DISPLAY_PAGEFLIP)
glSettings.flags |= GHOST_glStereoVisual;
@@ -521,9 +510,6 @@ static void wm_window_ghostwindow_add(wmWindowManager *wm, const char *title, wm
if (win->eventstate == NULL)
win->eventstate = MEM_callocN(sizeof(wmEvent), "window event state");
- /* store multisamples window was created with, in case user prefs change */
- win->multisamples = multisamples;
-
/* store actual window size in blender window */
bounds = GHOST_GetClientBounds(win->ghostwin);
@@ -1627,6 +1613,7 @@ wmTimer *WM_event_add_timer_notifier(wmWindowManager *wm, wmWindow *win, unsigne
wt->timestep = timestep;
wt->win = win;
wt->customdata = SET_UINT_IN_POINTER(type);
+ wt->flags |= WM_TIMER_NO_FREE_CUSTOM_DATA;
BLI_addtail(&wm->timers, wt);
@@ -1648,8 +1635,9 @@ void WM_event_remove_timer(wmWindowManager *wm, wmWindow *UNUSED(win), wmTimer *
wm->reports.reporttimer = NULL;
BLI_remlink(&wm->timers, wt);
- if (wt->customdata)
+ if (wt->customdata != NULL && (wt->flags & WM_TIMER_NO_FREE_CUSTOM_DATA) == 0) {
MEM_freeN(wt->customdata);
+ }
MEM_freeN(wt);
/* there might be events in queue with this timer as customdata */
@@ -1979,6 +1967,18 @@ WorkSpace *WM_windows_workspace_get_from_screen(const wmWindowManager *wm, const
return NULL;
}
+eObjectMode WM_windows_object_mode_get(const struct wmWindowManager *wm)
+{
+ eObjectMode object_mode = 0;
+ for (wmWindow *win = wm->windows.first; win; win = win->next) {
+ const WorkSpace *workspace = BKE_workspace_active_get(win->workspace_hook);
+ if (workspace != NULL) {
+ object_mode |= workspace->object_mode;
+ }
+ }
+ return object_mode;
+}
+
Scene *WM_window_get_active_scene(const wmWindow *win)
{
return win->scene;
diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulator_map.c b/source/blender/windowmanager/manipulators/intern/wm_manipulator_map.c
index a9875020fbb..153052d7e1c 100644
--- a/source/blender/windowmanager/manipulators/intern/wm_manipulator_map.c
+++ b/source/blender/windowmanager/manipulators/intern/wm_manipulator_map.c
@@ -390,16 +390,9 @@ static void manipulators_draw_list(const wmManipulatorMap *mmap, const bContext
return;
}
- const bool draw_multisample = (U.ogl_multisamples != USER_MULTISAMPLE_NONE);
-
/* TODO this will need it own shader probably? don't think it can be handled from that point though. */
/* const bool use_lighting = (U.manipulator_flag & V3D_MANIPULATOR_SHADED) != 0; */
- /* enable multisampling */
- if (draw_multisample) {
- glEnable(GL_MULTISAMPLE);
- }
-
bool is_depth_prev = false;
/* draw_manipulators contains all visible manipulators - draw them */
@@ -435,10 +428,6 @@ static void manipulators_draw_list(const wmManipulatorMap *mmap, const bContext
if (is_depth_prev) {
glDisable(GL_DEPTH_TEST);
}
-
- if (draw_multisample) {
- glDisable(GL_MULTISAMPLE);
- }
}
void WM_manipulatormap_draw(
@@ -619,7 +608,7 @@ wmManipulator *wm_manipulatormap_highlight_find(
if (do_step[step]) {
if ((mmap->update_flag[step] & MANIPULATORMAP_IS_REFRESH_CALLBACK) &&
- (mgroup->type->refresh != NULL))
+ (mgroup->type->refresh != NULL))
{
mgroup->type->refresh(C, mgroup);
/* cleared below */
@@ -760,7 +749,7 @@ static bool wm_manipulatormap_select_all_intern(
int i;
bool changed = false;
- wm_manipulatormap_select_array_ensure_len_alloc(mmap, BLI_ghash_size(hash));
+ wm_manipulatormap_select_array_ensure_len_alloc(mmap, BLI_ghash_len(hash));
GHASH_ITER_INDEX (gh_iter, hash, i) {
wmManipulator *mpr_iter = BLI_ghashIterator_getValue(&gh_iter);
@@ -769,7 +758,7 @@ static bool wm_manipulatormap_select_all_intern(
/* highlight first manipulator */
wm_manipulatormap_highlight_set(mmap, C, msel->items[0], msel->items[0]->highlight_part);
- BLI_assert(BLI_ghash_size(hash) == msel->len);
+ BLI_assert(BLI_ghash_len(hash) == msel->len);
BLI_ghash_free(hash, NULL, NULL);
return changed;
diff --git a/source/blender/windowmanager/message_bus/intern/wm_message_bus.c b/source/blender/windowmanager/message_bus/intern/wm_message_bus.c
index 7183655b0de..dba38dc8c8c 100644
--- a/source/blender/windowmanager/message_bus/intern/wm_message_bus.c
+++ b/source/blender/windowmanager/message_bus/intern/wm_message_bus.c
@@ -86,6 +86,9 @@ void WM_msgbus_clear_by_owner(struct wmMsgBus *mbus, void *owner)
for (wmMsgSubscribeValueLink *msg_lnk = msg_key->values.first; msg_lnk; msg_lnk = msg_lnk_next) {
msg_lnk_next = msg_lnk->next;
if (msg_lnk->params.owner == owner) {
+ if (msg_lnk->params.tag) {
+ mbus->messages_tag_count -= 1;
+ }
if (msg_lnk->params.free_data) {
msg_lnk->params.free_data(msg_key, &msg_lnk->params);
}
diff --git a/source/blender/windowmanager/message_bus/intern/wm_message_bus_static.c b/source/blender/windowmanager/message_bus/intern/wm_message_bus_static.c
index 59bebad7f7b..d768e77c8fe 100644
--- a/source/blender/windowmanager/message_bus/intern/wm_message_bus_static.c
+++ b/source/blender/windowmanager/message_bus/intern/wm_message_bus_static.c
@@ -18,7 +18,7 @@
* ***** END GPL LICENSE BLOCK *****
*/
-/** \file blender/windowmanager/intern/wm_message_bus_static.c
+/** \file blender/windowmanager/intern/message_bus/wm_message_bus_static.c
* \ingroup wm
*/
diff --git a/source/blender/windowmanager/message_bus/wm_message_bus.h b/source/blender/windowmanager/message_bus/wm_message_bus.h
index 53f283cacd2..8a800d18101 100644
--- a/source/blender/windowmanager/message_bus/wm_message_bus.h
+++ b/source/blender/windowmanager/message_bus/wm_message_bus.h
@@ -18,7 +18,7 @@
* ***** END GPL LICENSE BLOCK *****
*/
-/** \file blender/windowmanager/wm_message_bus.h
+/** \file blender/windowmanager/message_bus/wm_message_bus.h
* \ingroup wm
*/
diff --git a/source/blender/windowmanager/wm_draw.h b/source/blender/windowmanager/wm_draw.h
index 56dff304719..fa3d443e6ae 100644
--- a/source/blender/windowmanager/wm_draw.h
+++ b/source/blender/windowmanager/wm_draw.h
@@ -34,12 +34,8 @@
#include "GPU_glew.h"
-#define USE_TEXTURE_RECTANGLE 1
-
typedef struct wmDrawTriple {
GLuint bind;
- int x, y;
- GLenum target;
} wmDrawTriple;
typedef struct wmDrawData {
diff --git a/source/blender/windowmanager/wm_subwindow.h b/source/blender/windowmanager/wm_subwindow.h
deleted file mode 100644
index cc9abf87514..00000000000
--- a/source/blender/windowmanager/wm_subwindow.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2007 Blender Foundation.
- * All rights reserved.
- *
- *
- * Contributor(s): Blender Foundation
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file blender/windowmanager/wm_subwindow.h
- * \ingroup wm
- */
-
-
-#ifndef __WM_SUBWINDOW_H__
-#define __WM_SUBWINDOW_H__
-
-
-/* *************** internal api ************** */
-void wm_subwindows_free(wmWindow *win);
-
-int wm_subwindow_open(wmWindow *win, const rcti *winrct, bool activate);
-void wm_subwindow_close(wmWindow *win, int swinid);
-int wm_subwindow_get_id(wmWindow *win); /* returns id */
-
-void wm_subwindow_position(wmWindow *win, int swinid, const rcti *winrct, bool activate);
-
-void wm_subwindow_size_get(wmWindow *win, int swinid, int *x, int *y);
-void wm_subwindow_origin_get(wmWindow *win, int swinid, int *x, int *y);
-void wm_subwindow_matrix_get(wmWindow *win, int swinid, float mat[4][4]);
-void wm_subwindow_rect_get(wmWindow *win, int swinid, struct rcti *r_rect);
-void wm_subwindow_rect_set(wmWindow *win, int swinid, const rcti *rect);
-
-#endif /* __WM_SUBWINDOW_H__ */
-
diff --git a/source/blenderplayer/CMakeLists.txt b/source/blenderplayer/CMakeLists.txt
index 328453df118..dc7acb5ccd7 100644
--- a/source/blenderplayer/CMakeLists.txt
+++ b/source/blenderplayer/CMakeLists.txt
@@ -197,10 +197,6 @@ endif()
list(APPEND BLENDER_SORTED_LIBS extern_ceres)
endif()
- if(WITH_MOD_BOOLEAN)
- list(APPEND BLENDER_SORTED_LIBS extern_carve)
- endif()
-
if(WITH_GHOST_XDND)
list(APPEND BLENDER_SORTED_LIBS extern_xdnd)
endif()
diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c
index 332a64f138f..a0489d7609a 100644
--- a/source/blenderplayer/bad_level_call_stubs/stubs.c
+++ b/source/blenderplayer/bad_level_call_stubs/stubs.c
@@ -448,7 +448,7 @@ void UI_view2d_sync(struct bScreen *screen, struct ScrArea *sa, struct View2D *v
struct EditBone *ED_armature_bone_get_mirrored(const struct ListBase *edbo, EditBone *ebo) RET_NULL
struct EditBone *ED_armature_edit_bone_add(struct bArmature *arm, const char *name) RET_NULL
-struct ListBase *get_active_constraints (struct Object *ob) RET_NULL
+struct ListBase *get_active_constraints (const struct EvaluationContext *eval_ctx, struct Object *ob) RET_NULL
struct ListBase *get_constraint_lb(struct Object *ob, struct bConstraint *con, struct bPoseChannel **r_pchan) RET_NULL
bool ED_space_image_show_uvedit(struct SpaceImage *sima, struct Object *obedit) RET_ZERO
@@ -521,7 +521,7 @@ bool ANIM_remove_driver(struct ReportList *reports, struct ID *id, const char rn
void ED_space_image_release_buffer(struct SpaceImage *sima, struct ImBuf *ibuf, void *lock) RET_NONE
struct ImBuf *ED_space_image_acquire_buffer(struct SpaceImage *sima, void **r_lock) RET_NULL
void ED_space_image_get_zoom(struct SpaceImage *sima, struct ARegion *ar, float *zoomx, float *zoomy) RET_NONE
-const char *ED_info_stats_string(struct Scene *scene, struct ViewLayer *view_layer) RET_NULL
+const char *ED_info_stats_string(struct Scene *scene, struct WorkSpace *workspace, struct ViewLayer *view_layer) RET_NULL
void ED_area_tag_redraw(struct ScrArea *sa) RET_NONE
void ED_area_tag_refresh(struct ScrArea *sa) RET_NONE
void ED_area_newspace(struct bContext *C, struct ScrArea *sa, int type, const bool skip_ar_exit) RET_NONE
@@ -548,21 +548,25 @@ void ED_view3d_quadview_update(struct ScrArea *sa, struct ARegion *ar, bool do_c
void ED_view3d_from_m4(float mat[4][4], float ofs[3], float quat[4], float *dist) RET_NONE
void ED_view3d_update_viewmat(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct View3D *v3d, struct ARegion *ar, float viewmat[4][4], float winmat[4][4], const struct rcti *rect) RET_NONE
float ED_view3d_grid_scale(struct Scene *scene, struct View3D *v3d, const char **grid_unit) RET_ZERO
-void ED_view3d_shade_update(struct Main *bmain, struct Scene *scene, struct View3D *v3d, struct ScrArea *sa) RET_NONE
+void ED_view3d_shade_update(struct Main *bmain, struct View3D *v3d, struct ScrArea *sa) RET_NONE
void ED_node_shader_default(const struct bContext *C, struct ID *id) RET_NONE
void ED_screen_animation_timer_update(struct bScreen *screen, int redraws, int refresh) RET_NONE
struct bScreen *ED_screen_animation_playing(const struct wmWindowManager *wm) RET_NULL
struct Scene *ED_screen_scene_find(const struct bScreen *screen, const struct wmWindowManager *wm) RET_NULL
+struct Scene *ED_screen_scene_find_with_window(const struct bScreen *screen, const struct wmWindowManager *wm, struct wmWindow **r_window) RET_NULL
+struct wmWindow *ED_screen_window_find(const struct bScreen *screen, const struct wmWindowManager *wm) RET_NULL;
void ED_screen_global_topbar_area_create(const struct bContext *C, struct wmWindow *win, const struct bScreen *screen) RET_NONE
bool ED_scene_view_layer_delete(struct Main *bmain, Scene *scene, ViewLayer *layer, ReportList *reports) RET_ZERO
void ED_object_base_select(struct Base *base, eObjectSelect_Mode mode) RET_NONE
+void ED_object_base_activate(struct bContext *C, struct Base *base) RET_NONE
bool ED_object_modifier_remove(struct ReportList *reports, struct Main *bmain, struct Object *ob, struct ModifierData *md) RET_ZERO
-struct ModifierData *ED_object_modifier_add(struct ReportList *reports, struct Main *bmain, struct Scene *scene, struct Object *ob, const char *name, int type) RET_ZERO
+struct ModifierData *ED_object_modifier_add(struct ReportList *reports, struct Main *bmain, struct Scene *scene, struct Object *ob, eObjectMode object_mode, const char *name, int type) RET_ZERO
void ED_object_modifier_clear(struct Main *bmain, struct Object *ob) RET_NONE
void ED_object_editmode_enter(struct bContext *C, int flag) RET_NONE
void ED_object_editmode_exit(struct bContext *C, int flag) RET_NONE
+void ED_object_editmode_exit_ex(struct bContext *C, struct WorkSpace *workspace, struct Scene *scene, struct Object *obedit, int flag) RET_NONE
bool ED_object_editmode_load(struct Object *obedit) RET_ZERO
-void ED_object_check_force_modifiers(struct Main *bmain, struct Scene *scene, struct Object *object) RET_NONE
+void ED_object_check_force_modifiers(struct Main *bmain, struct Scene *scene, struct Object *object, eObjectMode object_mode) RET_NONE
bool uiLayoutGetActive(struct uiLayout *layout) RET_ZERO
int uiLayoutGetOperatorContext(struct uiLayout *layout) RET_ZERO
int uiLayoutGetAlignment(struct uiLayout *layout) RET_ZERO
@@ -602,7 +606,7 @@ int ED_mesh_mirror_spatial_table(struct Object *ob, struct BMEditMesh *em, struc
float ED_rollBoneToVector(EditBone *bone, const float new_up_axis[3], const bool axis_only) RET_ZERO
void ED_space_image_get_size(struct SpaceImage *sima, int *width, int *height) RET_NONE
-bool ED_space_image_check_show_maskedit(struct ViewLayer *view_layer, struct SpaceImage *sima) RET_ZERO
+bool ED_space_image_check_show_maskedit(struct SpaceImage *sima, const struct WorkSpace *workspace, struct ViewLayer *view_layer) RET_ZERO
bool ED_texture_context_check_world(const struct bContext *C) RET_ZERO
bool ED_texture_context_check_material(const struct bContext *C) RET_ZERO
@@ -774,7 +778,7 @@ void RE_point_density_cache(struct Scene *scene, struct ViewLayer *view_layer, s
void RE_point_density_minmax(struct Scene *scene, struct ViewLayer *view_layer, struct PointDensity *pd, const bool use_render_params, float r_min[3], float r_max[3]) RET_NONE
void RE_point_density_sample(struct Scene *scene, struct ViewLayer *view_layer, struct PointDensity *pd, const int resolution, const bool use_render_params, float *values) RET_NONE
void RE_point_density_free(struct PointDensity *pd) RET_NONE
-void RE_instance_get_particle_info(struct ObjectInstanceRen *obi, float *index, float *age, float *lifetime, float co[3], float *size, float vel[3], float angvel[3]) RET_NONE
+void RE_instance_get_particle_info(struct ObjectInstanceRen *obi, float *index, float *random, float *age, float *lifetime, float co[3], float *size, float vel[3], float angvel[3]) RET_NONE
void RE_FreeAllPersistentData(void) RET_NONE
float RE_fresnel_dielectric(float incoming[3], float normal[3], float eta) RET_ZERO
void RE_engine_register_pass(struct RenderEngine *engine, struct Scene *scene, struct ViewLayer *view_layer, const char *name, int channels, const char *chanid, int type) RET_NONE
diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt
index c5acd7e640e..b6229539cd9 100644
--- a/source/creator/CMakeLists.txt
+++ b/source/creator/CMakeLists.txt
@@ -1030,70 +1030,4 @@ if(WIN32 AND NOT WITH_PYTHON_MODULE)
COMPONENT Blender
DESTINATION "."
)
- if(CMAKE_CL_64)
- set(_WIN_PLATFORM x64)
- else()
- set(_WIN_PLATFORM x86)
- endif()
- if(MSVC12_REDIST_DIR)
- install(
- FILES
- ${MSVC12_REDIST_DIR}/${_WIN_PLATFORM}/Microsoft.VC120.CRT/msvcp120.dll
- ${MSVC12_REDIST_DIR}/${_WIN_PLATFORM}/Microsoft.VC120.CRT/msvcr120.dll
- DESTINATION "."
- )
- if(WITH_OPENMP)
- install(
- FILES ${MSVC12_REDIST_DIR}/${_WIN_PLATFORM}/Microsoft.VC120.OpenMP/vcomp120.dll
- DESTINATION "."
- )
- endif()
- endif()
-
- if(MSVC14_REDIST_DIR)
- set(KITSDIRx86 "$ENV{${ProgramFilesX86_NAME}}/Windows Kits/10/")
- set(KITSDIR "$ENV{ProgramFiles}/Windows Kits/10/")
- if(IS_DIRECTORY ${KITSDIR})
- set(KITSPATH "${KITSDIR}/Redist/ucrt/DLLs/${_WIN_PLATFORM}")
- else()
- if(IS_DIRECTORY ${KITSDIRx86})
- set(KITSPATH "${KITSDIRx86}/Redist/ucrt/DLLs/${_WIN_PLATFORM}")
- else()
- message(FATAL_ERROR "Windows 10 SDK directory not found")
- endif()
- endif()
- FILE(TO_CMAKE_PATH ${KITSPATH} KITSPATH)
- install(
- FILES
- ${KITSPATH}/api-ms-win-core-file-l1-2-0.dll
- ${KITSPATH}/api-ms-win-core-file-l2-1-0.dll
- ${KITSPATH}/api-ms-win-core-localization-l1-2-0.dll
- ${KITSPATH}/api-ms-win-core-processthreads-l1-1-0.dll
- ${KITSPATH}/api-ms-win-core-processthreads-l1-1-1.dll
- ${KITSPATH}/api-ms-win-core-synch-l1-1-0.dll
- ${KITSPATH}/api-ms-win-core-synch-l1-2-0.dll
- ${KITSPATH}/api-ms-win-core-timezone-l1-1-0.dll
- ${KITSPATH}/api-ms-win-crt-conio-l1-1-0.dll
- ${KITSPATH}/api-ms-win-crt-convert-l1-1-0.dll
- ${KITSPATH}/api-ms-win-crt-environment-l1-1-0.dll
- ${KITSPATH}/api-ms-win-crt-filesystem-l1-1-0.dll
- ${KITSPATH}/api-ms-win-crt-heap-l1-1-0.dll
- ${KITSPATH}/api-ms-win-crt-locale-l1-1-0.dll
- ${KITSPATH}/api-ms-win-crt-math-l1-1-0.dll
- ${KITSPATH}/api-ms-win-crt-process-l1-1-0.dll
- ${KITSPATH}/api-ms-win-crt-runtime-l1-1-0.dll
- ${KITSPATH}/api-ms-win-crt-stdio-l1-1-0.dll
- ${KITSPATH}/api-ms-win-crt-string-l1-1-0.dll
- ${KITSPATH}/api-ms-win-crt-time-l1-1-0.dll
- ${KITSPATH}/ucrtbase.dll
- ${MSVC14_REDIST_DIR}/${_WIN_PLATFORM}/Microsoft.VC140.CRT/vcruntime140.dll
- DESTINATION "."
- )
- if(WITH_OPENMP)
- install(
- FILES ${MSVC14_REDIST_DIR}/${_WIN_PLATFORM}/Microsoft.VC140.OpenMP/vcomp140.dll
- DESTINATION "."
- )
- endif()
- endif()
endif()
diff --git a/source/creator/creator_args.c b/source/creator/creator_args.c
index 6b47d7c3474..fba3189d5ed 100644
--- a/source/creator/creator_args.c
+++ b/source/creator/creator_args.c
@@ -1348,7 +1348,7 @@ static const char arg_handle_render_frame_doc[] =
"\n"
"\t* +<frame> start frame relative, -<frame> end frame relative.\n"
"\t* A comma separated list of frames can also be used (no spaces).\n"
-"\t* A range of frames can be expressed using '..' seperator between the first and last frames (inclusive).\n"
+"\t* A range of frames can be expressed using '..' separator between the first and last frames (inclusive).\n"
;
static int arg_handle_render_frame(int argc, const char **argv, void *data)
{
@@ -1373,7 +1373,7 @@ static int arg_handle_render_frame(int argc, const char **argv, void *data)
}
re = RE_NewSceneRender(scene);
- BLI_begin_threaded_malloc();
+ BLI_threaded_malloc_begin();
BKE_reports_init(&reports, RPT_STORE);
RE_SetReports(re, &reports);
render_set_depgraph(C, re);
@@ -1390,7 +1390,7 @@ static int arg_handle_render_frame(int argc, const char **argv, void *data)
}
RE_SetReports(re, NULL);
BKE_reports_clear(&reports);
- BLI_end_threaded_malloc();
+ BLI_threaded_malloc_end();
MEM_freeN(frame_range_arr);
return 1;
}
@@ -1416,14 +1416,14 @@ static int arg_handle_render_animation(int UNUSED(argc), const char **UNUSED(arg
Main *bmain = CTX_data_main(C);
Render *re = RE_NewSceneRender(scene);
ReportList reports;
- BLI_begin_threaded_malloc();
+ BLI_threaded_malloc_begin();
BKE_reports_init(&reports, RPT_STORE);
RE_SetReports(re, &reports);
render_set_depgraph(C, re);
RE_BlenderAnim(re, bmain, scene, NULL, scene->lay, scene->r.sfra, scene->r.efra, scene->r.frame_step);
RE_SetReports(re, NULL);
BKE_reports_clear(&reports);
- BLI_end_threaded_malloc();
+ BLI_threaded_malloc_end();
}
else {
printf("\nError: no blend loaded. cannot use '-a'.\n");
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
index acd425e788a..dda1864f07c 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -132,7 +132,7 @@
#include "DNA_key_types.h"
#include "DNA_armature_types.h"
#include "DNA_action_types.h"
-#include "DNA_object_force.h"
+#include "DNA_object_force_types.h"
#include "DNA_constraint_types.h"
#include "MEM_guardedalloc.h"
@@ -1688,6 +1688,7 @@ struct parentChildLink {
SG_Node* m_gamechildnode;
};
+#if 0
static bPoseChannel *get_active_posechannel2(Object *ob)
{
bArmature *arm= (bArmature*)ob->data;
@@ -1701,6 +1702,7 @@ static bPoseChannel *get_active_posechannel2(Object *ob)
return NULL;
}
+#endif
static ListBase *get_active_constraints2(Object *ob)
{
@@ -1708,6 +1710,7 @@ static ListBase *get_active_constraints2(Object *ob)
return NULL;
// XXX - shouldnt we care about the pose data and not the mode???
+#if 0
if (ob->mode & OB_MODE_POSE) {
bPoseChannel *pchan;
@@ -1715,8 +1718,11 @@ static ListBase *get_active_constraints2(Object *ob)
if (pchan)
return &pchan->constraints;
}
- else
+ else
+#endif
+ {
return &ob->constraints;
+ }
return NULL;
}
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
index 72c96668fe7..78d2d88cc65 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
@@ -49,7 +49,7 @@ subject to the following restrictions:
#include "DNA_scene_types.h"
#include "DNA_world_types.h"
-#include "DNA_object_force.h"
+#include "DNA_object_force_types.h"
extern "C" {
#include "BLI_utildefines.h"
diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.cpp b/source/gameengine/VideoTexture/VideoFFmpeg.cpp
index 083e9e28502..10196804656 100644
--- a/source/gameengine/VideoTexture/VideoFFmpeg.cpp
+++ b/source/gameengine/VideoTexture/VideoFFmpeg.cpp
@@ -467,8 +467,8 @@ bool VideoFFmpeg::startCache()
CachePacket *packet = new CachePacket();
BLI_addtail(&m_packetCacheFree, packet);
}
- BLI_init_threads(&m_thread, cacheThread, 1);
- BLI_insert_thread(&m_thread, this);
+ BLI_threadpool_init(&m_thread, cacheThread, 1);
+ BLI_threadpool_insert(&m_thread, this);
m_cacheStarted = true;
}
return m_cacheStarted;
@@ -479,7 +479,7 @@ void VideoFFmpeg::stopCache()
if (m_cacheStarted)
{
m_stopThread = true;
- BLI_end_threads(&m_thread);
+ BLI_threadpool_end(&m_thread);
// now delete the cache
CacheFrame *frame;
CachePacket *packet;
diff --git a/source/tools b/source/tools
-Subproject ccf20e08702ee6424edbda01544bb9f8bc386de
+Subproject b11375e89061303401376f7aeae42ac2fd64692