Animation: Add in Parent space alignment option to the Transform Orientation gizmo #104724
|
@ -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()
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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", ""),
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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__ = ()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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"),
|
||||
|
|
|
@ -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'}
|
||||
|
|
|
@ -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'}
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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'}
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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'}
|
||||
|
|
|
@ -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'}
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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_)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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});
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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_);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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()));
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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])});
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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,
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)});
|
||||
|
|
|
@ -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,
|
||||
{
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -99,6 +99,7 @@
|
|||
\
|
||||
.mtex = _DNA_DEFAULT_MTex, \
|
||||
.mask_mtex = _DNA_DEFAULT_MTex, \
|
||||
.falloff_shape = 0,\
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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[] = {
|
||||
|
|
|
@ -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... */
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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});
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue