diff options
author | Sam Kottler <dev@samkottler.net> | 2020-08-20 19:40:02 +0300 |
---|---|---|
committer | Sam Kottler <dev@samkottler.net> | 2020-08-20 19:40:02 +0300 |
commit | 9dd50b39a433dc09b634d70ca8533ad19b4d1d5e (patch) | |
tree | 96341c40a13f620aa7f6a92fd6783dc6883216b0 | |
parent | 35624cdfe5186ee916e4519a013ef5c078d9c667 (diff) | |
parent | c74b4caa724bf74de41ba3928cdd824aa9ba59d2 (diff) |
Merge remote-tracking branch 'origin/blender-v2.90-release' into soc-2020-production-ready-light-tree-2soc-2020-production-ready-light-tree-2
76 files changed, 779 insertions, 231 deletions
diff --git a/.clang-format b/.clang-format index cb5cdab496f..77b90dc68f9 100644 --- a/.clang-format +++ b/.clang-format @@ -236,6 +236,7 @@ ForEachMacros: - LISTBASE_CIRCULAR_FORWARD_BEGIN - LISTBASE_FOREACH - LISTBASE_FOREACH_BACKWARD + - LISTBASE_FOREACH_INDEX - LISTBASE_FOREACH_MUTABLE - LISTBASE_FOREACH_BACKWARD_MUTABLE - MAN_ITER_AXES_BEGIN diff --git a/CMakeLists.txt b/CMakeLists.txt index bc4d4e032af..cee8675934d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -428,6 +428,10 @@ if(WIN32) option(WITH_TBB_MALLOC_PROXY "Enable the TBB malloc replacement" ON) endif() +# This should be turned off when Blender enter beta/rc/release +option(WITH_EXPERIMENTAL_FEATURES "Enable experimental features (still need to enable them in the user preferences)" OFF) +mark_as_advanced(WITH_EXPERIMENTAL_FEATURES) + # Unit testsing option(WITH_GTESTS "Enable GTest unit testing" OFF) option(WITH_OPENGL_RENDER_TESTS "Enable OpenGL render related unit testing (Experimental)" OFF) diff --git a/build_files/cmake/platform/platform_apple.cmake b/build_files/cmake/platform/platform_apple.cmake index a80b0b56901..2dc724f8376 100644 --- a/build_files/cmake/platform/platform_apple.cmake +++ b/build_files/cmake/platform/platform_apple.cmake @@ -373,8 +373,9 @@ if(WITH_CYCLES_OSL) list(APPEND OSL_LIBRARIES ${OSL_LIB_COMP} -force_load ${OSL_LIB_EXEC} ${OSL_LIB_QUERY}) find_path(OSL_INCLUDE_DIR OSL/oslclosure.h PATHS ${CYCLES_OSL}/include) find_program(OSL_COMPILER NAMES oslc PATHS ${CYCLES_OSL}/bin) + find_path(OSL_SHADER_DIR NAMES stdosl.h PATHS ${CYCLES_OSL}/shaders) - if(OSL_INCLUDE_DIR AND OSL_LIBRARIES AND OSL_COMPILER) + if(OSL_INCLUDE_DIR AND OSL_LIBRARIES AND OSL_COMPILER AND OSL_SHADER_DIR) set(OSL_FOUND TRUE) else() message(STATUS "OSL not found") diff --git a/intern/cycles/blender/CMakeLists.txt b/intern/cycles/blender/CMakeLists.txt index 2316800e21e..e0fa45dffbc 100644 --- a/intern/cycles/blender/CMakeLists.txt +++ b/intern/cycles/blender/CMakeLists.txt @@ -109,6 +109,10 @@ if(WITH_OPENIMAGEDENOISE) ) endif() +if(WITH_EXPERIMENTAL_FEATURES) + add_definitions(-DWITH_HAIR_NODES) +endif() + blender_add_lib(bf_intern_cycles "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") # avoid link failure with clang 3.4 debug diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp index 82c99631a89..6288c370567 100644 --- a/intern/cycles/blender/blender_curves.cpp +++ b/intern/cycles/blender/blender_curves.cpp @@ -628,6 +628,7 @@ void BlenderSync::sync_particle_hair( } } +#ifdef WITH_HAIR_NODES static float4 hair_point_as_float4(BL::HairPoint b_point) { float4 mP = float3_to_float4(get_float3(b_point.co())); @@ -806,6 +807,15 @@ void BlenderSync::sync_hair(Hair *hair, BL::Object &b_ob, bool motion, int motio export_hair_curves(scene, hair, b_hair); } } +#else +void BlenderSync::sync_hair(Hair *hair, BL::Object &b_ob, bool motion, int motion_step) +{ + (void)hair; + (void)b_ob; + (void)motion; + (void)motion_step; +} +#endif void BlenderSync::sync_hair(BL::Depsgraph b_depsgraph, BL::Object b_ob, diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index 3ea6892a349..e0792962b01 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -458,15 +458,19 @@ void BlenderSync::sync_motion(BL::RenderSettings &b_render, python_thread_state_restore(python_thread_state); b_engine.frame_set(frame, subframe); python_thread_state_save(python_thread_state); - sync_camera_motion(b_render, b_cam, width, height, 0.0f); + if (b_cam) { + sync_camera_motion(b_render, b_cam, width, height, 0.0f); + } sync_objects(b_depsgraph, b_v3d, 0.0f); } /* Insert motion times from camera. Motion times from other objects * have already been added in a sync_objects call. */ - uint camera_motion_steps = object_motion_steps(b_cam, b_cam); - for (size_t step = 0; step < camera_motion_steps; step++) { - motion_times.insert(scene->camera->motion_time(step)); + if (b_cam) { + uint camera_motion_steps = object_motion_steps(b_cam, b_cam); + for (size_t step = 0; step < camera_motion_steps; step++) { + motion_times.insert(scene->camera->motion_time(step)); + } } /* note iteration over motion_times set happens in sorted order */ diff --git a/intern/cycles/bvh/bvh_embree.cpp b/intern/cycles/bvh/bvh_embree.cpp index 17e1f86a589..4ef873634f0 100644 --- a/intern/cycles/bvh/bvh_embree.cpp +++ b/intern/cycles/bvh/bvh_embree.cpp @@ -126,9 +126,13 @@ static void rtc_filter_occluded_func(const RTCFilterFunctionNArguments *args) } else { kernel_embree_convert_hit(kg, ray, hit, ¤t_isect); - if (ctx->local_object_id != current_isect.object) { + int object = (current_isect.object == OBJECT_NONE) ? + kernel_tex_fetch(__prim_object, current_isect.prim) : + current_isect.object; + if (ctx->local_object_id != object) { /* This tells Embree to continue tracing. */ *args->valid = 0; + break; } } diff --git a/intern/cycles/kernel/svm/svm_sky.h b/intern/cycles/kernel/svm/svm_sky.h index f824184c1d4..b908732f026 100644 --- a/intern/cycles/kernel/svm/svm_sky.h +++ b/intern/cycles/kernel/svm/svm_sky.h @@ -137,7 +137,7 @@ ccl_device float3 sky_radiance_nishita(KernelGlobals *kg, float sun_rotation = nishita_data[7]; float angular_diameter = nishita_data[8]; float sun_intensity = nishita_data[9]; - bool sun_disc = (angular_diameter > 0.0f); + bool sun_disc = (angular_diameter >= 0.0f); float3 xyz; /* convert dir to spherical coordinates */ float2 direction = direction_to_spherical(dir); diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp index 9193067f444..33bd9f655b4 100644 --- a/intern/cycles/render/light.cpp +++ b/intern/cycles/render/light.cpp @@ -985,7 +985,7 @@ void LightManager::device_update_background(Device *device, sun_direction = transform_direction(&sky_transform, sun_direction); /* Pack sun direction and size. */ - float half_angle = sky->sun_size * 0.5f; + float half_angle = sky->get_sun_size() * 0.5f; kbackground->sun = make_float4( sun_direction.x, sun_direction.y, sun_direction.z, half_angle); diff --git a/intern/cycles/render/mesh_volume.cpp b/intern/cycles/render/mesh_volume.cpp index 0b57243fec1..2ee51f4b732 100644 --- a/intern/cycles/render/mesh_volume.cpp +++ b/intern/cycles/render/mesh_volume.cpp @@ -555,6 +555,7 @@ void GeometryManager::create_volume_mesh(Mesh *mesh, Progress &progress) mesh->clear(true); mesh->reserve_mesh(vertices.size(), indices.size() / 3); mesh->used_shaders.push_back(volume_shader); + mesh->need_update_rebuild = true; for (size_t i = 0; i < vertices.size(); ++i) { mesh->add_vertex(vertices[i]); diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index d5f65fb54db..a50544242f7 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -776,7 +776,7 @@ static void sky_texture_precompute_nishita(SunSky *sunsky, sunsky->nishita_data[5] = pixel_top[2]; sunsky->nishita_data[6] = sun_elevation; sunsky->nishita_data[7] = sun_rotation; - sunsky->nishita_data[8] = sun_disc ? sun_size : 0.0f; + sunsky->nishita_data[8] = sun_disc ? sun_size : -1.0f; sunsky->nishita_data[9] = sun_intensity; } @@ -834,7 +834,7 @@ void SkyTextureNode::compile(SVMCompiler &compiler) sky_texture_precompute_nishita(&sunsky, sun_disc, - sun_size, + get_sun_size(), sun_intensity, sun_elevation, sun_rotation, @@ -930,7 +930,7 @@ void SkyTextureNode::compile(OSLCompiler &compiler) sky_texture_precompute_nishita(&sunsky, sun_disc, - sun_size, + get_sun_size(), sun_intensity, sun_elevation, sun_rotation, diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index 326f1d14168..c21bcacb3ce 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -179,6 +179,12 @@ class SkyTextureNode : public TextureNode { float ozone_density; float3 vector; ImageHandle handle; + + float get_sun_size() + { + /* Clamping for numerical precision. */ + return fmaxf(sun_size, 0.0005f); + } }; class OutputNode : public ShaderNode { diff --git a/intern/ghost/intern/GHOST_XrContext.cpp b/intern/ghost/intern/GHOST_XrContext.cpp index 16687c34679..6bbb6ea1bcc 100644 --- a/intern/ghost/intern/GHOST_XrContext.cpp +++ b/intern/ghost/intern/GHOST_XrContext.cpp @@ -23,6 +23,7 @@ #include <cassert> #include <sstream> #include <string> +#include <string_view> #include "GHOST_Types.h" #include "GHOST_XrException.h" @@ -88,18 +89,26 @@ void GHOST_XrContext::initialize(const GHOST_XrContextCreateInfo *create_info) printAvailableAPILayersAndExtensionsInfo(); } - m_gpu_binding_type = determineGraphicsBindingTypeToEnable(create_info); + /* Multiple graphics binding extensions can be enabled, but only one will actually be used + * (determined later on). */ + const std::vector<GHOST_TXrGraphicsBinding> graphics_binding_types = + determineGraphicsBindingTypesToEnable(create_info); assert(m_oxr->instance == XR_NULL_HANDLE); - createOpenXRInstance(); + createOpenXRInstance(graphics_binding_types); storeInstanceProperties(); + + /* Multiple bindings may be enabled. Now that we know the runtime in use, settle for one. */ + m_gpu_binding_type = determineGraphicsBindingTypeToUse(graphics_binding_types); + printInstanceInfo(); if (isDebugMode()) { initDebugMessenger(); } } -void GHOST_XrContext::createOpenXRInstance() +void GHOST_XrContext::createOpenXRInstance( + const std::vector<GHOST_TXrGraphicsBinding> &graphics_binding_types) { XrInstanceCreateInfo create_info = {XR_TYPE_INSTANCE_CREATE_INFO}; @@ -108,7 +117,7 @@ void GHOST_XrContext::createOpenXRInstance() create_info.applicationInfo.apiVersion = XR_CURRENT_API_VERSION; getAPILayersToEnable(m_enabled_layers); - getExtensionsToEnable(m_enabled_extensions); + getExtensionsToEnable(graphics_binding_types, m_enabled_extensions); create_info.enabledApiLayerCount = m_enabled_layers.size(); create_info.enabledApiLayerNames = m_enabled_layers.data(); create_info.enabledExtensionCount = m_enabled_extensions.size(); @@ -340,7 +349,7 @@ static bool openxr_layer_is_available(const std::vector<XrApiLayerProperties> la } static bool openxr_extension_is_available(const std::vector<XrExtensionProperties> extensions_info, - const std::string &extension_name) + const std::string_view &extension_name) { for (const XrExtensionProperties &ext_info : extensions_info) { if (ext_info.extensionName == extension_name) { @@ -393,32 +402,30 @@ static const char *openxr_ext_name_from_wm_gpu_binding(GHOST_TXrGraphicsBinding /** * Gather an array of names for the extensions to enable. */ -void GHOST_XrContext::getExtensionsToEnable(std::vector<const char *> &r_ext_names) +void GHOST_XrContext::getExtensionsToEnable( + const std::vector<GHOST_TXrGraphicsBinding> &graphics_binding_types, + std::vector<const char *> &r_ext_names) { - assert(m_gpu_binding_type != GHOST_kXrGraphicsUnknown); - - const char *gpu_binding = openxr_ext_name_from_wm_gpu_binding(m_gpu_binding_type); - static std::vector<std::string> try_ext; - - try_ext.clear(); + std::vector<std::string_view> try_ext; /* Try enabling debug extension. */ -#ifndef WIN32 if (isDebugMode()) { try_ext.push_back(XR_EXT_DEBUG_UTILS_EXTENSION_NAME); } -#endif - r_ext_names.reserve(try_ext.size() + 1); /* + 1 for graphics binding extension. */ + r_ext_names.reserve(try_ext.size() + graphics_binding_types.size()); - /* Add graphics binding extension. */ - assert(gpu_binding); - assert(openxr_extension_is_available(m_oxr->extensions, gpu_binding)); - r_ext_names.push_back(gpu_binding); + /* Add graphics binding extensions (may be multiple ones, we'll settle for one to use later, once + * we have more info about the runtime). */ + for (GHOST_TXrGraphicsBinding type : graphics_binding_types) { + const char *gpu_binding = openxr_ext_name_from_wm_gpu_binding(type); + assert(openxr_extension_is_available(m_oxr->extensions, gpu_binding)); + r_ext_names.push_back(gpu_binding); + } - for (const std::string &ext : try_ext) { + for (const std::string_view &ext : try_ext) { if (openxr_extension_is_available(m_oxr->extensions, ext)) { - r_ext_names.push_back(ext.c_str()); + r_ext_names.push_back(ext.data()); } } } @@ -427,9 +434,10 @@ void GHOST_XrContext::getExtensionsToEnable(std::vector<const char *> &r_ext_nam * Decide which graphics binding extension to use based on * #GHOST_XrContextCreateInfo.gpu_binding_candidates and available extensions. */ -GHOST_TXrGraphicsBinding GHOST_XrContext::determineGraphicsBindingTypeToEnable( +std::vector<GHOST_TXrGraphicsBinding> GHOST_XrContext::determineGraphicsBindingTypesToEnable( const GHOST_XrContextCreateInfo *create_info) { + std::vector<GHOST_TXrGraphicsBinding> result; assert(create_info->gpu_binding_candidates != NULL); assert(create_info->gpu_binding_candidates_count > 0); @@ -438,11 +446,35 @@ GHOST_TXrGraphicsBinding GHOST_XrContext::determineGraphicsBindingTypeToEnable( const char *ext_name = openxr_ext_name_from_wm_gpu_binding( create_info->gpu_binding_candidates[i]); if (openxr_extension_is_available(m_oxr->extensions, ext_name)) { - return create_info->gpu_binding_candidates[i]; + result.push_back(create_info->gpu_binding_candidates[i]); } } - return GHOST_kXrGraphicsUnknown; + if (result.empty()) { + throw GHOST_XrException("No supported graphics binding found."); + } + + return result; +} + +GHOST_TXrGraphicsBinding GHOST_XrContext::determineGraphicsBindingTypeToUse( + const std::vector<GHOST_TXrGraphicsBinding> &enabled_types) +{ + /* Return the first working type. */ + for (GHOST_TXrGraphicsBinding type : enabled_types) { +#ifdef WIN32 + /* The SteamVR OpenGL backend fails currently. Disable it and allow falling back to the DirectX + * one. */ + if ((m_runtime_id == OPENXR_RUNTIME_STEAMVR) && (type == GHOST_kXrGraphicsOpenGL)) { + continue; + } +#endif + + assert(type != GHOST_kXrGraphicsUnknown); + return type; + } + + throw GHOST_XrException("Failed to determine a graphics binding to use."); } /** \} */ /* OpenXR API-Layers and Extensions */ diff --git a/intern/ghost/intern/GHOST_XrContext.h b/intern/ghost/intern/GHOST_XrContext.h index d2edb40c080..0b59c934c4d 100644 --- a/intern/ghost/intern/GHOST_XrContext.h +++ b/intern/ghost/intern/GHOST_XrContext.h @@ -114,7 +114,7 @@ class GHOST_XrContext : public GHOST_IXrContext { bool m_debug = false; bool m_debug_time = false; - void createOpenXRInstance(); + void createOpenXRInstance(const std::vector<GHOST_TXrGraphicsBinding> &graphics_binding_types); void storeInstanceProperties(); void initDebugMessenger(); @@ -126,7 +126,10 @@ class GHOST_XrContext : public GHOST_IXrContext { void initExtensions(); void initExtensionsEx(std::vector<XrExtensionProperties> &extensions, const char *layer_name); void getAPILayersToEnable(std::vector<const char *> &r_ext_names); - void getExtensionsToEnable(std::vector<const char *> &r_ext_names); - GHOST_TXrGraphicsBinding determineGraphicsBindingTypeToEnable( + void getExtensionsToEnable(const std::vector<GHOST_TXrGraphicsBinding> &graphics_binding_types, + std::vector<const char *> &r_ext_names); + std::vector<GHOST_TXrGraphicsBinding> determineGraphicsBindingTypesToEnable( const GHOST_XrContextCreateInfo *create_info); + GHOST_TXrGraphicsBinding determineGraphicsBindingTypeToUse( + const std::vector<GHOST_TXrGraphicsBinding> &enabled_types); }; diff --git a/intern/ghost/intern/GHOST_XrSwapchain.cpp b/intern/ghost/intern/GHOST_XrSwapchain.cpp index f7808c20112..2f900c853ba 100644 --- a/intern/ghost/intern/GHOST_XrSwapchain.cpp +++ b/intern/ghost/intern/GHOST_XrSwapchain.cpp @@ -95,7 +95,8 @@ GHOST_XrSwapchain::GHOST_XrSwapchain(GHOST_IXrGraphicsBinding &gpu_binding, GHOST_XrSwapchain::GHOST_XrSwapchain(GHOST_XrSwapchain &&other) : m_oxr(std::move(other.m_oxr)), m_image_width(other.m_image_width), - m_image_height(other.m_image_height) + m_image_height(other.m_image_height), + m_is_srgb_buffer(other.m_is_srgb_buffer) { /* Prevent xrDestroySwapchain call for the moved out item. */ other.m_oxr = nullptr; diff --git a/release/scripts/modules/rna_prop_ui.py b/release/scripts/modules/rna_prop_ui.py index 662c1d908fc..98722ea322b 100644 --- a/release/scripts/modules/rna_prop_ui.py +++ b/release/scripts/modules/rna_prop_ui.py @@ -309,13 +309,15 @@ def draw(layout, context, context_member, property_type, use_edit=True): # Do not allow editing of overridden properties (we cannot use a poll function of the operators here # since they's have no access to the specific property...). row.enabled = not(is_lib_override and key in rna_item.id_data.override_library.reference) - if not is_rna: + if is_rna: + row.label(text="API Defined") + elif is_lib_override: + row.label(text="Library Override") + else: props = row.operator("wm.properties_edit", text="Edit") assign_props(props, val_draw, key) props = row.operator("wm.properties_remove", text="", icon='REMOVE') assign_props(props, val_draw, key) - else: - row.label(text="API Defined") del flow diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index 570b4663f1d..83039a5c333 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -1276,6 +1276,11 @@ class WM_OT_properties_edit(Operator): # First remove item = eval("context.%s" % data_path) + + if (item.id_data and item.id_data.override_library and item.id_data.override_library.reference): + self.report({'ERROR'}, "Cannot edit properties from override data") + return {'CANCELLED'} + prop_type_old = type(item[prop_old]) rna_idprop_ui_prop_clear(item, prop_old) @@ -1375,6 +1380,10 @@ class WM_OT_properties_edit(Operator): item = eval("context.%s" % data_path) + if (item.id_data and item.id_data.override_library and item.id_data.override_library.reference): + self.report({'ERROR'}, "Cannot edit properties from override data") + return {'CANCELLED'} + # retrieve overridable static exec_str = "item.is_property_overridable_library('[\"%s\"]')" % (self.property) self.is_overridable_library = bool(eval(exec_str)) @@ -1498,6 +1507,10 @@ class WM_OT_properties_add(Operator): data_path = self.data_path item = eval("context.%s" % data_path) + if (item.id_data and item.id_data.override_library and item.id_data.override_library.reference): + self.report({'ERROR'}, "Cannot add properties to override data") + return {'CANCELLED'} + def unique_name(names): prop = "prop" prop_new = prop @@ -1550,6 +1563,11 @@ class WM_OT_properties_remove(Operator): ) data_path = self.data_path item = eval("context.%s" % data_path) + + if (item.id_data and item.id_data.override_library and item.id_data.override_library.reference): + self.report({'ERROR'}, "Cannot remove properties from override data") + return {'CANCELLED'} + prop = self.property rna_idprop_ui_prop_update(item, prop) del item[prop] diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py index 7ff2688f2a7..64bc694d5ca 100644 --- a/release/scripts/startup/bl_ui/properties_data_mesh.py +++ b/release/scripts/startup/bl_ui/properties_data_mesh.py @@ -468,7 +468,7 @@ class DATA_PT_sculpt_vertex_colors(MeshButtonsPanel, Panel): @classmethod def poll(cls, context): - return context.preferences.experimental.use_sculpt_vertex_colors + return super().poll(context) and context.preferences.experimental.use_sculpt_vertex_colors def draw(self, context): layout = self.layout diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py index 6dde1e715bb..c7df2bbb7eb 100644 --- a/release/scripts/startup/bl_ui/properties_paint_common.py +++ b/release/scripts/startup/bl_ui/properties_paint_common.py @@ -313,6 +313,7 @@ class TextureMaskPanel(BrushPanel): class StrokePanel(BrushPanel): bl_label = "Stroke" bl_options = {'DEFAULT_CLOSED'} + bl_ui_units_x = 13 def draw(self, context): layout = self.layout diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py index 75c1bb5e3f9..3aedc04af88 100644 --- a/release/scripts/startup/bl_ui/space_image.py +++ b/release/scripts/startup/bl_ui/space_image.py @@ -1137,6 +1137,7 @@ class IMAGE_PT_paint_settings_advanced(Panel, ImagePaintPanel): bl_parent_id = "IMAGE_PT_paint_settings" bl_category = "Tool" bl_label = "Advanced" + bl_ui_units_x = 12 def draw(self, context): layout = self.layout @@ -1193,6 +1194,7 @@ class IMAGE_PT_tools_brush_display(Panel, BrushButtonsPanel, DisplayPanel): bl_category = "Tool" bl_label = "Brush Tip" bl_options = {'DEFAULT_CLOSED'} + bl_ui_units_x = 15 class IMAGE_PT_tools_brush_texture(BrushButtonsPanel, Panel): @@ -1219,6 +1221,7 @@ class IMAGE_PT_tools_mask_texture(Panel, BrushButtonsPanel, TextureMaskPanel): bl_parent_id = "IMAGE_PT_paint_settings" bl_category = "Tool" bl_label = "Texture Mask" + bl_ui_units_x = 12 class IMAGE_PT_paint_stroke(BrushButtonsPanel, Panel, StrokePanel): diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index 03f85578b6e..9548de20752 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -2118,6 +2118,10 @@ class ExperimentalPanel: url_prefix = "https://developer.blender.org/" + @classmethod + def poll(cls, context): + return bpy.app.version_cycle == 'alpha' + def _draw_items(self, context, items): prefs = context.preferences experimental = prefs.experimental @@ -2178,6 +2182,12 @@ class USERPREF_PT_experimental_prototypes(ExperimentalPanel, Panel): class USERPREF_PT_experimental_debugging(ExperimentalPanel, Panel): bl_label = "Debugging" + @classmethod + def poll(cls, context): + # Unlike the other experimental panels, the debugging one is always visible + # even in beta or release. + return True + def draw(self, context): self._draw_items( context, ( diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index 6e31808d27d..e6d27d531be 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -392,6 +392,7 @@ class VIEW3D_PT_tools_brush_settings_advanced(Panel, View3DPaintBrushPanel): bl_parent_id = "VIEW3D_PT_tools_brush_settings" bl_label = "Advanced" bl_options = {'DEFAULT_CLOSED'} + bl_ui_units_x = 14 def draw(self, context): layout = self.layout @@ -598,6 +599,7 @@ class VIEW3D_PT_tools_brush_display(Panel, View3DPaintBrushPanel, DisplayPanel): bl_parent_id = "VIEW3D_PT_tools_brush_settings" bl_label = "Cursor" bl_options = {'DEFAULT_CLOSED'} + bl_ui_units_x = 12 # TODO, move to space_view3d.py @@ -828,6 +830,7 @@ class VIEW3D_PT_sculpt_options(Panel, View3DPaintPanel): bl_context = ".sculpt_mode" # dot on purpose (access from topbar) bl_label = "Options" bl_options = {'DEFAULT_CLOSED'} + bl_ui_units_x = 12 @classmethod def poll(cls, context): @@ -1375,6 +1378,7 @@ class VIEW3D_PT_tools_grease_pencil_brush_advanced(View3DPanel, Panel): bl_parent_id = 'VIEW3D_PT_tools_grease_pencil_brush_settings' bl_category = "Tool" bl_options = {'DEFAULT_CLOSED'} + bl_ui_units_x = 11 @classmethod def poll(cls, context): @@ -1434,6 +1438,7 @@ class VIEW3D_PT_tools_grease_pencil_brush_stroke(Panel, View3DPanel): bl_label = "Stroke" bl_category = "Tool" bl_options = {'DEFAULT_CLOSED'} + bl_ui_units_x = 12 @classmethod def poll(cls, context): @@ -2110,6 +2115,7 @@ class VIEW3D_PT_tools_grease_pencil_paint_appearance(GreasePencilDisplayPanel, P bl_parent_id = 'VIEW3D_PT_tools_grease_pencil_brush_settings' bl_label = "Cursor" bl_category = "Tool" + bl_ui_units_x = 15 class VIEW3D_PT_tools_grease_pencil_sculpt_appearance(GreasePencilDisplayPanel, Panel, View3DPanel): diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index 3df09d08814..c340e1f1ff7 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -50,6 +50,9 @@ extern "C" { /** User readable version string. */ const char *BKE_blender_version_string(void); +/* Returns true when version cycle is alpha, otherwise (beta, rc) returns false. */ +bool BKE_blender_version_is_alpha(void); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index e8aa13a8beb..1d5c8f76cc5 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -135,6 +135,12 @@ const char *BKE_blender_version_string(void) return blender_version_string; } +bool BKE_blender_version_is_alpha(void) +{ + bool is_alpha = STREQ(STRINGIFY(BLENDER_VERSION_CYCLE), "alpha"); + return is_alpha; +} + void BKE_blender_globals_init(void) { blender_version_init(); diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c index 2989c910c45..6929d3a3c4b 100644 --- a/source/blender/blenkernel/intern/lib_override.c +++ b/source/blender/blenkernel/intern/lib_override.c @@ -1147,7 +1147,15 @@ void BKE_lib_override_library_main_operations_create(Main *bmain, const bool for FOREACH_MAIN_ID_BEGIN (bmain, id) { if (ID_IS_OVERRIDE_LIBRARY_REAL(id) && (force_auto || (id->tag & LIB_TAG_OVERRIDE_LIBRARY_AUTOREFRESH))) { - BLI_task_pool_push(task_pool, lib_override_library_operations_create_cb, id, false, NULL); + /* Only check overrides if we do have the real reference data available, and not some empty + * 'placeholder' for missing data (broken links). */ + if ((id->override_library->reference->tag & LIB_TAG_MISSING) == 0) { + BLI_task_pool_push(task_pool, lib_override_library_operations_create_cb, id, false, NULL); + } + else { + BKE_lib_override_library_properties_tag( + id->override_library, IDOVERRIDE_LIBRARY_TAG_UNUSED, false); + } } id->tag &= ~LIB_TAG_OVERRIDE_LIBRARY_AUTOREFRESH; } diff --git a/source/blender/blenkernel/intern/seqcache.c b/source/blender/blenkernel/intern/seqcache.c index 5c2d5b0087f..fa4951da161 100644 --- a/source/blender/blenkernel/intern/seqcache.c +++ b/source/blender/blenkernel/intern/seqcache.c @@ -1329,6 +1329,7 @@ void BKE_sequencer_cache_put(const SeqRenderData *context, context = BKE_sequencer_prefetch_get_original_context(context); scene = context->scene; seq = BKE_sequencer_prefetch_get_original_sequence(seq, scene); + BLI_assert(seq != NULL); } /* Prevent reinserting, it breaks cache key linking. */ diff --git a/source/blender/blenkernel/intern/unit.c b/source/blender/blenkernel/intern/unit.c index efe10b02940..c702a98f5e6 100644 --- a/source/blender/blenkernel/intern/unit.c +++ b/source/blender/blenkernel/intern/unit.c @@ -757,7 +757,6 @@ static char *find_next_op(const char *str, char *remaining_str, int len_max) if (ch_is_op(remaining_str[i])) { if (scientific_notation) { scientific_notation = false; - continue; } /* Make sure we don't look backwards before the start of the string. */ diff --git a/source/blender/blenlib/BLI_listbase.h b/source/blender/blenlib/BLI_listbase.h index fa7cf7a1847..932b63e43f7 100644 --- a/source/blender/blenlib/BLI_listbase.h +++ b/source/blender/blenlib/BLI_listbase.h @@ -186,6 +186,14 @@ struct LinkData *BLI_genericNodeN(void *data); ((var != NULL) ? ((void)(var##_iter_prev = (type)(((Link *)(var))->prev)), 1) : 0); \ var = var##_iter_prev) +/** + * A version of #LISTBASE_FOREACH that takes an index variable (declared outside this macro). + * This avoids possible accidents where using `continue` could miss incrementing the counter. + */ +#define LISTBASE_FOREACH_INDEX(type, var, list, index_var) \ + for (type var = (((void)(index_var = 0)), (type)((list)->first)); var != NULL; \ + var = (type)(((Link *)(var))->next), index_var++) + #ifdef __cplusplus } #endif diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h index 97c77ed2e19..580c833d8dc 100644 --- a/source/blender/blenloader/BLO_readfile.h +++ b/source/blender/blenloader/BLO_readfile.h @@ -186,6 +186,9 @@ void BLO_update_defaults_workspace(struct WorkSpace *workspace, const char *app_ /* Version patch user preferences. */ void BLO_version_defaults_userpref_blend(struct Main *mainvar, struct UserDef *userdef); +/* Disable unwanted experimental feature settings on startup. */ +void BLO_sanitize_experimental_features_userpref_blend(struct UserDef *userdef); + struct BlendThumbnail *BLO_thumbnail_from_file(const char *filepath); /* datafiles (generated theme) */ diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index 111ac728cc3..51df61143e0 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -4951,8 +4951,6 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) const View3D *v3d_default = DNA_struct_default_get(View3D); wm->xr.session_settings.shading = v3d_default->shading; - /* Don't rotate light with the viewer by default, make it fixed. */ - wm->xr.session_settings.shading.flag |= V3D_SHADING_WORLD_ORIENTATION; wm->xr.session_settings.draw_flags = (V3D_OFSDRAW_SHOW_GRIDFLOOR | V3D_OFSDRAW_SHOW_ANNOTATION); wm->xr.session_settings.clip_start = v3d_default->clip_start; @@ -5110,6 +5108,12 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } } + for (wmWindowManager *wm = bmain->wm.first; wm; wm = wm->id.next) { + /* Don't rotate light with the viewer by default, make it fixed. Shading settings can't be + * edited and this flag should always be set. So we can always execute this. */ + wm->xr.session_settings.shading.flag |= V3D_SHADING_WORLD_ORIENTATION; + } + /* Keep this block, even when empty. */ } } diff --git a/source/blender/blenloader/intern/versioning_290.c b/source/blender/blenloader/intern/versioning_290.c index a96b82e2e91..aef2a59580c 100644 --- a/source/blender/blenloader/intern/versioning_290.c +++ b/source/blender/blenloader/intern/versioning_290.c @@ -188,17 +188,19 @@ void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports)) /* Patch first frame for old files. */ Scene *scene = bmain->scenes.first; - LISTBASE_FOREACH (Object *, ob, &bmain->objects) { - if (ob->type != OB_GPENCIL) { - continue; - } - bGPdata *gpd = ob->data; - LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) { - bGPDframe *gpf = gpl->frames.first; - if (gpf && gpf->framenum > scene->r.sfra) { - bGPDframe *gpf_dup = BKE_gpencil_frame_duplicate(gpf); - gpf_dup->framenum = scene->r.sfra; - BLI_addhead(&gpl->frames, gpf_dup); + if (scene != NULL) { + LISTBASE_FOREACH (Object *, ob, &bmain->objects) { + if (ob->type != OB_GPENCIL) { + continue; + } + bGPdata *gpd = ob->data; + LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) { + bGPDframe *gpf = gpl->frames.first; + if (gpf && gpf->framenum > scene->r.sfra) { + bGPDframe *gpf_dup = BKE_gpencil_frame_duplicate(gpf); + gpf_dup->framenum = scene->r.sfra; + BLI_addhead(&gpl->frames, gpf_dup); + } } } } diff --git a/source/blender/blenloader/intern/versioning_userdef.c b/source/blender/blenloader/intern/versioning_userdef.c index 50e3b375166..ec631eb64f3 100644 --- a/source/blender/blenloader/intern/versioning_userdef.c +++ b/source/blender/blenloader/intern/versioning_userdef.c @@ -38,6 +38,7 @@ #include "DNA_windowmanager_types.h" #include "BKE_addon.h" +#include "BKE_blender_version.h" #include "BKE_colorband.h" #include "BKE_idprop.h" #include "BKE_keyconfig.h" @@ -784,4 +785,23 @@ void BLO_version_defaults_userpref_blend(Main *bmain, UserDef *userdef) #undef USER_VERSION_ATLEAST } +void BLO_sanitize_experimental_features_userpref_blend(UserDef *userdef) +{ + /* User preference experimental settings are only supported in alpha builds. + * This prevents users corrupting data and relying on API that may change. + * + * If user preferences are saved this will be stored in disk as expected. + * This only starts to take effect when there is a release branch (on beta). + * + * At that time master already has its version bumped so its user preferences + * are not touched by these settings. */ + + if (BKE_blender_version_is_alpha()) { + return; + } + userdef->experimental.use_new_particle_system = false; + userdef->experimental.use_new_hair_type = false; + userdef->experimental.use_sculpt_vertex_colors = false; +} + #undef USER_LMOUSESELECT diff --git a/source/blender/draw/engines/overlay/shaders/edit_curve_handle_geom.glsl b/source/blender/draw/engines/overlay/shaders/edit_curve_handle_geom.glsl index a400aadb052..9311542a79e 100644 --- a/source/blender/draw/engines/overlay/shaders/edit_curve_handle_geom.glsl +++ b/source/blender/draw/engines/overlay/shaders/edit_curve_handle_geom.glsl @@ -58,7 +58,7 @@ void main() if ((curveHandleDisplay != CURVE_HANDLE_ALL) && (!handle_selected)) { /* Nurbs must show the handles always. */ bool is_u_segment = (((vertFlag[1] ^ vertFlag[0]) & EVEN_U_BIT) != 0); - if (!is_u_segment) { + if ((!is_u_segment) && (color_id <= 4)) { return; } } diff --git a/source/blender/draw/intern/draw_cache_impl_curve.c b/source/blender/draw/intern/draw_cache_impl_curve.c index 73e0ff7ef83..b93c782a5b9 100644 --- a/source/blender/draw/intern/draw_cache_impl_curve.c +++ b/source/blender/draw/intern/draw_cache_impl_curve.c @@ -307,7 +307,7 @@ static int curve_render_data_normal_len_get(const CurveRenderData *rdata) return rdata->normal.len; } -static void curve_cd_calc_used_gpu_layers(int *cd_layers, +static void curve_cd_calc_used_gpu_layers(CustomDataMask *cd_layers, struct GPUMaterial **gpumat_array, int gpumat_array_len) { @@ -334,16 +334,16 @@ static void curve_cd_calc_used_gpu_layers(int *cd_layers, switch (type) { case CD_MTFACE: - *cd_layers |= CD_MLOOPUV; + *cd_layers |= CD_MASK_MLOOPUV; break; case CD_TANGENT: - *cd_layers |= CD_TANGENT; + *cd_layers |= CD_MASK_TANGENT; break; case CD_MCOL: /* Curve object don't have Color data. */ break; case CD_ORCO: - *cd_layers |= CD_ORCO; + *cd_layers |= CD_MASK_ORCO; break; } } @@ -397,7 +397,7 @@ typedef struct CurveBatchCache { GPUIndexBuf **surf_per_mat_tris; GPUBatch **surf_per_mat; int mat_len; - int cd_used, cd_needed; + CustomDataMask cd_used, cd_needed; /* settings to determine if cache is invalid */ bool is_dirty; @@ -998,10 +998,10 @@ void DRW_curve_batch_cache_create_requested(Object *ob) if (cache->mat_len > 1) { DRW_ibo_request(cache->surf_per_mat[i], &cache->surf_per_mat_tris[i]); } - if (cache->cd_used & CD_MLOOPUV) { + if (cache->cd_used & CD_MASK_MLOOPUV) { DRW_vbo_request(cache->surf_per_mat[i], &cache->ordered.loop_uv); } - if (cache->cd_used & CD_TANGENT) { + if (cache->cd_used & CD_MASK_TANGENT) { DRW_vbo_request(cache->surf_per_mat[i], &cache->ordered.loop_tan); } DRW_vbo_request(cache->surf_per_mat[i], &cache->ordered.loop_pos_nor); diff --git a/source/blender/editors/curve/editcurve_paint.c b/source/blender/editors/curve/editcurve_paint.c index 748bf040fbb..ebad1995717 100644 --- a/source/blender/editors/curve/editcurve_paint.c +++ b/source/blender/editors/curve/editcurve_paint.c @@ -666,7 +666,7 @@ static void curve_draw_exec_precalc(wmOperator *op) selem_prev = selem; } scale_px = ((len_3d > 0.0f) && (len_2d > 0.0f)) ? (len_3d / len_2d) : 0.0f; - float error_threshold = (cps->error_threshold * U.pixelsize) * scale_px; + float error_threshold = (cps->error_threshold * U.dpi_fac) * scale_px; RNA_property_float_set(op->ptr, prop, error_threshold); } @@ -685,7 +685,7 @@ static void curve_draw_exec_precalc(wmOperator *op) } if (len_squared_v2v2(selem_first->mval, selem_last->mval) <= - square_f(STROKE_CYCLIC_DIST_PX * U.pixelsize)) { + square_f(STROKE_CYCLIC_DIST_PX * U.dpi_fac)) { use_cyclic = true; } } diff --git a/source/blender/editors/include/ED_info.h b/source/blender/editors/include/ED_info.h index df6b6a20ddc..e3ce494e09a 100644 --- a/source/blender/editors/include/ED_info.h +++ b/source/blender/editors/include/ED_info.h @@ -31,8 +31,13 @@ struct Main; /* info_stats.c */ void ED_info_stats_clear(struct ViewLayer *view_layer); const char *ED_info_statusbar_string(struct Main *bmain, - struct bScreen *screen, - struct bContext *C); + struct Scene *scene, + struct ViewLayer *view_layer); + +const char *ED_info_statistics_string(struct Main *bmain, + struct Scene *scene, + struct ViewLayer *view_layer); + void ED_info_draw_stats( struct Main *bmain, Scene *scene, ViewLayer *view_layer, int x, int *y, int height); diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index 59567803f35..5a79e2de8d6 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -187,11 +187,7 @@ void ED_area_newspace(struct bContext *C, ScrArea *area, int type, const bool sk void ED_area_prevspace(struct bContext *C, ScrArea *area); void ED_area_swapspace(struct bContext *C, ScrArea *sa1, ScrArea *sa2); int ED_area_headersize(void); -int ED_area_header_alignment_or_fallback(const ScrArea *area, int fallback); -int ED_area_header_alignment(const ScrArea *area); int ED_area_footersize(void); -int ED_area_footer_alignment_or_fallback(const ScrArea *area, int fallback); -int ED_area_footer_alignment(const ScrArea *area); int ED_area_global_size_y(const ScrArea *area); int ED_area_global_min_size_y(const ScrArea *area); int ED_area_global_max_size_y(const ScrArea *area); diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 286cb1571bd..d19c677efb4 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -44,6 +44,8 @@ #include "BLI_utildefines.h" +#include "BLO_readfile.h" + #include "BKE_animsys.h" #include "BKE_context.h" #include "BKE_idprop.h" @@ -6818,6 +6820,8 @@ void UI_init_userdef(Main *bmain) /* fix saved themes */ init_userdef_do_versions(bmain); uiStyleInit(); + + BLO_sanitize_experimental_features_userpref_blend(&U); } void UI_reinit_font(void) diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index bcb4f7c672f..20d07f97647 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -4790,7 +4790,7 @@ static bool ui_numedit_but_NUM(uiBut *but, if (is_float == false) { /* at minimum, moving cursor 2 pixels should change an int button. */ - CLAMP_MIN(non_linear_scale, 0.5f * U.pixelsize); + CLAMP_MIN(non_linear_scale, 0.5f * UI_DPI_FAC); } data->dragf += (((float)(mx - data->draglastx)) / deler) * non_linear_scale; diff --git a/source/blender/editors/interface/interface_region_menu_popup.c b/source/blender/editors/interface/interface_region_menu_popup.c index 077e8888d53..dbb072fa4a6 100644 --- a/source/blender/editors/interface/interface_region_menu_popup.c +++ b/source/blender/editors/interface/interface_region_menu_popup.c @@ -284,17 +284,10 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi else { /* for a header menu we set the direction automatic */ if (!pup->slideout && flip) { - ScrArea *area = CTX_wm_area(C); ARegion *region = CTX_wm_region(C); - if (area && region) { - if (ELEM(region->regiontype, RGN_TYPE_HEADER, RGN_TYPE_TOOL_HEADER)) { - if (RGN_ALIGN_ENUM_FROM_MASK(ED_area_header_alignment(area)) == RGN_ALIGN_BOTTOM) { - UI_block_direction_set(block, UI_DIR_UP); - UI_block_order_flip(block); - } - } - if (region->regiontype == RGN_TYPE_FOOTER) { - if (RGN_ALIGN_ENUM_FROM_MASK(ED_area_footer_alignment(area)) == RGN_ALIGN_BOTTOM) { + if (region) { + if (RGN_TYPE_IS_HEADER_ANY(region->regiontype)) { + if (RGN_ALIGN_ENUM_FROM_MASK(region->alignment) == RGN_ALIGN_BOTTOM) { UI_block_direction_set(block, UI_DIR_UP); UI_block_order_flip(block); } diff --git a/source/blender/editors/interface/interface_region_popover.c b/source/blender/editors/interface/interface_region_popover.c index 0ad7e570e80..18c31dde66f 100644 --- a/source/blender/editors/interface/interface_region_popover.c +++ b/source/blender/editors/interface/interface_region_popover.c @@ -171,7 +171,6 @@ static uiBlock *ui_block_func_POPOVER(bContext *C, uiPopupBlockHandle *handle, v } if (!slideout) { - ScrArea *area = CTX_wm_area(C); ARegion *region = CTX_wm_region(C); if (region && region->panels.first) { @@ -180,14 +179,9 @@ static uiBlock *ui_block_func_POPOVER(bContext *C, uiPopupBlockHandle *handle, v UI_block_direction_set(block, UI_DIR_UP | UI_DIR_CENTER_X); } /* Prefer popover from header to be positioned into the editor. */ - else if (area && region) { - if (ELEM(region->regiontype, RGN_TYPE_HEADER, RGN_TYPE_TOOL_HEADER)) { - if (RGN_ALIGN_ENUM_FROM_MASK(ED_area_header_alignment(area)) == RGN_ALIGN_BOTTOM) { - UI_block_direction_set(block, UI_DIR_UP | UI_DIR_CENTER_X); - } - } - if (region->regiontype == RGN_TYPE_FOOTER) { - if (RGN_ALIGN_ENUM_FROM_MASK(ED_area_footer_alignment(area)) == RGN_ALIGN_BOTTOM) { + else if (region) { + if (RGN_TYPE_IS_HEADER_ANY(region->regiontype)) { + if (RGN_ALIGN_ENUM_FROM_MASK(region->alignment) == RGN_ALIGN_BOTTOM) { UI_block_direction_set(block, UI_DIR_UP | UI_DIR_CENTER_X); } } diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c index 64cacd44e3d..4308310fac6 100644 --- a/source/blender/editors/interface/view2d_ops.c +++ b/source/blender/editors/interface/view2d_ops.c @@ -1157,8 +1157,8 @@ static void view_zoomdrag_apply(bContext *C, wmOperator *op) const bool zoom_to_pos = use_cursor_init && (U.uiflag & USER_ZOOM_TO_MOUSEPOS); /* get amount to move view by */ - dx = RNA_float_get(op->ptr, "deltax") / U.pixelsize; - dy = RNA_float_get(op->ptr, "deltay") / U.pixelsize; + dx = RNA_float_get(op->ptr, "deltax") / U.dpi_fac; + dy = RNA_float_get(op->ptr, "deltay") / U.dpi_fac; if (U.uiflag & USER_ZOOM_INVERT) { dx *= -1; diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c index bcb1b8afbdd..70404af6433 100644 --- a/source/blender/editors/object/object_constraint.c +++ b/source/blender/editors/object/object_constraint.c @@ -663,10 +663,13 @@ static const EnumPropertyItem constraint_owner_items[] = { {0, NULL, 0, NULL, NULL}, }; -static bool edit_constraint_poll_generic(bContext *C, StructRNA *rna_type) +static bool edit_constraint_poll_generic(bContext *C, + StructRNA *rna_type, + const bool is_liboverride_allowed) { PointerRNA ptr = CTX_data_pointer_get_type(C, "constraint", rna_type); Object *ob = (ptr.owner_id) ? (Object *)ptr.owner_id : ED_object_active_context(C); + bConstraint *con = ptr.data; if (!ob) { CTX_wm_operator_poll_msg_set(C, "Context missing active object"); @@ -678,9 +681,11 @@ static bool edit_constraint_poll_generic(bContext *C, StructRNA *rna_type) return false; } - if (ID_IS_OVERRIDE_LIBRARY(ob) && ptr.data != NULL) { - CTX_wm_operator_poll_msg_set(C, "Cannot edit constraints coming from library override"); - return (((bConstraint *)ptr.data)->flag & CONSTRAINT_OVERRIDE_LIBRARY_LOCAL) != 0; + if (ID_IS_OVERRIDE_LIBRARY(ob) && !is_liboverride_allowed) { + if ((con == NULL) || (con->flag & CONSTRAINT_OVERRIDE_LIBRARY_LOCAL) != 0) { + CTX_wm_operator_poll_msg_set(C, "Cannot edit constraints coming from library override"); + return false; + } } return true; @@ -688,7 +693,14 @@ static bool edit_constraint_poll_generic(bContext *C, StructRNA *rna_type) static bool edit_constraint_poll(bContext *C) { - return edit_constraint_poll_generic(C, &RNA_Constraint); + return edit_constraint_poll_generic(C, &RNA_Constraint, false); +} + +/* Used by operators performing actions allowed also on constraints from the overridden linked + * object (not only from added 'local' ones). */ +static bool edit_constraint_liboverride_allowed_poll(bContext *C) +{ + return edit_constraint_poll_generic(C, &RNA_Constraint, true); } static void edit_constraint_properties(wmOperatorType *ot) @@ -864,7 +876,7 @@ void CONSTRAINT_OT_stretchto_reset(wmOperatorType *ot) /* callbacks */ ot->invoke = stretchto_reset_invoke; ot->exec = stretchto_reset_exec; - ot->poll = edit_constraint_poll; + ot->poll = edit_constraint_liboverride_allowed_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -919,7 +931,7 @@ void CONSTRAINT_OT_limitdistance_reset(wmOperatorType *ot) /* callbacks */ ot->invoke = limitdistance_reset_invoke; ot->exec = limitdistance_reset_exec; - ot->poll = edit_constraint_poll; + ot->poll = edit_constraint_liboverride_allowed_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -997,7 +1009,7 @@ void CONSTRAINT_OT_childof_set_inverse(wmOperatorType *ot) /* callbacks */ ot->invoke = childof_set_inverse_invoke; ot->exec = childof_set_inverse_exec; - ot->poll = edit_constraint_poll; + ot->poll = edit_constraint_liboverride_allowed_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -1046,7 +1058,7 @@ void CONSTRAINT_OT_childof_clear_inverse(wmOperatorType *ot) /* callbacks */ ot->invoke = childof_clear_inverse_invoke; ot->exec = childof_clear_inverse_exec; - ot->poll = edit_constraint_poll; + ot->poll = edit_constraint_liboverride_allowed_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -1693,8 +1705,8 @@ void POSE_OT_constraints_clear(wmOperatorType *ot) /* callbacks */ ot->exec = pose_constraints_clear_exec; - ot->poll = - ED_operator_posemode_exclusive; // XXX - do we want to ensure there are selected bones too? + ot->poll = ED_operator_posemode_exclusive; // XXX - do we want to ensure there are selected + // bones too? } static int object_constraints_clear_exec(bContext *C, wmOperator *UNUSED(op)) @@ -1942,7 +1954,8 @@ static bool get_new_constraint_target( /* perform some special operations on the target */ if (only_curve) { - /* Curve-Path option must be enabled for follow-path constraints to be able to work */ + /* Curve-Path option must be enabled for follow-path constraints to be able to work + */ Curve *cu = (Curve *)ob->data; cu->flag |= CU_PATH; } @@ -2214,8 +2227,8 @@ void OBJECT_OT_constraint_add_with_targets(wmOperatorType *ot) /* identifiers */ ot->name = "Add Constraint (with Targets)"; ot->description = - "Add a constraint to the active object, with target (where applicable) set to the selected " - "Objects/Bones"; + "Add a constraint to the active object, with target (where applicable) set to the " + "selected Objects/Bones"; ot->idname = "OBJECT_OT_constraint_add_with_targets"; /* api callbacks */ diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index f87f631c643..df33222ce37 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -2053,6 +2053,241 @@ void ED_area_data_swap(ScrArea *area_dst, ScrArea *area_src) SWAP(ListBase, area_dst->regionbase, area_src->regionbase); } +/* -------------------------------------------------------------------- */ +/** \name Region Alignment Syncing for Space Switching + * \{ */ + +/** + * Store the alignment & other info per region type + * (use as a region-type aligned array). + * + * \note Currently this is only done for headers, + * we might want to do this with the tool-bar in the future too. + */ +struct RegionTypeAlignInfo { + struct { + /** + * Values match #ARegion.alignment without flags (see #RGN_ALIGN_ENUM_FROM_MASK). + * store all so we can sync alignment without adding extra checks. + */ + short alignment; + /** + * Needed for detecting which header displays the space-type switcher. + */ + bool hidden; + } by_type[RGN_TYPE_LEN]; +}; + +static void region_align_info_from_area(ScrArea *area, struct RegionTypeAlignInfo *r_align_info) +{ + for (int index = 0; index < RGN_TYPE_LEN; index++) { + r_align_info->by_type[index].alignment = -1; + /* Default to true, when it doesn't exist - it's effectively hidden. */ + r_align_info->by_type[index].hidden = true; + } + + LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { + const int index = region->regiontype; + if ((uint)index < RGN_TYPE_LEN) { + r_align_info->by_type[index].alignment = RGN_ALIGN_ENUM_FROM_MASK(region->alignment); + r_align_info->by_type[index].hidden = (region->flag & RGN_FLAG_HIDDEN) != 0; + } + } +} + +/** + * Keeping alignment between headers keep the space-type selector button in the same place. + * This is complicated by the editor-type selector being placed on the header + * closest to the screen edge which changes based on hidden state. + * + * The tool-header is used when visible, otherwise the header is used. + */ +static short region_alignment_from_header_and_tool_header_state( + const struct RegionTypeAlignInfo *region_align_info, const short fallback) +{ + const short header_alignment = region_align_info->by_type[RGN_TYPE_HEADER].alignment; + const short tool_header_alignment = region_align_info->by_type[RGN_TYPE_TOOL_HEADER].alignment; + + const bool header_hidden = region_align_info->by_type[RGN_TYPE_HEADER].hidden; + const bool tool_header_hidden = region_align_info->by_type[RGN_TYPE_TOOL_HEADER].hidden; + + if ((tool_header_alignment != -1) && + /* If tool-header is hidden, use header alignment. */ + ((tool_header_hidden == false) || + /* Don't prioritize the tool-header if both are hidden (behave as if both are visible). + * Without this, switching to a space with headers hidden will flip the alignment + * upon switching to a space with visible headers. */ + (header_hidden && tool_header_hidden))) { + return tool_header_alignment; + } + if (header_alignment != -1) { + return header_alignment; + } + return fallback; +} + +/** + * Notes on header alignment syncing. + * + * This is as involved as it is because: + * + * - There are currently 3 kinds of headers. + * - All headers can independently visible & flipped to another side + * (except for the tool-header that depends on the header visibility). + * - We don't want the space-switching button to flip when switching spaces. + * From the user perspective it feels like a bug to move the button you click on + * to the opposite side of the area. + * - The space-switcher may be on either the header or the tool-header + * depending on the tool-header visibility. + * + * How this works: + * + * - When headers match on both spaces, we copy the alignment + * from the previous regions to the next regions when syncing. + * - Otherwise detect the _primary_ header (the one that shows the space type) + * and use this to set alignment for the headers in the destination area. + * - Header & tool-header/footer may be on opposite sides, this is preserved when syncing. + */ +static void region_align_info_to_area_for_headers( + const struct RegionTypeAlignInfo *region_align_info_src, + const struct RegionTypeAlignInfo *region_align_info_dst, + ARegion *region_by_type[RGN_TYPE_LEN]) +{ + /* Abbreviate access. */ + const short header_alignment_src = region_align_info_src->by_type[RGN_TYPE_HEADER].alignment; + const short tool_header_alignment_src = + region_align_info_src->by_type[RGN_TYPE_TOOL_HEADER].alignment; + + const bool tool_header_hidden_src = region_align_info_src->by_type[RGN_TYPE_TOOL_HEADER].hidden; + + const short primary_header_alignment_src = region_alignment_from_header_and_tool_header_state( + region_align_info_src, -1); + + /* Neither alignments are usable, don't sync. */ + if (primary_header_alignment_src == -1) { + return; + } + + const short header_alignment_dst = region_align_info_dst->by_type[RGN_TYPE_HEADER].alignment; + const short tool_header_alignment_dst = + region_align_info_dst->by_type[RGN_TYPE_TOOL_HEADER].alignment; + const short footer_alignment_dst = region_align_info_dst->by_type[RGN_TYPE_FOOTER].alignment; + + const bool tool_header_hidden_dst = region_align_info_dst->by_type[RGN_TYPE_TOOL_HEADER].hidden; + + /* New synchronized alignments to set (or ignore when left as -1). */ + short header_alignment_sync = -1; + short tool_header_alignment_sync = -1; + short footer_alignment_sync = -1; + + /* Both source/destination areas have same region configurations regarding headers. + * Simply copy the values. */ + if (((header_alignment_src != -1) == (header_alignment_dst != -1)) && + ((tool_header_alignment_src != -1) == (tool_header_alignment_dst != -1)) && + (tool_header_hidden_src == tool_header_hidden_dst)) { + if (header_alignment_dst != -1) { + header_alignment_sync = header_alignment_src; + } + if (tool_header_alignment_dst != -1) { + tool_header_alignment_sync = tool_header_alignment_src; + } + } + else { + /* Not an exact match, check the space selector isn't moving. */ + const short primary_header_alignment_dst = region_alignment_from_header_and_tool_header_state( + region_align_info_dst, -1); + + if (primary_header_alignment_src != primary_header_alignment_dst) { + if ((header_alignment_dst != -1) && (tool_header_alignment_dst != -1)) { + if (header_alignment_dst == tool_header_alignment_dst) { + /* Apply to both. */ + tool_header_alignment_sync = primary_header_alignment_src; + header_alignment_sync = primary_header_alignment_src; + } + else { + /* Keep on opposite sides. */ + tool_header_alignment_sync = primary_header_alignment_src; + header_alignment_sync = (tool_header_alignment_sync == RGN_ALIGN_BOTTOM) ? + RGN_ALIGN_TOP : + RGN_ALIGN_BOTTOM; + } + } + else { + /* Apply what we can to regions that exist. */ + if (header_alignment_dst != -1) { + header_alignment_sync = primary_header_alignment_src; + } + if (tool_header_alignment_dst != -1) { + tool_header_alignment_sync = primary_header_alignment_src; + } + } + } + } + + if (footer_alignment_dst != -1) { + if ((header_alignment_dst != -1) && (header_alignment_dst == footer_alignment_dst)) { + /* Apply to both. */ + footer_alignment_sync = primary_header_alignment_src; + } + else { + /* Keep on opposite sides. */ + footer_alignment_sync = (primary_header_alignment_src == RGN_ALIGN_BOTTOM) ? + RGN_ALIGN_TOP : + RGN_ALIGN_BOTTOM; + } + } + + /* Finally apply synchronized flags. */ + if (header_alignment_sync != -1) { + ARegion *region = region_by_type[RGN_TYPE_HEADER]; + if (region != NULL) { + region->alignment = RGN_ALIGN_ENUM_FROM_MASK(header_alignment_sync) | + RGN_ALIGN_FLAG_FROM_MASK(region->alignment); + } + } + + if (tool_header_alignment_sync != -1) { + ARegion *region = region_by_type[RGN_TYPE_TOOL_HEADER]; + if (region != NULL) { + region->alignment = RGN_ALIGN_ENUM_FROM_MASK(tool_header_alignment_sync) | + RGN_ALIGN_FLAG_FROM_MASK(region->alignment); + } + } + + if (footer_alignment_sync != -1) { + ARegion *region = region_by_type[RGN_TYPE_FOOTER]; + if (region != NULL) { + region->alignment = RGN_ALIGN_ENUM_FROM_MASK(footer_alignment_sync) | + RGN_ALIGN_FLAG_FROM_MASK(region->alignment); + } + } +} + +static void region_align_info_to_area( + ScrArea *area, const struct RegionTypeAlignInfo region_align_info_src[RGN_TYPE_LEN]) +{ + ARegion *region_by_type[RGN_TYPE_LEN] = {NULL}; + LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { + const int index = region->regiontype; + if ((uint)index < RGN_TYPE_LEN) { + region_by_type[index] = region; + } + } + + struct RegionTypeAlignInfo region_align_info_dst; + region_align_info_from_area(area, ®ion_align_info_dst); + + if ((region_by_type[RGN_TYPE_HEADER] != NULL) || + (region_by_type[RGN_TYPE_TOOL_HEADER] != NULL)) { + region_align_info_to_area_for_headers( + region_align_info_src, ®ion_align_info_dst, region_by_type); + } + + /* Note that we could support other region types. */ +} + +/** \} */ + /* *********** Space switching code *********** */ void ED_area_swapspace(bContext *C, ScrArea *sa1, ScrArea *sa2) @@ -2104,9 +2339,13 @@ void ED_area_newspace(bContext *C, ScrArea *area, int type, const bool skip_regi * the space type defaults to in this case instead * (needed for preferences to have space-type on bottom). */ - int header_alignment = ED_area_header_alignment_or_fallback(area, -1); - const bool sync_header_alignment = ((header_alignment != -1) && - ((slold->link_flag & SPACE_FLAG_TYPE_TEMPORARY) == 0)); + + bool sync_header_alignment = false; + struct RegionTypeAlignInfo region_align_info[RGN_TYPE_LEN]; + if ((slold != NULL) && (slold->link_flag & SPACE_FLAG_TYPE_TEMPORARY) == 0) { + region_align_info_from_area(area, region_align_info); + sync_header_alignment = true; + } /* in some cases (opening temp space) we don't want to * call area exit callback, so we temporarily unset it */ @@ -2180,28 +2419,7 @@ void ED_area_newspace(bContext *C, ScrArea *area, int type, const bool skip_regi /* Sync header alignment. */ if (sync_header_alignment) { - /* Spaces with footer. */ - if (st->spaceid == SPACE_TEXT) { - LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { - if (ELEM(region->regiontype, RGN_TYPE_HEADER, RGN_TYPE_TOOL_HEADER)) { - region->alignment = header_alignment; - } - if (region->regiontype == RGN_TYPE_FOOTER) { - int footer_alignment = (header_alignment == RGN_ALIGN_BOTTOM) ? RGN_ALIGN_TOP : - RGN_ALIGN_BOTTOM; - region->alignment = footer_alignment; - break; - } - } - } - else { - LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { - if (ELEM(region->regiontype, RGN_TYPE_HEADER, RGN_TYPE_TOOL_HEADER)) { - region->alignment = header_alignment; - break; - } - } - } + region_align_info_to_area(area, region_align_info); } ED_area_initialize(CTX_wm_manager(C), win, area); @@ -2941,43 +3159,11 @@ int ED_area_headersize(void) return U.widget_unit + (int)(UI_DPI_FAC * HEADER_PADDING_Y); } -int ED_area_header_alignment_or_fallback(const ScrArea *area, int fallback) -{ - LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { - if (region->regiontype == RGN_TYPE_HEADER) { - return region->alignment; - } - } - return fallback; -} - -int ED_area_header_alignment(const ScrArea *area) -{ - return ED_area_header_alignment_or_fallback( - area, (U.uiflag & USER_HEADER_BOTTOM) ? RGN_ALIGN_BOTTOM : RGN_ALIGN_TOP); -} - int ED_area_footersize(void) { return ED_area_headersize(); } -int ED_area_footer_alignment_or_fallback(const ScrArea *area, int fallback) -{ - LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { - if (region->regiontype == RGN_TYPE_FOOTER) { - return region->alignment; - } - } - return fallback; -} - -int ED_area_footer_alignment(const ScrArea *area) -{ - return ED_area_footer_alignment_or_fallback( - area, (U.uiflag & USER_HEADER_BOTTOM) ? RGN_ALIGN_TOP : RGN_ALIGN_BOTTOM); -} - /** * \return the final height of a global \a area, accounting for DPI. */ diff --git a/source/blender/editors/sculpt_paint/sculpt_cloth.c b/source/blender/editors/sculpt_paint/sculpt_cloth.c index 4232be91034..b401ed6d889 100644 --- a/source/blender/editors/sculpt_paint/sculpt_cloth.c +++ b/source/blender/editors/sculpt_paint/sculpt_cloth.c @@ -766,7 +766,7 @@ static EnumPropertyItem prop_cloth_filter_type[] = { "PINCH", 0, "Pinch", - "Pinches the cloth to the point were the cursor was when the filter started"}, + "Pinches the cloth to the point where the cursor was when the filter started"}, {0, NULL, 0, NULL, NULL}, }; diff --git a/source/blender/editors/space_buttons/CMakeLists.txt b/source/blender/editors/space_buttons/CMakeLists.txt index 25ff6bbd098..75d91174470 100644 --- a/source/blender/editors/space_buttons/CMakeLists.txt +++ b/source/blender/editors/space_buttons/CMakeLists.txt @@ -54,4 +54,9 @@ if(WITH_FREESTYLE) add_definitions(-DWITH_FREESTYLE) endif() +if(WITH_EXPERIMENTAL_FEATURES) + add_definitions(-DWITH_PARTICLE_NODES) + add_definitions(-DWITH_HAIR_NODES) +endif() + blender_add_lib(bf_editor_space_buttons "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c index 16256f6c97e..044fadb9a50 100644 --- a/source/blender/editors/space_buttons/buttons_context.c +++ b/source/blender/editors/space_buttons/buttons_context.c @@ -249,12 +249,16 @@ static int buttons_context_path_data(ButsContextPath *path, int type) if (RNA_struct_is_a(ptr->type, &RNA_GreasePencil) && (type == -1 || type == OB_GPENCIL)) { return 1; } +#ifdef WITH_HAIR_NODES if (RNA_struct_is_a(ptr->type, &RNA_Hair) && (type == -1 || type == OB_HAIR)) { return 1; } +#endif +#ifdef WITH_PARTICLE_NODES if (RNA_struct_is_a(ptr->type, &RNA_PointCloud) && (type == -1 || type == OB_POINTCLOUD)) { return 1; } +#endif if (RNA_struct_is_a(ptr->type, &RNA_Volume) && (type == -1 || type == OB_VOLUME)) { return 1; } @@ -871,14 +875,18 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r set_pointer_type(path, result, &RNA_LightProbe); return 1; } +#ifdef WITH_HAIR_NODES if (CTX_data_equals(member, "hair")) { set_pointer_type(path, result, &RNA_Hair); return 1; } +#endif +#ifdef WITH_PARTICLE_NODES if (CTX_data_equals(member, "pointcloud")) { set_pointer_type(path, result, &RNA_PointCloud); return 1; } +#endif if (CTX_data_equals(member, "volume")) { set_pointer_type(path, result, &RNA_Volume); return 1; diff --git a/source/blender/editors/space_info/info_stats.c b/source/blender/editors/space_info/info_stats.c index 4e91da01cc9..e97031736ca 100644 --- a/source/blender/editors/space_info/info_stats.c +++ b/source/blender/editors/space_info/info_stats.c @@ -547,19 +547,20 @@ static void get_stats_string( info + *ofs, len - *ofs, TIP_(" | Objects:%s/%s"), stats_fmt->totobjsel, stats_fmt->totobj); } -const char *ED_info_statusbar_string(Main *bmain, bScreen *screen, bContext *C) +static const char *info_statusbar_string(Main *bmain, + Scene *scene, + ViewLayer *view_layer, + char statusbar_flag) { char formatted_mem[15]; size_t ofs = 0; - char *info = screen->statusbar_info; - int len = sizeof(screen->statusbar_info); + static char info[256]; + int len = sizeof(info); info[0] = '\0'; /* Scene statistics. */ - if (U.statusbar_flag & STATUSBAR_SHOW_STATS) { - ViewLayer *view_layer = CTX_data_view_layer(C); - Scene *scene = CTX_data_scene(C); + if (statusbar_flag & STATUSBAR_SHOW_STATS) { SceneStatsFmt stats_fmt; if (format_stats(bmain, scene, view_layer, &stats_fmt)) { get_stats_string(info + ofs, len, &ofs, view_layer, &stats_fmt); @@ -567,7 +568,7 @@ const char *ED_info_statusbar_string(Main *bmain, bScreen *screen, bContext *C) } /* Memory status. */ - if (U.statusbar_flag & STATUSBAR_SHOW_MEMORY) { + if (statusbar_flag & STATUSBAR_SHOW_MEMORY) { if (info[0]) { ofs += BLI_snprintf(info + ofs, len - ofs, " | "); } @@ -577,7 +578,7 @@ const char *ED_info_statusbar_string(Main *bmain, bScreen *screen, bContext *C) } /* GPU VRAM status. */ - if ((U.statusbar_flag & STATUSBAR_SHOW_VRAM) && (GPU_mem_stats_supported())) { + if ((statusbar_flag & STATUSBAR_SHOW_VRAM) && (GPU_mem_stats_supported())) { int gpu_free_mem_kb, gpu_tot_mem_kb; GPU_mem_stats_get(&gpu_tot_mem_kb, &gpu_free_mem_kb); float gpu_total_gb = gpu_tot_mem_kb / 1048576.0f; @@ -599,7 +600,7 @@ const char *ED_info_statusbar_string(Main *bmain, bScreen *screen, bContext *C) } /* Blender version. */ - if (U.statusbar_flag & STATUSBAR_SHOW_VERSION) { + if (statusbar_flag & STATUSBAR_SHOW_VERSION) { if (info[0]) { ofs += BLI_snprintf(info + ofs, len - ofs, " | "); } @@ -609,6 +610,20 @@ const char *ED_info_statusbar_string(Main *bmain, bScreen *screen, bContext *C) return info; } +const char *ED_info_statusbar_string(Main *bmain, Scene *scene, ViewLayer *view_layer) +{ + return info_statusbar_string(bmain, scene, view_layer, U.statusbar_flag); +} + +const char *ED_info_statistics_string(Main *bmain, Scene *scene, ViewLayer *view_layer) +{ + const eUserpref_StatusBar_Flag statistics_status_bar_flag = STATUSBAR_SHOW_STATS | + STATUSBAR_SHOW_MEMORY | + STATUSBAR_SHOW_VERSION; + + return info_statusbar_string(bmain, scene, view_layer, statistics_status_bar_flag); +} + static void stats_row(int col1, const char *key, int col2, diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index 22b549cbd5d..6ce51db2005 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -47,11 +47,13 @@ #include "BIF_glutil.h" +#include "GPU_batch_presets.h" #include "GPU_framebuffer.h" #include "GPU_immediate.h" #include "GPU_immediate_util.h" #include "GPU_matrix.h" #include "GPU_state.h" +#include "GPU_viewport.h" #include "WM_api.h" #include "WM_types.h" @@ -1771,10 +1773,18 @@ void drawnodespace(const bContext *C, ARegion *region) SpaceNode *snode = CTX_wm_space_node(C); View2D *v2d = ®ion->v2d; + UI_view2d_view_ortho(v2d); + + /* Setup offscreen buffers. */ + GPUViewport *viewport = WM_draw_region_get_viewport(region); + + GPUFrameBuffer *framebuffer_overlay = GPU_viewport_framebuffer_overlay_get(viewport); + GPU_framebuffer_bind_no_srgb(framebuffer_overlay); + GPU_batch_presets_reset(); + UI_ThemeClearColor(TH_BACK); GPU_clear(GPU_COLOR_BIT); - - UI_view2d_view_ortho(v2d); + GPU_depth_test(false); /* XXX snode->cursor set in coordspace for placing new nodes, used for drawing noodles too */ UI_view2d_region_to_view(®ion->v2d, diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index 995e980aba0..4b76f1432ee 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -50,12 +50,14 @@ #include "IMB_colormanagement.h" #include "IMB_imbuf.h" +#include "GPU_batch_presets.h" #include "GPU_framebuffer.h" #include "GPU_immediate.h" #include "GPU_immediate_util.h" #include "GPU_matrix.h" #include "GPU_state.h" #include "GPU_vertex_buffer.h" +#include "GPU_viewport.h" #include "ED_anim_api.h" #include "ED_gpencil.h" @@ -1537,7 +1539,7 @@ static void sequencer_preview_clear(void) float col[3]; UI_GetThemeColor3fv(TH_SEQ_PREVIEW, col); - GPU_clear_color(col[0], col[1], col[2], 0.0); + GPU_clear_color(col[0], col[1], col[2], 1.0); GPU_clear(GPU_COLOR_BIT); } @@ -1775,6 +1777,14 @@ void sequencer_draw_preview(const bContext *C, return; } + /* Setup offscreen buffers. */ + GPUViewport *viewport = WM_draw_region_get_viewport(region); + + GPUFrameBuffer *framebuffer_overlay = GPU_viewport_framebuffer_overlay_get(viewport); + GPU_framebuffer_bind_no_srgb(framebuffer_overlay); + GPU_batch_presets_reset(); + GPU_depth_test(false); + if (sseq->render_size == SEQ_PROXY_RENDER_SIZE_NONE) { sequencer_preview_clear(); return; @@ -1798,6 +1808,9 @@ void sequencer_draw_preview(const bContext *C, ibuf = sequencer_ibuf_get( bmain, depsgraph, scene, sseq, cfra, frame_ofs, names[sseq->multiview_eye]); + /* sequencer_ibuf_get can call GPU_framebuffer_bind. So disable srgb framebuffer again. */ + GPU_framebuffer_bind_no_srgb(framebuffer_overlay); + if (ibuf) { scope = sequencer_get_scope(scene, sseq, ibuf, draw_backdrop); diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index b2d0362602e..bab099a77c1 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -2751,6 +2751,8 @@ static int sequencer_separate_images_exec(bContext *C, wmOperator *op) seq = ed->seqbasep->first; /* Poll checks this is valid. */ + BKE_sequencer_prefetch_stop(scene); + while (seq) { if ((seq->flag & SELECT) && (seq->type == SEQ_TYPE_IMAGE) && (seq->len > 1)) { Sequence *seq_next; @@ -2946,6 +2948,8 @@ static int sequencer_meta_make_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } + BKE_sequencer_prefetch_stop(scene); + /* Remove all selected from main list, and put in meta. */ seqm = BKE_sequence_alloc(ed->seqbasep, 1, 1, SEQ_TYPE_META); /* Channel number set later. */ @@ -3031,6 +3035,8 @@ static int sequencer_meta_separate_exec(bContext *C, wmOperator *UNUSED(op)) return OPERATOR_CANCELLED; } + BKE_sequencer_prefetch_stop(scene); + for (seq = last_seq->seqbase.first; seq != NULL; seq = seq->next) { BKE_sequence_invalidate_cache_composite(scene, seq); } diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 19aa9cb203b..7fafd9f7cd2 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -822,7 +822,7 @@ static void viewrotate_apply(ViewOpsData *vod, const int event_xy[2]) float xaxis[3]; /* Radians per-pixel. */ - const float sensitivity = U.view_rotate_sensitivity_turntable / U.pixelsize; + const float sensitivity = U.view_rotate_sensitivity_turntable / U.dpi_fac; /* Get the 3x3 matrix and its inverse from the quaternion */ quat_to_mat3(m, vod->curr.viewquat); @@ -2038,7 +2038,7 @@ static float viewzoom_scale_value(const rcti *winrct, fac = (float)(xy_init[1] - xy_curr[1]); } - fac /= U.pixelsize; + fac /= U.dpi_fac; if (zoom_invert != zoom_invert_force) { fac = -fac; @@ -2055,8 +2055,8 @@ static float viewzoom_scale_value(const rcti *winrct, BLI_rcti_cent_x(winrct), BLI_rcti_cent_y(winrct), }; - float len_new = (5 * U.pixelsize) + ((float)len_v2v2_int(ctr, xy_curr) / U.pixelsize); - float len_old = (5 * U.pixelsize) + ((float)len_v2v2_int(ctr, xy_init) / U.pixelsize); + float len_new = (5 * U.dpi_fac) + ((float)len_v2v2_int(ctr, xy_curr) / U.dpi_fac); + float len_old = (5 * U.dpi_fac) + ((float)len_v2v2_int(ctr, xy_init) / U.dpi_fac); /* intentionally ignore 'zoom_invert' for scale */ if (zoom_invert_force) { @@ -2066,16 +2066,16 @@ static float viewzoom_scale_value(const rcti *winrct, zfac = val_orig * (len_old / max_ff(len_new, 1.0f)) / val; } else { /* USER_ZOOM_DOLLY */ - float len_new = 5 * U.pixelsize; - float len_old = 5 * U.pixelsize; + float len_new = 5 * U.dpi_fac; + float len_old = 5 * U.dpi_fac; if (U.uiflag & USER_ZOOM_HORIZ) { - len_new += (winrct->xmax - (xy_curr[0])) / U.pixelsize; - len_old += (winrct->xmax - (xy_init[0])) / U.pixelsize; + len_new += (winrct->xmax - (xy_curr[0])) / U.dpi_fac; + len_old += (winrct->xmax - (xy_init[0])) / U.dpi_fac; } else { - len_new += (winrct->ymax - (xy_curr[1])) / U.pixelsize; - len_old += (winrct->ymax - (xy_init[1])) / U.pixelsize; + len_new += (winrct->ymax - (xy_curr[1])) / U.dpi_fac; + len_old += (winrct->ymax - (xy_init[1])) / U.dpi_fac; } if (zoom_invert != zoom_invert_force) { diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index 66efa5b5de3..839f8c60a66 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -1733,6 +1733,8 @@ void ED_view3d_xr_shading_update(wmWindowManager *wm, const View3D *v3d, const S { if (v3d->runtime.flag & V3D_RUNTIME_XR_SESSION_ROOT) { View3DShading *xr_shading = &wm->xr.session_settings.shading; + /* Flags that shouldn't be overridden by the 3D View shading. */ + const int flag_copy = V3D_SHADING_WORLD_ORIENTATION; BLI_assert(WM_xr_session_exists(&wm->xr)); @@ -1750,7 +1752,9 @@ void ED_view3d_xr_shading_update(wmWindowManager *wm, const View3D *v3d, const S } /* Copy shading from View3D to VR view. */ + const int old_xr_shading_flag = xr_shading->flag; *xr_shading = v3d->shading; + xr_shading->flag = (xr_shading->flag & ~flag_copy) | (old_xr_shading_flag & flag_copy); if (v3d->shading.prop) { xr_shading->prop = IDP_CopyProperty(xr_shading->prop); } diff --git a/source/blender/gpu/GPU_framebuffer.h b/source/blender/gpu/GPU_framebuffer.h index 4958d1eaac8..ee99f1f68c8 100644 --- a/source/blender/gpu/GPU_framebuffer.h +++ b/source/blender/gpu/GPU_framebuffer.h @@ -61,6 +61,7 @@ typedef struct GPUOffScreen GPUOffScreen; GPUFrameBuffer *GPU_framebuffer_create(void); void GPU_framebuffer_free(GPUFrameBuffer *fb); void GPU_framebuffer_bind(GPUFrameBuffer *fb); +void GPU_framebuffer_bind_no_srgb(GPUFrameBuffer *fb); void GPU_framebuffer_restore(void); bool GPU_framebuffer_bound(GPUFrameBuffer *fb); diff --git a/source/blender/gpu/intern/gpu_framebuffer.c b/source/blender/gpu/intern/gpu_framebuffer.c index 77abb786117..838450e6528 100644 --- a/source/blender/gpu/intern/gpu_framebuffer.c +++ b/source/blender/gpu/intern/gpu_framebuffer.c @@ -544,6 +544,18 @@ void GPU_framebuffer_bind(GPUFrameBuffer *fb) glViewport(0, 0, fb->width, fb->height); } +/* Workaround for binding a srgb framebuffer without doing the srgb transform. */ +void GPU_framebuffer_bind_no_srgb(GPUFrameBuffer *fb) +{ + GPU_framebuffer_bind(fb); + + glDisable(GL_FRAMEBUFFER_SRGB); + + GPUTexture *first_target = fb->attachments[GPU_FB_COLOR_ATTACHMENT0].tex; + const bool is_srgb_target = (first_target && (GPU_texture_format(first_target) == GPU_SRGB8_A8)); + GPU_shader_set_framebuffer_srgb_target(!is_srgb_target); +} + void GPU_framebuffer_restore(void) { if (GPU_framebuffer_active_get() != NULL) { diff --git a/source/blender/gpu/intern/gpu_texture.c b/source/blender/gpu/intern/gpu_texture.c index 5bbfd04c114..53feaa3ed76 100644 --- a/source/blender/gpu/intern/gpu_texture.c +++ b/source/blender/gpu/intern/gpu_texture.c @@ -678,7 +678,7 @@ static bool gpu_texture_check_capacity( GPUTexture *tex, GLenum proxy, GLenum internalformat, GLenum data_format, GLenum data_type) { if (proxy == GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB && - GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_MAC, GPU_DRIVER_ANY)) { + GPU_type_matches(GPU_DEVICE_ANY, GPU_OS_MAC, GPU_DRIVER_ANY)) { /* Special fix for T79703. */ /* Depth has already been checked. */ return tex->w <= GPU_max_cube_map_size(); diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h index d5b828c898d..e8c4d5cde20 100644 --- a/source/blender/makesdna/DNA_screen_types.h +++ b/source/blender/makesdna/DNA_screen_types.h @@ -68,8 +68,6 @@ typedef struct bScreen { /** User-setting for which editors get redrawn during anim playback. */ short redraws_flag; - char statusbar_info[256]; - /** Temp screen in a temp window, don't save (like user prefs). */ char temp; /** Temp screen for image render display or fileselect. */ @@ -635,13 +633,21 @@ typedef enum eRegionType { RGN_TYPE_EXECUTE = 10, RGN_TYPE_FOOTER = 11, RGN_TYPE_TOOL_HEADER = 12, + +#define RGN_TYPE_LEN (RGN_TYPE_TOOL_HEADER + 1) } eRegionType; + /* use for function args */ #define RGN_TYPE_ANY -1 /* Region supports panel tabs (categories). */ #define RGN_TYPE_HAS_CATEGORY_MASK (1 << RGN_TYPE_UI) +/* Check for any kind of header region. */ +#define RGN_TYPE_IS_HEADER_ANY(regiontype) \ + (((1 << (regiontype)) & \ + ((1 << RGN_TYPE_HEADER) | 1 << (RGN_TYPE_TOOL_HEADER) | (1 << RGN_TYPE_FOOTER))) != 0) + /** #ARegion.alignment */ enum { RGN_ALIGN_NONE = 0, @@ -661,6 +667,7 @@ enum { /** Mask out flags so we can check the alignment. */ #define RGN_ALIGN_ENUM_FROM_MASK(align) ((align) & ((1 << 4) - 1)) +#define RGN_ALIGN_FLAG_FROM_MASK(align) ((align) & ~((1 << 4) - 1)) /** #ARegion.flag */ enum { diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index a632d42fd8b..15fe1619ca4 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -689,16 +689,17 @@ typedef struct UserDef { int audioformat; int audiochannels; - /** Setting for UI scale. */ + /** Setting for UI scale (fractional), before screen DPI has been applied. */ float ui_scale; /** Setting for UI line width. */ int ui_line_width; /** Runtime, full DPI divided by `pixelsize`. */ int dpi; - /** Runtime, multiplier to scale UI elements based on DPI. */ + /** Runtime, multiplier to scale UI elements based on DPI (fractional). */ float dpi_fac; + /** Runtime, `1.0 / dpi_fac` */ float inv_dpi_fac; - /** Runtime, line width and point size based on DPI. */ + /** Runtime, calculated from line-width and point-size based on DPI (rounded to int). */ float pixelsize; /** Deprecated, for forward compatibility. */ int virtual_pixel; diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt index 0b43a5a6653..1896813bdb3 100644 --- a/source/blender/makesrna/intern/CMakeLists.txt +++ b/source/blender/makesrna/intern/CMakeLists.txt @@ -47,7 +47,6 @@ set(DEFSRC rna_fluid.c rna_gpencil.c rna_gpencil_modifier.c - rna_hair.c rna_image.c rna_key.c rna_lattice.c @@ -69,7 +68,6 @@ set(DEFSRC rna_packedfile.c rna_palette.c rna_particle.c - rna_pointcloud.c rna_pose.c rna_render.c rna_rigidbody.c @@ -79,7 +77,6 @@ set(DEFSRC rna_sculpt_paint.c rna_sequencer.c rna_shader_fx.c - rna_simulation.c rna_sound.c rna_space.c rna_speaker.c @@ -99,6 +96,16 @@ set(DEFSRC rna_xr.c ) +if(WITH_EXPERIMENTAL_FEATURES) + add_definitions(-DWITH_PARTICLE_NODES) + add_definitions(-DWITH_HAIR_NODES) + list(APPEND DEFSRC + rna_pointcloud.c + rna_simulation.c + rna_hair.c + ) +endif() + set(APISRC rna_action_api.c rna_animation_api.c diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index b7f0fb87536..b49a6885675 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -4285,7 +4285,9 @@ static RNAProcessItem PROCESS_ITEMS[] = { {"rna_dynamicpaint.c", NULL, RNA_def_dynamic_paint}, {"rna_fcurve.c", "rna_fcurve_api.c", RNA_def_fcurve}, {"rna_gpencil.c", NULL, RNA_def_gpencil}, +#ifdef WITH_HAIR_NODES {"rna_hair.c", NULL, RNA_def_hair}, +#endif {"rna_image.c", "rna_image_api.c", RNA_def_image}, {"rna_key.c", NULL, RNA_def_key}, {"rna_light.c", NULL, RNA_def_light}, @@ -4308,7 +4310,9 @@ static RNAProcessItem PROCESS_ITEMS[] = { {"rna_packedfile.c", NULL, RNA_def_packedfile}, {"rna_palette.c", NULL, RNA_def_palette}, {"rna_particle.c", NULL, RNA_def_particle}, +#ifdef WITH_PARTICLE_NODES {"rna_pointcloud.c", NULL, RNA_def_pointcloud}, +#endif {"rna_pose.c", "rna_pose_api.c", RNA_def_pose}, {"rna_curveprofile.c", NULL, RNA_def_profile}, {"rna_lightprobe.c", NULL, RNA_def_lightprobe}, @@ -4318,7 +4322,9 @@ static RNAProcessItem PROCESS_ITEMS[] = { {"rna_screen.c", NULL, RNA_def_screen}, {"rna_sculpt_paint.c", NULL, RNA_def_sculpt_paint}, {"rna_sequencer.c", "rna_sequencer_api.c", RNA_def_sequencer}, +#ifdef WITH_PARTICLE_NODES {"rna_simulation.c", NULL, RNA_def_simulation}, +#endif {"rna_space.c", "rna_space_api.c", RNA_def_space}, {"rna_speaker.c", NULL, RNA_def_speaker}, {"rna_test.c", NULL, RNA_def_test}, diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c index e9ca0d577ce..f1c125fcbb9 100644 --- a/source/blender/makesrna/intern/rna_ID.c +++ b/source/blender/makesrna/intern/rna_ID.c @@ -251,9 +251,11 @@ short RNA_type_to_ID_code(const StructRNA *type) if (base_type == &RNA_FreestyleLineStyle) { return ID_LS; } +# ifdef WITH_HAIR_NODES if (base_type == &RNA_Hair) { return ID_HA; } +# endif if (base_type == &RNA_Lattice) { return ID_LT; } @@ -287,9 +289,11 @@ short RNA_type_to_ID_code(const StructRNA *type) if (base_type == &RNA_PaintCurve) { return ID_PC; } +# ifdef WITH_PARTICLE_NODES if (base_type == &RNA_PointCloud) { return ID_PT; } +# endif if (base_type == &RNA_LightProbe) { return ID_LP; } @@ -299,9 +303,11 @@ short RNA_type_to_ID_code(const StructRNA *type) if (base_type == &RNA_Screen) { return ID_SCR; } +# ifdef WITH_PARTICLE_NODES if (base_type == &RNA_Simulation) { return ID_SIM; } +# endif if (base_type == &RNA_Sound) { return ID_SO; } @@ -355,7 +361,11 @@ StructRNA *ID_code_to_RNA_type(short idcode) case ID_GR: return &RNA_Collection; case ID_HA: +# ifdef WITH_HAIR_NODES return &RNA_Hair; +# else + return &RNA_ID; +# endif case ID_IM: return &RNA_Image; case ID_KE: @@ -389,7 +399,11 @@ StructRNA *ID_code_to_RNA_type(short idcode) case ID_PC: return &RNA_PaintCurve; case ID_PT: +# ifdef WITH_PARTICLE_NODES return &RNA_PointCloud; +# else + return &RNA_ID; +# endif case ID_LP: return &RNA_LightProbe; case ID_SCE: @@ -397,7 +411,11 @@ StructRNA *ID_code_to_RNA_type(short idcode) case ID_SCR: return &RNA_Screen; case ID_SIM: +# ifdef WITH_PARTICLE_NODES return &RNA_Simulation; +# else + return &RNA_ID; +# endif case ID_SO: return &RNA_Sound; case ID_SPK: diff --git a/source/blender/makesrna/intern/rna_access_compare_override.c b/source/blender/makesrna/intern/rna_access_compare_override.c index 0a739dcfc5a..ac4553349cc 100644 --- a/source/blender/makesrna/intern/rna_access_compare_override.c +++ b/source/blender/makesrna/intern/rna_access_compare_override.c @@ -484,13 +484,13 @@ static bool rna_property_override_operation_apply(Main *bmain, /* Special case for IDProps, we use default callback then. */ if (prop_dst->magic != RNA_MAGIC) { override_apply = rna_property_override_apply_default; - if (prop_src->magic == RNA_MAGIC && prop_src->override_apply != override_apply) { + if (prop_src->magic == RNA_MAGIC && !ELEM(prop_src->override_apply, NULL, override_apply)) { override_apply = NULL; } } else if (prop_src->magic != RNA_MAGIC) { override_apply = rna_property_override_apply_default; - if (prop_dst->override_apply != override_apply) { + if (!ELEM(prop_dst->override_apply, NULL, override_apply)) { override_apply = NULL; } } diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h index 8045279eef2..6254e40a410 100644 --- a/source/blender/makesrna/intern/rna_internal.h +++ b/source/blender/makesrna/intern/rna_internal.h @@ -455,10 +455,16 @@ void RNA_def_main_cachefiles(BlenderRNA *brna, PropertyRNA *cprop); void RNA_def_main_paintcurves(BlenderRNA *brna, PropertyRNA *cprop); void RNA_def_main_workspaces(BlenderRNA *brna, PropertyRNA *cprop); void RNA_def_main_lightprobes(BlenderRNA *brna, PropertyRNA *cprop); +#ifdef WITH_PARTICLE_NODES void RNA_def_main_hairs(BlenderRNA *brna, PropertyRNA *cprop); +#endif +#ifdef WITH_HAIR_NODES void RNA_def_main_pointclouds(BlenderRNA *brna, PropertyRNA *cprop); +#endif void RNA_def_main_volumes(BlenderRNA *brna, PropertyRNA *cprop); +#ifdef WITH_PARTICLE_NODES void RNA_def_main_simulations(BlenderRNA *brna, PropertyRNA *cprop); +#endif /* ID Properties */ diff --git a/source/blender/makesrna/intern/rna_main.c b/source/blender/makesrna/intern/rna_main.c index 97702b06b6f..d83fca69278 100644 --- a/source/blender/makesrna/intern/rna_main.c +++ b/source/blender/makesrna/intern/rna_main.c @@ -109,7 +109,9 @@ RNA_MAIN_LISTBASE_FUNCS_DEF(collections) RNA_MAIN_LISTBASE_FUNCS_DEF(curves) RNA_MAIN_LISTBASE_FUNCS_DEF(fonts) RNA_MAIN_LISTBASE_FUNCS_DEF(gpencils) +# ifdef WITH_HAIR_NODES RNA_MAIN_LISTBASE_FUNCS_DEF(hairs) +# endif RNA_MAIN_LISTBASE_FUNCS_DEF(images) RNA_MAIN_LISTBASE_FUNCS_DEF(lattices) RNA_MAIN_LISTBASE_FUNCS_DEF(libraries) @@ -126,11 +128,15 @@ RNA_MAIN_LISTBASE_FUNCS_DEF(objects) RNA_MAIN_LISTBASE_FUNCS_DEF(paintcurves) RNA_MAIN_LISTBASE_FUNCS_DEF(palettes) RNA_MAIN_LISTBASE_FUNCS_DEF(particles) +# ifdef WITH_PARTICLE_NODES RNA_MAIN_LISTBASE_FUNCS_DEF(pointclouds) +# endif RNA_MAIN_LISTBASE_FUNCS_DEF(scenes) RNA_MAIN_LISTBASE_FUNCS_DEF(screens) RNA_MAIN_LISTBASE_FUNCS_DEF(shapekeys) +# ifdef WITH_PARTICLE_NODES RNA_MAIN_LISTBASE_FUNCS_DEF(simulations) +# endif RNA_MAIN_LISTBASE_FUNCS_DEF(sounds) RNA_MAIN_LISTBASE_FUNCS_DEF(speakers) RNA_MAIN_LISTBASE_FUNCS_DEF(texts) @@ -384,25 +390,31 @@ void RNA_def_main(BlenderRNA *brna) "LightProbes", "LightProbe data-blocks", RNA_def_main_lightprobes}, +# ifdef WITH_HAIR_NODES {"hairs", "Hair", "rna_Main_hairs_begin", "Hairs", "Hair data-blocks", RNA_def_main_hairs}, +# endif +# ifdef WITH_PARTICLE_NODES {"pointclouds", "PointCloud", "rna_Main_pointclouds_begin", "Point Clouds", "Point cloud data-blocks", RNA_def_main_pointclouds}, +# endif {"volumes", "Volume", "rna_Main_volumes_begin", "Volumes", "Volume data-blocks", RNA_def_main_volumes}, +# ifdef WITH_PARTICLE_NODES {"simulations", "Simulation", "rna_Main_simulations_begin", "Simulations", "Simulation data-blocks", RNA_def_main_simulations}, +# endif {NULL, NULL, NULL, NULL, NULL, NULL}, }; diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c index 990a5412093..7c941ddb524 100644 --- a/source/blender/makesrna/intern/rna_main_api.c +++ b/source/blender/makesrna/intern/rna_main_api.c @@ -708,6 +708,7 @@ static bGPdata *rna_Main_gpencils_new(Main *bmain, const char *name) return gpd; } +# ifdef WITH_HAIR_NODES static Hair *rna_Main_hairs_new(Main *bmain, const char *name) { char safe_name[MAX_ID_NAME - 2]; @@ -717,7 +718,9 @@ static Hair *rna_Main_hairs_new(Main *bmain, const char *name) id_us_min(&hair->id); return hair; } +# endif +# ifdef WITH_PARTICLE_NODES static PointCloud *rna_Main_pointclouds_new(Main *bmain, const char *name) { char safe_name[MAX_ID_NAME - 2]; @@ -727,6 +730,7 @@ static PointCloud *rna_Main_pointclouds_new(Main *bmain, const char *name) id_us_min(&pointcloud->id); return pointcloud; } +# endif static Volume *rna_Main_volumes_new(Main *bmain, const char *name) { @@ -738,6 +742,7 @@ static Volume *rna_Main_volumes_new(Main *bmain, const char *name) return volume; } +# ifdef WITH_PARTICLE_NODES static Simulation *rna_Main_simulations_new(Main *bmain, const char *name) { char safe_name[MAX_ID_NAME - 2]; @@ -747,6 +752,7 @@ static Simulation *rna_Main_simulations_new(Main *bmain, const char *name) id_us_min(&simulation->id); return simulation; } +# endif /* tag functions, all the same */ # define RNA_MAIN_ID_TAG_FUNCS_DEF(_func_name, _listbase_name, _id_type) \ @@ -790,10 +796,16 @@ RNA_MAIN_ID_TAG_FUNCS_DEF(cachefiles, cachefiles, ID_CF) RNA_MAIN_ID_TAG_FUNCS_DEF(paintcurves, paintcurves, ID_PC) RNA_MAIN_ID_TAG_FUNCS_DEF(workspaces, workspaces, ID_WS) RNA_MAIN_ID_TAG_FUNCS_DEF(lightprobes, lightprobes, ID_LP) +# ifdef WITH_HAIR_NODES RNA_MAIN_ID_TAG_FUNCS_DEF(hairs, hairs, ID_HA) +# endif +# ifdef WITH_PARTICLE_NODES RNA_MAIN_ID_TAG_FUNCS_DEF(pointclouds, pointclouds, ID_PT) +# endif RNA_MAIN_ID_TAG_FUNCS_DEF(volumes, volumes, ID_VO) +# ifdef WITH_PARTICLE_NODES RNA_MAIN_ID_TAG_FUNCS_DEF(simulations, simulations, ID_SIM) +# endif # undef RNA_MAIN_ID_TAG_FUNCS_DEF @@ -2194,6 +2206,7 @@ void RNA_def_main_lightprobes(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); } +# ifdef WITH_HAIR_NODES void RNA_def_main_hairs(BlenderRNA *brna, PropertyRNA *cprop) { StructRNA *srna; @@ -2237,7 +2250,9 @@ void RNA_def_main_hairs(BlenderRNA *brna, PropertyRNA *cprop) parm = RNA_def_boolean(func, "value", 0, "Value", ""); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); } +# endif +# ifdef WITH_PARTICLE_NODES void RNA_def_main_pointclouds(BlenderRNA *brna, PropertyRNA *cprop) { StructRNA *srna; @@ -2284,6 +2299,7 @@ void RNA_def_main_pointclouds(BlenderRNA *brna, PropertyRNA *cprop) parm = RNA_def_boolean(func, "value", 0, "Value", ""); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); } +# endif void RNA_def_main_volumes(BlenderRNA *brna, PropertyRNA *cprop) { @@ -2329,6 +2345,7 @@ void RNA_def_main_volumes(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); } +# ifdef WITH_PARTICLE_NODES void RNA_def_main_simulations(BlenderRNA *brna, PropertyRNA *cprop) { StructRNA *srna; @@ -2368,5 +2385,6 @@ void RNA_def_main_simulations(BlenderRNA *brna, PropertyRNA *cprop) parm = RNA_def_boolean(func, "value", 0, "Value", ""); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); } +# endif #endif diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index 86f05c350f3..bd507d7b1fc 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -723,7 +723,9 @@ static StructRNA *rna_Modifier_refine(struct PointerRNA *ptr) case eModifierType_WeightedNormal: return &RNA_WeightedNormalModifier; case eModifierType_Simulation: +# ifdef WITH_PARTICLE_NODES return &RNA_SimulationModifier; +# endif /* Default */ case eModifierType_Fluidsim: /* deprecated */ case eModifierType_None: @@ -1630,6 +1632,7 @@ static void rna_ParticleInstanceModifier_particle_system_set(PointerRNA *ptr, CLAMP_MIN(psmd->psys, 1); } +# ifdef WITH_PARTICLE_NODES static void rna_SimulationModifier_simulation_update(Main *bmain, Scene *scene, PointerRNA *ptr) { SimulationModifierData *smd = ptr->data; @@ -1672,6 +1675,7 @@ static void rna_SimulationModifier_data_path_set(PointerRNA *ptr, const char *va smd->data_path = NULL; } } +# endif /** * Special set callback that just changes the first bit of the expansion flag. @@ -6898,6 +6902,7 @@ static void rna_def_modifier_weightednormal(BlenderRNA *brna) RNA_define_lib_overridable(false); } +# ifdef WITH_PARTICLE_NODES static void rna_def_modifier_simulation(BlenderRNA *brna) { StructRNA *srna; @@ -6926,6 +6931,7 @@ static void rna_def_modifier_simulation(BlenderRNA *brna) RNA_define_lib_overridable(false); } +# endif void RNA_def_modifier(BlenderRNA *brna) { @@ -7055,7 +7061,9 @@ void RNA_def_modifier(BlenderRNA *brna) rna_def_modifier_meshseqcache(brna); rna_def_modifier_surfacedeform(brna); rna_def_modifier_weightednormal(brna); +# ifdef WITH_PARTICLE_NODES rna_def_modifier_simulation(brna); +# endif } #endif diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 84b83bee089..347ac6fd5a7 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -564,9 +564,17 @@ static StructRNA *rna_Object_data_typef(PointerRNA *ptr) case OB_GPENCIL: return &RNA_GreasePencil; case OB_HAIR: +# ifdef WITH_HAIR_NODES return &RNA_Hair; +# else + return &RNA_ID; +# endif case OB_POINTCLOUD: +# ifdef WITH_PARTICLE_NODES return &RNA_PointCloud; +# else + return &RNA_ID; +# endif case OB_VOLUME: return &RNA_Volume; default: diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 66698d60423..d723642e65a 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -924,6 +924,13 @@ static void rna_Scene_volume_update(Main *UNUSED(bmain), Scene *UNUSED(scene), P DEG_id_tag_update(&scene->id, ID_RECALC_AUDIO_VOLUME | ID_RECALC_SEQUENCER_STRIPS); } +static const char *rna_Scene_statistics_string_get(Scene *scene, + Main *bmain, + ViewLayer *view_layer) +{ + return ED_info_statistics_string(bmain, scene, view_layer); +} + static void rna_Scene_framelen_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNUSED(ptr)) { scene->r.framelen = (float)scene->r.framapto / (float)scene->r.images; @@ -1866,11 +1873,10 @@ static void object_simplify_update(Object *ob) } if (ob->instance_collection) { - CollectionObject *cob; - - for (cob = ob->instance_collection->gobject.first; cob; cob = cob->next) { - object_simplify_update(cob->ob); + FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (ob->instance_collection, ob_collection) { + object_simplify_update(ob_collection); } + FOREACH_COLLECTION_OBJECT_RECURSIVE_END; } } @@ -7277,6 +7283,9 @@ void RNA_def_scene(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; + FunctionRNA *func; + PropertyRNA *parm; + static const EnumPropertyItem audio_distance_model_items[] = { {0, "NONE", 0, "None", "No distance attenuation"}, {1, "INVERSE", 0, "Inverse", "Inverse distance model"}, @@ -7668,6 +7677,14 @@ void RNA_def_scene(BlenderRNA *brna) RNA_def_property_update(prop, NC_SCENE, NULL); RNA_def_property_update(prop, NC_SCENE, "rna_Scene_volume_update"); + /* Statistics */ + func = RNA_def_function(srna, "statistics", "rna_Scene_statistics_string_get"); + RNA_def_function_flag(func, FUNC_USE_MAIN); + parm = RNA_def_pointer(func, "view_layer", "ViewLayer", "View Layer", ""); + RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); + parm = RNA_def_string(func, "statistics", NULL, 0, "Statistics", ""); + RNA_def_function_return(func, parm); + /* Grease Pencil */ prop = RNA_def_property(srna, "grease_pencil", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "gpd"); diff --git a/source/blender/makesrna/intern/rna_screen.c b/source/blender/makesrna/intern/rna_screen.c index 24c4818694f..842fa64e680 100644 --- a/source/blender/makesrna/intern/rna_screen.c +++ b/source/blender/makesrna/intern/rna_screen.c @@ -288,9 +288,11 @@ static void rna_View2D_view_to_region( } } -static const char *rna_Screen_statusbar_info_get(struct bScreen *screen, Main *bmain, bContext *C) +static const char *rna_Screen_statusbar_info_get(struct bScreen *UNUSED(screen), + Main *bmain, + bContext *C) { - return ED_info_statusbar_string(bmain, screen, C); + return ED_info_statusbar_string(bmain, CTX_data_scene(C), CTX_data_view_layer(C)); } #else diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c index 0cfc6fd569c..629dc104ab5 100644 --- a/source/blender/makesrna/intern/rna_sequencer.c +++ b/source/blender/makesrna/intern/rna_sequencer.c @@ -637,6 +637,8 @@ static void rna_Sequence_name_set(PointerRNA *ptr, const char *value) char oldname[sizeof(seq->name)]; AnimData *adt; + BKE_sequencer_prefetch_stop(scene); + /* make a copy of the old name first */ BLI_strncpy(oldname, seq->name + 2, sizeof(seq->name) - 2); diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 494fcec4c31..5765dac881e 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -2181,6 +2181,7 @@ static void rna_SpaceNodeEditor_node_tree_update(const bContext *C, PointerRNA * ED_node_tree_update(C); } +# ifdef WITH_PARTICLE_NODES static PointerRNA rna_SpaceNodeEditor_simulation_get(PointerRNA *ptr) { SpaceNode *snode = (SpaceNode *)ptr->data; @@ -2212,6 +2213,7 @@ static void rna_SpaceNodeEditor_simulation_set(PointerRNA *ptr, } snode->id = &sim->id; } +# endif static int rna_SpaceNodeEditor_tree_type_get(PointerRNA *ptr) { @@ -6266,6 +6268,7 @@ static void rna_def_space_node(BlenderRNA *brna) RNA_def_property_ui_text( prop, "ID From", "Data-block from which the edited data-block is linked"); +# ifdef WITH_PARTICLE_NODES prop = RNA_def_property(srna, "simulation", PROP_POINTER, PROP_NONE); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_struct_type(prop, "Simulation"); @@ -6276,6 +6279,7 @@ static void rna_def_space_node(BlenderRNA *brna) NULL, NULL); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_NODE, NULL); +# endif prop = RNA_def_property(srna, "path", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_sdna(prop, NULL, "treepath", NULL); diff --git a/source/blender/modifiers/intern/MOD_multires.c b/source/blender/modifiers/intern/MOD_multires.c index f091385ff8e..7f0ed9af106 100644 --- a/source/blender/modifiers/intern/MOD_multires.c +++ b/source/blender/modifiers/intern/MOD_multires.c @@ -407,10 +407,7 @@ static void subdivisions_panel_draw(const bContext *C, Panel *panel) uiItemS(layout); uiItemO(layout, IFACE_("Unsubdivide"), ICON_NONE, "OBJECT_OT_multires_unsubdivide"); - - row = uiLayoutRow(layout, false); - uiItemL(row, "", ICON_NONE); - uiItemO(row, IFACE_("Delete Higher"), ICON_NONE, "OBJECT_OT_multires_higher_levels_delete"); + uiItemO(layout, IFACE_("Delete Higher"), ICON_NONE, "OBJECT_OT_multires_higher_levels_delete"); } static void shape_panel_draw(const bContext *C, Panel *panel) @@ -487,7 +484,7 @@ static void panelRegister(ARegionType *region_type) { PanelType *panel_type = modifier_panel_register(region_type, eModifierType_Multires, panel_draw); modifier_subpanel_register( - region_type, "subdivide", "Subdivions", NULL, subdivisions_panel_draw, panel_type); + region_type, "subdivide", "Subdivisions", NULL, subdivisions_panel_draw, panel_type); modifier_subpanel_register(region_type, "shape", "Shape", NULL, shape_panel_draw, panel_type); modifier_subpanel_register( region_type, "generate", "Generate", NULL, generate_panel_draw, panel_type); diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c index 075202e8a79..0790d40d56c 100644 --- a/source/blender/render/intern/source/external_engine.c +++ b/source/blender/render/intern/source/external_engine.c @@ -513,15 +513,15 @@ void RE_engine_active_view_set(RenderEngine *engine, const char *viewname) float RE_engine_get_camera_shift_x(RenderEngine *engine, Object *camera, bool use_spherical_stereo) { - Render *re = engine->re; - /* When using spherical stereo, get camera shift without multiview, * leaving stereo to be handled by the engine. */ - if (use_spherical_stereo) { - re = NULL; + Render *re = engine->re; + if (use_spherical_stereo || re == NULL) { + return BKE_camera_multiview_shift_x(NULL, camera, NULL); + } + else { + return BKE_camera_multiview_shift_x(&re->r, camera, re->viewname); } - - return BKE_camera_multiview_shift_x(re ? &re->r : NULL, camera, re->viewname); } void RE_engine_get_camera_model_matrix(RenderEngine *engine, @@ -529,16 +529,15 @@ void RE_engine_get_camera_model_matrix(RenderEngine *engine, bool use_spherical_stereo, float *r_modelmat) { - Render *re = engine->re; - /* When using spherical stereo, get model matrix without multiview, * leaving stereo to be handled by the engine. */ - if (use_spherical_stereo) { - re = NULL; + Render *re = engine->re; + if (use_spherical_stereo || re == NULL) { + BKE_camera_multiview_model_matrix(NULL, camera, NULL, (float(*)[4])r_modelmat); + } + else { + BKE_camera_multiview_model_matrix(&re->r, camera, re->viewname, (float(*)[4])r_modelmat); } - - BKE_camera_multiview_model_matrix( - re ? &re->r : NULL, camera, re->viewname, (float(*)[4])r_modelmat); } bool RE_engine_get_spherical_stereo(RenderEngine *engine, Object *camera) diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c index fdbc7a7d136..622e8359541 100644 --- a/source/blender/windowmanager/intern/wm_draw.c +++ b/source/blender/windowmanager/intern/wm_draw.c @@ -308,7 +308,9 @@ static void wm_region_test_xr_do_draw(const wmWindowManager *wm, static bool wm_region_use_viewport_by_type(short space_type, short region_type) { - return (ELEM(space_type, SPACE_VIEW3D, SPACE_IMAGE) && region_type == RGN_TYPE_WINDOW); + return (ELEM(space_type, SPACE_VIEW3D, SPACE_IMAGE, SPACE_NODE) && + region_type == RGN_TYPE_WINDOW) || + ((space_type == SPACE_SEQ) && region_type == RGN_TYPE_PREVIEW); } bool WM_region_use_viewport(ScrArea *area, ARegion *region) diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 8dbb608cd30..c14413e3d01 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -1363,8 +1363,7 @@ static int wm_operator_invoke(bContext *C, ScrArea *area = CTX_wm_area(C); /* Wrap only in X for header. */ - if (region && - ELEM(region->regiontype, RGN_TYPE_HEADER, RGN_TYPE_TOOL_HEADER, RGN_TYPE_FOOTER)) { + if (region && RGN_TYPE_IS_HEADER_ANY(region->regiontype)) { wrap = WM_CURSOR_WRAP_X; } diff --git a/source/blender/windowmanager/xr/intern/wm_xr_session.c b/source/blender/windowmanager/xr/intern/wm_xr_session.c index 9c6b8e8fbda..4edfd53c37a 100644 --- a/source/blender/windowmanager/xr/intern/wm_xr_session.c +++ b/source/blender/windowmanager/xr/intern/wm_xr_session.c @@ -251,9 +251,14 @@ void wm_xr_session_draw_data_update(const wmXrSessionState *state, switch (event) { case SESSION_STATE_EVENT_START: - /* We want to start the session exactly at landmark position. Runtimes may have a non-[0,0,0] - * starting position that we have to substract for that. */ - copy_v3_v3(draw_data->eye_position_ofs, draw_view->local_pose.position); + if (use_position_tracking) { + /* We want to start the session exactly at landmark position. + * Run-times may have a non-[0,0,0] starting position that we have to subtract for that. */ + copy_v3_v3(draw_data->eye_position_ofs, draw_view->local_pose.position); + } + else { + copy_v3_fl(draw_data->eye_position_ofs, 0.0f); + } break; /* This should be triggered by the VR add-on if a landmark changes. */ case SESSION_STATE_EVENT_RESET_TO_BASE_POSE: |