Animation: Add in Parent space alignment option to the Transform Orientation gizmo #104724

Merged
Nate Rupsis merged 47 commits from nrupsis/blender:parent-space into main 2023-04-20 17:40:31 +02:00
97 changed files with 728 additions and 425 deletions
Showing only changes of commit 996c76f5b6 - Show all commits

View File

@ -108,7 +108,11 @@ FIND_PACKAGE_HANDLE_STANDARD_ARGS(SYCL
IF(SYCL_FOUND)
SET(SYCL_INCLUDE_DIR ${SYCL_INCLUDE_DIR} ${SYCL_INCLUDE_DIR}/sycl)
SET(SYCL_LIBRARIES ${SYCL_LIBRARY})
IF(WIN32 AND SYCL_LIBRARY_DEBUG)
SET(SYCL_LIBRARIES optimized ${SYCL_LIBRARY} debug ${SYCL_LIBRARY_DEBUG})
ELSE()
SET(SYCL_LIBRARIES ${SYCL_LIBRARY})
ENDIF()
ELSE()
SET(SYCL_SYCL_FOUND FALSE)
ENDIF()

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0-or-later
'''
"""
This script generates the blender.1 man page, embedding the help text
from the Blender executable itself. Invoke it as follows:
@ -9,7 +9,7 @@ from the Blender executable itself. Invoke it as follows:
where <path-to-blender> is the path to the Blender executable,
and <output-filename> is where to write the generated man page.
'''
"""
import argparse
import os
@ -87,29 +87,29 @@ def man_page_from_blender_help(fh: TextIO, blender_bin: str, verbose: bool) -> N
(blender_info["date"], blender_info["version"].replace(".", "\\&."))
)
fh.write(r'''
fh.write(r"""
.SH NAME
blender \- a full-featured 3D application''')
blender \- a full-featured 3D application""")
fh.write(r'''
fh.write(r"""
.SH SYNOPSIS
.B blender [args ...] [file] [args ...]''')
.B blender [args ...] [file] [args ...]""")
fh.write(r'''
fh.write(r"""
.br
.SH DESCRIPTION
.PP
.B blender
is a full-featured 3D application. It supports the entirety of the 3D pipeline - '''
'''modeling, rigging, animation, simulation, rendering, compositing, motion tracking, and video editing.
is a full-featured 3D application. It supports the entirety of the 3D pipeline - """
"""modeling, rigging, animation, simulation, rendering, compositing, motion tracking, and video editing.
Use Blender to create 3D images and animations, films and commercials, content for games, '''
r'''architectural and industrial visualizations, and scientific visualizations.
Use Blender to create 3D images and animations, films and commercials, content for games, """
r"""architectural and industrial visualizations, and scientific visualizations.
https://www.blender.org''')
https://www.blender.org""")
fh.write(r'''
.SH OPTIONS''')
fh.write(r"""
.SH OPTIONS""")
fh.write("\n\n")
@ -152,7 +152,7 @@ https://www.blender.org''')
# Footer Content.
fh.write(r'''
fh.write(r"""
.br
.SH SEE ALSO
.B luxrender(1)
@ -162,7 +162,7 @@ https://www.blender.org''')
This manpage was written for a Debian GNU/Linux system by Daniel Mester
<mester@uni-bremen.de> and updated by Cyril Brulebois
<cyril.brulebois@enst-bretagne.fr> and Dan Eicher <dan@trollwerks.org>.
''')
""")
def create_argparse() -> argparse.ArgumentParser:

View File

@ -342,7 +342,7 @@ ccl_device_forceinline void area_light_update_position(const ccl_global KernelLi
ls->D = normalize_len(ls->P - P, &ls->t);
ls->pdf = invarea;
if (klight->area.tan_half_spread > 0) {
if (klight->area.normalize_spread > 0) {
ls->eval_fac = 0.25f * invarea;
ls->eval_fac *= area_light_spread_attenuation(
ls->D, ls->Ng, klight->area.tan_half_spread, klight->area.normalize_spread);

View File

@ -450,6 +450,9 @@ void LightManager::device_update_tree(Device *,
* More benchmarking is needed to determine what number works best. */
LightTree light_tree(scene, dscene, progress, 8);
LightTreeNode *root = light_tree.build(scene, dscene);
if (progress.get_cancel()) {
return;
}
/* We want to create separate arrays corresponding to triangles and lights,
* which will be used to index back into the light tree for PDF calculations. */

View File

@ -1,7 +1,7 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright 2011-2022 Blender Foundation
if(WITH_GTESTS)
if(WITH_GTESTS AND WITH_CYCLES_LOGGING)
Include(GTestTesting)
# Otherwise we get warnings here that we can't fix in external projects
@ -53,6 +53,6 @@ if(NOT APPLE)
endif()
endif()
if(WITH_GTESTS)
if(WITH_GTESTS AND WITH_CYCLES_LOGGING)
blender_src_gtest(cycles "${SRC}" "${LIB}")
endif()

View File

@ -36,8 +36,7 @@ class LogMessageVoidify {
# define CHECK(expression) LOG_SUPPRESS()
# define CHECK_NOTNULL(expression) LOG_SUPPRESS()
# define CHECK_NULL(expression) LOG_SUPPRESS()
# define CHECK_NOTNULL(expression) (expression)
# define CHECK_NEAR(actual, expected, eps) LOG_SUPPRESS()
@ -50,8 +49,7 @@ class LogMessageVoidify {
# define DCHECK(expression) LOG_SUPPRESS()
# define DCHECK_NOTNULL(expression) LOG_SUPPRESS()
# define DCHECK_NULL(expression) LOG_SUPPRESS()
# define DCHECK_NOTNULL(expression) (expression)
# define DCHECK_NEAR(actual, expected, eps) LOG_SUPPRESS()

View File

@ -900,12 +900,13 @@ GHOST_TSuccess GHOST_SystemCocoa::getButtons(GHOST_Buttons &buttons) const
GHOST_TCapabilityFlag GHOST_SystemCocoa::getCapabilities() const
{
return GHOST_TCapabilityFlag(GHOST_CAPABILITY_FLAG_ALL &
~(
/* Cocoa has no support for a primary selection clipboard. */
GHOST_kCapabilityPrimaryClipboard |
/* This Cocoa back-end has not yet implemented image copy/paste. */
GHOST_kCapabilityClipboardImages));
return GHOST_TCapabilityFlag(
GHOST_CAPABILITY_FLAG_ALL &
~(
/* Cocoa has no support for a primary selection clipboard. */
GHOST_kCapabilityPrimaryClipboard |
/* This Cocoa back-end has not yet implemented image copy/paste. */
GHOST_kCapabilityClipboardImages));
}
#pragma mark Event handlers

View File

@ -149,7 +149,7 @@ def activate(*, template_id=None, reload_scripts=False):
template_id_prev = _app_template["id"]
# not needed but may as well avoids redundant
# disable/enable for all add-ons on 'File -> New'
# disable/enable for all add-ons on "File -> New".
if not reload_scripts and template_id_prev == template_id:
return

View File

@ -16,12 +16,12 @@ TEMP_N = len(TEMP)
def is_dict(obj):
"""Returns whether obj is a dictionary"""
return hasattr(obj, 'keys') and hasattr(getattr(obj, 'keys'), '__call__')
return hasattr(obj, "keys") and hasattr(getattr(obj, "keys"), "__call__")
def is_struct_seq(obj):
"""Returns whether obj is a structured sequence subclass: sys.float_info"""
return isinstance(obj, tuple) and hasattr(obj, 'n_fields')
return isinstance(obj, tuple) and hasattr(obj, "n_fields")
def complete_names(word, namespace):

View File

@ -340,7 +340,7 @@ def dump_rna_messages(msgs, reports, settings, verbose=False):
msgctxt = bl_rna.translation_context or default_context
if bl_rna.name and (bl_rna.name != bl_rna.identifier or
(msgctxt != default_context and not hasattr(bl_rna, 'bl_label'))):
(msgctxt != default_context and not hasattr(bl_rna, "bl_label"))):
process_msg(msgs, msgctxt, bl_rna.name, msgsrc, reports, check_ctxt_rna, settings)
if bl_rna.description:
@ -349,14 +349,14 @@ def dump_rna_messages(msgs, reports, settings, verbose=False):
process_msg(msgs, default_context, cls.__doc__, msgsrc, reports, check_ctxt_rna_tip, settings)
# Panels' "tabs" system.
if hasattr(bl_rna, 'bl_category') and bl_rna.bl_category:
if hasattr(bl_rna, "bl_category") and bl_rna.bl_category:
process_msg(msgs, default_context, bl_rna.bl_category, msgsrc, reports, check_ctxt_rna, settings)
if hasattr(bl_rna, 'bl_label') and bl_rna.bl_label:
if hasattr(bl_rna, "bl_label") and bl_rna.bl_label:
process_msg(msgs, msgctxt, bl_rna.bl_label, msgsrc, reports, check_ctxt_rna, settings)
# Tools Panels definitions.
if hasattr(bl_rna, 'tools_all') and bl_rna.tools_all:
if hasattr(bl_rna, "tools_all") and bl_rna.tools_all:
walk_tools_definitions(cls)
walk_properties(cls)
@ -472,7 +472,7 @@ def dump_rna_messages(msgs, reports, settings, verbose=False):
##### Python source code #####
def dump_py_messages_from_files(msgs, reports, files, settings):
"""
Dump text inlined in the python files given, e.g. 'My Name' in:
Dump text inlined in the python files given, e.g. "My Name" in:
layout.prop("someprop", text="My Name")
"""
import ast

View File

@ -473,7 +473,7 @@ class I18nMessages:
@staticmethod
def _new_messages():
return getattr(collections, 'OrderedDict', dict)()
return getattr(collections, "OrderedDict", dict)()
@classmethod
def gen_empty_messages(cls, uid, blender_ver, blender_hash, time, year, default_copyright=True, settings=settings):

View File

@ -131,7 +131,7 @@ def main():
settings = settings_i18n.I18nSettings()
settings.load(args.settings)
if getattr(args, 'template', None) is not None:
if getattr(args, "template", None) is not None:
settings.FILE_NAME_POT = args.template
args.func(args=args, settings=settings)

View File

@ -24,7 +24,7 @@ def keyconfig_update(keyconfig_data, keyconfig_version):
for _km_name, _km_parms, km_items_data in keyconfig_data:
for (_item_op, item_event, _item_prop) in km_items_data["items"]:
if item_event.get("value") == 'PRESS':
# Unfortunately we don't know the 'map_type' at this point.
# Unfortunately we don't know the `map_type` at this point.
# Setting repeat true on other kinds of events is harmless.
item_event["repeat"] = True

View File

@ -68,7 +68,7 @@ def do_previews(do_objects, do_collections, do_scenes, do_data_intern):
if engine == '__SCENE':
backup_scene, backup_world, backup_camera, backup_light, backup_camera_data, backup_light_data = [()] * 6
scene = bpy.context.window.scene
exclude_props = {('world',), ('camera',), ('tool_settings',), ('preview',)}
exclude_props = {("world",), ("camera",), ("tool_settings",), ("preview",)}
backup_scene = tuple(rna_backup_gen(scene, exclude_props=exclude_props))
world = scene.world
camera = scene.camera
@ -343,7 +343,7 @@ def do_previews(do_objects, do_collections, do_scenes, do_data_intern):
ob.hide_render = False
bpy.context.view_layer.update()
preview_render_do(render_context, 'objects', root.name, objects)
preview_render_do(render_context, "objects", root.name, objects)
# XXX Hyper Super Uber Suspicious Hack!
# Without this, on windows build, script excepts with following message:
@ -390,7 +390,7 @@ def do_previews(do_objects, do_collections, do_scenes, do_data_intern):
offset_matrix = Matrix.Translation(grp.instance_offset).inverted()
preview_render_do(render_context, 'collections', grp.name, objects, offset_matrix)
preview_render_do(render_context, "collections", grp.name, objects, offset_matrix)
scene = bpy.data.scenes[render_context.scene, None]
scene.collection.objects.unlink(bpy.data.objects[grp_obname, None])
@ -413,7 +413,7 @@ def do_previews(do_objects, do_collections, do_scenes, do_data_intern):
objects = tuple((ob.name, ob.library.filepath if ob.library else None) for ob in scene.objects
if (not ob.hide_render) and (ob.type in OBJECT_TYPES_RENDER))
preview_render_do(render_context, 'scenes', scene.name, objects)
preview_render_do(render_context, "scenes", scene.name, objects)
if not render_context_delete(render_context):
do_save = False

View File

@ -292,7 +292,7 @@ def load_scripts(*, reload_scripts=False, refresh_scripts=False):
if _os.path.isdir(path):
_sys_path_ensure_prepend(path)
# Only add to 'sys.modules' unless this is 'startup'.
# Only add to `sys.modules` unless this is 'startup'.
if path_subdir == "startup":
for mod in modules_from_path(path, loaded_modules):
test_register(mod)

View File

@ -122,7 +122,7 @@ def orientation_helper(axis_forward='Y', axis_up='Z'):
'XYZ'[('XYZ'.index(self.axis_up[-1]) + 1) % 3]
)
cls.__annotations__['axis_forward'] = EnumProperty(
cls.__annotations__["axis_forward"] = EnumProperty(
name="Forward",
items=(
('X', "X Forward", ""),
@ -143,7 +143,7 @@ def orientation_helper(axis_forward='Y', axis_up='Z'):
'XYZ'[('XYZ'.index(self.axis_forward[-1]) + 1) % 3]
)
cls.__annotations__['axis_up'] = EnumProperty(
cls.__annotations__["axis_up"] = EnumProperty(
name="Up",
items=(
('X', "X Up", ""),

View File

@ -372,7 +372,7 @@ class PrincipledBSDFWrapper(ShaderWrapper):
self, self.node_principled_bsdf,
self.node_principled_bsdf.inputs["Metallic"],
grid_row_diff=0,
colorspace_name='Non-Color',
colorspace_name="Non-Color",
)
metallic_texture = property(metallic_texture_get)
@ -784,32 +784,32 @@ class ShaderImageTextureWrapper():
def translation_get(self):
if self.node_mapping is None:
return Vector((0.0, 0.0, 0.0))
return self.node_mapping.inputs['Location'].default_value
return self.node_mapping.inputs["Location"].default_value
@_set_check
def translation_set(self, translation):
self.node_mapping.inputs['Location'].default_value = translation
self.node_mapping.inputs["Location"].default_value = translation
translation = property(translation_get, translation_set)
def rotation_get(self):
if self.node_mapping is None:
return Vector((0.0, 0.0, 0.0))
return self.node_mapping.inputs['Rotation'].default_value
return self.node_mapping.inputs["Rotation"].default_value
@_set_check
def rotation_set(self, rotation):
self.node_mapping.inputs['Rotation'].default_value = rotation
self.node_mapping.inputs["Rotation"].default_value = rotation
rotation = property(rotation_get, rotation_set)
def scale_get(self):
if self.node_mapping is None:
return Vector((1.0, 1.0, 1.0))
return self.node_mapping.inputs['Scale'].default_value
return self.node_mapping.inputs["Scale"].default_value
@_set_check
def scale_set(self, scale):
self.node_mapping.inputs['Scale'].default_value = scale
self.node_mapping.inputs["Scale"].default_value = scale
scale = property(scale_get, scale_set)

View File

@ -26,10 +26,10 @@ class ProgressReport:
progress.leave_substeps() # No need to step here, this implicitly does it.
progress.leave_substeps("Finished!") # You may pass some message too.
"""
__slots__ = ('wm', 'running', 'steps', 'curr_step', 'start_time')
__slots__ = ("wm", "running", "steps", "curr_step", "start_time")
def __init__(self, wm=None):
self_wm = getattr(self, 'wm', None)
self_wm = getattr(self, "wm", None)
if self_wm:
self.finalize()
self.running = False
@ -117,11 +117,11 @@ class ProgressReportSubstep:
for j in range(100):
subprogress2.step()
"""
__slots__ = ('progress', 'nbr', 'msg', 'final_msg', 'level')
__slots__ = ("progress", "nbr", "msg", "final_msg", "level")
def __init__(self, progress, nbr, msg="", final_msg=""):
# Allows to generate a subprogress context handler from another one.
progress = getattr(progress, 'progress', progress)
progress = getattr(progress, "progress", progress)
self.progress = progress
self.nbr = nbr

View File

@ -440,7 +440,7 @@ class _GenericBone:
def _other_bones(self):
id_data = self.id_data
# `id_data` is an 'Object' for `PosePone`, otherwise it's an `Armature`.
# `id_data` is an `Object` for `PosePone`, otherwise it's an `Armature`.
if isinstance(self, PoseBone):
return id_data.pose.bones
if isinstance(self, EditBone):
@ -688,7 +688,7 @@ class RNAMetaPropGroup(StructMetaPropGroup, RNAMeta):
pass
# Same as 'Operator'
# Same as `Operator`.
# only without 'as_keywords'
class Gizmo(StructRNA):
__slots__ = ()

View File

@ -91,7 +91,7 @@ def graph_armature(obj, filepath, FAKE_PARENT=True, CONSTRAINTS=True, DRIVERS=Tr
parent_name = parent.name
connected = bone.use_connect
elif FAKE_PARENT:
parent_name = 'Object::%s' % obj.name
parent_name = "Object::%s" % obj.name
connected = False
else:
continue

View File

@ -93,7 +93,7 @@ def RKS_ITER_selected_bones(ksi, context, ks):
# Generate Callbacks
# 'Available' F-Curves
# "Available" F-Curves.
def RKS_GEN_available(_ksi, _context, ks, data):
# try to get the animation data associated with the closest
# ID-block to the data (neither of which may exist/be easy to find)

View File

@ -735,7 +735,7 @@ def BuildRNAInfo():
i += 1
if not ok:
print('Dependancy "%s" could not be found for "%s"' % (identifier, rna_base))
print("Dependency \"%s\" could not be found for \"%s\"" % (identifier, rna_base))
break

View File

@ -1373,6 +1373,7 @@ url_manual_mapping = (
("bpy.ops.pose.visual_transform_apply*", "animation/armatures/posing/editing/apply.html#bpy-ops-pose-visual-transform-apply"),
("bpy.ops.poselib.convert_old_poselib*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-convert-old-poselib"),
("bpy.ops.render.shutter_curve_preset*", "render/cycles/render_settings/motion_blur.html#bpy-ops-render-shutter-curve-preset"),
("bpy.ops.scene.view_layer_remove_aov*", "render/layers/passes.html#bpy-ops-scene-view-layer-remove-aov"),
("bpy.ops.sculpt_curves.select_random*", "sculpt_paint/curves_sculpting/introduction.html#bpy-ops-sculpt-curves-select-random"),
("bpy.ops.sequencer.view_ghost_border*", "editors/video_sequencer/preview/sidebar.html#bpy-ops-sequencer-view-ghost-border"),
("bpy.ops.ui.override_idtemplate_make*", "files/linked_libraries/library_overrides.html#bpy-ops-ui-override-idtemplate-make"),
@ -1774,9 +1775,11 @@ url_manual_mapping = (
("bpy.ops.outliner.collection_hide*", "editors/outliner/editing.html#bpy-ops-outliner-collection-hide"),
("bpy.ops.outliner.collection_show*", "editors/outliner/editing.html#bpy-ops-outliner-collection-show"),
("bpy.ops.paint.mask_lasso_gesture*", "sculpt_paint/sculpting/editing/mask.html#bpy-ops-paint-mask-lasso-gesture"),
("bpy.ops.paint.vert_select_linked*", "sculpt_paint/selection_visibility.html#bpy-ops-paint-vert-select-linked"),
("bpy.ops.poselib.apply_pose_asset*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-apply-pose-asset"),
("bpy.ops.poselib.blend_pose_asset*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-blend-pose-asset"),
("bpy.ops.rigidbody.mass_calculate*", "scene_layout/object/editing/rigid_body.html#bpy-ops-rigidbody-mass-calculate"),
("bpy.ops.scene.view_layer_add_aov*", "render/layers/passes.html#bpy-ops-scene-view-layer-add-aov"),
("bpy.ops.screen.spacedata_cleanup*", "advanced/operators.html#bpy-ops-screen-spacedata-cleanup"),
("bpy.ops.sculpt.detail_flood_fill*", "sculpt_paint/sculpting/tool_settings/dyntopo.html#bpy-ops-sculpt-detail-flood-fill"),
("bpy.ops.sculpt_curves.select_end*", "sculpt_paint/curves_sculpting/introduction.html#bpy-ops-sculpt-curves-select-end"),
@ -1934,6 +1937,7 @@ url_manual_mapping = (
("bpy.ops.object.shape_key_remove*", "animation/shape_keys/shape_keys_panel.html#bpy-ops-object-shape-key-remove"),
("bpy.ops.object.shape_key_retime*", "animation/shape_keys/shape_keys_panel.html#bpy-ops-object-shape-key-retime"),
("bpy.ops.object.vertex_group_add*", "modeling/meshes/properties/vertex_groups/vertex_groups.html#bpy-ops-object-vertex-group-add"),
("bpy.ops.object.vertex_group_fix*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-fix"),
("bpy.ops.outliner.collection_new*", "editors/outliner/editing.html#bpy-ops-outliner-collection-new"),
("bpy.ops.outliner.show_hierarchy*", "editors/outliner/editing.html#bpy-ops-outliner-show-hierarchy"),
("bpy.ops.outliner.show_one_level*", "editors/outliner/editing.html#bpy-ops-outliner-show-one-level"),
@ -2083,7 +2087,6 @@ url_manual_mapping = (
("bpy.ops.screen.region_quadview*", "editors/3dview/navigate/views.html#bpy-ops-screen-region-quadview"),
("bpy.ops.screen.screenshot_area*", "interface/window_system/topbar.html#bpy-ops-screen-screenshot-area"),
("bpy.ops.screen.workspace_cycle*", "interface/window_system/workspaces.html#bpy-ops-screen-workspace-cycle"),
("bpy.ops.sequencer.change_scene*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-change-scene"),
("bpy.ops.sequencer.offset_clear*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-offset-clear"),
("bpy.ops.spreadsheet.toggle_pin*", "editors/spreadsheet.html#bpy-ops-spreadsheet-toggle-pin"),
("bpy.ops.uv.follow_active_quads*", "modeling/meshes/editing/uv.html#bpy-ops-uv-follow-active-quads"),

View File

@ -121,7 +121,7 @@ class SCENE_OT_freestyle_fill_range_by_selection(Operator):
class SCENE_OT_freestyle_add_edge_marks_to_keying_set(Operator):
'''Add the data paths to the Freestyle Edge Mark property of selected edges to the active keying set'''
"""Add the data paths to the Freestyle Edge Mark property of selected edges to the active keying set"""
bl_idname = "scene.freestyle_add_edge_marks_to_keying_set"
bl_label = "Add Edge Marks to Keying Set"
bl_options = {'UNDO'}
@ -152,7 +152,7 @@ class SCENE_OT_freestyle_add_edge_marks_to_keying_set(Operator):
class SCENE_OT_freestyle_add_face_marks_to_keying_set(Operator):
'''Add the data paths to the Freestyle Face Mark property of selected polygons to the active keying set'''
"""Add the data paths to the Freestyle Face Mark property of selected polygons to the active keying set"""
bl_idname = "scene.freestyle_add_face_marks_to_keying_set"
bl_label = "Add Face Marks to Keying Set"
bl_options = {'UNDO'}

View File

@ -24,7 +24,7 @@ class NodeSetting(PropertyGroup):
)
# Base class for node 'Add' operators
# Base class for node "Add" operators.
class NodeAddOperator:
type: StringProperty(
@ -141,14 +141,14 @@ class NodeAddOperator:
# Simple basic operator for adding a node
class NODE_OT_add_node(NodeAddOperator, Operator):
'''Add a node to the active tree'''
"""Add a node to the active tree"""
bl_idname = "node.add_node"
bl_label = "Add Node"
bl_options = {'REGISTER', 'UNDO'}
class NODE_OT_collapse_hide_unused_toggle(Operator):
'''Toggle collapsed nodes and hide unused sockets'''
"""Toggle collapsed nodes and hide unused sockets"""
bl_idname = "node.collapse_hide_unused_toggle"
bl_label = "Collapse and Hide Unused Sockets"
bl_options = {'REGISTER', 'UNDO'}
@ -179,7 +179,7 @@ class NODE_OT_collapse_hide_unused_toggle(Operator):
class NODE_OT_tree_path_parent(Operator):
'''Go to parent node tree'''
"""Go to parent node tree"""
bl_idname = "node.tree_path_parent"
bl_label = "Parent Node Tree"
bl_options = {'REGISTER', 'UNDO'}

View File

@ -317,7 +317,7 @@ class QuickExplode(ObjectModeOperator, Operator):
node_out_mat = node
break
node_surface = node_out_mat.inputs['Surface'].links[0].from_node
node_surface = node_out_mat.inputs["Surface"].links[0].from_node
node_x = node_surface.location[0]
node_y = node_surface.location[1] - 400
@ -326,7 +326,7 @@ class QuickExplode(ObjectModeOperator, Operator):
node_mix = nodes.new('ShaderNodeMixShader')
node_mix.location = (node_x - offset_x, node_y)
mat.node_tree.links.new(node_surface.outputs[0], node_mix.inputs[1])
mat.node_tree.links.new(node_mix.outputs["Shader"], node_out_mat.inputs['Surface'])
mat.node_tree.links.new(node_mix.outputs["Shader"], node_out_mat.inputs["Surface"])
offset_x += 200
node_trans = nodes.new('ShaderNodeBsdfTransparent')

View File

@ -96,7 +96,7 @@ class AddPresetBase:
# Reset preset name
wm = bpy.data.window_managers[0]
if name == wm.preset_name:
wm.preset_name = data_('New Preset')
wm.preset_name = data_("New Preset")
filename = self.as_filename(name)

View File

@ -9,7 +9,7 @@ from bpy.props import (
class CopyRigidbodySettings(Operator):
'''Copy Rigid Body settings from active object to selected'''
"""Copy Rigid Body settings from active object to selected"""
bl_idname = "rigidbody.object_settings_copy"
bl_label = "Copy Rigid Body Settings"
bl_options = {'REGISTER', 'UNDO'}
@ -74,7 +74,7 @@ class CopyRigidbodySettings(Operator):
class BakeToKeyframes(Operator):
'''Bake rigid body transformations of selected objects to keyframes'''
"""Bake rigid body transformations of selected objects to keyframes"""
bl_idname = "rigidbody.bake_to_keyframes"
bl_label = "Bake to Keyframes"
bl_options = {'REGISTER', 'UNDO'}
@ -198,7 +198,7 @@ class BakeToKeyframes(Operator):
class ConnectRigidBodies(Operator):
'''Create rigid body constraints between selected rigid bodies'''
"""Create rigid body constraints between selected rigid bodies"""
bl_idname = "rigidbody.connect"
bl_label = "Connect Rigid Bodies"
bl_options = {'REGISTER', 'UNDO'}

View File

@ -166,20 +166,22 @@ class SequencerFadesAdd(Operator):
name="Fade Duration",
description="Duration of the fade in seconds",
default=1.0,
min=0.01)
min=0.01,
)
type: EnumProperty(
items=(
('IN_OUT', 'Fade In and Out', 'Fade selected strips in and out'),
('IN', 'Fade In', 'Fade in selected strips'),
('OUT', 'Fade Out', 'Fade out selected strips'),
('CURSOR_FROM', 'From Current Frame',
'Fade from the time cursor to the end of overlapping sequences'),
('CURSOR_TO', 'To Current Frame',
'Fade from the start of sequences under the time cursor to the current frame'),
('IN_OUT', "Fade In and Out", "Fade selected strips in and out"),
('IN', "Fade In", "Fade in selected strips"),
('OUT', "Fade Out", "Fade out selected strips"),
('CURSOR_FROM', "From Current Frame",
"Fade from the time cursor to the end of overlapping sequences"),
('CURSOR_TO', "To Current Frame",
"Fade from the start of sequences under the time cursor to the current frame"),
),
name="Fade Type",
description="Fade in, out, both in and out, to, or from the current frame. Default is both in and out",
default='IN_OUT')
default='IN_OUT',
)
@classmethod
def poll(cls, context):

View File

@ -6,7 +6,7 @@ from bpy.types import Operator
class SPREADSHEET_OT_toggle_pin(Operator):
'''Turn on or off pinning'''
"""Turn on or off pinning"""
bl_idname = "spreadsheet.toggle_pin"
bl_label = "Toggle Pin"
bl_options = {'REGISTER'}

View File

@ -129,7 +129,7 @@ from math import pi
class VertexPaintDirt(Operator):
'''Generate a dirt map gradient based on cavity'''
"""Generate a dirt map gradient based on cavity"""
bl_idname = "paint.vertex_color_dirt"
bl_label = "Dirty Vertex Colors"
bl_options = {'REGISTER', 'UNDO'}

View File

@ -243,7 +243,7 @@ class OBJECT_PT_instancing(ObjectButtonsPanel, Panel):
@classmethod
def poll(cls, context):
ob = context.object
# FONT objects need (vertex) instancing for the 'Object Font' feature
# FONT objects need (vertex) instancing for the "Object Font" feature.
return (ob.type in {'MESH', 'EMPTY', 'FONT'})
def draw(self, context):

View File

@ -103,7 +103,7 @@ class EEVEE_WORLD_PT_surface(WorldButtonsPanel, Panel):
node = ntree.get_output_node('EEVEE')
if node:
input = find_node_input(node, 'Surface')
input = find_node_input(node, "Surface")
if input:
layout.template_node_view(ntree, node, input)
else:
@ -136,7 +136,7 @@ class EEVEE_WORLD_PT_volume(WorldButtonsPanel, Panel):
layout.use_property_split = True
if node:
input = find_node_input(node, 'Volume')
input = find_node_input(node, "Volume")
if input:
layout.template_node_view(ntree, node, input)
else:

View File

@ -752,7 +752,7 @@ class CLIP_PT_track(CLIP_PT_tracking_panel, Panel):
row = layout.row(align=True)
row.prop(act_track, "use_custom_color", text="")
CLIP_PT_track_color_presets.draw_menu(row, iface_('Custom Color Presets'))
CLIP_PT_track_color_presets.draw_menu(row, iface_("Custom Color Presets"))
row.operator("clip.track_copy_color", icon='COPY_ID', text="")
if act_track.use_custom_color:

View File

@ -150,7 +150,7 @@ class NLA_MT_marker(Menu):
class NLA_MT_marker_select(Menu):
bl_label = 'Select'
bl_label = "Select"
def draw(self, _context):
layout = self.layout

View File

@ -1769,7 +1769,7 @@ class SEQUENCER_PT_scene(SequencerButtonsPanel, Panel):
layout.prop(strip, "use_annotations", text="Annotations")
if scene:
# Warning, this is not a good convention to follow.
# Expose here because setting the alpha from the 'Render' menu is very inconvenient.
# Expose here because setting the alpha from the "Render" menu is very inconvenient.
layout.prop(scene.render, "film_transparent")

View File

@ -2620,7 +2620,7 @@ class IMAGE_PT_tools_active(ToolSelectPanelHelper, Panel):
bl_label = "Tools" # not visible
bl_options = {'HIDE_HEADER'}
# Satisfy the 'ToolSelectPanelHelper' API.
# Satisfy the `ToolSelectPanelHelper` API.
keymap_prefix = "Image Editor Tool:"
# Default group to use as a fallback.
@ -2715,7 +2715,7 @@ class NODE_PT_tools_active(ToolSelectPanelHelper, Panel):
bl_label = "Tools" # not visible
bl_options = {'HIDE_HEADER'}
# Satisfy the 'ToolSelectPanelHelper' API.
# Satisfy the `ToolSelectPanelHelper` API.
keymap_prefix = "Node Editor Tool:"
# Default group to use as a fallback.
@ -2779,7 +2779,7 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
bl_label = "Tools" # not visible
bl_options = {'HIDE_HEADER'}
# Satisfy the 'ToolSelectPanelHelper' API.
# Satisfy the `ToolSelectPanelHelper` API.
keymap_prefix = "3D View Tool:"
# Default group to use as a fallback.
@ -3147,7 +3147,7 @@ class SEQUENCER_PT_tools_active(ToolSelectPanelHelper, Panel):
bl_label = "Tools" # not visible
bl_options = {'HIDE_HEADER'}
# Satisfy the 'ToolSelectPanelHelper' API.
# Satisfy the `ToolSelectPanelHelper` API.
keymap_prefix = "Sequence Editor Tool:"
# Default group to use as a fallback.

View File

@ -19,7 +19,7 @@ class MyCustomTree(NodeTree):
# Custom socket type
class MyCustomSocket(NodeSocket):
# Description string
'''Custom node socket type'''
"""Custom node socket type"""
# Optional identifier string. If not explicitly defined, the python class name is used.
bl_idname = 'CustomSocketType'
# Label for nice name display

View File

@ -1,7 +1,7 @@
# This script defines functions to be used directly in driver expressions to
# extend the built-in set of python functions.
#
# This can be executed on manually or set to 'Register' to
# This can be executed on manually or set to "Register" to
# initialize the functions on file load.

View File

@ -11,7 +11,7 @@ class MyPanel(bpy.types.Panel):
bl_idname = "SCENE_PT_list_demo"
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_category = 'My Category'
bl_category = "My Category"
def draw(self, context):
layout = self.layout

View File

@ -138,7 +138,9 @@ class CurvesGeometry : public ::CurvesGeometry {
/**
* The index of the first point in every curve. The size of this span is one larger than the
* number of curves. Consider using #points_by_curve rather than using the offsets directly.
* number of curves, but the spans will be empty if there are no curves/points.
*
* Consider using #points_by_curve rather than these offsets directly.
*/
Span<int> offsets() const;
MutableSpan<int> offsets_for_write();

View File

@ -464,18 +464,27 @@ struct ID *BKE_id_copy_for_use_in_bmain(struct Main *bmain, const struct ID *id)
* Does a mere memory swap over the whole IDs data (including type-specific memory).
* \note Most internal ID data itself is not swapped (only IDProperties are).
*
* \param bmain: May be NULL, in which case there will be no remapping of internal pointers to
* itself.
* \param bmain: May be NULL, in which case there is no guarantee that internal remapping of ID
* pointers to themselves will be complete (reguarding depsgraph and/or runtime data updates).
* \param do_self_remap: Whether to remap internal pointers to itself or not.
* \param self_remap_flags: Flags controlling self remapping, see BKE_lib_remap.h.
*/
void BKE_lib_id_swap(struct Main *bmain, struct ID *id_a, struct ID *id_b);
void BKE_lib_id_swap(struct Main *bmain,
struct ID *id_a,
struct ID *id_b,
const bool do_self_remap,
const int self_remap_flags);
/**
* Does a mere memory swap over the whole IDs data (including type-specific memory).
* \note All internal ID data itself is also swapped.
*
* \param bmain: May be NULL, in which case there will be no remapping of internal pointers to
* itself.
* For parameters description, see #BKE_lib_id_swap above.
*/
void BKE_lib_id_swap_full(struct Main *bmain, struct ID *id_a, struct ID *id_b);
void BKE_lib_id_swap_full(struct Main *bmain,
struct ID *id_a,
struct ID *id_b,
const bool do_self_remap,
const int self_remap_flags);
/**
* Sort given \a id into given \a lb list, using case-insensitive comparison of the id names.

View File

@ -88,6 +88,23 @@ struct WorkSpaceLayout *BKE_workspace_layout_iter_circular(
void BKE_workspace_tool_remove(struct WorkSpace *workspace, struct bToolRef *tref)
ATTR_NONNULL(1, 2);
/**
* Replace tools ID's, intended for use in versioning code.
* \param space_type: The space-type to match #bToolRef::space_type.
* \param mode: The space-type to match #bToolRef::mode.
* \param idname_prefix_skip: Ignore when NULL, otherwise only operate
* on tools that have this text as the #bToolRef::idname prefix, which is skipped before
* the replacement runs. This avoids having to duplicate a common prefix in the replacement text.
* \param replace_table: An array of (source, destination) pairs.
* \param replace_table_num: The number of items in `replace_table`.
*/
void BKE_workspace_tool_id_replace_table(struct WorkSpace *workspace,
const int space_type,
const int mode,
const char *idname_prefix_skip,
const char *replace_table[][2],
int replace_table_num) ATTR_NONNULL(1, 5);
/** \} */
/* -------------------------------------------------------------------- */

View File

@ -322,10 +322,11 @@ GVArray BuiltinCustomDataLayerProvider::try_get_for_read(const void *owner) cons
}
/* When the number of elements is zero, layers might have null data but still exist. */
const CPPType &type = *custom_data_type_to_cpp_type(data_type_);
const int element_num = custom_data_access_.get_element_num(owner);
if (element_num == 0) {
if (this->layer_exists(*custom_data)) {
return as_read_attribute_(nullptr, 0);
return GVArray::ForSpan({type, nullptr, 0});
}
return {};
}
@ -340,7 +341,7 @@ GVArray BuiltinCustomDataLayerProvider::try_get_for_read(const void *owner) cons
if (data == nullptr) {
return {};
}
return as_read_attribute_(data, element_num);
return GVArray::ForSpan({type, data, element_num});
}
GAttributeWriter BuiltinCustomDataLayerProvider::try_get_for_write(void *owner) const
@ -356,10 +357,11 @@ GAttributeWriter BuiltinCustomDataLayerProvider::try_get_for_write(void *owner)
}
/* When the number of elements is zero, layers might have null data but still exist. */
const CPPType &type = *custom_data_type_to_cpp_type(data_type_);
const int element_num = custom_data_access_.get_element_num(owner);
if (element_num == 0) {
if (this->layer_exists(*custom_data)) {
return {as_write_attribute_(nullptr, 0), domain_, std::move(tag_modified_fn)};
return {GVMutableArray::ForSpan({type, nullptr, 0}), domain_, std::move(tag_modified_fn)};
}
return {};
}
@ -375,7 +377,7 @@ GAttributeWriter BuiltinCustomDataLayerProvider::try_get_for_write(void *owner)
if (data == nullptr) {
return {};
}
return {as_write_attribute_(data, element_num), domain_, std::move(tag_modified_fn)};
return {GVMutableArray::ForSpan({type, data, element_num}), domain_, std::move(tag_modified_fn)};
}
bool BuiltinCustomDataLayerProvider::try_delete(void *owner) const

View File

@ -163,16 +163,6 @@ class CustomDataAttributeProvider final : public DynamicAttributesProvider {
}
};
template<typename T> GVArray make_array_read_attribute(const void *data, const int domain_num)
{
return VArray<T>::ForSpan(Span<T>((const T *)data, domain_num));
}
template<typename T> GVMutableArray make_array_write_attribute(void *data, const int domain_num)
{
return VMutableArray<T>::ForSpan(MutableSpan<T>((T *)data, domain_num));
}
/**
* This provider is used to provide access to builtin attributes. It supports making internal types
* available as different types.
@ -181,14 +171,10 @@ template<typename T> GVMutableArray make_array_write_attribute(void *data, const
* if the stored type is the same as the attribute type.
*/
class BuiltinCustomDataLayerProvider final : public BuiltinAttributeProvider {
using AsReadAttribute = GVArray (*)(const void *data, int element_num);
using AsWriteAttribute = GVMutableArray (*)(void *data, int element_num);
using UpdateOnRead = void (*)(const void *owner);
using UpdateOnChange = void (*)(void *owner);
const eCustomDataType stored_type_;
const CustomDataAccessInfo custom_data_access_;
const AsReadAttribute as_read_attribute_;
const AsWriteAttribute as_write_attribute_;
const UpdateOnChange update_on_change_;
bool stored_as_named_attribute_;
@ -200,16 +186,12 @@ class BuiltinCustomDataLayerProvider final : public BuiltinAttributeProvider {
const CreatableEnum creatable,
const DeletableEnum deletable,
const CustomDataAccessInfo custom_data_access,
const AsReadAttribute as_read_attribute,
const AsWriteAttribute as_write_attribute,
const UpdateOnChange update_on_write,
const AttributeValidator validator = {})
: BuiltinAttributeProvider(
std::move(attribute_name), domain, attribute_type, creatable, deletable, validator),
stored_type_(stored_type),
custom_data_access_(custom_data_access),
as_read_attribute_(as_read_attribute),
as_write_attribute_(as_write_attribute),
update_on_change_(update_on_write),
stored_as_named_attribute_(data_type_ == stored_type_)
{

View File

@ -416,7 +416,7 @@ static int brush_undo_preserve_cb(LibraryIDLinkCallbackData *cb_data)
static void brush_undo_preserve(BlendLibReader *reader, ID *id_new, ID *id_old)
{
/* Whole Brush is preserved across undo-steps. */
BKE_lib_id_swap(nullptr, id_new, id_old);
BKE_lib_id_swap(nullptr, id_new, id_old, false, 0);
/* `id_new` now has content from `id_old`, we need to ensure those old ID pointers are valid.
* NOTE: Since we want to re-use all old pointers here, code is much simpler than for Scene. */
@ -521,6 +521,7 @@ static void brush_defaults(Brush *brush)
FROM_DEFAULT(stencil_dimension);
FROM_DEFAULT(mtex);
FROM_DEFAULT(mask_mtex);
FROM_DEFAULT(falloff_shape);
#undef FROM_DEFAULT
#undef FROM_DEFAULT_PTR

View File

@ -375,8 +375,6 @@ static ComponentAttributeProviders create_attribute_providers_for_curve()
BuiltinAttributeProvider::NonCreatable,
BuiltinAttributeProvider::NonDeletable,
point_access,
make_array_read_attribute<float3>,
make_array_write_attribute<float3>,
tag_component_positions_changed);
static BuiltinCustomDataLayerProvider radius("radius",
@ -386,8 +384,6 @@ static ComponentAttributeProviders create_attribute_providers_for_curve()
BuiltinAttributeProvider::Creatable,
BuiltinAttributeProvider::Deletable,
point_access,
make_array_read_attribute<float>,
make_array_write_attribute<float>,
tag_component_radii_changed);
static BuiltinCustomDataLayerProvider id("id",
@ -397,8 +393,6 @@ static ComponentAttributeProviders create_attribute_providers_for_curve()
BuiltinAttributeProvider::Creatable,
BuiltinAttributeProvider::Deletable,
point_access,
make_array_read_attribute<int>,
make_array_write_attribute<int>,
nullptr);
static BuiltinCustomDataLayerProvider tilt("tilt",
@ -408,8 +402,6 @@ static ComponentAttributeProviders create_attribute_providers_for_curve()
BuiltinAttributeProvider::Creatable,
BuiltinAttributeProvider::Deletable,
point_access,
make_array_read_attribute<float>,
make_array_write_attribute<float>,
tag_component_normals_changed);
static BuiltinCustomDataLayerProvider handle_right("handle_right",
@ -419,8 +411,6 @@ static ComponentAttributeProviders create_attribute_providers_for_curve()
BuiltinAttributeProvider::Creatable,
BuiltinAttributeProvider::Deletable,
point_access,
make_array_read_attribute<float3>,
make_array_write_attribute<float3>,
tag_component_positions_changed);
static BuiltinCustomDataLayerProvider handle_left("handle_left",
@ -430,8 +420,6 @@ static ComponentAttributeProviders create_attribute_providers_for_curve()
BuiltinAttributeProvider::Creatable,
BuiltinAttributeProvider::Deletable,
point_access,
make_array_read_attribute<float3>,
make_array_write_attribute<float3>,
tag_component_positions_changed);
static auto handle_type_clamp = mf::build::SI1_SO<int8_t, int8_t>(
@ -447,8 +435,6 @@ static ComponentAttributeProviders create_attribute_providers_for_curve()
BuiltinAttributeProvider::Creatable,
BuiltinAttributeProvider::Deletable,
point_access,
make_array_read_attribute<int8_t>,
make_array_write_attribute<int8_t>,
tag_component_topology_changed,
AttributeValidator{&handle_type_clamp});
@ -459,8 +445,6 @@ static ComponentAttributeProviders create_attribute_providers_for_curve()
BuiltinAttributeProvider::Creatable,
BuiltinAttributeProvider::Deletable,
point_access,
make_array_read_attribute<int8_t>,
make_array_write_attribute<int8_t>,
tag_component_topology_changed,
AttributeValidator{&handle_type_clamp});
@ -471,8 +455,6 @@ static ComponentAttributeProviders create_attribute_providers_for_curve()
BuiltinAttributeProvider::Creatable,
BuiltinAttributeProvider::Deletable,
point_access,
make_array_read_attribute<float>,
make_array_write_attribute<float>,
tag_component_positions_changed);
static const auto nurbs_order_clamp = mf::build::SI1_SO<int8_t, int8_t>(
@ -486,8 +468,6 @@ static ComponentAttributeProviders create_attribute_providers_for_curve()
BuiltinAttributeProvider::Creatable,
BuiltinAttributeProvider::Deletable,
curve_access,
make_array_read_attribute<int8_t>,
make_array_write_attribute<int8_t>,
tag_component_topology_changed,
AttributeValidator{&nurbs_order_clamp});
@ -504,8 +484,6 @@ static ComponentAttributeProviders create_attribute_providers_for_curve()
BuiltinAttributeProvider::Creatable,
BuiltinAttributeProvider::Deletable,
curve_access,
make_array_read_attribute<int8_t>,
make_array_write_attribute<int8_t>,
tag_component_normals_changed,
AttributeValidator{&normal_mode_clamp});
@ -522,8 +500,6 @@ static ComponentAttributeProviders create_attribute_providers_for_curve()
BuiltinAttributeProvider::Creatable,
BuiltinAttributeProvider::Deletable,
curve_access,
make_array_read_attribute<int8_t>,
make_array_write_attribute<int8_t>,
tag_component_topology_changed,
AttributeValidator{&knots_mode_clamp});
@ -540,8 +516,6 @@ static ComponentAttributeProviders create_attribute_providers_for_curve()
BuiltinAttributeProvider::Creatable,
BuiltinAttributeProvider::Deletable,
curve_access,
make_array_read_attribute<int8_t>,
make_array_write_attribute<int8_t>,
tag_component_curve_types_changed,
AttributeValidator{&curve_type_clamp});
@ -556,8 +530,6 @@ static ComponentAttributeProviders create_attribute_providers_for_curve()
BuiltinAttributeProvider::Creatable,
BuiltinAttributeProvider::Deletable,
curve_access,
make_array_read_attribute<int>,
make_array_write_attribute<int>,
tag_component_topology_changed,
AttributeValidator{&resolution_clamp});
@ -568,8 +540,6 @@ static ComponentAttributeProviders create_attribute_providers_for_curve()
BuiltinAttributeProvider::Creatable,
BuiltinAttributeProvider::Deletable,
curve_access,
make_array_read_attribute<bool>,
make_array_write_attribute<bool>,
tag_component_topology_changed);
static CustomDataAttributeProvider curve_custom_data(ATTR_DOMAIN_CURVE, curve_access);

View File

@ -200,8 +200,6 @@ static ComponentAttributeProviders create_attribute_providers_for_instances()
BuiltinAttributeProvider::Creatable,
BuiltinAttributeProvider::Deletable,
instance_custom_data_access,
make_array_read_attribute<int>,
make_array_write_attribute<int>,
nullptr);
static CustomDataAttributeProvider instance_custom_data(ATTR_DOMAIN_INSTANCE,

View File

@ -859,23 +859,6 @@ static blender::GVArray adapt_mesh_attribute_domain(const Mesh &mesh,
namespace blender::bke {
template<typename StructT, typename ElemT, ElemT (*GetFunc)(const StructT &)>
static GVArray make_derived_read_attribute(const void *data, const int domain_num)
{
return VArray<ElemT>::template ForDerivedSpan<StructT, GetFunc>(
Span<StructT>((const StructT *)data, domain_num));
}
template<typename StructT,
typename ElemT,
ElemT (*GetFunc)(const StructT &),
void (*SetFunc)(StructT &, ElemT)>
static GVMutableArray make_derived_write_attribute(void *data, const int domain_num)
{
return VMutableArray<ElemT>::template ForDerivedSpan<StructT, GetFunc, SetFunc>(
MutableSpan<StructT>((StructT *)data, domain_num));
}
static void tag_component_positions_changed(void *owner)
{
Mesh *mesh = static_cast<Mesh *>(owner);
@ -884,16 +867,6 @@ static void tag_component_positions_changed(void *owner)
}
}
static float get_crease(const float &crease)
{
return crease;
}
static void set_crease(float &crease, const float value)
{
crease = std::clamp(value, 0.0f, 1.0f);
}
class VArrayImpl_For_VertexWeights final : public VMutableArrayImpl<float> {
private:
MDeformVert *dverts_;
@ -1144,8 +1117,6 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh()
BuiltinAttributeProvider::NonCreatable,
BuiltinAttributeProvider::NonDeletable,
point_access,
make_array_read_attribute<float3>,
make_array_write_attribute<float3>,
tag_component_positions_changed);
static BuiltinCustomDataLayerProvider id("id",
@ -1155,8 +1126,6 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh()
BuiltinAttributeProvider::Creatable,
BuiltinAttributeProvider::Deletable,
point_access,
make_array_read_attribute<int>,
make_array_write_attribute<int>,
nullptr);
static const auto material_index_clamp = mf::build::SI1_SO<int, int>(
@ -1173,8 +1142,6 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh()
BuiltinAttributeProvider::Creatable,
BuiltinAttributeProvider::Deletable,
face_access,
make_array_read_attribute<int>,
make_array_write_attribute<int>,
nullptr,
AttributeValidator{&material_index_clamp});
@ -1189,8 +1156,6 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh()
BuiltinAttributeProvider::NonCreatable,
BuiltinAttributeProvider::NonDeletable,
edge_access,
make_array_read_attribute<int2>,
make_array_write_attribute<int2>,
nullptr,
AttributeValidator{&int2_index_clamp});
@ -1207,8 +1172,6 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh()
BuiltinAttributeProvider::NonCreatable,
BuiltinAttributeProvider::NonDeletable,
corner_access,
make_array_read_attribute<int>,
make_array_write_attribute<int>,
nullptr,
AttributeValidator{&int_index_clamp});
static BuiltinCustomDataLayerProvider corner_edge(".corner_edge",
@ -1218,8 +1181,6 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh()
BuiltinAttributeProvider::NonCreatable,
BuiltinAttributeProvider::NonDeletable,
corner_access,
make_array_read_attribute<int>,
make_array_write_attribute<int>,
nullptr,
AttributeValidator{&int_index_clamp});
@ -1230,8 +1191,6 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh()
BuiltinAttributeProvider::Creatable,
BuiltinAttributeProvider::Deletable,
face_access,
make_array_read_attribute<bool>,
make_array_write_attribute<bool>,
nullptr);
static BuiltinCustomDataLayerProvider sharp_edge("sharp_edge",
@ -1241,21 +1200,21 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh()
BuiltinAttributeProvider::Creatable,
BuiltinAttributeProvider::Deletable,
edge_access,
make_array_read_attribute<bool>,
make_array_write_attribute<bool>,
nullptr);
static BuiltinCustomDataLayerProvider crease(
"crease",
ATTR_DOMAIN_EDGE,
CD_PROP_FLOAT,
CD_CREASE,
BuiltinAttributeProvider::Creatable,
BuiltinAttributeProvider::Deletable,
edge_access,
make_array_read_attribute<float>,
make_derived_write_attribute<float, float, get_crease, set_crease>,
nullptr);
static const auto crease_clamp = mf::build::SI1_SO<float, float>(
"Crease Clamp",
[](float value) { return std::clamp(value, 0.0f, 1.0f); },
mf::build::exec_presets::AllSpanOrSingle());
static BuiltinCustomDataLayerProvider crease("crease",
ATTR_DOMAIN_EDGE,
CD_PROP_FLOAT,
CD_CREASE,
BuiltinAttributeProvider::Creatable,
BuiltinAttributeProvider::Deletable,
edge_access,
nullptr,
AttributeValidator{&crease_clamp});
static VertexGroupsAttributeProvider vertex_groups;
static CustomDataAttributeProvider corner_custom_data(ATTR_DOMAIN_CORNER, corner_access);

View File

@ -142,8 +142,6 @@ static ComponentAttributeProviders create_attribute_providers_for_point_cloud()
BuiltinAttributeProvider::NonCreatable,
BuiltinAttributeProvider::NonDeletable,
point_access,
make_array_read_attribute<float3>,
make_array_write_attribute<float3>,
tag_component_positions_changed);
static BuiltinCustomDataLayerProvider radius("radius",
ATTR_DOMAIN_POINT,
@ -152,8 +150,6 @@ static ComponentAttributeProviders create_attribute_providers_for_point_cloud()
BuiltinAttributeProvider::Creatable,
BuiltinAttributeProvider::Deletable,
point_access,
make_array_read_attribute<float>,
make_array_write_attribute<float>,
tag_component_radius_changed);
static BuiltinCustomDataLayerProvider id("id",
ATTR_DOMAIN_POINT,
@ -162,8 +158,6 @@ static ComponentAttributeProviders create_attribute_providers_for_point_cloud()
BuiltinAttributeProvider::Creatable,
BuiltinAttributeProvider::Deletable,
point_access,
make_array_read_attribute<int>,
make_array_write_attribute<int>,
nullptr);
static CustomDataAttributeProvider point_custom_data(ATTR_DOMAIN_POINT, point_access);
return ComponentAttributeProviders({&position, &radius, &id}, {&point_custom_data});

View File

@ -765,14 +765,38 @@ ID *BKE_id_copy_for_use_in_bmain(Main *bmain, const ID *id)
return newid;
}
static void id_embedded_swap(ID **embedded_id_a,
ID **embedded_id_b,
const bool do_full_id,
struct IDRemapper *remapper_id_a,
struct IDRemapper *remapper_id_b);
/**
* Does a mere memory swap over the whole IDs data (including type-specific memory).
* \note Most internal ID data itself is not swapped (only IDProperties are).
*/
static void id_swap(Main *bmain, ID *id_a, ID *id_b, const bool do_full_id)
static void id_swap(Main *bmain,
ID *id_a,
ID *id_b,
const bool do_full_id,
const bool do_self_remap,
struct IDRemapper *input_remapper_id_a,
struct IDRemapper *input_remapper_id_b,
const int self_remap_flags)
{
BLI_assert(GS(id_a->name) == GS(id_b->name));
struct IDRemapper *remapper_id_a = input_remapper_id_a;
struct IDRemapper *remapper_id_b = input_remapper_id_b;
if (do_self_remap) {
if (remapper_id_a == NULL) {
remapper_id_a = BKE_id_remapper_create();
}
if (remapper_id_b == NULL) {
remapper_id_b = BKE_id_remapper_create();
}
}
const IDTypeInfo *id_type = BKE_idtype_get_info_from_id(id_a);
BLI_assert(id_type != NULL);
const size_t id_struct_size = id_type->struct_size;
@ -799,21 +823,87 @@ static void id_swap(Main *bmain, ID *id_a, ID *id_b, const bool do_full_id)
id_b->recalc = id_a_back.recalc;
}
if (bmain != NULL) {
/* Swap will have broken internal references to itself, restore them. */
BKE_libblock_relink_ex(bmain, id_a, id_b, id_a, ID_REMAP_SKIP_NEVER_NULL_USAGE);
BKE_libblock_relink_ex(bmain, id_b, id_a, id_b, ID_REMAP_SKIP_NEVER_NULL_USAGE);
id_embedded_swap((ID **)BKE_ntree_ptr_from_id(id_a),
(ID **)BKE_ntree_ptr_from_id(id_b),
do_full_id,
remapper_id_a,
remapper_id_b);
if (GS(id_a->name) == ID_SCE) {
Scene *scene_a = (Scene *)id_a;
Scene *scene_b = (Scene *)id_b;
id_embedded_swap((ID **)&scene_a->master_collection,
(ID **)&scene_b->master_collection,
do_full_id,
remapper_id_a,
remapper_id_b);
}
if (remapper_id_a != NULL) {
BKE_id_remapper_add(remapper_id_a, id_b, id_a);
}
if (remapper_id_b != NULL) {
BKE_id_remapper_add(remapper_id_b, id_a, id_b);
}
/* Finalize remapping of internal referrences to self broken by swapping, if requested. */
if (do_self_remap) {
LinkNode ids = {.next = NULL, .link = id_a};
BKE_libblock_relink_multiple(
bmain, &ids, ID_REMAP_TYPE_REMAP, remapper_id_a, self_remap_flags);
ids.link = id_b;
BKE_libblock_relink_multiple(
bmain, &ids, ID_REMAP_TYPE_REMAP, remapper_id_b, self_remap_flags);
}
if (input_remapper_id_a == NULL && remapper_id_a != NULL) {
BKE_id_remapper_free(remapper_id_a);
}
if (input_remapper_id_b == NULL && remapper_id_b != NULL) {
BKE_id_remapper_free(remapper_id_b);
}
}
void BKE_lib_id_swap(Main *bmain, ID *id_a, ID *id_b)
/* Conceptually, embedded IDs are part of their owner's data. However, some parts of the code
* (like e.g. the depsgraph) may treat them as independant IDs, so swapping them here and
* switching their pointers in the owner IDs allows to help not break cached relationships and
* such (by preserving the pointer values). */
static void id_embedded_swap(ID **embedded_id_a,
ID **embedded_id_b,
const bool do_full_id,
struct IDRemapper *remapper_id_a,
struct IDRemapper *remapper_id_b)
{
id_swap(bmain, id_a, id_b, false);
if (embedded_id_a != NULL && *embedded_id_a != NULL) {
BLI_assert(embedded_id_b != NULL && *embedded_id_b != NULL);
/* Do not remap internal references to itself here, since embedded IDs pointers also need to be
* potentially remapped in owner ID's data, which will also handle embedded IDs data. */
id_swap(
NULL, *embedded_id_a, *embedded_id_b, do_full_id, false, remapper_id_a, remapper_id_b, 0);
/* Manual 'remap' of owning embedded pointer in owner ID. */
SWAP(ID *, *embedded_id_a, *embedded_id_b);
/* Restore internal pointers to the swapped embedded IDs in their owners' data. This also
* includes the potential self-references inside the embedded IDs themselves. */
if (remapper_id_a != NULL) {
BKE_id_remapper_add(remapper_id_a, *embedded_id_b, *embedded_id_a);
}
if (remapper_id_b != NULL) {
BKE_id_remapper_add(remapper_id_b, *embedded_id_a, *embedded_id_b);
}
}
}
void BKE_lib_id_swap_full(Main *bmain, ID *id_a, ID *id_b)
void BKE_lib_id_swap(
Main *bmain, ID *id_a, ID *id_b, const bool do_self_remap, const int self_remap_flags)
{
id_swap(bmain, id_a, id_b, true);
id_swap(bmain, id_a, id_b, false, do_self_remap, NULL, NULL, self_remap_flags);
}
void BKE_lib_id_swap_full(
Main *bmain, ID *id_a, ID *id_b, const bool do_self_remap, const int self_remap_flags)
{
id_swap(bmain, id_a, id_b, true, do_self_remap, NULL, NULL, self_remap_flags);
}
bool id_single_user(bContext *C, ID *id, PointerRNA *ptr, PropertyRNA *prop)

View File

@ -3784,7 +3784,7 @@ void BKE_lib_override_library_main_unused_cleanup(Main *bmain)
static void lib_override_id_swap(Main *bmain, ID *id_local, ID *id_temp)
{
BKE_lib_id_swap(bmain, id_local, id_temp);
BKE_lib_id_swap(bmain, id_local, id_temp, true, 0);
/* We need to keep these tags from temp ID into orig one.
* ID swap does not swap most of ID data itself. */
id_local->tag |= (id_temp->tag & LIB_TAG_LIB_OVERRIDE_NEED_RESYNC);

View File

@ -1515,7 +1515,7 @@ bNodeSocket *node_find_enabled_socket(bNode &node,
{
ListBase *sockets = (in_out == SOCK_IN) ? &node.inputs : &node.outputs;
LISTBASE_FOREACH (bNodeSocket *, socket, sockets) {
if (!(socket->flag & SOCK_UNAVAIL) && socket->name == name) {
if (socket->is_available() && socket->name == name) {
return socket;
}
}
@ -2582,7 +2582,7 @@ bNodeLink *nodeAddLink(
BKE_ntree_update_tag_link_added(ntree, link);
}
if (link != nullptr && link->tosock->flag & SOCK_MULTI_INPUT) {
if (link != nullptr && link->tosock->is_multi_input()) {
link->multi_input_socket_index = node_count_links(ntree, link->tosock) - 1;
}
@ -2608,7 +2608,7 @@ void nodeRemLink(bNodeTree *ntree, bNodeLink *link)
void nodeLinkSetMute(bNodeTree *ntree, bNodeLink *link, const bool muted)
{
const bool was_muted = link->flag & NODE_LINK_MUTED;
const bool was_muted = link->is_muted();
SET_FLAG_FROM_TEST(link->flag, muted, NODE_LINK_MUTED);
if (muted != was_muted) {
BKE_ntree_update_tag_link_mute(ntree, link);
@ -2670,7 +2670,7 @@ void nodeInternalRelink(bNodeTree *ntree, bNode *node)
bNodeLink *fromlink = internal_link ? internal_link->fromsock->link : nullptr;
if (fromlink == nullptr) {
if (link->tosock->flag & SOCK_MULTI_INPUT) {
if (link->tosock->is_multi_input()) {
adjust_multi_input_indices_after_removed_link(
ntree, link->tosock, link->multi_input_socket_index);
}
@ -2678,7 +2678,7 @@ void nodeInternalRelink(bNodeTree *ntree, bNode *node)
continue;
}
if (link->tosock->flag & SOCK_MULTI_INPUT) {
if (link->tosock->is_multi_input()) {
/* remove the link that would be the same as the relinked one */
LISTBASE_FOREACH_MUTABLE (bNodeLink *, link_to_compare, &ntree->links) {
if (link_to_compare->fromsock == fromlink->fromsock &&
@ -3086,7 +3086,7 @@ void nodeUnlinkNode(bNodeTree *ntree, bNode *node)
if (lb) {
/* Only bother adjusting if the socket is not on the node we're deleting. */
if (link->tonode != node && link->tosock->flag & SOCK_MULTI_INPUT) {
if (link->tonode != node && link->tosock->is_multi_input()) {
adjust_multi_input_indices_after_removed_link(
ntree, link->tosock, link->multi_input_socket_index);
}
@ -3733,8 +3733,7 @@ void nodeSetActive(bNodeTree *ntree, bNode *node)
void nodeSetSocketAvailability(bNodeTree *ntree, bNodeSocket *sock, const bool is_available)
{
const bool was_available = (sock->flag & SOCK_UNAVAIL) == 0;
if (is_available == was_available) {
if (is_available == sock->is_available()) {
return;
}
if (is_available) {
@ -3748,7 +3747,7 @@ void nodeSetSocketAvailability(bNodeTree *ntree, bNodeSocket *sock, const bool i
int nodeSocketLinkLimit(const bNodeSocket *sock)
{
if (sock->flag & SOCK_MULTI_INPUT) {
if (sock->is_multi_input()) {
return 4095;
}
if (sock->typeinfo == nullptr) {

View File

@ -130,7 +130,7 @@ static void palette_undo_preserve(BlendLibReader * /*reader*/, ID *id_new, ID *i
/* NOTE: We do not care about potential internal references to self here, Palette has none. */
/* NOTE: We do not swap IDProperties, as dealing with potential ID pointers in those would be
* fairly delicate. */
BKE_lib_id_swap(nullptr, id_new, id_old);
BKE_lib_id_swap(nullptr, id_new, id_old, false, 0);
std::swap(id_new->properties, id_old->properties);
}
@ -1897,7 +1897,7 @@ void BKE_sculpt_update_object_before_eval(Object *ob_eval)
/* In vertex/weight paint, force maps to be rebuilt. */
BKE_sculptsession_free_vwpaint_data(ob_eval->sculpt);
}
else {
else if (ss->pbvh) {
Vector<PBVHNode *> nodes = blender::bke::pbvh::search_gather(ss->pbvh, nullptr, nullptr);
for (PBVHNode *node : nodes) {

View File

@ -511,6 +511,32 @@ void BKE_workspace_tool_remove(struct WorkSpace *workspace, struct bToolRef *tre
MEM_freeN(tref);
}
void BKE_workspace_tool_id_replace_table(struct WorkSpace *workspace,
const int space_type,
const int mode,
const char *idname_prefix_skip,
const char *replace_table[][2],
int replace_table_num)
{
const size_t idname_prefix_len = idname_prefix_skip ? strlen(idname_prefix_skip) : 0;
const size_t idname_suffix_len = sizeof(((bToolRef *)nullptr)->idname) - idname_prefix_len;
LISTBASE_FOREACH (bToolRef *, tref, &workspace->tools) {
if (!(tref->space_type == space_type && tref->mode == mode)) {
continue;
}
char *idname_suffix = tref->idname;
if (idname_prefix_skip) {
if (!STRPREFIX(idname_suffix, idname_prefix_skip)) {
continue;
}
idname_suffix += idname_prefix_len;
}
BLI_str_replace_table_exact(
idname_suffix, idname_suffix_len, replace_table, replace_table_num);
}
}
bool BKE_workspace_owner_id_check(const WorkSpace *workspace, const char *owner_id)
{
if ((*owner_id == '\0') || ((workspace->flags & WORKSPACE_USE_FILTER_BY_ORIGIN) == 0)) {

View File

@ -885,12 +885,14 @@ class Map {
}
/**
* Remove all key-value-pairs for that the given predicate is true.
* Remove all key-value-pairs for that the given predicate is true and return the number of
* removed pairs.
*
* This is similar to std::erase_if.
*/
template<typename Predicate> void remove_if(Predicate &&predicate)
template<typename Predicate> int64_t remove_if(Predicate &&predicate)
{
const int64_t prev_size = this->size();
for (Slot &slot : slots_) {
if (slot.is_occupied()) {
const Key &key = *slot.key();
@ -901,6 +903,7 @@ class Map {
}
}
}
return prev_size - this->size();
}
/**

View File

@ -489,12 +489,14 @@ class Set {
}
/**
* Remove all values for which the given predicate is true.
* Remove all values for which the given predicate is true and return the number of removed
* values.
*
* This is similar to std::erase_if.
*/
template<typename Predicate> void remove_if(Predicate &&predicate)
template<typename Predicate> int64_t remove_if(Predicate &&predicate)
{
const int64_t prev_size = this->size();
for (Slot &slot : slots_) {
if (slot.is_occupied()) {
const Key &key = *slot.key();
@ -504,6 +506,7 @@ class Set {
}
}
}
return prev_size - this->size();
}
/**

View File

@ -816,14 +816,17 @@ class Vector {
}
/**
* Remove all values for which the given predicate is true.
* Remove all values for which the given predicate is true and return the number of values
* removed.
*
* This is similar to std::erase_if.
*/
template<typename Predicate> void remove_if(Predicate &&predicate)
template<typename Predicate> int64_t remove_if(Predicate &&predicate)
{
const T *prev_end = this->end();
end_ = std::remove_if(this->begin(), this->end(), predicate);
UPDATE_VECTOR_SIZE(this);
return int64_t(prev_end - end_);
}
/**

View File

@ -347,13 +347,14 @@ class VectorSet {
}
/**
* Remove all values for which the given predicate is true. This may change the order of elements
* in the vector.
* Remove all values for which the given predicate is true and return the number or values
* removed. This may change the order of elements in the vector.
*
* This is similar to std::erase_if.
*/
template<typename Predicate> void remove_if(Predicate &&predicate)
template<typename Predicate> int64_t remove_if(Predicate &&predicate)
{
const int64_t prev_size = this->size();
for (Slot &slot : slots_) {
if (slot.is_occupied()) {
const int64_t index = slot.index();
@ -363,6 +364,7 @@ class VectorSet {
}
}
}
return prev_size - this->size();
}
/**

View File

@ -646,8 +646,8 @@ TEST(map, RemoveIf)
for (const int64_t i : IndexRange(100)) {
map.add(i * i, i);
}
map.remove_if([](auto item) { return item.key > 100; });
EXPECT_EQ(map.size(), 11);
const int64_t removed = map.remove_if([](auto item) { return item.key > 100; });
EXPECT_EQ(map.size() + removed, 100);
for (const int64_t i : IndexRange(100)) {
if (i <= 10) {
EXPECT_EQ(map.lookup(i * i), i);

View File

@ -582,8 +582,8 @@ TEST(set, RemoveIf)
for (const int64_t i : IndexRange(100)) {
set.add(i * i);
}
set.remove_if([](const int64_t key) { return key > 100; });
EXPECT_EQ(set.size(), 11);
const int64_t removed = set.remove_if([](const int64_t key) { return key > 100; });
EXPECT_EQ(set.size() + removed, 100);
for (const int64_t i : IndexRange(100)) {
EXPECT_EQ(set.contains(i * i), i <= 10);
}

View File

@ -134,8 +134,8 @@ TEST(vector_set, RemoveIf)
for (const int64_t i : IndexRange(100)) {
set.add(i * i);
}
set.remove_if([](const int64_t key) { return key % 2 == 0; });
EXPECT_EQ(set.size(), 50);
const int64_t removed = set.remove_if([](const int64_t key) { return key % 2 == 0; });
EXPECT_EQ(set.size() + removed, 100);
for (const int64_t i : IndexRange(100)) {
EXPECT_EQ(set.contains(i * i), i % 2 == 1);
}

View File

@ -422,7 +422,8 @@ TEST(vector, Remove)
TEST(vector, RemoveIf)
{
Vector<int> vec = {1, 2, 3, 4, 5, 6, 7, 8};
vec.remove_if([](const int x) { return x % 2 == 0; });
const int64_t removed = vec.remove_if([](const int x) { return x % 2 == 0; });
EXPECT_EQ(vec.size() + removed, 8);
const Vector<int> expected_vec = {1, 3, 5, 7};
EXPECT_EQ(vec.size(), expected_vec.size());
EXPECT_EQ_ARRAY(vec.data(), expected_vec.data(), size_t(vec.size()));

View File

@ -72,6 +72,7 @@
#include "BKE_lib_id.h"
#include "BKE_lib_override.h"
#include "BKE_lib_query.h"
#include "BKE_lib_remap.h"
#include "BKE_main.h" /* for Main */
#include "BKE_main_idmap.h"
#include "BKE_material.h"
@ -3095,10 +3096,17 @@ static void read_libblock_undo_restore_at_old_address(FileData *fd, Main *main,
BLI_remlink(old_lb, id_old);
BLI_remlink(new_lb, id);
/* We do not need any remapping from this call here, since no ID pointer is valid in the data
* currently (they are all pointing to old addresses, and need to go through `lib_link`
* process). So we can pass nullptr for the Main pointer parameter. */
BKE_lib_id_swap_full(nullptr, id, id_old);
/* We do need remapping of internal pointers to the ID itself here.
*
* Passing a NULL BMain means that not all potential runtime data (like collections' parent
* pointers etc.) will be up-to-date. However, this should not be a problem here, since these
* data are re-generated later in fileread process anyway.. */
BKE_lib_id_swap_full(nullptr,
id,
id_old,
true,
ID_REMAP_SKIP_NEVER_NULL_USAGE | ID_REMAP_SKIP_UPDATE_TAGGING |
ID_REMAP_SKIP_USER_REFCOUNT);
/* Special temporary usage of this pointer, necessary for the `undo_preserve` call after
* lib-linking to restore some data that should never be affected by undo, e.g. the 3D cursor of
@ -3126,10 +3134,8 @@ static bool read_libblock_undo_restore(
else if (id_type->flags & IDTYPE_FLAGS_NO_MEMFILE_UNDO) {
/* Skip reading any 'no undo' datablocks (typically UI-like ones), existing ones are kept.
* See `setup_app_data` for details. */
CLOG_INFO(&LOG_UNDO,
2,
"UNDO: skip restore datablock %s, 'NO_MEMFILE_UNDO' type of ID",
id->name);
CLOG_INFO(
&LOG_UNDO, 2, "UNDO: skip restore datablock %s, 'NO_MEMFILE_UNDO' type of ID", id->name);
return true;
}
else if (bhead->code == ID_LINK_PLACEHOLDER) {

View File

@ -67,6 +67,7 @@
#include "BKE_modifier.h"
#include "BKE_node.h"
#include "BKE_screen.h"
#include "BKE_workspace.h"
#include "RNA_access.h"
#include "RNA_enum_types.h"
@ -4280,6 +4281,29 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain)
}
}
}
/* Replace old hard coded names with brush names, see: #106057. */
const char *tool_replace_table[][2] = {
{"selection_paint", "Paint Selection"},
{"add", "Add"},
{"delete", "Delete"},
{"density", "Density"},
{"comb", "Comb"},
{"snake_hook", "Snake Hook"},
{"grow_shrink", "Grow / Shrink"},
{"pinch", "Pinch"},
{"puff", "Puff"},
{"smooth", "Comb"},
{"slide", "Slide"},
};
LISTBASE_FOREACH (WorkSpace *, workspace, &bmain->workspaces) {
BKE_workspace_tool_id_replace_table(workspace,
SPACE_VIEW3D,
CTX_MODE_SCULPT_CURVES,
"builtin_brush.",
tool_replace_table,
ARRAY_SIZE(tool_replace_table));
}
}
}

View File

@ -1840,8 +1840,14 @@ void DepsgraphRelationBuilder::build_driver_variables(ID *id, FCurve *fcu)
* - Modifications of evaluated IDs from a Python handler.
* Such modifications are not fully integrated in the dependency graph evaluation as it
* has issues with copy-on-write tagging and the fact that relations are defined by the
* original main database status. */
if (target_id != variable_exit_key.ptr.owner_id) {
* original main database status.
*
* The original report for this is #98618.
*
* The not-so-obvious part is that we don't do such relation for the context properties.
* They are resolved at the graph build time and do not change at runtime (#107081).
*/
if (target_id != variable_exit_key.ptr.owner_id && dvar->type != DVAR_TYPE_CONTEXT_PROP) {
if (deg_copy_on_write_is_needed(GS(target_id->name))) {
ComponentKey target_id_key(target_id, NodeType::COPY_ON_WRITE);
add_relation(target_id_key, driver_key, "Target ID -> Driver");

View File

@ -42,8 +42,9 @@ int EEVEE_bloom_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
effects->blit_texel_size[0] = 1.0f / (float)blitsize[0];
effects->blit_texel_size[1] = 1.0f / (float)blitsize[1];
effects->bloom_blit = DRW_texture_pool_query_2d(
blitsize[0], blitsize[1], GPU_R11F_G11F_B10F, &draw_engine_eevee_type);
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT;
effects->bloom_blit = DRW_texture_pool_query_2d_ex(
blitsize[0], blitsize[1], GPU_R11F_G11F_B10F, usage, &draw_engine_eevee_type);
GPU_framebuffer_ensure_config(
&fbl->bloom_blit_fb, {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(effects->bloom_blit)});
@ -83,8 +84,11 @@ int EEVEE_bloom_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
effects->downsamp_texel_size[i][0] = 1.0f / (float)texsize[0];
effects->downsamp_texel_size[i][1] = 1.0f / (float)texsize[1];
effects->bloom_downsample[i] = DRW_texture_pool_query_2d(
texsize[0], texsize[1], GPU_R11F_G11F_B10F, &draw_engine_eevee_type);
eGPUTextureUsage downsample_usage = GPU_TEXTURE_USAGE_SHADER_READ |
GPU_TEXTURE_USAGE_ATTACHMENT |
GPU_TEXTURE_USAGE_MIP_SWIZZLE_VIEW;
effects->bloom_downsample[i] = DRW_texture_pool_query_2d_ex(
texsize[0], texsize[1], GPU_R11F_G11F_B10F, downsample_usage, &draw_engine_eevee_type);
GPU_framebuffer_ensure_config(
&fbl->bloom_down_fb[i],
{GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(effects->bloom_downsample[i])});
@ -99,8 +103,12 @@ int EEVEE_bloom_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
texsize[0] = MAX2(texsize[0], 2);
texsize[1] = MAX2(texsize[1], 2);
effects->bloom_upsample[i] = DRW_texture_pool_query_2d(
texsize[0], texsize[1], GPU_R11F_G11F_B10F, &draw_engine_eevee_type);
eGPUTextureUsage upsample_usage = GPU_TEXTURE_USAGE_SHADER_READ |
GPU_TEXTURE_USAGE_ATTACHMENT |
GPU_TEXTURE_USAGE_MIP_SWIZZLE_VIEW;
effects->bloom_upsample[i] = DRW_texture_pool_query_2d_ex(
texsize[0], texsize[1], GPU_R11F_G11F_B10F, upsample_usage, &draw_engine_eevee_type);
GPU_framebuffer_ensure_config(
&fbl->bloom_accum_fb[i],
{GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(effects->bloom_upsample[i])});

View File

@ -576,7 +576,8 @@ static void dof_reduce_pass_init(EEVEE_FramebufferList *fbl,
DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
void *owner = (void *)&EEVEE_depth_of_field_init;
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT;
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT |
GPU_TEXTURE_USAGE_MIP_SWIZZLE_VIEW;
fx->dof_downsample_tx = DRW_texture_pool_query_2d_ex(
UNPACK2(quater_res), COLOR_FORMAT, usage, owner);

View File

@ -118,8 +118,13 @@ void EEVEE_effects_init(EEVEE_ViewLayerData *sldata,
});
}
else {
DRW_texture_ensure_2d(
&txl->maxzbuffer, UNPACK2(effects->hiz_size), GPU_DEPTH_COMPONENT24, DRW_TEX_MIPMAP);
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_ATTACHMENT | GPU_TEXTURE_USAGE_SHADER_READ |
GPU_TEXTURE_USAGE_MIP_SWIZZLE_VIEW;
DRW_texture_ensure_2d_ex(&txl->maxzbuffer,
UNPACK2(effects->hiz_size),
GPU_DEPTH_COMPONENT24,
usage,
DRW_TEX_MIPMAP);
GPU_framebuffer_ensure_config(&fbl->maxzbuffer_fb,
{
GPU_ATTACHMENT_TEXTURE(txl->maxzbuffer),
@ -146,10 +151,13 @@ void EEVEE_effects_init(EEVEE_ViewLayerData *sldata,
* Used for SSReflections & SSRefractions.
*/
if ((effects->enabled_effects & EFFECT_RADIANCE_BUFFER) != 0) {
DRW_texture_ensure_2d(&txl->filtered_radiance,
UNPACK2(effects->hiz_size),
GPU_R11F_G11F_B10F,
DRW_TEX_FILTER | DRW_TEX_MIPMAP);
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_ATTACHMENT | GPU_TEXTURE_USAGE_SHADER_READ |
GPU_TEXTURE_USAGE_MIP_SWIZZLE_VIEW;
DRW_texture_ensure_2d_ex(&txl->filtered_radiance,
UNPACK2(effects->hiz_size),
GPU_R11F_G11F_B10F,
usage,
DRW_TEX_FILTER | DRW_TEX_MIPMAP);
GPU_framebuffer_ensure_config(&fbl->radiance_filtered_fb,
{
@ -166,8 +174,9 @@ void EEVEE_effects_init(EEVEE_ViewLayerData *sldata,
* Normal buffer for deferred passes.
*/
if ((effects->enabled_effects & EFFECT_NORMAL_BUFFER) != 0) {
effects->ssr_normal_input = DRW_texture_pool_query_2d(
size_fs[0], size_fs[1], GPU_RG16, &draw_engine_eevee_type);
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT;
effects->ssr_normal_input = DRW_texture_pool_query_2d_ex(
size_fs[0], size_fs[1], GPU_RG16, usage, &draw_engine_eevee_type);
GPU_framebuffer_texture_attach(fbl->main_fb, effects->ssr_normal_input, 1, 0);
}
@ -179,8 +188,9 @@ void EEVEE_effects_init(EEVEE_ViewLayerData *sldata,
* Motion vector buffer for correct TAA / motion blur.
*/
if ((effects->enabled_effects & EFFECT_VELOCITY_BUFFER) != 0) {
effects->velocity_tx = DRW_texture_pool_query_2d(
size_fs[0], size_fs[1], GPU_RGBA16, &draw_engine_eevee_type);
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT;
effects->velocity_tx = DRW_texture_pool_query_2d_ex(
size_fs[0], size_fs[1], GPU_RGBA16, usage, &draw_engine_eevee_type);
GPU_framebuffer_ensure_config(&fbl->velocity_fb,
{

View File

@ -101,22 +101,28 @@ static void planar_pool_ensure_alloc(EEVEE_Data *vedata, int num_planar_ref)
/* We need an Array texture so allocate it ourself */
if (!txl->planar_pool) {
eGPUTextureUsage planar_usage = GPU_TEXTURE_USAGE_ATTACHMENT | GPU_TEXTURE_USAGE_SHADER_READ |
GPU_TEXTURE_USAGE_MIP_SWIZZLE_VIEW;
eGPUTextureUsage planar_usage_depth = GPU_TEXTURE_USAGE_ATTACHMENT |
GPU_TEXTURE_USAGE_SHADER_READ;
if (num_planar_ref > 0) {
txl->planar_pool = DRW_texture_create_2d_array(width,
height,
num_planar_ref,
GPU_R11F_G11F_B10F,
DRW_TEX_FILTER | DRW_TEX_MIPMAP,
NULL);
txl->planar_depth = DRW_texture_create_2d_array(
width, height, num_planar_ref, GPU_DEPTH_COMPONENT24, 0, NULL);
txl->planar_pool = DRW_texture_create_2d_array_ex(width,
height,
num_planar_ref,
GPU_R11F_G11F_B10F,
planar_usage,
DRW_TEX_FILTER | DRW_TEX_MIPMAP,
NULL);
txl->planar_depth = DRW_texture_create_2d_array_ex(
width, height, num_planar_ref, GPU_DEPTH_COMPONENT24, planar_usage_depth, 0, NULL);
}
else if (num_planar_ref == 0) {
/* Makes Opengl Happy : Create a placeholder texture that will never be sampled but still
* bound to shader. */
txl->planar_pool = DRW_texture_create_2d_array(
1, 1, 1, GPU_RGBA8, DRW_TEX_FILTER | DRW_TEX_MIPMAP, NULL);
txl->planar_depth = DRW_texture_create_2d_array(1, 1, 1, GPU_DEPTH_COMPONENT24, 0, NULL);
txl->planar_pool = DRW_texture_create_2d_array_ex(
1, 1, 1, GPU_RGBA8, planar_usage, DRW_TEX_FILTER | DRW_TEX_MIPMAP, NULL);
txl->planar_depth = DRW_texture_create_2d_array_ex(
1, 1, 1, GPU_DEPTH_COMPONENT24, planar_usage_depth, 0, NULL);
}
}
}
@ -182,8 +188,10 @@ void EEVEE_lightprobes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
/* Placeholder planar pool: used when rendering planar reflections (avoid dependency loop). */
if (!e_data.planar_pool_placeholder) {
e_data.planar_pool_placeholder = DRW_texture_create_2d_array(
1, 1, 1, GPU_RGBA8, DRW_TEX_FILTER, NULL);
eGPUTextureUsage planar_usage = GPU_TEXTURE_USAGE_ATTACHMENT | GPU_TEXTURE_USAGE_SHADER_READ |
GPU_TEXTURE_USAGE_MIP_SWIZZLE_VIEW;
e_data.planar_pool_placeholder = DRW_texture_create_2d_array_ex(
1, 1, 1, GPU_RGBA8, planar_usage, DRW_TEX_FILTER, NULL);
}
}

View File

@ -197,8 +197,9 @@ static void eevee_init_util_texture(void)
texels_layer += 64 * 64;
}
e_data.util_tex = DRW_texture_create_2d_array(
64, 64, layers, GPU_RGBA16F, DRW_TEX_FILTER | DRW_TEX_WRAP, (float *)texels);
eGPUTextureUsage util_usage = GPU_TEXTURE_USAGE_ATTACHMENT | GPU_TEXTURE_USAGE_SHADER_READ;
e_data.util_tex = DRW_texture_create_2d_array_ex(
64, 64, layers, GPU_RGBA16F, util_usage, DRW_TEX_FILTER | DRW_TEX_WRAP, (float *)texels);
MEM_freeN(texels);
#if RUNTIME_LUT_CREATION

View File

@ -36,8 +36,10 @@ int EEVEE_occlusion_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
if (!e_data.dummy_horizon_tx) {
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_ATTACHMENT | GPU_TEXTURE_USAGE_SHADER_READ;
const float pixel[4] = {0.0f, 0.0f, 0.0f, 0.0f};
e_data.dummy_horizon_tx = DRW_texture_create_2d(1, 1, GPU_RGBA8, DRW_TEX_WRAP, pixel);
e_data.dummy_horizon_tx = DRW_texture_create_2d_ex(
1, 1, GPU_RGBA8, usage, DRW_TEX_WRAP, pixel);
}
if (scene_eval->eevee.flag & SCE_EEVEE_GTAO_ENABLED ||
@ -61,8 +63,9 @@ int EEVEE_occlusion_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
common_data->ao_bounce_fac = (scene_eval->eevee.flag & SCE_EEVEE_GTAO_BOUNCE) ? 1.0f : 0.0f;
effects->gtao_horizons_renderpass = DRW_texture_pool_query_2d(
UNPACK2(effects->hiz_size), GPU_RGBA8, &draw_engine_eevee_type);
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_ATTACHMENT | GPU_TEXTURE_USAGE_SHADER_READ;
effects->gtao_horizons_renderpass = DRW_texture_pool_query_2d_ex(
UNPACK2(effects->hiz_size), GPU_RGBA8, usage, &draw_engine_eevee_type);
GPU_framebuffer_ensure_config(
&fbl->gtao_fb,
{GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(effects->gtao_horizons_renderpass)});

View File

@ -72,13 +72,17 @@ int EEVEE_screen_raytrace_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
common_data->ssr_uv_scale[1] = size_fs[1] / ((float)tracing_res[1] * divisor);
/* MRT for the shading pass in order to output needed data for the SSR pass. */
effects->ssr_specrough_input = DRW_texture_pool_query_2d(UNPACK2(size_fs), format, owner);
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT;
effects->ssr_specrough_input = DRW_texture_pool_query_2d_ex(
UNPACK2(size_fs), format, usage, owner);
GPU_framebuffer_texture_attach(fbl->main_fb, effects->ssr_specrough_input, 2, 0);
/* Ray-tracing output. */
effects->ssr_hit_output = DRW_texture_pool_query_2d(UNPACK2(tracing_res), GPU_RGBA16F, owner);
effects->ssr_hit_depth = DRW_texture_pool_query_2d(UNPACK2(tracing_res), GPU_R16F, owner);
effects->ssr_hit_output = DRW_texture_pool_query_2d_ex(
UNPACK2(tracing_res), GPU_RGBA16F, usage, owner);
effects->ssr_hit_depth = DRW_texture_pool_query_2d_ex(
UNPACK2(tracing_res), GPU_R16F, usage, owner);
GPU_framebuffer_ensure_config(&fbl->screen_tracing_fb,
{

View File

@ -213,22 +213,26 @@ void EEVEE_shadows_update(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
linfo->cache_num_cascade_layer = linfo->num_cascade_layer;
}
eGPUTextureUsage shadow_usage = GPU_TEXTURE_USAGE_ATTACHMENT | GPU_TEXTURE_USAGE_SHADER_READ;
if (!sldata->shadow_cube_pool) {
sldata->shadow_cube_pool = DRW_texture_create_2d_array(linfo->shadow_cube_size,
linfo->shadow_cube_size,
max_ii(1, linfo->num_cube_layer * 6),
shadow_pool_format,
DRW_TEX_FILTER | DRW_TEX_COMPARE,
NULL);
sldata->shadow_cube_pool = DRW_texture_create_2d_array_ex(linfo->shadow_cube_size,
linfo->shadow_cube_size,
max_ii(1, linfo->num_cube_layer * 6),
shadow_pool_format,
shadow_usage,
DRW_TEX_FILTER | DRW_TEX_COMPARE,
NULL);
}
if (!sldata->shadow_cascade_pool) {
sldata->shadow_cascade_pool = DRW_texture_create_2d_array(linfo->shadow_cascade_size,
linfo->shadow_cascade_size,
max_ii(1, linfo->num_cascade_layer),
shadow_pool_format,
DRW_TEX_FILTER | DRW_TEX_COMPARE,
NULL);
sldata->shadow_cascade_pool = DRW_texture_create_2d_array_ex(
linfo->shadow_cascade_size,
linfo->shadow_cascade_size,
max_ii(1, linfo->num_cascade_layer),
shadow_pool_format,
shadow_usage,
DRW_TEX_FILTER | DRW_TEX_COMPARE,
NULL);
}
if (sldata->shadow_fb == NULL) {

View File

@ -36,16 +36,18 @@ void EEVEE_subsurface_draw_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
* as the depth buffer we are sampling from. This could be avoided if the stencil is
* a separate texture but that needs OpenGL 4.4 or ARB_texture_stencil8.
* OR OpenGL 4.3 / ARB_ES3_compatibility if using a render-buffer instead. */
effects->sss_stencil = DRW_texture_pool_query_2d(
fs_size[0], fs_size[1], GPU_DEPTH24_STENCIL8, &draw_engine_eevee_type);
effects->sss_blur = DRW_texture_pool_query_2d(
fs_size[0], fs_size[1], GPU_R11F_G11F_B10F, &draw_engine_eevee_type);
effects->sss_irradiance = DRW_texture_pool_query_2d(
fs_size[0], fs_size[1], GPU_R11F_G11F_B10F, &draw_engine_eevee_type);
effects->sss_radius = DRW_texture_pool_query_2d(
fs_size[0], fs_size[1], GPU_R16F, &draw_engine_eevee_type);
effects->sss_albedo = DRW_texture_pool_query_2d(
fs_size[0], fs_size[1], GPU_R11F_G11F_B10F, &draw_engine_eevee_type);
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT;
effects->sss_stencil = DRW_texture_pool_query_2d_ex(
fs_size[0], fs_size[1], GPU_DEPTH24_STENCIL8, usage, &draw_engine_eevee_type);
effects->sss_blur = DRW_texture_pool_query_2d_ex(
fs_size[0], fs_size[1], GPU_R11F_G11F_B10F, usage, &draw_engine_eevee_type);
effects->sss_irradiance = DRW_texture_pool_query_2d_ex(
fs_size[0], fs_size[1], GPU_R11F_G11F_B10F, usage, &draw_engine_eevee_type);
effects->sss_radius = DRW_texture_pool_query_2d_ex(
fs_size[0], fs_size[1], GPU_R16F, usage, &draw_engine_eevee_type);
effects->sss_albedo = DRW_texture_pool_query_2d_ex(
fs_size[0], fs_size[1], GPU_R11F_G11F_B10F, usage, &draw_engine_eevee_type);
GPUTexture *stencil_tex = effects->sss_stencil;

View File

@ -192,8 +192,11 @@ void EEVEE_volumes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
if (!e_data.dummy_scatter) {
const float scatter[4] = {0.0f, 0.0f, 0.0f, 0.0f};
const float transmit[4] = {1.0f, 1.0f, 1.0f, 1.0f};
e_data.dummy_scatter = DRW_texture_create_3d(1, 1, 1, GPU_RGBA8, DRW_TEX_WRAP, scatter);
e_data.dummy_transmit = DRW_texture_create_3d(1, 1, 1, GPU_RGBA8, DRW_TEX_WRAP, transmit);
eGPUTextureUsage dummy_usage = GPU_TEXTURE_USAGE_ATTACHMENT | GPU_TEXTURE_USAGE_SHADER_READ;
e_data.dummy_scatter = DRW_texture_create_3d_ex(
1, 1, 1, GPU_RGBA8, dummy_usage, DRW_TEX_WRAP, scatter);
e_data.dummy_transmit = DRW_texture_create_3d_ex(
1, 1, 1, GPU_RGBA8, dummy_usage, DRW_TEX_WRAP, transmit);
}
}
@ -424,31 +427,54 @@ void EEVEE_volumes_draw_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
if (txl->volume_prop_scattering == NULL) {
/* Volume properties: We evaluate all volumetric objects
* and store their final properties into each froxel */
txl->volume_prop_scattering = DRW_texture_create_3d(
tex_size[0], tex_size[1], tex_size[2], GPU_R11F_G11F_B10F, DRW_TEX_FILTER, NULL);
txl->volume_prop_extinction = DRW_texture_create_3d(
tex_size[0], tex_size[1], tex_size[2], GPU_R11F_G11F_B10F, DRW_TEX_FILTER, NULL);
txl->volume_prop_emission = DRW_texture_create_3d(
tex_size[0], tex_size[1], tex_size[2], GPU_R11F_G11F_B10F, DRW_TEX_FILTER, NULL);
txl->volume_prop_phase = DRW_texture_create_3d(
tex_size[0], tex_size[1], tex_size[2], GPU_RG16F, DRW_TEX_FILTER, NULL);
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_ATTACHMENT | GPU_TEXTURE_USAGE_SHADER_READ;
txl->volume_prop_scattering = DRW_texture_create_3d_ex(
tex_size[0], tex_size[1], tex_size[2], GPU_R11F_G11F_B10F, usage, DRW_TEX_FILTER, NULL);
txl->volume_prop_extinction = DRW_texture_create_3d_ex(
tex_size[0], tex_size[1], tex_size[2], GPU_R11F_G11F_B10F, usage, DRW_TEX_FILTER, NULL);
txl->volume_prop_emission = DRW_texture_create_3d_ex(
tex_size[0], tex_size[1], tex_size[2], GPU_R11F_G11F_B10F, usage, DRW_TEX_FILTER, NULL);
txl->volume_prop_phase = DRW_texture_create_3d_ex(
tex_size[0], tex_size[1], tex_size[2], GPU_RG16F, usage, DRW_TEX_FILTER, NULL);
/* Volume scattering: We compute for each froxel the
* Scattered light towards the view. We also resolve temporal
* super sampling during this stage. */
txl->volume_scatter = DRW_texture_create_3d(
tex_size[0], tex_size[1], tex_size[2], GPU_R11F_G11F_B10F, DRW_TEX_FILTER, NULL);
txl->volume_transmit = DRW_texture_create_3d(
tex_size[0], tex_size[1], tex_size[2], GPU_R11F_G11F_B10F, DRW_TEX_FILTER, NULL);
eGPUTextureUsage usage_write = GPU_TEXTURE_USAGE_ATTACHMENT | GPU_TEXTURE_USAGE_SHADER_READ |
GPU_TEXTURE_USAGE_SHADER_WRITE;
txl->volume_scatter = DRW_texture_create_3d_ex(tex_size[0],
tex_size[1],
tex_size[2],
GPU_R11F_G11F_B10F,
usage_write,
DRW_TEX_FILTER,
NULL);
txl->volume_transmit = DRW_texture_create_3d_ex(tex_size[0],
tex_size[1],
tex_size[2],
GPU_R11F_G11F_B10F,
usage_write,
DRW_TEX_FILTER,
NULL);
/* Final integration: We compute for each froxel the
* amount of scattered light and extinction coef at this
* given depth. We use these textures as double buffer
* for the volumetric history. */
txl->volume_scatter_history = DRW_texture_create_3d(
tex_size[0], tex_size[1], tex_size[2], GPU_R11F_G11F_B10F, DRW_TEX_FILTER, NULL);
txl->volume_transmit_history = DRW_texture_create_3d(
tex_size[0], tex_size[1], tex_size[2], GPU_R11F_G11F_B10F, DRW_TEX_FILTER, NULL);
txl->volume_scatter_history = DRW_texture_create_3d_ex(tex_size[0],
tex_size[1],
tex_size[2],
GPU_R11F_G11F_B10F,
usage_write,
DRW_TEX_FILTER,
NULL);
txl->volume_transmit_history = DRW_texture_create_3d_ex(tex_size[0],
tex_size[1],
tex_size[2],
GPU_R11F_G11F_B10F,
usage_write,
DRW_TEX_FILTER,
NULL);
}
GPU_framebuffer_ensure_config(&fbl->volumetric_fb,

View File

@ -280,6 +280,9 @@ void WM_OT_alembic_export(wmOperatorType *ot)
FILE_DEFAULTDISPLAY,
FILE_SORT_DEFAULT);
PropertyRNA *prop = RNA_def_string(ot->srna, "filter_glob", "*.abc", 0, "", "");
RNA_def_property_flag(prop, PROP_HIDDEN);
RNA_def_int(ot->srna,
"start",
INT_MIN,
@ -673,6 +676,9 @@ void WM_OT_alembic_import(wmOperatorType *ot)
FILE_DEFAULTDISPLAY,
FILE_SORT_DEFAULT);
PropertyRNA *prop = RNA_def_string(ot->srna, "filter_glob", "*.abc", 0, "", "");
RNA_def_property_flag(prop, PROP_HIDDEN);
RNA_def_float(
ot->srna,
"scale",

View File

@ -454,6 +454,9 @@ void WM_OT_collada_export(wmOperatorType *ot)
FILE_DEFAULTDISPLAY,
FILE_SORT_DEFAULT);
PropertyRNA *prop = RNA_def_string(ot->srna, "filter_glob", "*.dae", 0, "", "");
RNA_def_property_flag(prop, PROP_HIDDEN);
RNA_def_enum(ot->srna,
"prop_bc_export_ui_section",
prop_bc_export_ui_section,
@ -776,6 +779,9 @@ void WM_OT_collada_import(wmOperatorType *ot)
FILE_DEFAULTDISPLAY,
FILE_SORT_DEFAULT);
PropertyRNA *prop = RNA_def_string(ot->srna, "filter_glob", "*.dae", 0, "", "");
RNA_def_property_flag(prop, PROP_HIDDEN);
RNA_def_boolean(ot->srna,
"import_units",
0,

View File

@ -258,6 +258,9 @@ void WM_OT_usd_export(struct wmOperatorType *ot)
FILE_DEFAULTDISPLAY,
FILE_SORT_DEFAULT);
PropertyRNA *prop = RNA_def_string(ot->srna, "filter_glob", "*.usd", 0, "", "");
RNA_def_property_flag(prop, PROP_HIDDEN);
RNA_def_boolean(ot->srna,
"selected_objects_only",
false,
@ -557,6 +560,9 @@ void WM_OT_usd_import(struct wmOperatorType *ot)
FILE_DEFAULTDISPLAY,
FILE_SORT_DEFAULT);
PropertyRNA *prop = RNA_def_string(ot->srna, "filter_glob", "*.usd", 0, "", "");
RNA_def_property_flag(prop, PROP_HIDDEN);
RNA_def_float(
ot->srna,
"scale",

View File

@ -746,7 +746,8 @@ static int dyntopo_detail_size_edit_invoke(bContext *C, wmOperator *op, const wm
ss->draw_faded_cursor = true;
const char *status_str = TIP_(
"Move the mouse to change the dyntopo detail size. LMB: confirm size, ESC/RMB: cancel, SHIFT: precision mode, CTRL: sample detail size");
"Move the mouse to change the dyntopo detail size. LMB: confirm size, ESC/RMB: cancel, "
"SHIFT: precision mode, CTRL: sample detail size");
ED_workspace_status_text(C, status_str);
return OPERATOR_RUNNING_MODAL;

View File

@ -470,7 +470,15 @@ void SCULPT_OT_color_filter(wmOperatorType *ot)
RNA_def_enum(ot->srna, "type", prop_color_filter_types, COLOR_FILTER_FILL, "Filter Type", "");
PropertyRNA *prop = RNA_def_float_color(
ot->srna, "fill_color", 3, fill_filter_default_color, 0.0f, FLT_MAX, "Fill Color", "", 0.0f, 1.0f);
PropertyRNA *prop = RNA_def_float_color(ot->srna,
"fill_color",
3,
fill_filter_default_color,
0.0f,
FLT_MAX,
"Fill Color",
"",
0.0f,
1.0f);
RNA_def_property_subtype(prop, PROP_COLOR_GAMMA);
}

View File

@ -240,12 +240,12 @@ static void memfile_undosys_step_decode(struct bContext *C,
}
/* NOTE: Tagging `ID_RECALC_COPY_ON_WRITE` here should not be needed in practice, since
* modified IDs should already have other depsgraph update tags anyway. However, for sakes of
* consistency, it's better to effectively use it, since content of that ID pointer does have
* been modified. */
* modified IDs should already have other depsgraph update tags anyway.
* However, for the sake of consistency, it's better to effectively use it,
* since content of that ID pointer does have been modified. */
unsigned int recalc_flags = id->recalc | ((id->tag & LIB_TAG_UNDO_OLD_ID_REREAD_IN_PLACE) ?
ID_RECALC_COPY_ON_WRITE :
0);
IDRecalcFlag(0));
/* Tag depsgraph to update data-block for changes that happened between the
* current and the target state, see direct_link_id_restore_recalc(). */
if (recalc_flags != 0) {

View File

@ -239,7 +239,7 @@ static void gpu_material_sky_texture_build(GPUMaterial *mat)
mat->sky_builder->current_layer,
1,
GPU_RGBA32F,
GPU_TEXTURE_USAGE_GENERAL,
GPU_TEXTURE_USAGE_SHADER_READ,
(float *)mat->sky_builder->pixels);
MEM_freeN(mat->sky_builder);

View File

@ -290,13 +290,14 @@ typedef struct bPoseChannel {
char _pad[2];
/**
* Matrix result of location/rotation/scale components & constraints.
* Matrix result of location/rotation/scale components, and evaluation of
* animation data and constraints.
*
* This is the dynamic component of `pose_mat` (without #Bone.arm_mat).
*/
float chan_mat[4][4];
/**
* Constraints accumulate here. in the end, `pose_mat = bone->arm_mat * chan_mat`
* this matrix is object space.
* Channel matrix in the armature object space, i.e. `pose_mat = bone->arm_mat * chan_mat`.
*/
float pose_mat[4][4];
/** For display, pose_mat with bone length applied. */

View File

@ -99,6 +99,7 @@
\
.mtex = _DNA_DEFAULT_MTex, \
.mask_mtex = _DNA_DEFAULT_MTex, \
.falloff_shape = 0,\
}
/** \} */

View File

@ -76,8 +76,7 @@ typedef struct Mesh {
int totloop;
/**
* Array owned by mesh. May be null of there are no polygons. Index of the first corner of each
* polygon, with the total number of corners at the end. See #Mesh::polys() and #OffsetIndices.
* Array owned by mesh. See #Mesh::polys() and #OffsetIndices.
*
* This array is shared based on the bke::MeshRuntime::poly_offsets_sharing_info.
* Avoid accessing directly when possible.
@ -249,7 +248,11 @@ typedef struct Mesh {
* #corner_edges arrays to find the vertices or edges that make up each face.
*/
blender::OffsetIndices<int> polys() const;
/** The first corner index of every polygon. */
/**
* Index of the first corner of each polygon, and the size of the polygon encoded as the next
* offset. The total number of corners is the final value, and the first value is always zero.
* May be empty if there are no polygons.
*/
blender::Span<int> poly_offsets() const;
/** Write access to #poly_offsets data. */
blender::MutableSpan<int> poly_offsets_for_write();

View File

@ -91,19 +91,45 @@ static const EnumPropertyItem rna_enum_brush_texture_slot_map_texture_mode_items
};
#endif
/* clang-format off */
/* Note: we don't actually turn these into a single enum bit-mask property,
* instead we construct individual boolean properties. */
const EnumPropertyItem rna_enum_brush_automasking_flag_items[] = {
{BRUSH_AUTOMASKING_TOPOLOGY, "use_automasking_topology", 0,"Topology", "Affect only vertices connected to the active vertex under the brush"},
{BRUSH_AUTOMASKING_FACE_SETS, "use_automasking_face_sets", 0,"Face Sets", "Affect only vertices that share Face Sets with the active vertex"},
{BRUSH_AUTOMASKING_BOUNDARY_EDGES, "use_automasking_boundary_edges", 0,"Mesh Boundary Auto-Masking", "Do not affect non manifold boundary edges"},
{BRUSH_AUTOMASKING_BOUNDARY_FACE_SETS, "use_automasking_boundary_face_sets", 0,"Face Sets Boundary Automasking", "Do not affect vertices that belong to a Face Set boundary"},
{BRUSH_AUTOMASKING_CAVITY_NORMAL, "use_automasking_cavity", 0,"Cavity Mask", "Do not affect vertices on peaks, based on the surface curvature"},
{BRUSH_AUTOMASKING_CAVITY_INVERTED, "use_automasking_cavity_inverted", 0,"Inverted Cavity Mask", "Do not affect vertices within crevices, based on the surface curvature"},
{BRUSH_AUTOMASKING_CAVITY_USE_CURVE, "use_automasking_custom_cavity_curve", 0,"Custom Cavity Curve", "Use custom curve"},
{0, NULL, 0, NULL, NULL}
};
{BRUSH_AUTOMASKING_TOPOLOGY,
"use_automasking_topology",
0,
"Topology",
"Affect only vertices connected to the active vertex under the brush"},
{BRUSH_AUTOMASKING_FACE_SETS,
"use_automasking_face_sets",
0,
"Face Sets",
"Affect only vertices that share Face Sets with the active vertex"},
{BRUSH_AUTOMASKING_BOUNDARY_EDGES,
"use_automasking_boundary_edges",
0,
"Mesh Boundary Auto-Masking",
"Do not affect non manifold boundary edges"},
{BRUSH_AUTOMASKING_BOUNDARY_FACE_SETS,
"use_automasking_boundary_face_sets",
0,
"Face Sets Boundary Automasking",
"Do not affect vertices that belong to a Face Set boundary"},
{BRUSH_AUTOMASKING_CAVITY_NORMAL,
"use_automasking_cavity",
0,
"Cavity Mask",
"Do not affect vertices on peaks, based on the surface curvature"},
{BRUSH_AUTOMASKING_CAVITY_INVERTED,
"use_automasking_cavity_inverted",
0,
"Inverted Cavity Mask",
"Do not affect vertices within crevices, based on the surface curvature"},
{BRUSH_AUTOMASKING_CAVITY_USE_CURVE,
"use_automasking_custom_cavity_curve",
0,
"Custom Cavity Curve",
"Use custom curve"},
{0, NULL, 0, NULL, NULL}};
const EnumPropertyItem rna_enum_brush_sculpt_tool_items[] = {
{SCULPT_TOOL_DRAW, "DRAW", ICON_BRUSH_SCULPT_DRAW, "Draw", ""},
@ -120,7 +146,11 @@ const EnumPropertyItem rna_enum_brush_sculpt_tool_items[] = {
{SCULPT_TOOL_FLATTEN, "FLATTEN", ICON_BRUSH_FLATTEN, "Flatten", ""},
{SCULPT_TOOL_FILL, "FILL", ICON_BRUSH_FILL, "Fill", ""},
{SCULPT_TOOL_SCRAPE, "SCRAPE", ICON_BRUSH_SCRAPE, "Scrape", ""},
{SCULPT_TOOL_MULTIPLANE_SCRAPE, "MULTIPLANE_SCRAPE", ICON_BRUSH_SCRAPE, "Multi-plane Scrape", ""},
{SCULPT_TOOL_MULTIPLANE_SCRAPE,
"MULTIPLANE_SCRAPE",
ICON_BRUSH_SCRAPE,
"Multi-plane Scrape",
""},
{SCULPT_TOOL_PINCH, "PINCH", ICON_BRUSH_PINCH, "Pinch", ""},
RNA_ENUM_ITEM_SEPR,
{SCULPT_TOOL_GRAB, "GRAB", ICON_BRUSH_GRAB, "Grab", ""},
@ -137,13 +167,20 @@ const EnumPropertyItem rna_enum_brush_sculpt_tool_items[] = {
{SCULPT_TOOL_SIMPLIFY, "SIMPLIFY", ICON_BRUSH_DATA, "Simplify", ""},
{SCULPT_TOOL_MASK, "MASK", ICON_BRUSH_MASK, "Mask", ""},
{SCULPT_TOOL_DRAW_FACE_SETS, "DRAW_FACE_SETS", ICON_BRUSH_MASK, "Draw Face Sets", ""},
{SCULPT_TOOL_DISPLACEMENT_ERASER, "DISPLACEMENT_ERASER", ICON_BRUSH_SCULPT_DRAW, "Multires Displacement Eraser", ""},
{SCULPT_TOOL_DISPLACEMENT_SMEAR, "DISPLACEMENT_SMEAR", ICON_BRUSH_SCULPT_DRAW, "Multires Displacement Smear", ""},
{SCULPT_TOOL_DISPLACEMENT_ERASER,
"DISPLACEMENT_ERASER",
ICON_BRUSH_SCULPT_DRAW,
"Multires Displacement Eraser",
""},
{SCULPT_TOOL_DISPLACEMENT_SMEAR,
"DISPLACEMENT_SMEAR",
ICON_BRUSH_SCULPT_DRAW,
"Multires Displacement Smear",
""},
{SCULPT_TOOL_PAINT, "PAINT", ICON_BRUSH_SCULPT_DRAW, "Paint", ""},
{SCULPT_TOOL_SMEAR, "SMEAR", ICON_BRUSH_SCULPT_DRAW, "Smear", ""},
{0, NULL, 0, NULL, NULL},
};
/* clang-format on */
const EnumPropertyItem rna_enum_brush_uv_sculpt_tool_items[] = {
{UV_SCULPT_TOOL_GRAB, "GRAB", 0, "Grab", "Grab UVs"},
@ -260,24 +297,30 @@ const EnumPropertyItem rna_enum_brush_gpencil_weight_types_items[] = {
{0, NULL, 0, NULL, NULL},
};
/* clang-format off */
const EnumPropertyItem rna_enum_brush_curves_sculpt_tool_items[] = {
{CURVES_SCULPT_TOOL_SELECTION_PAINT, "SELECTION_PAINT", ICON_BRUSH_PAINT_SELECT, "Paint Selection", ""},
{CURVES_SCULPT_TOOL_SELECTION_PAINT,
"SELECTION_PAINT",
ICON_BRUSH_PAINT_SELECT,
"Paint Selection",
""},
RNA_ENUM_ITEM_SEPR,
{CURVES_SCULPT_TOOL_ADD, "ADD", ICON_BRUSH_CURVES_ADD, "Add Curves", ""},
{CURVES_SCULPT_TOOL_DELETE, "DELETE", ICON_BRUSH_CURVES_DELETE, "Delete Curves", ""},
{CURVES_SCULPT_TOOL_DENSITY, "DENSITY", ICON_BRUSH_CURVES_DENSITY, "Density Curves", ""},
{CURVES_SCULPT_TOOL_ADD, "ADD", ICON_BRUSH_CURVES_ADD, "Add", ""},
{CURVES_SCULPT_TOOL_DELETE, "DELETE", ICON_BRUSH_CURVES_DELETE, "Delete", ""},
{CURVES_SCULPT_TOOL_DENSITY, "DENSITY", ICON_BRUSH_CURVES_DENSITY, "Density", ""},
RNA_ENUM_ITEM_SEPR,
{CURVES_SCULPT_TOOL_COMB, "COMB", ICON_BRUSH_CURVES_COMB, "Comb Curves", ""},
{CURVES_SCULPT_TOOL_SNAKE_HOOK, "SNAKE_HOOK", ICON_BRUSH_CURVES_SNAKE_HOOK, "Curves Snake Hook", ""},
{CURVES_SCULPT_TOOL_GROW_SHRINK, "GROW_SHRINK", ICON_BRUSH_CURVES_GROW_SHRINK, "Grow / Shrink Curves", ""},
{CURVES_SCULPT_TOOL_PINCH, "PINCH", ICON_BRUSH_CURVES_PINCH, "Pinch Curves", ""},
{CURVES_SCULPT_TOOL_PUFF, "PUFF", ICON_BRUSH_CURVES_PUFF, "Puff Curves", ""},
{CURVES_SCULPT_TOOL_SMOOTH, "SMOOTH", ICON_BRUSH_CURVES_SMOOTH, "Smooth Curves", ""},
{CURVES_SCULPT_TOOL_SLIDE, "SLIDE", ICON_BRUSH_CURVES_SLIDE, "Slide Curves", ""},
{CURVES_SCULPT_TOOL_COMB, "COMB", ICON_BRUSH_CURVES_COMB, "Comb", ""},
{CURVES_SCULPT_TOOL_SNAKE_HOOK, "SNAKE_HOOK", ICON_BRUSH_CURVES_SNAKE_HOOK, "Snake Hook", ""},
{CURVES_SCULPT_TOOL_GROW_SHRINK,
"GROW_SHRINK",
ICON_BRUSH_CURVES_GROW_SHRINK,
"Grow / Shrink",
""},
{CURVES_SCULPT_TOOL_PINCH, "PINCH", ICON_BRUSH_CURVES_PINCH, "Pinch", ""},
{CURVES_SCULPT_TOOL_PUFF, "PUFF", ICON_BRUSH_CURVES_PUFF, "Puff", ""},
{CURVES_SCULPT_TOOL_SMOOTH, "SMOOTH", ICON_BRUSH_CURVES_SMOOTH, "Smooth", ""},
{CURVES_SCULPT_TOOL_SLIDE, "SLIDE", ICON_BRUSH_CURVES_SLIDE, "Slide", ""},
{0, NULL, 0, NULL, NULL},
};
/* clang-format on */
#ifndef RNA_RUNTIME
static EnumPropertyItem rna_enum_gpencil_brush_eraser_modes_items[] = {

View File

@ -1134,7 +1134,10 @@ static void rna_def_pose_channel(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "chan_mat");
RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Channel Matrix", "4x4 matrix, before constraints");
RNA_def_property_ui_text(prop,
"Channel Matrix",
"4x4 matrix of the bone's location/rotation/scale channels (including "
"animation and drivers) and the effect of bone constraints");
/* writable because it touches loc/scale/rot directly */
prop = RNA_def_property(srna, "matrix_basis", PROP_FLOAT, PROP_MATRIX);
@ -1156,7 +1159,7 @@ static void rna_def_pose_channel(BlenderRNA *brna)
RNA_def_property_ui_text(
prop,
"Pose Matrix",
"Final 4x4 matrix after constraints and drivers are applied (object space)");
"Final 4x4 matrix after constraints and drivers are applied, in the armature object space");
RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update");
/* Head/Tail Coordinates (in Pose Space) - Automatically calculated... */

View File

@ -21,8 +21,6 @@
namespace blender::nodes::node_geo_delete_geometry_cc {
using blender::bke::CustomDataAttributes;
template<typename T>
static void copy_data_based_on_map(const Span<T> src,
const Span<int> index_map,

View File

@ -37,11 +37,9 @@ class HandlePositionFieldInput final : public bke::CurvesFieldInput {
evaluator.evaluate();
const VArray<bool> relative = evaluator.get_evaluated<bool>(0);
const Span<float3> positions = curves.positions();
const AttributeAccessor attributes = curves.attributes();
VArray<float3> positions = attributes.lookup_or_default<float3>(
"position", ATTR_DOMAIN_POINT, {0, 0, 0});
StringRef side = left_ ? "handle_left" : "handle_right";
VArray<float3> handles = attributes.lookup_or_default<float3>(
side, ATTR_DOMAIN_POINT, {0, 0, 0});

View File

@ -2371,6 +2371,13 @@ static PyObject *pyrna_prop_collection_subscript_str(BPy_PropertyRNA *self, cons
RNA_property_collection_begin(&self->ptr, self->prop, &iter);
for (int i = 0; iter.valid; RNA_property_collection_next(&iter), i++) {
PropertyRNA *nameprop = RNA_struct_name_property(iter.ptr.type);
BLI_assert_msg(
nameprop,
"Attempted to use a string to index into a collection of items with no 'nameproperty'.");
if (nameprop == NULL) {
/* For non-debug builds, bail if there's no 'nameproperty' to check. */
break;
}
char *nameptr = RNA_property_string_get_alloc(
&iter.ptr, nameprop, name, sizeof(name), &namelen);
if ((keylen == namelen) && STREQ(nameptr, keyname)) {

View File

@ -113,6 +113,15 @@ void WM_exit(struct bContext *C) ATTR_NORETURN;
void WM_main(struct bContext *C) ATTR_NORETURN;
/**
* Show the splash screen as needed on startup.
*
* The splash may not show depending on a file being loaded and user preferences.
*/
void WM_init_splash_on_startup(struct bContext *C);
/**
* Show the splash screen.
*/
void WM_init_splash(struct bContext *C);
void WM_init_opengl(void);

View File

@ -25,6 +25,7 @@
#include "DNA_userdef_types.h"
#include "DNA_windowmanager_types.h"
#include "BLI_fileops.h"
#include "BLI_listbase.h"
#include "BLI_path_util.h"
#include "BLI_string.h"
@ -358,18 +359,59 @@ void WM_init(bContext *C, int argc, const char **argv)
wm_homefile_read_post(C, params_file_read_post);
}
void WM_init_splash(bContext *C)
static bool wm_init_splash_show_on_startup_check()
{
if ((U.uiflag & USER_SPLASH_DISABLE) == 0) {
wmWindowManager *wm = CTX_wm_manager(C);
wmWindow *prevwin = CTX_wm_window(C);
if (U.uiflag & USER_SPLASH_DISABLE) {
return false;
}
if (wm->windows.first) {
CTX_wm_window_set(C, static_cast<wmWindow *>(wm->windows.first));
WM_operator_name_call(C, "WM_OT_splash", WM_OP_INVOKE_DEFAULT, nullptr, nullptr);
CTX_wm_window_set(C, prevwin);
bool use_splash = false;
const char *blendfile_path = BKE_main_blendfile_path_from_global();
if (blendfile_path[0] == '\0') {
/* Common case, no file is loaded, show the splash. */
use_splash = true;
}
else {
/* A less common case, if there is no user preferences, show the splash screen
* so the user has the opportunity to restore settings from a previous version. */
const char *const cfgdir = BKE_appdir_folder_id(BLENDER_USER_CONFIG, NULL);
if (cfgdir) {
char userpref[FILE_MAX];
BLI_path_join(userpref, sizeof(userpref), cfgdir, BLENDER_USERPREF_FILE);
if (!BLI_exists(userpref)) {
use_splash = true;
}
}
else {
use_splash = true;
}
}
return use_splash;
}
void WM_init_splash_on_startup(bContext *C)
{
if (!wm_init_splash_show_on_startup_check()) {
return;
}
WM_init_splash(C);
}
void WM_init_splash(bContext *C)
{
wmWindowManager *wm = CTX_wm_manager(C);
/* NOTE(@ideasman42): this should practically never happen. */
if (UNLIKELY(BLI_listbase_is_empty(&wm->windows))) {
return;
}
wmWindow *prevwin = CTX_wm_window(C);
CTX_wm_window_set(C, static_cast<wmWindow *>(wm->windows.first));
WM_operator_name_call(C, "WM_OT_splash", WM_OP_INVOKE_DEFAULT, nullptr, nullptr);
CTX_wm_window_set(C, prevwin);
}
/* free strings of open recent files */

View File

@ -723,7 +723,7 @@ static const char *toolsystem_default_tool(const bToolKey *tkey)
case CTX_MODE_VERTEX_GPENCIL:
return "builtin_brush.Draw";
case CTX_MODE_SCULPT_CURVES:
return "builtin_brush.density";
return "builtin_brush.Density";
/* end temporary hack. */
case CTX_MODE_PARTICLE:

View File

@ -24,8 +24,6 @@
#include "DNA_genfile.h"
#include "BLI_fileops.h"
#include "BLI_path_util.h"
#include "BLI_string.h"
#include "BLI_system.h"
#include "BLI_task.h"
@ -579,18 +577,9 @@ int main(int argc,
WM_exit(C);
}
else {
/* When no file is loaded or if there is no userprefs, show the splash screen. */
const char *blendfile_path = BKE_main_blendfile_path_from_global();
/* Shows the splash as needed. */
WM_init_splash_on_startup(C);
char userpref[FILE_MAX] = {0};
const char *const cfgdir = BKE_appdir_folder_id(BLENDER_USER_CONFIG, NULL);
if (cfgdir) {
BLI_path_join(userpref, sizeof(userpref), cfgdir, BLENDER_USERPREF_FILE);
}
if (blendfile_path[0] == '\0' || !BLI_exists(userpref)) {
WM_init_splash(C);
}
WM_main(C);
}
/* Neither #WM_exit, #WM_main return, this quiets CLANG's `unreachable-code-return` warning. */

View File

@ -32,6 +32,7 @@ class ImBufTest(AbstractImBufTest):
colorspace = img.colorspace_settings.name
alpha_mode = img.alpha_mode
actual_metadata = f"{channels=} {is_float=} {colorspace=} {alpha_mode=}"
expected_metadata = ""
# Save actual metadata
out_metadata_path.write_text(actual_metadata, encoding="utf-8")
@ -52,10 +53,14 @@ class ImBufTest(AbstractImBufTest):
failed = True
if failed and self.update:
# Update reference if requested.
ref_metadata_path.write_text(actual_metadata, encoding="utf-8")
failed = False
if failed:
if self.update:
# Update reference if requested.
ref_metadata_path.write_text(actual_metadata, encoding="utf-8")
failed = False
else:
print_message(
"Expected [{}] but got [{}]".format(expected_metadata, actual_metadata))
return not failed

View File

@ -73,12 +73,14 @@ class AbstractImBufTest(unittest.TestCase):
shutil.copy(out_filepath, ref_filepath)
failed = False
# Generate diff image.
# Generate diff image (set fail thresholds high to reduce output spam).
diff_img = str(self.diff_dir.joinpath(out_name + ".diff.png"))
command = (
str(self.idiff),
"-o", diff_img,
"-fail", "1",
"-failpercent", "100",
"-abs", "-scale", "16",
"-o", diff_img,
ref_filepath,
out_filepath
)