WIP: Brush assets project #106303
|
@ -9,13 +9,13 @@ body:
|
|||
attributes:
|
||||
value: |
|
||||
### Instructions
|
||||
First time reporting? See [tips](https://wiki.blender.org/wiki/Process/Bug_Reports).
|
||||
First time reporting? See [tips](https://developer.blender.org/docs/handbook/bug_reports/making_good_bug_reports/).
|
||||
|
||||
* Use **Help > Report a Bug** in Blender to fill system information and exact Blender version.
|
||||
* Test [daily builds](https://builder.blender.org/) to verify if the issue is already fixed.
|
||||
* Test [previous versions](https://download.blender.org/release/) to find an older working version.
|
||||
* For feature requests, feedback, questions or build issues, see [communication channels](https://wiki.blender.org/wiki/Communication/Contact#User_Feedback_and_Requests).
|
||||
* Security vulnerabilities should be [reported privately](https://wiki.blender.org/wiki/Process/Vulnerability_Reports).
|
||||
* For feature requests, feedback, questions or build issues, see [communication channels](https://developer.blender.org/docs/handbook/communication/user_feedback/).
|
||||
* Security vulnerabilities should be [reported privately](https://developer.blender.org/docs/handbook/bug_reports/vulnerability_reports/).
|
||||
* If there are multiple bugs, make multiple bug reports.
|
||||
|
||||
- type: textarea
|
||||
|
|
|
@ -6,7 +6,7 @@ body:
|
|||
value: |
|
||||
### Instructions
|
||||
|
||||
Guides to [contributing code](https://wiki.blender.org/index.php/Dev:Doc/Process/Contributing_Code) and effective [code review](https://wiki.blender.org/index.php/Dev:Doc/Tools/Code_Review).
|
||||
Guides to [contributing code](https://developer.blender.org/docs/handbook/contributing/) and effective [code review](https://developer.blender.org/docs/handbook/contributing/pull_requests/).
|
||||
|
||||
By submitting code here, you agree that the code is (compatible with) GNU GPL v2 or later.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
This repository is only used as a mirror. Blender development happens on projects.blender.org.
|
||||
|
||||
To get started with contributing code, please see:
|
||||
https://wiki.blender.org/wiki/Process/Contributing_Code
|
||||
https://developer.blender.org/docs/handbook/contributing/
|
||||
|
|
|
@ -18,4 +18,4 @@ closeComment: >
|
|||
used as a mirror. Blender development happens on projects.blender.org.
|
||||
|
||||
To get started contributing code, please read:
|
||||
https://wiki.blender.org/wiki/Process/Contributing_Code
|
||||
https://developer.blender.org/docs/handbook/contributing/
|
||||
|
|
|
@ -110,7 +110,7 @@ enable_testing()
|
|||
# -----------------------------------------------------------------------------
|
||||
# Test Compiler Support
|
||||
#
|
||||
# Keep in sync with: https://wiki.blender.org/wiki/Building_Blender
|
||||
# Keep in sync with: https://developer.blender.org/docs/handbook/building_blender/
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCC)
|
||||
if("${CMAKE_C_COMPILER_VERSION}" VERSION_LESS "11.0.0")
|
||||
|
|
|
@ -76,7 +76,7 @@ Documentation Checking
|
|||
* check_wiki_file_structure:
|
||||
Check the WIKI documentation for the source-tree's file structure
|
||||
matches Blender's source-code.
|
||||
See: https://wiki.blender.org/wiki/Source/File_Structure
|
||||
See: https://developer.blender.org/docs/features/code_layout/
|
||||
|
||||
Spell Checkers
|
||||
This runs the spell checker from the developer tools repositor.
|
||||
|
|
|
@ -23,10 +23,10 @@ Project Pages
|
|||
Development
|
||||
-----------
|
||||
|
||||
- [Build Instructions](https://wiki.blender.org/wiki/Building_Blender)
|
||||
- [Build Instructions](https://developer.blender.org/docs/handbook/building_blender/)
|
||||
- [Code Review & Bug Tracker](https://projects.blender.org)
|
||||
- [Developer Forum](https://devtalk.blender.org)
|
||||
- [Developer Documentation](https://wiki.blender.org)
|
||||
- [Developer Documentation](https://developer.blender.org/docs/)
|
||||
|
||||
|
||||
License
|
||||
|
|
|
@ -1714,7 +1714,7 @@ def argparse_create():
|
|||
"NOTE: To build with system package libraries instead of the precompiled ones when both are available,\n"
|
||||
"the `WITH_LIBS_PRECOMPILED` option must be disabled in CMake.\n"
|
||||
"\n"
|
||||
"See https://wiki.blender.org/wiki/Building_Blender for more details.\n"
|
||||
"See https://developer.blender.org/docs/handbook/building_blender/ for more details.\n"
|
||||
"\n"
|
||||
)
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
# This script is part of the official build environment, see wiki page for details.
|
||||
# https://wiki.blender.org/wiki/Building_Blender/Other/Rocky8ReleaseEnvironment
|
||||
# https://developer.blender.org/docs/handbook/release_process/build/rocky_8/
|
||||
|
||||
set -e
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
# assumes you have dependencies installed already
|
||||
|
||||
# See this page for more info:
|
||||
# https://wiki.blender.org/wiki/Building_Blender/Linux/Generic_Distro/CMake
|
||||
# https://developer.blender.org/docs/handbook/building_blender/linux/
|
||||
|
||||
# grab blender
|
||||
mkdir ~/blender-git
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
*
|
||||
* \subsection implinks Important Links
|
||||
* - <a href="https://developer.blender.org">developer.blender.org</a> with bug tracker.
|
||||
* - <a href="https://wiki.blender.org">Development documents</a> on our wiki.
|
||||
* - <a href="https://developer.blender.org/docs/">Development documentation</a>.
|
||||
*
|
||||
* \subsection blother Other
|
||||
* For more information on using Blender browse to https://www.blender.org
|
||||
|
|
|
@ -23,8 +23,8 @@ Then, call ``bpy.app.translations.register(__name__, your_dict)`` in your ``regi
|
|||
The ``Manage UI translations`` add-on has several functions to help you collect strings to translate, and
|
||||
generate the needed python code (the translation dictionary), as well as optional intermediary po files
|
||||
if you want some... See
|
||||
`How to Translate Blender <https://wiki.blender.org/wiki/Process/Translate_Blender>`_ and
|
||||
`Using i18n in Blender Code <https://wiki.blender.org/wiki/Source/Interface/Internationalization>`_
|
||||
`How to Translate Blender <https://developer.blender.org/docs/handbook/translating/translator_guide/>`_ and
|
||||
`Using i18n in Blender Code <https://developer.blender.org/docs/handbook/translating/developer_guide/>`_
|
||||
for more info.
|
||||
|
||||
Module References
|
||||
|
@ -35,7 +35,7 @@ Module References
|
|||
import bpy
|
||||
|
||||
# This block can be automatically generated by UI translations addon, which also handles conversion with PO format.
|
||||
# See also https://wiki.blender.org/wiki/Process/Translate_Blender#Translating_non-official_addons
|
||||
# See also https://developer.blender.org/docs/handbook/translating/translator_guide/#translating-non-official-add-ons
|
||||
# It can (should) also be put in a different, specific py file.
|
||||
|
||||
# ##### BEGIN AUTOGENERATED I18N SECTION #####
|
||||
|
|
|
@ -14,7 +14,7 @@ The features exposed closely follow the C API,
|
|||
giving Python access to the functions used by Blender's own mesh editing tools.
|
||||
|
||||
For an overview of BMesh data types and how they reference each other see:
|
||||
`BMesh Design Document <https://wiki.blender.org/index.php/Dev:Source/Modeling/BMesh/Design>`__.
|
||||
`BMesh Design Document <https://developer.blender.org/docs/features/objects/mesh/bmesh/>`__.
|
||||
|
||||
|
||||
.. note::
|
||||
|
|
|
@ -13,7 +13,7 @@ allowing ``import bpy`` to be added to any Python script, providing access to Bl
|
|||
- A pre-compiled ``bpy`` module is
|
||||
`available via PIP <https://pypi.org/project/bpy/>`__.
|
||||
- Or you may compile this yourself using the
|
||||
`build instructions <https://wiki.blender.org/w/index.php?title=Building_Blender/Other/BlenderAsPyModule>`__.
|
||||
`build instructions <https://developer.blender.org/docs/handbook/building_blender/python_module/>`__.
|
||||
|
||||
|
||||
Use Cases
|
||||
|
|
|
@ -91,7 +91,7 @@ They are only loaded on startup if selected from the user preferences.
|
|||
The only difference between add-ons and built-in Python modules is that add-ons must contain a ``bl_info`` variable
|
||||
which Blender uses to read metadata such as name, author, category and project link.
|
||||
The User Preferences add-on listing uses ``bl_info`` to display information about each add-on.
|
||||
`See Add-ons <https://wiki.blender.org/index.php/Dev:Py/Scripts/Guidelines/Addons>`__
|
||||
`See Add-ons <https://developer.blender.org/docs/handbook/addons/guidelines/>`__
|
||||
for details on the ``bl_info`` dictionary.
|
||||
|
||||
|
||||
|
|
|
@ -295,7 +295,7 @@ Advantages include:
|
|||
|
||||
This is marked advanced because to run Blender as a Python module requires a special build option.
|
||||
For instructions on building see
|
||||
`Building Blender as a Python module <https://wiki.blender.org/wiki/Building_Blender/Other/BlenderAsPyModule>`__.
|
||||
`Building Blender as a Python module <https://developer.blender.org/docs/handbook/building_blender/python_module/>`__.
|
||||
|
||||
|
||||
Python Safety (Build Option)
|
||||
|
|
|
@ -302,8 +302,8 @@ bool GHOST_NDOFManager::setDevice(ushort vendor_id, ushort product_id)
|
|||
break;
|
||||
case 0x256F: /* 3Dconnexion. */
|
||||
switch (product_id) {
|
||||
case 0xC62E: /* Plugged in. */
|
||||
case 0xC62F: /* Wireless. */
|
||||
case 0xC62E: /* SpaceMouse Wireless (cabled). */
|
||||
case 0xC62F: /* SpaceMouse Wireless Receiver. */
|
||||
case 0xC658: /* Wireless (3DConnexion Universal Wireless Receiver in WIN32), see #82412. */
|
||||
{
|
||||
device_type_ = NDOF_SpaceMouseWireless;
|
||||
|
@ -311,8 +311,11 @@ bool GHOST_NDOFManager::setDevice(ushort vendor_id, ushort product_id)
|
|||
hid_map_ = ndof_HID_map_Modern3Dx;
|
||||
break;
|
||||
}
|
||||
case 0xC631: /* Plugged in. */
|
||||
case 0xC632: /* Wireless. */
|
||||
case 0xC631: /* SpaceMouse Pro Wireless (cabled). */
|
||||
case 0xC632: /* SpaceMouse Pro Wireless Receiver. */
|
||||
case 0xC638: /* SpaceMouse Pro Wireless BT (cabled), see #116393.
|
||||
* 3Dconnexion docs describe this as "Wireless BT", but it is cabled. */
|
||||
case 0xC652: /* Universal Receiver. */
|
||||
{
|
||||
device_type_ = NDOF_SpaceMouseProWireless;
|
||||
hid_map_button_num_ = 27; /* 15 physical buttons, but HID codes range from 0 to 26. */
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
<url type="faq">https://www.blender.org/support/faq/</url>
|
||||
<url type="help">https://www.blender.org/support/</url>
|
||||
<url type="donation">https://fund.blender.org/</url>
|
||||
<url type="translate">https://wiki.blender.org/wiki/Process/Translate_Blender</url>
|
||||
<url type="translate">https://developer.blender.org/docs/handbook/translating/translator_guide/</url>
|
||||
<url type="vcs-browser">https://projects.blender.org/blender/blender</url>
|
||||
<url type="contribute">https://www.blender.org/get-involved/</url>
|
||||
<screenshots>
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
<p class="p4">
|
||||
The Blender Foundation and online developer community is proud to present Blender
|
||||
@BLENDER_VERSION@.
|
||||
<a href="https://wiki.blender.org/wiki/Reference/Release_Notes/@BLENDER_VERSION@">
|
||||
<a href="https://developer.blender.org/docs/release_notes/@BLENDER_VERSION@">
|
||||
<span class="s1">More information about this release</span>
|
||||
</a>.
|
||||
</p>
|
||||
|
@ -95,8 +95,8 @@
|
|||
<span class="s4">www.blender.org</span>
|
||||
</a><br>
|
||||
Release Notes
|
||||
<a href="https://wiki.blender.org/wiki/Reference/Release_Notes/@BLENDER_VERSION@">
|
||||
<span class="s4">wiki.blender.org/wiki/Reference/Release_Notes/@BLENDER_VERSION@</span>
|
||||
<a href="https://developer.blender.org/docs/release_notes/@BLENDER_VERSION@">
|
||||
<span class="s4">https://developer.blender.org/docs/release_notes/@BLENDER_VERSION@</span>
|
||||
</a><br>
|
||||
Tutorials
|
||||
<a href="https://www.blender.org/support/tutorials/">
|
||||
|
|
|
@ -612,7 +612,10 @@ class _ext_global:
|
|||
|
||||
# Store a map of `preferences.filepaths.extension_repos` -> `module_id`.
|
||||
# Only needed to detect renaming between `bpy.app.handlers.extension_repos_update_{pre & post}` events.
|
||||
idmap = {}
|
||||
#
|
||||
# The first dictionary is for enabled repositories, the second for disabled repositories
|
||||
# which can be ignored in most cases and is only needed for a module rename.
|
||||
idmap_pair = {}, {}
|
||||
|
||||
# The base package created by `JunctionModuleHandle`.
|
||||
module_handle = None
|
||||
|
@ -624,12 +627,14 @@ _ext_base_pkg_idname = "bl_ext"
|
|||
|
||||
def _extension_preferences_idmap():
|
||||
repos_idmap = {}
|
||||
repos_idmap_disabled = {}
|
||||
if _preferences.experimental.use_extension_repos:
|
||||
for repo in _preferences.filepaths.extension_repos:
|
||||
if not repo.enabled:
|
||||
continue
|
||||
repos_idmap[repo.as_pointer()] = repo.module
|
||||
return repos_idmap
|
||||
if repo.enabled:
|
||||
repos_idmap[repo.as_pointer()] = repo.module
|
||||
else:
|
||||
repos_idmap_disabled[repo.as_pointer()] = repo.module
|
||||
return repos_idmap, repos_idmap_disabled
|
||||
|
||||
|
||||
def _extension_dirpath_from_preferences():
|
||||
|
@ -654,24 +659,161 @@ def _extension_dirpath_from_handle():
|
|||
repos_info[module_id] = dirpath
|
||||
return repos_info
|
||||
|
||||
|
||||
# Ensure the add-ons follow changes to repositories, enabling, disabling and module renaming.
|
||||
def _initialize_extension_repos_post_addons_prepare(
|
||||
module_handle,
|
||||
*,
|
||||
submodules_del,
|
||||
submodules_add,
|
||||
submodules_rename_module,
|
||||
submodules_del_disabled,
|
||||
submodules_rename_module_disabled,
|
||||
):
|
||||
addons_to_enable = []
|
||||
if not (
|
||||
submodules_del or
|
||||
submodules_add or
|
||||
submodules_rename_module or
|
||||
submodules_del_disabled or
|
||||
submodules_rename_module_disabled
|
||||
):
|
||||
return addons_to_enable
|
||||
|
||||
# All preferences info.
|
||||
# Map: `repo_id -> {submodule_id -> addon, ...}`.
|
||||
addon_userdef_info = {}
|
||||
module_prefix = _ext_base_pkg_idname + "."
|
||||
for addon in _preferences.addons:
|
||||
module = addon.module
|
||||
if not module.startswith(module_prefix):
|
||||
continue
|
||||
module_id, submodule_id = module[len(module_prefix):].partition(".")[0::2]
|
||||
try:
|
||||
addon_userdef_info[module_id][submodule_id] = addon
|
||||
except KeyError:
|
||||
addon_userdef_info[module_id] = {submodule_id: addon}
|
||||
|
||||
# All run-time info.
|
||||
# Map: `module_id -> {submodule_id -> module, ...}`.
|
||||
addon_runtime_info = {}
|
||||
for module_id, repo_module in module_handle.submodule_items():
|
||||
extensions_info = {}
|
||||
for submodule_id in dir(repo_module):
|
||||
if submodule_id.startswith("_"):
|
||||
continue
|
||||
mod = getattr(repo_module, submodule_id)
|
||||
# Filter out non add-on, non-modules.
|
||||
if not hasattr(mod, "__addon_enabled__"):
|
||||
continue
|
||||
extensions_info[submodule_id] = mod
|
||||
addon_runtime_info[module_id] = extensions_info
|
||||
del extensions_info
|
||||
|
||||
# Apply changes to add-ons.
|
||||
if submodules_add:
|
||||
# Re-enable add-ons that exist in the user preferences,
|
||||
# this lets the add-ons state be restored when toggling a repository.
|
||||
for module_id, _dirpath in submodules_add:
|
||||
repo_userdef = addon_userdef_info.get(module_id, {})
|
||||
repo_runtime = addon_runtime_info.get(module_id, {})
|
||||
|
||||
for submodule_id, addon in repo_userdef.items():
|
||||
module_name_next = "%s.%s.%s" % (_ext_base_pkg_idname, module_id, submodule_id)
|
||||
# Only default & persistent add-ons are kept for re-activation.
|
||||
default_set = True
|
||||
persistent = True
|
||||
addons_to_enable.append((module_name_next, addon, default_set, persistent))
|
||||
|
||||
for module_id_prev, module_id_next in submodules_rename_module:
|
||||
repo_userdef = addon_userdef_info.get(module_id_prev, {})
|
||||
repo_runtime = addon_runtime_info.get(module_id_prev, {})
|
||||
for submodule_id, mod in repo_runtime.items():
|
||||
if not getattr(mod, "__addon_enabled__", False):
|
||||
continue
|
||||
module_name_prev = "%s.%s.%s" % (_ext_base_pkg_idname, module_id_prev, submodule_id)
|
||||
module_name_next = "%s.%s.%s" % (_ext_base_pkg_idname, module_id_next, submodule_id)
|
||||
disable(module_name_prev, default_set=False)
|
||||
addon = repo_userdef.get(submodule_id)
|
||||
default_set = addon is not None
|
||||
persistent = getattr(mod, "__addon_persistent__", False)
|
||||
addons_to_enable.append((module_name_next, addon, default_set, persistent))
|
||||
|
||||
for module_id_prev, module_id_next in submodules_rename_module_disabled:
|
||||
repo_userdef = addon_userdef_info.get(module_id_prev, {})
|
||||
repo_runtime = addon_runtime_info.get(module_id_prev, {})
|
||||
for submodule_id, addon in repo_userdef.items():
|
||||
mod = repo_runtime.get(submodule_id)
|
||||
if mod is not None and getattr(mod, "__addon_enabled__", False):
|
||||
continue
|
||||
# Either there is no run-time data or the module wasn't enabled.
|
||||
# Rename the add-on without enabling it so the next time it's enabled it's preferences are kept.
|
||||
module_name_next = "%s.%s.%s" % (_ext_base_pkg_idname, module_id_next, submodule_id)
|
||||
addon.module = module_name_next
|
||||
|
||||
if submodules_del:
|
||||
repo_module_map = {repo.module: repo for repo in _preferences.filepaths.extension_repos}
|
||||
for module_id in submodules_del:
|
||||
repo_userdef = addon_userdef_info.get(module_id, {})
|
||||
repo_runtime = addon_runtime_info.get(module_id, {})
|
||||
|
||||
repo = repo_module_map.get(module_id)
|
||||
default_set = True
|
||||
if repo and not repo.enabled:
|
||||
# The repository exists but has been disabled, keep the add-on preferences
|
||||
# because the user may want to re-enable the repository temporarily.
|
||||
default_set = False
|
||||
|
||||
for submodule_id, mod in repo_runtime.items():
|
||||
module_name_prev = "%s.%s.%s" % (_ext_base_pkg_idname, module_id, submodule_id)
|
||||
disable(module_name_prev, default_set=default_set)
|
||||
del repo
|
||||
del repo_module_map
|
||||
|
||||
if submodules_del_disabled:
|
||||
for module_id_prev in submodules_del_disabled:
|
||||
repo_userdef = addon_userdef_info.get(module_id_prev, {})
|
||||
for submodule_id in repo_userdef.keys():
|
||||
module_name_prev = "%s.%s.%s" % (_ext_base_pkg_idname, module_id_prev, submodule_id)
|
||||
disable(module_name_prev, default_set=True)
|
||||
|
||||
return addons_to_enable
|
||||
|
||||
|
||||
# Enable add-ons after the modules have been manipulated.
|
||||
def _initialize_extension_repos_post_addons_restore(addons_to_enable):
|
||||
if not addons_to_enable:
|
||||
return
|
||||
|
||||
for (module_name_next, addon, default_set, persistent) in addons_to_enable:
|
||||
# Ensure the preferences are kept.
|
||||
if addon is not None:
|
||||
addon.module = module_name_next
|
||||
enable(module_name_next, default_set=default_set, persistent=persistent)
|
||||
# Needed for module rename.
|
||||
modules._is_first = True
|
||||
|
||||
|
||||
# Use `bpy.app.handlers.extension_repos_update_{pre/post}` to track changes to extension repositories
|
||||
# and sync the changes to the Python module.
|
||||
|
||||
|
||||
@_bpy.app.handlers.persistent
|
||||
def _initialize_extension_repos_pre(*_):
|
||||
_ext_global.idmap = _extension_preferences_idmap()
|
||||
_ext_global.idmap_pair = _extension_preferences_idmap()
|
||||
|
||||
|
||||
@_bpy.app.handlers.persistent
|
||||
def _initialize_extension_repos_post(*_):
|
||||
def _initialize_extension_repos_post(*_, is_first=False):
|
||||
do_addons = not is_first
|
||||
|
||||
# Map `module_id` -> `dirpath`.
|
||||
repos_info_prev = _extension_dirpath_from_handle()
|
||||
repos_info_next = _extension_dirpath_from_preferences()
|
||||
|
||||
# Map `repo.as_pointer()` -> `module_id`.
|
||||
repos_idmap_prev = _ext_global.idmap
|
||||
repos_idmap_next = _extension_preferences_idmap()
|
||||
repos_idmap_prev, repos_idmap_prev_disabled = _ext_global.idmap_pair
|
||||
repos_idmap_next, repos_idmap_next_disabled = _extension_preferences_idmap()
|
||||
|
||||
# Map `module_id` -> `repo.as_pointer()`.
|
||||
repos_idmap_next_reverse = {value: key for key, value in repos_idmap_next.items()}
|
||||
|
@ -690,10 +832,6 @@ def _initialize_extension_repos_post(*_):
|
|||
if module_id_prev not in repos_info_prev:
|
||||
del repos_idmap_prev[repo_id_prev]
|
||||
|
||||
# NOTE(@ideasman42): supporting renaming at all is something we might limit to extensions
|
||||
# which have no add-ons loaded as supporting renaming add-ons in-place seems error prone as the add-on
|
||||
# may define internal variables based on the full package path.
|
||||
|
||||
submodules_add = [] # List of module names to add: `(module_id, dirpath)`.
|
||||
submodules_del = [] # List of module names to remove: `module_id`.
|
||||
submodules_rename_module = [] # List of module names: `(module_id_src, module_id_dst)`.
|
||||
|
@ -732,7 +870,38 @@ def _initialize_extension_repos_post(*_):
|
|||
if (module_id not in repos_info_next) and (module_id not in renamed_prev):
|
||||
submodules_del.append(module_id)
|
||||
|
||||
# Apply changes to the `_ext_base_pkg_idname` named module so it matches extension data from the preferences.
|
||||
if do_addons:
|
||||
submodules_del_disabled = [] # A version of `submodules_del` for disabled repositories.
|
||||
submodules_rename_module_disabled = [] # A version of `submodules_rename_module` for disabled repositories.
|
||||
|
||||
# Detect deleted modules.
|
||||
for repo_id_prev, module_id_prev in repos_idmap_prev_disabled.items():
|
||||
if (
|
||||
(repo_id_prev not in repos_idmap_next_disabled) and
|
||||
(repo_id_prev not in repos_idmap_next)
|
||||
):
|
||||
submodules_del_disabled.append(module_id_prev)
|
||||
|
||||
# Detect rename of disabled modules.
|
||||
for repo_id_next, module_id_next in repos_idmap_next_disabled.items():
|
||||
module_id_prev = repos_idmap_prev_disabled.get(repo_id_next)
|
||||
if module_id_prev is None:
|
||||
continue
|
||||
# Detect rename.
|
||||
if module_id_next != module_id_prev:
|
||||
submodules_rename_module_disabled.append((module_id_prev, module_id_next))
|
||||
|
||||
addons_to_enable = _initialize_extension_repos_post_addons_prepare(
|
||||
_ext_global.module_handle,
|
||||
submodules_del=submodules_del,
|
||||
submodules_add=submodules_add,
|
||||
submodules_rename_module=submodules_rename_module,
|
||||
submodules_del_disabled=submodules_del_disabled,
|
||||
submodules_rename_module_disabled=submodules_rename_module_disabled,
|
||||
)
|
||||
del submodules_del_disabled, submodules_rename_module_disabled
|
||||
|
||||
# Apply changes to the `_ext_base_pkg_idname` named module so it matches extension data from the preferences.
|
||||
module_handle = _ext_global.module_handle
|
||||
for module_id in submodules_del:
|
||||
module_handle.unregister_submodule(module_id)
|
||||
|
@ -743,7 +912,11 @@ def _initialize_extension_repos_post(*_):
|
|||
for module_id, dirpath in submodules_rename_dirpath:
|
||||
module_handle.rename_directory(module_id, dirpath)
|
||||
|
||||
_ext_global.idmap.clear()
|
||||
_ext_global.idmap_pair[0].clear()
|
||||
_ext_global.idmap_pair[1].clear()
|
||||
|
||||
if do_addons:
|
||||
_initialize_extension_repos_post_addons_restore(addons_to_enable)
|
||||
|
||||
# Force refreshing if directory paths change.
|
||||
if submodules_del or submodules_add or submodules_rename_dirpath:
|
||||
|
@ -759,7 +932,7 @@ def _initialize_extensions_repos_once():
|
|||
# Setup repositories for the first time.
|
||||
# Intentionally don't call `_initialize_extension_repos_pre` as this is the first time,
|
||||
# the previous state is not useful to read.
|
||||
_initialize_extension_repos_post()
|
||||
_initialize_extension_repos_post(is_first=True)
|
||||
|
||||
# Internal handlers intended for Blender's own handling of repositories.
|
||||
_bpy.app.handlers._extension_repos_update_pre.append(_initialize_extension_repos_pre)
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
# XXX: This script is meant to be used from inside Blender!
|
||||
# You should not directly use this script, rather use update_msg.py!
|
||||
|
||||
import datetime
|
||||
import time
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
@ -1011,10 +1011,9 @@ def dump_addon_bl_info(msgs, reports, module, settings):
|
|||
def dump_messages(do_messages, do_checks, settings):
|
||||
bl_ver = "Blender " + bpy.app.version_string
|
||||
bl_hash = bpy.app.build_hash
|
||||
bl_date = datetime.datetime.strptime(bpy.app.build_date.decode() + "T" + bpy.app.build_time.decode(),
|
||||
"%Y-%m-%dT%H:%M:%S")
|
||||
pot = utils.I18nMessages.gen_empty_messages(settings.PARSER_TEMPLATE_ID, bl_ver, bl_hash, bl_date, bl_date.year,
|
||||
settings=settings)
|
||||
bl_time = time.strptime(f"{bpy.app.build_date.decode()} {bpy.app.build_time.decode()} UTC", "%Y-%m-%d %H:%M:%S %Z")
|
||||
pot = utils.I18nMessages.gen_empty_messages(
|
||||
settings.PARSER_TEMPLATE_ID, bl_ver, bl_hash, bl_time, settings=settings)
|
||||
msgs = pot.msgs
|
||||
|
||||
# Enable all wanted addons.
|
||||
|
@ -1113,13 +1112,12 @@ def dump_addon_messages(module_name, do_checks, settings):
|
|||
addon_info = addon_utils.module_bl_info(addon)
|
||||
ver = addon_info["name"] + " " + ".".join(str(v) for v in addon_info["version"])
|
||||
rev = 0
|
||||
date = datetime.datetime.now()
|
||||
pot = utils.I18nMessages.gen_empty_messages(settings.PARSER_TEMPLATE_ID, ver, rev, date, date.year,
|
||||
settings=settings)
|
||||
curr_time = time.gmtime()
|
||||
pot = utils.I18nMessages.gen_empty_messages(settings.PARSER_TEMPLATE_ID, ver, rev, curr_time, settings=settings)
|
||||
msgs = pot.msgs
|
||||
|
||||
minus_pot = utils.I18nMessages.gen_empty_messages(settings.PARSER_TEMPLATE_ID, ver, rev, date, date.year,
|
||||
settings=settings)
|
||||
minus_pot = utils.I18nMessages.gen_empty_messages(
|
||||
settings.PARSER_TEMPLATE_ID, ver, rev, curr_time, settings=settings)
|
||||
minus_msgs = minus_pot.msgs
|
||||
|
||||
check_ctxt = _gen_check_ctxt(settings) if do_checks else None
|
||||
|
|
|
@ -9,7 +9,7 @@ import os
|
|||
import re
|
||||
import struct
|
||||
import tempfile
|
||||
# import time
|
||||
import time
|
||||
|
||||
from bl_i18n_utils import (
|
||||
settings,
|
||||
|
@ -478,13 +478,17 @@ class I18nMessages:
|
|||
return getattr(collections, "OrderedDict", dict)()
|
||||
|
||||
@classmethod
|
||||
def gen_empty_messages(cls, uid, blender_ver, blender_hash, time, year, default_copyright=True, settings=settings):
|
||||
def gen_empty_messages(cls, uid, blender_ver, blender_hash, bl_time, default_copyright=True, settings=settings):
|
||||
"""Generate an empty I18nMessages object (only header is present!)."""
|
||||
fmt = settings.PO_HEADER_MSGSTR
|
||||
msgstr = fmt.format(blender_ver=str(blender_ver), blender_hash=blender_hash, time=str(time), uid=str(uid))
|
||||
msgstr = fmt.format(
|
||||
blender_ver=str(blender_ver),
|
||||
blender_hash=blender_hash,
|
||||
time=time.strftime("%Y-%m-%d %H:%M%z", bl_time),
|
||||
uid=str(uid))
|
||||
comment = ""
|
||||
if default_copyright:
|
||||
comment = settings.PO_HEADER_COMMENT_COPYRIGHT.format(year=str(year))
|
||||
comment = settings.PO_HEADER_COMMENT_COPYRIGHT.format(year=str(time.gmtime().tm_year))
|
||||
comment = comment + settings.PO_HEADER_COMMENT
|
||||
|
||||
msgs = cls(uid=uid, settings=settings)
|
||||
|
|
|
@ -425,8 +425,8 @@ def do_previews(do_objects, do_collections, do_scenes, do_data_intern):
|
|||
try:
|
||||
bpy.ops.wm.save_mainfile()
|
||||
except BaseException as ex:
|
||||
# Might fail in some odd cases, like e.g. in regression files we have glsl/ram_glsl.blend which
|
||||
# references an inexistent texture... Better not break in this case, just spit error to console.
|
||||
# Might fail in some odd cases, like e.g. in regression files we have `glsl/ram_glsl.blend` which
|
||||
# references an nonexistent texture. Better not break in this case, just spit error to console.
|
||||
print("ERROR:", ex)
|
||||
else:
|
||||
print("*NOT* Saving %s, because some error(s) happened while deleting temp render data..." % bpy.data.filepath)
|
||||
|
|
|
@ -124,6 +124,27 @@ class JunctionModuleHandle:
|
|||
delattr(self._module, submodule_name)
|
||||
del sys.modules[name_full]
|
||||
|
||||
# Remove all sub-modules, to prevent them being reused in the future.
|
||||
#
|
||||
# While it might not seem like a problem to keep these around it means if a module
|
||||
# with the same name is registered later, importing sub-modules uses the cached values
|
||||
# from `sys.modules` and does *not* assign the module to the name-space of the new `submodule`.
|
||||
# This isn't exactly a bug, it's often assumed that inspecting a module
|
||||
# is a way to find its sub-modules, using `dir(submodule)` for example.
|
||||
# For more technical example `sys.modules["foo.bar"] == sys.modules["foo"].bar`
|
||||
# which can fail with and attribute error unless the modules are cleared here.
|
||||
#
|
||||
# An alternative solution could be re-attach sub-modules to the modules name-space when its re-registered.
|
||||
# This has some advantages since the module doesn't have to be re-imported however it has the down
|
||||
# side that stale data would be kept in `sys.modules` unnecessarily in many cases.
|
||||
name_full_prefix = name_full + "."
|
||||
submodule_name_list = [
|
||||
submodule_name for submodule_name in sys.modules.keys()
|
||||
if submodule_name.startswith(name_full_prefix)
|
||||
]
|
||||
for submodule_name in submodule_name_list:
|
||||
del sys.modules[submodule_name]
|
||||
|
||||
def rename_submodule(self, submodule_name_src: str, submodule_name_dst: str) -> None:
|
||||
name_full_prev = self._module_name + "." + submodule_name_src
|
||||
name_full_next = self._module_name + "." + submodule_name_dst
|
||||
|
|
|
@ -11,6 +11,7 @@ __all__ = (
|
|||
"object_add_grid_scale",
|
||||
"object_add_grid_scale_apply_operator",
|
||||
"world_to_camera_view",
|
||||
"object_verify_active_shape_key_is_editable",
|
||||
)
|
||||
|
||||
|
||||
|
@ -263,3 +264,26 @@ def world_to_camera_view(scene, obj, coord):
|
|||
y = (co_local.y - min_y) / (max_y - min_y)
|
||||
|
||||
return Vector((x, y, z))
|
||||
|
||||
|
||||
def object_report_if_active_shape_key_is_locked(obj, operator):
|
||||
"""
|
||||
Checks if the active shape key of the specified object is locked, and reports an error if so.
|
||||
|
||||
If the object has no shape keys, there is nothing to lock, and the function returns False.
|
||||
|
||||
:arg obj: Object to check.
|
||||
:type obj: :class:`bpy.types.Object`
|
||||
:arg operator: Currently running operator to report the error through. Use None to suppress emitting the message.
|
||||
:type operator: :class:`bpy.types.Operator`
|
||||
:return: True if the shape key was locked.
|
||||
"""
|
||||
key = obj.active_shape_key
|
||||
|
||||
if key and key.lock_shape:
|
||||
if operator:
|
||||
operator.report({'ERROR'}, "The active shape key of %s is locked" % obj.name)
|
||||
|
||||
return True
|
||||
|
||||
return False
|
||||
|
|
|
@ -21,6 +21,11 @@ class VIEW3D_OT_edit_mesh_extrude_individual_move(Operator):
|
|||
return (obj is not None and obj.mode == 'EDIT')
|
||||
|
||||
def execute(self, context):
|
||||
from bpy_extras.object_utils import object_report_if_active_shape_key_is_locked
|
||||
|
||||
if object_report_if_active_shape_key_is_locked(context.object, self):
|
||||
return {'CANCELLED'}
|
||||
|
||||
mesh = context.object.data
|
||||
select_mode = context.tool_settings.mesh_select_mode
|
||||
|
||||
|
@ -83,7 +88,12 @@ class VIEW3D_OT_edit_mesh_extrude_move(Operator):
|
|||
return (obj is not None and obj.mode == 'EDIT')
|
||||
|
||||
@staticmethod
|
||||
def extrude_region(context, use_vert_normals, dissolve_and_intersect):
|
||||
def extrude_region(operator, context, use_vert_normals, dissolve_and_intersect):
|
||||
from bpy_extras.object_utils import object_report_if_active_shape_key_is_locked
|
||||
|
||||
if object_report_if_active_shape_key_is_locked(context.object, operator):
|
||||
return {'CANCELLED'}
|
||||
|
||||
mesh = context.object.data
|
||||
|
||||
totface = mesh.total_face_sel
|
||||
|
@ -146,7 +156,7 @@ class VIEW3D_OT_edit_mesh_extrude_move(Operator):
|
|||
|
||||
def execute(self, context):
|
||||
return VIEW3D_OT_edit_mesh_extrude_move.extrude_region(
|
||||
context, False, self.dissolve_and_intersect)
|
||||
self, context, False, self.dissolve_and_intersect)
|
||||
|
||||
def invoke(self, context, _event):
|
||||
return self.execute(context)
|
||||
|
@ -163,7 +173,7 @@ class VIEW3D_OT_edit_mesh_extrude_shrink_fatten(Operator):
|
|||
return (obj is not None and obj.mode == 'EDIT')
|
||||
|
||||
def execute(self, context):
|
||||
return VIEW3D_OT_edit_mesh_extrude_move.extrude_region(context, True, False)
|
||||
return VIEW3D_OT_edit_mesh_extrude_move.extrude_region(self, context, True, False)
|
||||
|
||||
def invoke(self, context, _event):
|
||||
return self.execute(context)
|
||||
|
@ -179,7 +189,11 @@ class VIEW3D_OT_edit_mesh_extrude_manifold_normal(Operator):
|
|||
obj = context.active_object
|
||||
return (obj is not None and obj.mode == 'EDIT')
|
||||
|
||||
def execute(self, _context):
|
||||
def execute(self, context):
|
||||
from bpy_extras.object_utils import object_report_if_active_shape_key_is_locked
|
||||
|
||||
if object_report_if_active_shape_key_is_locked(context.object, self):
|
||||
return {'CANCELLED'}
|
||||
bpy.ops.mesh.extrude_manifold(
|
||||
'INVOKE_REGION_WIN',
|
||||
MESH_OT_extrude_region={
|
||||
|
|
|
@ -3228,7 +3228,7 @@ class WM_MT_splash_quick_setup(Menu):
|
|||
)
|
||||
col.operator(
|
||||
"wm.url_open", text="See What's New...", icon='URL',
|
||||
).url = "https://wiki.blender.org/wiki/Reference/Release_Notes/4.0"
|
||||
).url = "https://developer.blender.org/docs/release_notes/%d.%d" % bpy.app.version[:2]
|
||||
col.separator(factor=2.0)
|
||||
|
||||
if can_import:
|
||||
|
|
|
@ -104,6 +104,13 @@ _modules_loaded = [_namespace[name] for name in _modules]
|
|||
del _namespace
|
||||
|
||||
|
||||
# Bypass the caching mechanism in the "Format" panel to make sure it is properly translated on language update.
|
||||
@bpy.app.handlers.persistent
|
||||
def translation_update(_):
|
||||
from .properties_output import RENDER_PT_format
|
||||
RENDER_PT_format._frame_rate_args_prev = None
|
||||
|
||||
|
||||
def register():
|
||||
from bpy.utils import register_class
|
||||
for mod in _modules_loaded:
|
||||
|
@ -166,6 +173,8 @@ def register():
|
|||
)
|
||||
del items
|
||||
|
||||
bpy.app.handlers.translation_update_post.append(translation_update)
|
||||
|
||||
# done...
|
||||
|
||||
|
||||
|
@ -176,6 +185,11 @@ def unregister():
|
|||
if cls.is_registered:
|
||||
unregister_class(cls)
|
||||
|
||||
try:
|
||||
bpy.app.handlers.translation_update_post.remove(translation_update)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
# Define a default UIList, when a list does not need any custom drawing...
|
||||
# Keep in sync with its #defined name in UI_interface.hh
|
||||
|
||||
|
|
|
@ -73,6 +73,9 @@ class MESH_MT_shape_key_context_menu(Menu):
|
|||
props.all = True
|
||||
props.apply_mix = True
|
||||
layout.separator()
|
||||
layout.operator("object.shape_key_lock", icon='LOCKED', text="Lock All").action = 'LOCK'
|
||||
layout.operator("object.shape_key_lock", icon='UNLOCKED', text="Unlock All").action = 'UNLOCK'
|
||||
layout.separator()
|
||||
layout.operator("object.shape_key_move", icon='TRIA_UP_BAR', text="Move to Top").type = 'TOP'
|
||||
layout.operator("object.shape_key_move", icon='TRIA_DOWN_BAR', text="Move to Bottom").type = 'BOTTOM'
|
||||
|
||||
|
@ -132,6 +135,7 @@ class MESH_UL_shape_keys(UIList):
|
|||
else:
|
||||
row.label(text="")
|
||||
row.prop(key_block, "mute", text="", emboss=False)
|
||||
row.prop(key_block, "lock_shape", text="", emboss=False)
|
||||
elif self.layout_type == 'GRID':
|
||||
layout.alignment = 'CENTER'
|
||||
layout.label(text="", icon_value=icon)
|
||||
|
|
|
@ -71,14 +71,16 @@ class OBJECT_MT_modifier_add(ModifierAddMenu, Menu):
|
|||
if geometry_nodes_supported:
|
||||
self.operator_modifier_add(layout, 'NODES')
|
||||
layout.separator()
|
||||
if ob_type in {'MESH', 'CURVE', 'FONT', 'SURFACE', 'LATTICE', 'GREASEPENCIL'}:
|
||||
if ob_type in {'MESH', 'CURVE', 'FONT', 'SURFACE', 'LATTICE'}:
|
||||
layout.menu("OBJECT_MT_modifier_add_edit")
|
||||
if ob_type in {'MESH', 'CURVE', 'FONT', 'SURFACE', 'VOLUME'}:
|
||||
if ob_type in {'MESH', 'CURVE', 'FONT', 'SURFACE', 'VOLUME', 'GREASEPENCIL'}:
|
||||
layout.menu("OBJECT_MT_modifier_add_generate")
|
||||
if ob_type in {'MESH', 'CURVE', 'FONT', 'SURFACE', 'LATTICE', 'VOLUME'}:
|
||||
layout.menu("OBJECT_MT_modifier_add_deform")
|
||||
if ob_type in {'MESH', 'CURVE', 'FONT', 'SURFACE', 'LATTICE'}:
|
||||
layout.menu("OBJECT_MT_modifier_add_physics")
|
||||
if ob_type in {'GREASEPENCIL'}:
|
||||
layout.menu("OBJECT_MT_modifier_add_color")
|
||||
|
||||
if geometry_nodes_supported:
|
||||
layout.menu_contents("OBJECT_MT_modifier_add_root_catalogs")
|
||||
|
@ -105,8 +107,6 @@ class OBJECT_MT_modifier_add_edit(ModifierAddMenu, Menu):
|
|||
self.operator_modifier_add(layout, 'VERTEX_WEIGHT_EDIT')
|
||||
self.operator_modifier_add(layout, 'VERTEX_WEIGHT_MIX')
|
||||
self.operator_modifier_add(layout, 'VERTEX_WEIGHT_PROXIMITY')
|
||||
if ob_type == 'GREASEPENCIL':
|
||||
self.operator_modifier_add(layout, 'GREASE_PENCIL_OPACITY')
|
||||
layout.template_modifier_asset_menu_items(catalog_path=self.bl_label)
|
||||
|
||||
|
||||
|
@ -149,6 +149,8 @@ class OBJECT_MT_modifier_add_generate(ModifierAddMenu, Menu):
|
|||
self.operator_modifier_add(layout, 'WELD')
|
||||
if ob_type == 'MESH':
|
||||
self.operator_modifier_add(layout, 'WIREFRAME')
|
||||
if ob_type == 'GREASEPENCIL':
|
||||
self.operator_modifier_add(layout, 'GREASEPENCIL_SUBDIV')
|
||||
layout.template_modifier_asset_menu_items(catalog_path=self.bl_label)
|
||||
|
||||
|
||||
|
@ -209,6 +211,18 @@ class OBJECT_MT_modifier_add_physics(ModifierAddMenu, Menu):
|
|||
layout.template_modifier_asset_menu_items(catalog_path=self.bl_label)
|
||||
|
||||
|
||||
class OBJECT_MT_modifier_add_color(ModifierAddMenu, Menu):
|
||||
bl_label = "Color"
|
||||
bl_options = {'SEARCH_ON_KEY_PRESS'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
ob_type = context.object.type
|
||||
if ob_type == 'GREASEPENCIL':
|
||||
self.operator_modifier_add(layout, 'GREASE_PENCIL_OPACITY')
|
||||
layout.template_modifier_asset_menu_items(catalog_path=self.bl_label)
|
||||
|
||||
|
||||
class DATA_PT_gpencil_modifiers(ModifierButtonsPanel, Panel):
|
||||
bl_label = "Modifiers"
|
||||
|
||||
|
@ -247,6 +261,7 @@ classes = (
|
|||
OBJECT_MT_modifier_add_generate,
|
||||
OBJECT_MT_modifier_add_deform,
|
||||
OBJECT_MT_modifier_add_physics,
|
||||
OBJECT_MT_modifier_add_color,
|
||||
DATA_PT_gpencil_modifiers,
|
||||
AddModifierMenu,
|
||||
)
|
||||
|
|
|
@ -248,7 +248,7 @@ class TIME_PT_playback(TimelinePanelButtons, Panel):
|
|||
layout.prop(scene, "sync_mode", text="Sync")
|
||||
col = layout.column(heading="Audio")
|
||||
col.prop(scene, "use_audio_scrub", text="Scrubbing")
|
||||
col.prop(scene, "use_audio", text="Mute")
|
||||
col.prop(scene, "use_audio")
|
||||
|
||||
col = layout.column(heading="Playback")
|
||||
col.prop(scene, "lock_frame_selection_to_range", text="Limit to Frame Range")
|
||||
|
|
|
@ -708,7 +708,7 @@ class TOPBAR_MT_help(Menu):
|
|||
"wm.url_open",
|
||||
text="Developer Documentation",
|
||||
icon='URL',
|
||||
).url = "https://wiki.blender.org/wiki/Main_Page"
|
||||
).url = "https://developer.blender.org/docs/"
|
||||
layout.operator("wm.url_open", text="Developer Community").url = "https://devtalk.blender.org"
|
||||
layout.operator("wm.url_open_preset", text="Python API Reference").type = 'API'
|
||||
layout.operator("wm.operator_cheat_sheet", icon='TEXT')
|
||||
|
|
|
@ -109,7 +109,10 @@ class USERPREF_MT_save_load(Menu):
|
|||
if prefs.use_preferences_save:
|
||||
layout.operator("wm.save_userpref", text="Save Preferences")
|
||||
sub_revert = layout.column(align=True)
|
||||
sub_revert.active = prefs.is_dirty
|
||||
# NOTE: regarding `factory_startup`. To correctly show the active state of this menu item,
|
||||
# the user preferences themselves would need to have a `factory_startup` state.
|
||||
# Since showing an active menu item whenever factory-startup is used is not such a problem, leave this as-is.
|
||||
sub_revert.active = prefs.is_dirty or bpy.app.factory_startup
|
||||
sub_revert.operator("wm.read_userpref", text="Revert to Saved Preferences")
|
||||
|
||||
layout.operator_context = 'INVOKE_AREA'
|
||||
|
|
|
@ -5286,6 +5286,7 @@ class VIEW3D_MT_edit_font(Menu):
|
|||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("FONT_OT_text_insert_unicode")
|
||||
layout.menu("VIEW3D_MT_edit_font_chars")
|
||||
|
||||
layout.separator()
|
||||
|
|
|
@ -30,6 +30,10 @@ bAction *id_action_ensure(Main *bmain, ID *id);
|
|||
*/
|
||||
void animdata_fcurve_delete(bAnimContext *ac, AnimData *adt, FCurve *fcu);
|
||||
|
||||
/** Iterate the FCurves of the given bAnimContext and validate the RNA path. Sets the flag
|
||||
* FCURVE_DISABLED if the path can't be resolved. */
|
||||
void reevaluate_fcurve_errors(bAnimContext *ac);
|
||||
|
||||
/**
|
||||
* Unlink the action from animdata if it's empty.
|
||||
*
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
/* SPDX-FileCopyrightText: 2024 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup animrig
|
||||
*
|
||||
* \brief Functions to work with drivers.
|
||||
*/
|
||||
|
||||
#include "RNA_types.hh"
|
||||
|
||||
struct AnimationEvalContext;
|
||||
struct FCurve;
|
||||
|
||||
namespace blender::animrig {
|
||||
|
||||
/** Evaluates the driver on the frame given in `anim_eval_context` and returns the value. Returns 0
|
||||
* if the RNA path can't be resolved. */
|
||||
float evaluate_driver_from_rna_pointer(const AnimationEvalContext *anim_eval_context,
|
||||
PointerRNA *ptr,
|
||||
PropertyRNA *prop,
|
||||
const FCurve *fcu);
|
||||
|
||||
} // namespace blender::animrig
|
|
@ -24,6 +24,7 @@ set(SRC
|
|||
intern/animdata.cc
|
||||
intern/bone_collections.cc
|
||||
intern/bonecolor.cc
|
||||
intern/driver.cc
|
||||
intern/fcurve.cc
|
||||
intern/keyframing.cc
|
||||
intern/keyframing_auto.cc
|
||||
|
@ -34,6 +35,7 @@ set(SRC
|
|||
ANIM_armature_iter.hh
|
||||
ANIM_bone_collections.hh
|
||||
ANIM_bonecolor.hh
|
||||
ANIM_driver.hh
|
||||
ANIM_fcurve.hh
|
||||
ANIM_keyframing.hh
|
||||
ANIM_rna.hh
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
#include "DEG_depsgraph_build.hh"
|
||||
#include "DNA_anim_types.h"
|
||||
#include "ED_anim_api.hh"
|
||||
#include "RNA_access.hh"
|
||||
#include "RNA_path.hh"
|
||||
|
||||
namespace blender::animrig {
|
||||
|
||||
|
@ -135,4 +137,35 @@ bool animdata_remove_empty_action(AnimData *adt)
|
|||
|
||||
/** \} */
|
||||
|
||||
void reevaluate_fcurve_errors(bAnimContext *ac)
|
||||
{
|
||||
/* Need to take off the flag before filtering, else the filter code would skip the FCurves, which
|
||||
* have not yet been validated. */
|
||||
const bool filtering_enabled = ac->ads->filterflag & ADS_FILTER_ONLY_ERRORS;
|
||||
if (filtering_enabled) {
|
||||
ac->ads->filterflag &= ~ADS_FILTER_ONLY_ERRORS;
|
||||
}
|
||||
ListBase anim_data = {nullptr, nullptr};
|
||||
const eAnimFilter_Flags filter = ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FCURVESONLY;
|
||||
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, eAnimCont_Types(ac->datatype));
|
||||
|
||||
LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
|
||||
FCurve *fcu = (FCurve *)ale->key_data;
|
||||
PointerRNA ptr;
|
||||
PropertyRNA *prop;
|
||||
PointerRNA id_ptr = RNA_id_pointer_create(ale->id);
|
||||
if (RNA_path_resolve_property(&id_ptr, fcu->rna_path, &ptr, &prop)) {
|
||||
fcu->flag &= ~FCURVE_DISABLED;
|
||||
}
|
||||
else {
|
||||
fcu->flag |= FCURVE_DISABLED;
|
||||
}
|
||||
}
|
||||
|
||||
ANIM_animdata_freelist(&anim_data);
|
||||
if (filtering_enabled) {
|
||||
ac->ads->filterflag |= ADS_FILTER_ONLY_ERRORS;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace blender::animrig
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
/* SPDX-FileCopyrightText: 2024 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup animrig
|
||||
*/
|
||||
|
||||
#include "ANIM_driver.hh"
|
||||
#include "BKE_animsys.h"
|
||||
#include "BKE_fcurve_driver.h"
|
||||
#include "DNA_anim_types.h"
|
||||
#include "RNA_access.hh"
|
||||
|
||||
namespace blender::animrig {
|
||||
|
||||
float evaluate_driver_from_rna_pointer(const AnimationEvalContext *anim_eval_context,
|
||||
PointerRNA *ptr,
|
||||
PropertyRNA *prop,
|
||||
const FCurve *fcu)
|
||||
{
|
||||
PathResolvedRNA anim_rna;
|
||||
if (!RNA_path_resolved_create(ptr, prop, fcu->array_index, &anim_rna)) {
|
||||
return 0.0f;
|
||||
}
|
||||
return evaluate_driver(&anim_rna, fcu->driver, fcu->driver, anim_eval_context);
|
||||
}
|
||||
|
||||
} // namespace blender::animrig
|
|
@ -21,7 +21,6 @@
|
|||
#include "BKE_anim_data.h"
|
||||
#include "BKE_animsys.h"
|
||||
#include "BKE_fcurve.h"
|
||||
#include "BKE_fcurve_driver.h"
|
||||
#include "BKE_idtype.h"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_nla.h"
|
||||
|
@ -279,12 +278,12 @@ static bool new_key_needed(FCurve *fcu, const float frame, const float value)
|
|||
return true;
|
||||
}
|
||||
|
||||
static AnimationEvalContext nla_time_remap(const AnimationEvalContext *anim_eval_context,
|
||||
PointerRNA *id_ptr,
|
||||
AnimData *adt,
|
||||
bAction *act,
|
||||
ListBase *nla_cache,
|
||||
NlaKeyframingContext **r_nla_context)
|
||||
static float nla_time_remap(const AnimationEvalContext *anim_eval_context,
|
||||
PointerRNA *id_ptr,
|
||||
AnimData *adt,
|
||||
bAction *act,
|
||||
ListBase *nla_cache,
|
||||
NlaKeyframingContext **r_nla_context)
|
||||
{
|
||||
if (adt && adt->action == act) {
|
||||
*r_nla_context = BKE_animsys_get_nla_keyframing_context(
|
||||
|
@ -292,28 +291,11 @@ static AnimationEvalContext nla_time_remap(const AnimationEvalContext *anim_eval
|
|||
|
||||
const float remapped_frame = BKE_nla_tweakedit_remap(
|
||||
adt, anim_eval_context->eval_time, NLATIME_CONVERT_UNMAP);
|
||||
return BKE_animsys_eval_context_construct_at(anim_eval_context, remapped_frame);
|
||||
return remapped_frame;
|
||||
}
|
||||
|
||||
*r_nla_context = nullptr;
|
||||
return *anim_eval_context;
|
||||
}
|
||||
|
||||
/* Adjust frame on which to add keyframe, to make it easier to add corrective drivers. */
|
||||
static float remap_driver_frame(const AnimationEvalContext *anim_eval_context,
|
||||
PointerRNA *ptr,
|
||||
PropertyRNA *prop,
|
||||
const FCurve *fcu)
|
||||
{
|
||||
float cfra = anim_eval_context->eval_time;
|
||||
PathResolvedRNA anim_rna;
|
||||
if (RNA_path_resolved_create(ptr, prop, fcu->array_index, &anim_rna)) {
|
||||
cfra = evaluate_driver(&anim_rna, fcu->driver, fcu->driver, anim_eval_context);
|
||||
}
|
||||
else {
|
||||
cfra = 0.0f;
|
||||
}
|
||||
return cfra;
|
||||
return anim_eval_context->eval_time;
|
||||
}
|
||||
|
||||
/* Insert the specified keyframe value into a single F-Curve. */
|
||||
|
@ -418,11 +400,7 @@ bool insert_keyframe_direct(ReportList *reports,
|
|||
return false;
|
||||
}
|
||||
|
||||
float cfra = anim_eval_context->eval_time;
|
||||
if ((flag & INSERTKEY_DRIVER) && (fcu->driver)) {
|
||||
cfra = remap_driver_frame(anim_eval_context, &ptr, prop, fcu);
|
||||
}
|
||||
|
||||
const float cfra = anim_eval_context->eval_time;
|
||||
const bool success = insert_keyframe_value(fcu, cfra, current_value, keytype, flag);
|
||||
|
||||
if (!success) {
|
||||
|
@ -445,7 +423,7 @@ static bool insert_keyframe_fcurve_value(Main *bmain,
|
|||
const char group[],
|
||||
const char rna_path[],
|
||||
int array_index,
|
||||
const AnimationEvalContext *anim_eval_context,
|
||||
const float fcurve_frame,
|
||||
float curval,
|
||||
eBezTriple_KeyframeType keytype,
|
||||
eInsertKeyFlags flag)
|
||||
|
@ -476,12 +454,7 @@ static bool insert_keyframe_fcurve_value(Main *bmain,
|
|||
/* Update F-Curve flags to ensure proper behavior for property type. */
|
||||
update_autoflags_fcurve_direct(fcu, prop);
|
||||
|
||||
float cfra = anim_eval_context->eval_time;
|
||||
if ((flag & INSERTKEY_DRIVER) && (fcu->driver)) {
|
||||
cfra = remap_driver_frame(anim_eval_context, ptr, prop, fcu);
|
||||
}
|
||||
|
||||
const bool success = insert_keyframe_value(fcu, cfra, curval, keytype, flag);
|
||||
const bool success = insert_keyframe_value(fcu, fcurve_frame, curval, keytype, flag);
|
||||
|
||||
if (!success) {
|
||||
BKE_reportf(reports,
|
||||
|
@ -552,7 +525,7 @@ int insert_keyframe(Main *bmain,
|
|||
NlaKeyframingContext *nla_context = nullptr;
|
||||
ListBase nla_cache = {nullptr, nullptr};
|
||||
AnimData *adt = BKE_animdata_from_id(id);
|
||||
const AnimationEvalContext remapped_context = nla_time_remap(
|
||||
const float nla_mapped_frame = nla_time_remap(
|
||||
anim_eval_context, &id_ptr, adt, act, &nla_cache, &nla_context);
|
||||
|
||||
bool force_all;
|
||||
|
@ -587,7 +560,7 @@ int insert_keyframe(Main *bmain,
|
|||
group,
|
||||
rna_path,
|
||||
array_index,
|
||||
&remapped_context,
|
||||
nla_mapped_frame,
|
||||
values[array_index],
|
||||
keytype,
|
||||
flag))
|
||||
|
@ -615,7 +588,7 @@ int insert_keyframe(Main *bmain,
|
|||
group,
|
||||
rna_path,
|
||||
array_index,
|
||||
&remapped_context,
|
||||
nla_mapped_frame,
|
||||
values[array_index],
|
||||
keytype,
|
||||
flag);
|
||||
|
@ -638,7 +611,7 @@ int insert_keyframe(Main *bmain,
|
|||
group,
|
||||
rna_path,
|
||||
array_index,
|
||||
&remapped_context,
|
||||
nla_mapped_frame,
|
||||
values[array_index],
|
||||
keytype,
|
||||
flag);
|
||||
|
@ -658,7 +631,7 @@ int insert_keyframe(Main *bmain,
|
|||
group,
|
||||
rna_path,
|
||||
array_index,
|
||||
&remapped_context,
|
||||
nla_mapped_frame,
|
||||
values[array_index],
|
||||
keytype,
|
||||
flag);
|
||||
|
|
|
@ -29,7 +29,7 @@ namespace blender::asset_system {
|
|||
* - Only slashes are used as path component separators.
|
||||
* - All paths are absolute, so there is no need for a leading slash.
|
||||
*
|
||||
* See https://wiki.blender.org/wiki/Source/Architecture/Asset_System/Catalogs
|
||||
* See https://developer.blender.org/docs/features/asset_system/backend/asset_catalogs/
|
||||
*
|
||||
* Paths are stored as byte sequences, and assumed to be UTF-8.
|
||||
*/
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
* \brief Information to uniquely identify and locate an asset.
|
||||
*
|
||||
* https://wiki.blender.org/wiki/Source/Architecture/Asset_System/Back_End#Asset_Identifier
|
||||
* https://developer.blender.org/docs/features/asset_system/backend/#asset-identifier
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
* \brief Main runtime representation of an asset.
|
||||
*
|
||||
* Abstraction to reference an asset, with necessary data for display & interaction.
|
||||
* https://wiki.blender.org/wiki/Source/Architecture/Asset_System/Back_End#Asset_Representation
|
||||
* https://developer.blender.org/docs/features/asset_system/backend/#asset-representation
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
* TODO Currently disabled because UI data depends on asset library data, so we have to make sure
|
||||
* it's freed in the right order (UI first). Pre-load handlers don't give us this order.
|
||||
* Should be addressed with a proper ownership model for the asset system:
|
||||
* https://wiki.blender.org/wiki/Source/Architecture/Asset_System/Back_End#Ownership_Model
|
||||
* https://developer.blender.org/docs/features/asset_system/backend/#ownership-model
|
||||
*/
|
||||
// #define WITH_DESTROY_VIA_LOAD_HANDLER
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@ struct KS_Path *BKE_keyingset_find_path(struct KeyingSet *ks,
|
|||
/* Copy all KeyingSets in the given list */
|
||||
void BKE_keyingsets_copy(struct ListBase *newlist, const struct ListBase *list);
|
||||
|
||||
/** Process the ID pointers inside a scene's keyingsets, in see `BKE_lib_query.h` for details. */
|
||||
/** Process the ID pointers inside a scene's keyingsets, in see `BKE_lib_query.hh` for details. */
|
||||
void BKE_keyingsets_foreach_id(struct LibraryForeachIDData *data,
|
||||
const struct ListBase *keyingsets);
|
||||
|
||||
|
|
|
@ -29,13 +29,15 @@ extern "C" {
|
|||
|
||||
/* Blender file format version. */
|
||||
#define BLENDER_FILE_VERSION BLENDER_VERSION
|
||||
#define BLENDER_FILE_SUBVERSION 11
|
||||
#define BLENDER_FILE_SUBVERSION 12
|
||||
|
||||
/* Minimum Blender version that supports reading file written with the current
|
||||
* version. Older Blender versions will test this and cancel loading the file, showing a warning to
|
||||
* the user.
|
||||
*
|
||||
* See https://wiki.blender.org/wiki/Process/Compatibility_Handling for details. */
|
||||
* See
|
||||
* https://developer.blender.org/docs/handbook/guidelines/compatibility_handling_for_blend_files/
|
||||
* for details. */
|
||||
#define BLENDER_FILE_MIN_VERSION 306
|
||||
#define BLENDER_FILE_MIN_SUBVERSION 13
|
||||
|
||||
|
|
|
@ -109,6 +109,7 @@ typedef enum {
|
|||
BKE_CB_EVT_COMPOSITE_CANCEL,
|
||||
BKE_CB_EVT_ANIMATION_PLAYBACK_PRE,
|
||||
BKE_CB_EVT_ANIMATION_PLAYBACK_POST,
|
||||
BKE_CB_EVT_TRANSLATION_UPDATE_POST,
|
||||
BKE_CB_EVT_EXTENSION_REPOS_UPDATE_PRE,
|
||||
BKE_CB_EVT_EXTENSION_REPOS_UPDATE_POST,
|
||||
BKE_CB_EVT_TOT,
|
||||
|
|
|
@ -180,7 +180,7 @@ void BKE_constraints_copy_ex(struct ListBase *dst,
|
|||
* Run the given callback on all ID-blocks in list of constraints.
|
||||
*
|
||||
* \param flag: the `IDWALK_` flags controlling the behavior of the foreach_id code, see
|
||||
* `BKE_lib_query.h`
|
||||
* `BKE_lib_query.hh`
|
||||
*/
|
||||
void BKE_constraints_id_loop(struct ListBase *list,
|
||||
ConstraintIDFunc func,
|
||||
|
|
|
@ -55,7 +55,7 @@ typedef struct IDCacheKey {
|
|||
unsigned int id_session_uuid;
|
||||
/* Value uniquely identifying the cache within its ID.
|
||||
* Typically the offset of its member in the data-block struct, but can be anything. */
|
||||
size_t offset_in_ID;
|
||||
size_t identifier;
|
||||
} IDCacheKey;
|
||||
|
||||
uint BKE_idtype_cache_key_hash(const void *key_v);
|
||||
|
|
|
@ -88,9 +88,9 @@ struct KeyBlock *BKE_keyblock_add(struct Key *key, const char *name);
|
|||
*/
|
||||
struct KeyBlock *BKE_keyblock_add_ctime(struct Key *key, const char *name, bool do_force);
|
||||
/**
|
||||
* Get the appropriate #KeyBlock given an index.
|
||||
* Get the appropriate #KeyBlock given an index (0 refers to the basis key). Key may be null.
|
||||
*/
|
||||
struct KeyBlock *BKE_keyblock_from_key(struct Key *key, int index);
|
||||
struct KeyBlock *BKE_keyblock_find_by_index(struct Key *key, int index);
|
||||
/**
|
||||
* Get the appropriate #KeyBlock given a name to search for.
|
||||
*/
|
||||
|
|
|
@ -21,10 +21,6 @@
|
|||
|
||||
#include "BLI_sys_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct ID;
|
||||
struct IDProperty;
|
||||
struct Main;
|
||||
|
@ -119,23 +115,23 @@ enum {
|
|||
IDWALK_RET_STOP_RECURSION = 1 << 1,
|
||||
};
|
||||
|
||||
typedef struct LibraryIDLinkCallbackData {
|
||||
struct LibraryIDLinkCallbackData {
|
||||
void *user_data;
|
||||
/** Main database used to call `BKE_library_foreach_ID_link()`. */
|
||||
struct Main *bmain;
|
||||
Main *bmain;
|
||||
/**
|
||||
* 'Real' ID, the one that might be in bmain, only differs from self_id when the later is an
|
||||
* embedded one.
|
||||
*/
|
||||
struct ID *owner_id;
|
||||
ID *owner_id;
|
||||
/**
|
||||
* ID from which the current ID pointer is being processed. It may be an embedded ID like master
|
||||
* collection or root node tree.
|
||||
*/
|
||||
struct ID *self_id;
|
||||
struct ID **id_pointer;
|
||||
ID *self_id;
|
||||
ID **id_pointer;
|
||||
int cb_flag;
|
||||
} LibraryIDLinkCallbackData;
|
||||
};
|
||||
|
||||
/**
|
||||
* Call a callback for each ID link which the given ID uses.
|
||||
|
@ -211,12 +207,10 @@ typedef struct LibraryForeachIDData LibraryForeachIDData;
|
|||
* Check whether current iteration over ID usages should be stopped or not.
|
||||
* \return true if the iteration should be stopped, false otherwise.
|
||||
*/
|
||||
bool BKE_lib_query_foreachid_iter_stop(const struct LibraryForeachIDData *data);
|
||||
void BKE_lib_query_foreachid_process(struct LibraryForeachIDData *data,
|
||||
struct ID **id_pp,
|
||||
int cb_flag);
|
||||
int BKE_lib_query_foreachid_process_flags_get(const struct LibraryForeachIDData *data);
|
||||
int BKE_lib_query_foreachid_process_callback_flag_override(struct LibraryForeachIDData *data,
|
||||
bool BKE_lib_query_foreachid_iter_stop(const LibraryForeachIDData *data);
|
||||
void BKE_lib_query_foreachid_process(LibraryForeachIDData *data, ID **id_pp, int cb_flag);
|
||||
int BKE_lib_query_foreachid_process_flags_get(const LibraryForeachIDData *data);
|
||||
int BKE_lib_query_foreachid_process_callback_flag_override(LibraryForeachIDData *data,
|
||||
int cb_flag,
|
||||
bool do_replace);
|
||||
|
||||
|
@ -268,18 +262,18 @@ int BKE_lib_query_foreachid_process_callback_flag_override(struct LibraryForeach
|
|||
* Those require specific care, since they are technically sub-data of their owner, yet in some
|
||||
* cases they still behave as regular IDs.
|
||||
*/
|
||||
void BKE_library_foreach_ID_embedded(struct LibraryForeachIDData *data, struct ID **id_pp);
|
||||
void BKE_lib_query_idpropertiesForeachIDLink_callback(struct IDProperty *id_prop, void *user_data);
|
||||
void BKE_library_foreach_ID_embedded(LibraryForeachIDData *data, ID **id_pp);
|
||||
void BKE_lib_query_idpropertiesForeachIDLink_callback(IDProperty *id_prop, void *user_data);
|
||||
|
||||
/**
|
||||
* Loop over all of the ID's this data-block links to.
|
||||
*/
|
||||
void BKE_library_foreach_ID_link(
|
||||
struct Main *bmain, struct ID *id, LibraryIDLinkCallback callback, void *user_data, int flag);
|
||||
Main *bmain, ID *id, LibraryIDLinkCallback callback, void *user_data, int flag);
|
||||
/**
|
||||
* Re-usable function, use when replacing ID's.
|
||||
*/
|
||||
void BKE_library_update_ID_link_user(struct ID *id_dst, struct ID *id_src, int cb_flag);
|
||||
void BKE_library_update_ID_link_user(ID *id_dst, ID *id_src, int cb_flag);
|
||||
|
||||
/**
|
||||
* Return the number of times given \a id_user uses/references \a id_used.
|
||||
|
@ -291,7 +285,7 @@ void BKE_library_update_ID_link_user(struct ID *id_dst, struct ID *id_src, int c
|
|||
* \param id_used: the ID which is supposed to be used (referenced) by \a id_user.
|
||||
* \return the number of direct usages/references of \a id_used by \a id_user.
|
||||
*/
|
||||
int BKE_library_ID_use_ID(struct ID *id_user, struct ID *id_used);
|
||||
int BKE_library_ID_use_ID(ID *id_user, ID *id_used);
|
||||
|
||||
/**
|
||||
* Say whether given \a owner_id may use (in any way) a data-block of \a id_type_used.
|
||||
|
@ -299,26 +293,26 @@ int BKE_library_ID_use_ID(struct ID *id_user, struct ID *id_used);
|
|||
* This is a 'simplified' abstract version of #BKE_library_foreach_ID_link() above,
|
||||
* quite useful to reduce useless iterations in some cases.
|
||||
*/
|
||||
bool BKE_library_id_can_use_idtype(struct ID *owner_id, short id_type_used);
|
||||
bool BKE_library_id_can_use_idtype(ID *owner_id, short id_type_used);
|
||||
|
||||
/**
|
||||
* Given the owner_id return the type of id_types it can use as a filter_id.
|
||||
*/
|
||||
uint64_t BKE_library_id_can_use_filter_id(const struct ID *owner_id, const bool include_ui);
|
||||
uint64_t BKE_library_id_can_use_filter_id(const ID *owner_id, const bool include_ui);
|
||||
|
||||
/**
|
||||
* Check whether given ID is used locally (i.e. by another non-linked ID).
|
||||
*/
|
||||
bool BKE_library_ID_is_locally_used(struct Main *bmain, void *idv);
|
||||
bool BKE_library_ID_is_locally_used(Main *bmain, void *idv);
|
||||
/**
|
||||
* Check whether given ID is used indirectly (i.e. by another linked ID).
|
||||
*/
|
||||
bool BKE_library_ID_is_indirectly_used(struct Main *bmain, void *idv);
|
||||
bool BKE_library_ID_is_indirectly_used(Main *bmain, void *idv);
|
||||
/**
|
||||
* Combine #BKE_library_ID_is_locally_used() and #BKE_library_ID_is_indirectly_used()
|
||||
* in a single call.
|
||||
*/
|
||||
void BKE_library_ID_test_usages(struct Main *bmain,
|
||||
void BKE_library_ID_test_usages(Main *bmain,
|
||||
void *idv,
|
||||
bool *r_is_used_local,
|
||||
bool *r_is_used_linked);
|
||||
|
@ -338,7 +332,7 @@ void BKE_library_ID_test_usages(struct Main *bmain,
|
|||
* Number of tagged-as-unused IDs is then set for each type, and as total in
|
||||
* #INDEX_ID_NULL item.
|
||||
*/
|
||||
void BKE_lib_query_unused_ids_tag(struct Main *bmain,
|
||||
void BKE_lib_query_unused_ids_tag(Main *bmain,
|
||||
int tag,
|
||||
bool do_local_ids,
|
||||
bool do_linked_ids,
|
||||
|
@ -354,7 +348,7 @@ void BKE_lib_query_unused_ids_tag(struct Main *bmain,
|
|||
* \param do_init_tag: if \a true, all linked data are checked, if \a false,
|
||||
* only linked data-blocks already tagged with #LIB_TAG_DOIT are checked.
|
||||
*/
|
||||
void BKE_library_unused_linked_data_set_tag(struct Main *bmain, bool do_init_tag);
|
||||
void BKE_library_unused_linked_data_set_tag(Main *bmain, bool do_init_tag);
|
||||
/**
|
||||
* Untag linked data blocks used by other untagged linked data-blocks.
|
||||
* Used to detect data-blocks that we can forcefully make local
|
||||
|
@ -363,8 +357,4 @@ void BKE_library_unused_linked_data_set_tag(struct Main *bmain, bool do_init_tag
|
|||
* after this function has ran caller knows data-blocks still tagged can directly be made local,
|
||||
* since they are only used by other data-blocks that will also be made fully local.
|
||||
*/
|
||||
void BKE_library_indirectly_used_data_tag_clear(struct Main *bmain);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
void BKE_library_indirectly_used_data_tag_clear(Main *bmain);
|
|
@ -58,7 +58,7 @@ struct MainIDRelationsEntryItem {
|
|||
/* Session uuid of the `id_pointer`. */
|
||||
uint session_uuid;
|
||||
|
||||
int usage_flag; /* Using IDWALK_ enums, defined in BKE_lib_query.h */
|
||||
int usage_flag; /* Using IDWALK_ enums, defined in BKE_lib_query.hh */
|
||||
};
|
||||
|
||||
struct MainIDRelationsEntry {
|
||||
|
|
|
@ -21,6 +21,10 @@ using index_mask::IndexMask;
|
|||
#include "BKE_mesh_types.hh"
|
||||
|
||||
namespace blender::bke {
|
||||
|
||||
enum class AttrDomain : int8_t;
|
||||
class AttributeIDRef;
|
||||
|
||||
namespace mesh {
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Polygon Data Evaluation
|
||||
|
@ -334,4 +338,10 @@ void mesh_select_edge_flush(Mesh &mesh);
|
|||
/** Make vertex and edge visibility consistent with faces. */
|
||||
void mesh_select_face_flush(Mesh &mesh);
|
||||
|
||||
/** Set the default name when adding a color attribute if there is no default yet. */
|
||||
void mesh_ensure_default_color_attribute_on_add(Mesh &mesh,
|
||||
const AttributeIDRef &id,
|
||||
AttrDomain domain,
|
||||
eCustomDataType data_type);
|
||||
|
||||
} // namespace blender::bke
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
* \ingroup bke
|
||||
*/
|
||||
#include "BLI_compiler_attrs.h"
|
||||
#include "BLI_function_ref.hh"
|
||||
#include "BLI_math_matrix_types.hh"
|
||||
#include "BLI_span.hh"
|
||||
|
||||
|
@ -33,6 +34,7 @@ struct ModifierData;
|
|||
struct Object;
|
||||
struct Scene;
|
||||
struct StructRNA;
|
||||
struct IDCacheKey;
|
||||
|
||||
enum class ModifierTypeType {
|
||||
/* Should not be used, only for None modifier type */
|
||||
|
@ -122,7 +124,7 @@ enum ModifierTypeFlag {
|
|||
/** Accepts #GreasePencil data input. */
|
||||
eModifierTypeFlag_AcceptsGreasePencil = (1 << 12),
|
||||
};
|
||||
ENUM_OPERATORS(ModifierTypeFlag, eModifierTypeFlag_AcceptsBMesh)
|
||||
ENUM_OPERATORS(ModifierTypeFlag, eModifierTypeFlag_AcceptsGreasePencil)
|
||||
|
||||
using IDWalkFunc = void (*)(void *user_data, Object *ob, ID **idpoin, int cb_flag);
|
||||
using TexWalkFunc = void (*)(void *user_data, Object *ob, ModifierData *md, const char *propname);
|
||||
|
@ -381,6 +383,14 @@ struct ModifierTypeInfo {
|
|||
* not been written (e.g. runtime data) can be reset.
|
||||
*/
|
||||
void (*blend_read)(BlendDataReader *reader, ModifierData *md);
|
||||
|
||||
/**
|
||||
* Iterate over all cache pointers of given modifier. Also see #IDTypeInfo::foreach_cache.
|
||||
*/
|
||||
void (*foreach_cache)(
|
||||
Object *object,
|
||||
ModifierData *md,
|
||||
blender::FunctionRef<void(const IDCacheKey &cache_key, void **cache_p, uint flags)> fn);
|
||||
};
|
||||
|
||||
/* Used to set a modifier's panel type. */
|
||||
|
|
|
@ -420,7 +420,7 @@ set(SRC
|
|||
BKE_layer.h
|
||||
BKE_lib_id.hh
|
||||
BKE_lib_override.hh
|
||||
BKE_lib_query.h
|
||||
BKE_lib_query.hh
|
||||
BKE_lib_remap.hh
|
||||
BKE_library.hh
|
||||
BKE_light.h
|
||||
|
|
|
@ -357,9 +357,9 @@ static float (*get_orco_coords(Object *ob, BMEditMesh *em, int layer, int *free)
|
|||
if (!em) {
|
||||
ClothModifierData *clmd = (ClothModifierData *)BKE_modifiers_findby_type(
|
||||
ob, eModifierType_Cloth);
|
||||
if (clmd) {
|
||||
KeyBlock *kb = BKE_keyblock_from_key(BKE_key_from_object(ob),
|
||||
clmd->sim_parms->shapekey_rest);
|
||||
if (clmd && clmd->sim_parms->shapekey_rest) {
|
||||
KeyBlock *kb = BKE_keyblock_find_by_index(BKE_key_from_object(ob),
|
||||
clmd->sim_parms->shapekey_rest);
|
||||
|
||||
if (kb && kb->data) {
|
||||
return (float(*)[3])kb->data;
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
#include "BKE_idprop.h"
|
||||
#include "BKE_idtype.h"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_query.hh"
|
||||
#include "BKE_main.hh"
|
||||
#include "BKE_object.hh"
|
||||
#include "BKE_object_types.hh"
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include "BKE_global.h"
|
||||
#include "BKE_idtype.h"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_query.hh"
|
||||
#include "BKE_main.hh"
|
||||
#include "BKE_nla.h"
|
||||
#include "BKE_node.h"
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
#include "BKE_fcurve.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_query.hh"
|
||||
#include "BKE_main.hh"
|
||||
#include "BKE_material.h"
|
||||
#include "BKE_nla.h"
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
#include "BKE_idprop.h"
|
||||
#include "BKE_idtype.h"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_query.hh"
|
||||
#include "BKE_main.hh"
|
||||
#include "BKE_object.hh"
|
||||
#include "BKE_object_types.hh"
|
||||
|
@ -1898,7 +1898,7 @@ static void find_bbone_segment_index_curved(const bPoseChannel *pchan,
|
|||
* reduce the gradient slope to the ideal value (the one you get for points directly on
|
||||
* the curve), using heuristic blend strength falloff coefficients based on the distances
|
||||
* to the boundary plane before and after mapping. See PR #110758 for more details, or
|
||||
* https://wiki.blender.org/wiki/Source/Animation/B-Bone_Vertex_Mapping#Curved_Mapping */
|
||||
* https://developer.blender.org/docs/features/animation/b-bone_vertex_mapping/#curved-mapping */
|
||||
const float segment_scale = pchan->runtime.bbone_arc_length_reciprocal;
|
||||
|
||||
for (int i = stack_top; i >= 0; --i) {
|
||||
|
|
|
@ -11,15 +11,6 @@
|
|||
|
||||
namespace blender::bke::bake {
|
||||
|
||||
static const CPPType &get_socket_cpp_type(const eNodeSocketDatatype socket_type)
|
||||
{
|
||||
const char *socket_idname = nodeStaticSocketType(socket_type, 0);
|
||||
const bNodeSocketType *typeinfo = nodeSocketTypeFind(socket_idname);
|
||||
BLI_assert(typeinfo);
|
||||
BLI_assert(typeinfo->geometry_nodes_cpp_type);
|
||||
return *typeinfo->geometry_nodes_cpp_type;
|
||||
}
|
||||
|
||||
Array<std::unique_ptr<BakeItem>> move_socket_values_to_bake_items(const Span<void *> socket_values,
|
||||
const BakeSocketConfig &config)
|
||||
{
|
||||
|
@ -201,6 +192,14 @@ static void rename_attributes(const Span<GeometrySet *> geometries,
|
|||
}
|
||||
}
|
||||
|
||||
static void default_initialize_socket_value(const eNodeSocketDatatype socket_type, void *r_value)
|
||||
{
|
||||
const char *socket_idname = nodeStaticSocketType(socket_type, 0);
|
||||
const bNodeSocketType *typeinfo = nodeSocketTypeFind(socket_idname);
|
||||
typeinfo->geometry_nodes_cpp_type->copy_construct(typeinfo->geometry_nodes_default_cpp_value,
|
||||
r_value);
|
||||
}
|
||||
|
||||
void move_bake_items_to_socket_values(
|
||||
const Span<BakeItem *> bake_items,
|
||||
const BakeSocketConfig &config,
|
||||
|
@ -214,11 +213,10 @@ void move_bake_items_to_socket_values(
|
|||
|
||||
for (const int i : bake_items.index_range()) {
|
||||
const eNodeSocketDatatype socket_type = config.types[i];
|
||||
const CPPType &type = get_socket_cpp_type(socket_type);
|
||||
BakeItem *bake_item = bake_items[i];
|
||||
void *r_socket_value = r_socket_values[i];
|
||||
if (bake_item == nullptr) {
|
||||
type.value_initialize(r_socket_value);
|
||||
default_initialize_socket_value(socket_type, r_socket_value);
|
||||
continue;
|
||||
}
|
||||
if (!copy_bake_item_to_socket_value(
|
||||
|
@ -228,7 +226,7 @@ void move_bake_items_to_socket_values(
|
|||
attribute_map,
|
||||
r_socket_value))
|
||||
{
|
||||
type.value_initialize(r_socket_value);
|
||||
default_initialize_socket_value(socket_type, r_socket_value);
|
||||
continue;
|
||||
}
|
||||
if (socket_type == SOCK_GEOMETRY) {
|
||||
|
@ -253,11 +251,10 @@ void copy_bake_items_to_socket_values(
|
|||
|
||||
for (const int i : bake_items.index_range()) {
|
||||
const eNodeSocketDatatype socket_type = config.types[i];
|
||||
const CPPType &type = get_socket_cpp_type(socket_type);
|
||||
const BakeItem *bake_item = bake_items[i];
|
||||
void *r_socket_value = r_socket_values[i];
|
||||
if (bake_item == nullptr) {
|
||||
type.value_initialize(r_socket_value);
|
||||
default_initialize_socket_value(socket_type, r_socket_value);
|
||||
continue;
|
||||
}
|
||||
if (!copy_bake_item_to_socket_value(
|
||||
|
@ -267,7 +264,7 @@ void copy_bake_items_to_socket_values(
|
|||
attribute_map,
|
||||
r_socket_value))
|
||||
{
|
||||
type.value_initialize(r_socket_value);
|
||||
default_initialize_socket_value(socket_type, r_socket_value);
|
||||
continue;
|
||||
}
|
||||
if (socket_type == SOCK_GEOMETRY) {
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
#include "BKE_layer.h"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_lib_override.hh"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_query.hh"
|
||||
#include "BKE_lib_remap.hh"
|
||||
#include "BKE_main.hh"
|
||||
#include "BKE_main_idmap.hh"
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
#include "BKE_layer.h"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_lib_override.hh"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_query.hh"
|
||||
#include "BKE_lib_remap.hh"
|
||||
#include "BKE_main.hh"
|
||||
#include "BKE_main_namemap.hh"
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
#include "BKE_idprop.hh"
|
||||
#include "BKE_idtype.h"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_query.hh"
|
||||
#include "BKE_lib_remap.hh"
|
||||
#include "BKE_main.hh"
|
||||
#include "BKE_material.h"
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#include "BKE_idtype.h"
|
||||
#include "BKE_layer.h"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_query.hh"
|
||||
#include "BKE_main.hh"
|
||||
#include "BKE_object.hh"
|
||||
#include "BKE_scene.h"
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#include "BKE_idtype.h"
|
||||
#include "BKE_layer.h"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_query.hh"
|
||||
#include "BKE_lib_remap.hh"
|
||||
#include "BKE_main.hh"
|
||||
#include "BKE_object.hh"
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
#include "BKE_global.h"
|
||||
#include "BKE_idprop.h"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_query.hh"
|
||||
#include "BKE_mesh.hh"
|
||||
#include "BKE_mesh_runtime.hh"
|
||||
#include "BKE_movieclip.h"
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
#include "BKE_idtype.h"
|
||||
#include "BKE_key.h"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_query.hh"
|
||||
#include "BKE_main.hh"
|
||||
#include "BKE_object.hh"
|
||||
#include "BKE_object_types.hh"
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
#include "BKE_global.h"
|
||||
#include "BKE_idtype.h"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_query.hh"
|
||||
#include "BKE_lib_remap.hh"
|
||||
#include "BKE_main.hh"
|
||||
#include "BKE_modifier.hh"
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
#include "BKE_fcurve_driver.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_idprop.h"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_query.hh"
|
||||
#include "BKE_nla.h"
|
||||
|
||||
#include "BLO_read_write.hh"
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
#include "BKE_idtype.h"
|
||||
#include "BKE_image.h"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_query.hh"
|
||||
#include "BKE_main.hh"
|
||||
#include "BKE_material.h"
|
||||
#include "BKE_paint.hh"
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
#include "BKE_gpencil_modifier_legacy.h"
|
||||
#include "BKE_lattice.hh"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_query.hh"
|
||||
#include "BKE_material.h"
|
||||
#include "BKE_modifier.hh"
|
||||
#include "BKE_object.hh"
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include "BKE_grease_pencil.hh"
|
||||
#include "BKE_idtype.h"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_query.hh"
|
||||
#include "BKE_material.h"
|
||||
#include "BKE_modifier.hh"
|
||||
#include "BKE_object.hh"
|
||||
|
|
|
@ -80,7 +80,7 @@ void legacy_gpencil_frame_to_grease_pencil_drawing(const bGPDframe &gpf,
|
|||
SpanAttributeWriter<float> stroke_hardnesses = attributes.lookup_or_add_for_write_span<float>(
|
||||
"hardness", AttrDomain::Curve);
|
||||
SpanAttributeWriter<float> stroke_point_aspect_ratios =
|
||||
attributes.lookup_or_add_for_write_span<float>("point_aspect_ratio", AttrDomain::Curve);
|
||||
attributes.lookup_or_add_for_write_span<float>("aspect_ratio", AttrDomain::Curve);
|
||||
SpanAttributeWriter<float2> stroke_fill_translations =
|
||||
attributes.lookup_or_add_for_write_span<float2>("fill_translation", AttrDomain::Curve);
|
||||
SpanAttributeWriter<float> stroke_fill_rotations =
|
||||
|
|
|
@ -33,7 +33,7 @@ uint BKE_idtype_cache_key_hash(const void *key_v)
|
|||
{
|
||||
const IDCacheKey *key = static_cast<const IDCacheKey *>(key_v);
|
||||
size_t hash = BLI_ghashutil_uinthash(key->id_session_uuid);
|
||||
hash = BLI_ghashutil_combine_hash(hash, BLI_ghashutil_uinthash(uint(key->offset_in_ID)));
|
||||
hash = BLI_ghashutil_combine_hash(hash, BLI_ghashutil_uinthash(uint(key->identifier)));
|
||||
return uint(hash);
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ bool BKE_idtype_cache_key_cmp(const void *key_a_v, const void *key_b_v)
|
|||
const IDCacheKey *key_a = static_cast<const IDCacheKey *>(key_a_v);
|
||||
const IDCacheKey *key_b = static_cast<const IDCacheKey *>(key_b_v);
|
||||
return (key_a->id_session_uuid != key_b->id_session_uuid) ||
|
||||
(key_a->offset_in_ID != key_b->offset_in_ID);
|
||||
(key_a->identifier != key_b->identifier);
|
||||
}
|
||||
|
||||
static IDTypeInfo *id_types[INDEX_ID_MAX] = {nullptr};
|
||||
|
|
|
@ -237,12 +237,12 @@ static void image_foreach_cache(ID *id,
|
|||
Image *image = (Image *)id;
|
||||
IDCacheKey key;
|
||||
key.id_session_uuid = id->session_uuid;
|
||||
key.offset_in_ID = offsetof(Image, cache);
|
||||
key.identifier = offsetof(Image, cache);
|
||||
function_callback(id, &key, (void **)&image->cache, 0, user_data);
|
||||
|
||||
key.offset_in_ID = offsetof(Image, anims.first);
|
||||
key.identifier = offsetof(Image, anims.first);
|
||||
function_callback(id, &key, (void **)&image->anims.first, 0, user_data);
|
||||
key.offset_in_ID = offsetof(Image, anims.last);
|
||||
key.identifier = offsetof(Image, anims.last);
|
||||
function_callback(id, &key, (void **)&image->anims.last, 0, user_data);
|
||||
|
||||
auto gputexture_offset = [image](int target, int eye) {
|
||||
|
@ -258,16 +258,16 @@ static void image_foreach_cache(ID *id,
|
|||
if (texture == nullptr) {
|
||||
continue;
|
||||
}
|
||||
key.offset_in_ID = gputexture_offset(a, eye);
|
||||
key.identifier = gputexture_offset(a, eye);
|
||||
function_callback(id, &key, (void **)&image->gputexture[a][eye], 0, user_data);
|
||||
}
|
||||
}
|
||||
|
||||
key.offset_in_ID = offsetof(Image, rr);
|
||||
key.identifier = offsetof(Image, rr);
|
||||
function_callback(id, &key, (void **)&image->rr, 0, user_data);
|
||||
|
||||
LISTBASE_FOREACH (RenderSlot *, slot, &image->renderslots) {
|
||||
key.offset_in_ID = size_t(BLI_ghashutil_strhash_p(slot->name));
|
||||
key.identifier = size_t(BLI_ghashutil_strhash_p(slot->name));
|
||||
function_callback(id, &key, (void **)&slot->render, 0, user_data);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
#include "BKE_ipo.h"
|
||||
#include "BKE_key.h"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_query.hh"
|
||||
#include "BKE_main.hh"
|
||||
#include "BKE_nla.h"
|
||||
|
||||
|
@ -443,7 +443,7 @@ static char *shapekey_adrcodes_to_paths(ID *id, int adrcode, int * /*r_array_ind
|
|||
else {
|
||||
/* Find the name of the ShapeKey (i.e. KeyBlock) to look for */
|
||||
Key *key = (Key *)id;
|
||||
KeyBlock *kb = BKE_keyblock_from_key(key, adrcode);
|
||||
KeyBlock *kb = BKE_keyblock_find_by_index(key, adrcode);
|
||||
|
||||
/* setting that we alter is the "value" (i.e. keyblock.curval) */
|
||||
if (kb) {
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
#include "BKE_key.h"
|
||||
#include "BKE_lattice.hh"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_query.hh"
|
||||
#include "BKE_main.hh"
|
||||
#include "BKE_mesh.hh"
|
||||
#include "BKE_scene.h"
|
||||
|
@ -1897,12 +1897,7 @@ KeyBlock *BKE_keyblock_from_object(Object *ob)
|
|||
{
|
||||
Key *key = BKE_key_from_object(ob);
|
||||
|
||||
if (key) {
|
||||
KeyBlock *kb = static_cast<KeyBlock *>(BLI_findlink(&key->block, ob->shapenr - 1));
|
||||
return kb;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
return BKE_keyblock_find_by_index(key, ob->shapenr - 1);
|
||||
}
|
||||
|
||||
KeyBlock *BKE_keyblock_from_object_reference(Object *ob)
|
||||
|
@ -1916,21 +1911,13 @@ KeyBlock *BKE_keyblock_from_object_reference(Object *ob)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
KeyBlock *BKE_keyblock_from_key(Key *key, int index)
|
||||
KeyBlock *BKE_keyblock_find_by_index(Key *key, int index)
|
||||
{
|
||||
if (key) {
|
||||
KeyBlock *kb = static_cast<KeyBlock *>(key->block.first);
|
||||
|
||||
for (int i = 1; i < key->totkey; i++) {
|
||||
kb = kb->next;
|
||||
|
||||
if (index == i) {
|
||||
return kb;
|
||||
}
|
||||
}
|
||||
if (!key) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
return static_cast<KeyBlock *>(BLI_findlink(&key->block, index));
|
||||
}
|
||||
|
||||
KeyBlock *BKE_keyblock_find_name(Key *key, const char name[])
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
#include "BKE_idtype.h"
|
||||
#include "BKE_lattice.hh"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_query.hh"
|
||||
#include "BKE_main.hh"
|
||||
#include "BKE_modifier.hh"
|
||||
#include "BKE_object.hh"
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
#include "BKE_key.h"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_lib_override.hh"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_query.hh"
|
||||
#include "BKE_lib_remap.hh"
|
||||
#include "BKE_main.hh"
|
||||
#include "BKE_main_namemap.hh"
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
#include "BKE_layer.h"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_lib_override.hh"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_query.hh"
|
||||
#include "BKE_lib_remap.hh"
|
||||
#include "BKE_main.hh"
|
||||
#include "BKE_main_namemap.hh"
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#include "BKE_idprop.h"
|
||||
#include "BKE_idtype.h"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_query.hh"
|
||||
#include "BKE_main.hh"
|
||||
#include "BKE_node.h"
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include "BKE_curve.hh"
|
||||
#include "BKE_layer.h"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_query.hh"
|
||||
#include "BKE_lib_remap.hh"
|
||||
#include "BKE_main.hh"
|
||||
#include "BKE_material.h"
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include "BKE_bpath.h"
|
||||
#include "BKE_idtype.h"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_query.hh"
|
||||
#include "BKE_library.hh"
|
||||
#include "BKE_main.hh"
|
||||
#include "BKE_main_namemap.hh"
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#include "BKE_icons.h"
|
||||
#include "BKE_idtype.h"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_query.hh"
|
||||
#include "BKE_light.h"
|
||||
#include "BKE_main.hh"
|
||||
#include "BKE_node.h"
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include "BKE_anim_data.h"
|
||||
#include "BKE_idtype.h"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_query.hh"
|
||||
#include "BKE_lightprobe.h"
|
||||
#include "BKE_main.hh"
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
#include "BKE_freestyle.h"
|
||||
#include "BKE_idtype.h"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_query.hh"
|
||||
#include "BKE_linestyle.h"
|
||||
#include "BKE_main.hh"
|
||||
#include "BKE_node.hh"
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#include "BKE_global.h"
|
||||
#include "BKE_idtype.h"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_query.hh"
|
||||
#include "BKE_lib_remap.hh"
|
||||
#include "BKE_main.hh"
|
||||
#include "BKE_main_idmap.hh"
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#include "BKE_anim_data.h"
|
||||
#include "BKE_image.h"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_query.hh"
|
||||
#include "BKE_main.hh"
|
||||
#include "BKE_mask.h"
|
||||
#include "BKE_movieclip.h"
|
||||
|
|
|
@ -56,7 +56,7 @@
|
|||
#include "BKE_idtype.h"
|
||||
#include "BKE_image.h"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_query.hh"
|
||||
#include "BKE_main.hh"
|
||||
#include "BKE_material.h"
|
||||
#include "BKE_mesh.hh"
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
#include "BKE_lattice.hh"
|
||||
#include "BKE_layer.h"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_query.hh"
|
||||
#include "BKE_material.h"
|
||||
#include "BKE_mball.h"
|
||||
#include "BKE_mball_tessellate.h"
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
#include "BKE_idtype.h"
|
||||
#include "BKE_key.h"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_query.hh"
|
||||
#include "BKE_main.hh"
|
||||
#include "BKE_material.h"
|
||||
#include "BKE_mesh.hh"
|
||||
|
@ -645,6 +645,25 @@ MutableSpan<MDeformVert> Mesh::deform_verts_for_write()
|
|||
|
||||
namespace blender::bke {
|
||||
|
||||
void mesh_ensure_default_color_attribute_on_add(Mesh &mesh,
|
||||
const AttributeIDRef &id,
|
||||
AttrDomain domain,
|
||||
eCustomDataType data_type)
|
||||
{
|
||||
if (id.is_anonymous()) {
|
||||
return;
|
||||
}
|
||||
if (!(CD_TYPE_AS_MASK(data_type) & CD_MASK_COLOR_ALL) ||
|
||||
!(ATTR_DOMAIN_AS_MASK(domain) & ATTR_DOMAIN_MASK_COLOR))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (mesh.default_color_attribute) {
|
||||
return;
|
||||
}
|
||||
mesh.default_color_attribute = BLI_strdupn(id.name().data(), id.name().size());
|
||||
}
|
||||
|
||||
static void mesh_ensure_cdlayers_primary(Mesh &mesh)
|
||||
{
|
||||
MutableAttributeAccessor attributes = mesh.attributes_for_write();
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#include "BKE_geometry_set_instances.hh"
|
||||
#include "BKE_key.h"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_query.hh"
|
||||
#include "BKE_main.hh"
|
||||
#include "BKE_material.h"
|
||||
#include "BKE_mball.h"
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include "DNA_object_types.h"
|
||||
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_query.hh"
|
||||
#include "BKE_mesh.hh"
|
||||
#include "BKE_mesh_fair.hh"
|
||||
#include "BKE_mesh_mapping.hh"
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include "BKE_attribute.hh"
|
||||
#include "BKE_deform.h"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_query.hh"
|
||||
#include "BKE_mesh.hh"
|
||||
#include "BKE_mesh_mirror.hh"
|
||||
#include "BKE_modifier.hh"
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
#include "BKE_idtype.h"
|
||||
#include "BKE_key.h"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_query.hh"
|
||||
#include "BKE_mesh.hh"
|
||||
#include "BKE_mesh_wrapper.hh"
|
||||
#include "BKE_multires.hh"
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
#include "BKE_idtype.h"
|
||||
#include "BKE_image.h" /* openanim */
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_query.hh"
|
||||
#include "BKE_main.hh"
|
||||
#include "BKE_movieclip.h"
|
||||
#include "BKE_node.h"
|
||||
|
@ -142,10 +142,10 @@ static void movie_clip_foreach_cache(ID *id,
|
|||
MovieClip *movie_clip = (MovieClip *)id;
|
||||
IDCacheKey key{};
|
||||
key.id_session_uuid = id->session_uuid;
|
||||
key.offset_in_ID = offsetof(MovieClip, cache);
|
||||
key.identifier = offsetof(MovieClip, cache);
|
||||
function_callback(id, &key, (void **)&movie_clip->cache, 0, user_data);
|
||||
|
||||
key.offset_in_ID = offsetof(MovieClip, tracking.camera.intrinsics);
|
||||
key.identifier = offsetof(MovieClip, tracking.camera.intrinsics);
|
||||
function_callback(id, &key, (void **)&movie_clip->tracking.camera.intrinsics, 0, user_data);
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
#include "BKE_fcurve.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_query.hh"
|
||||
#include "BKE_main.hh"
|
||||
#include "BKE_nla.h"
|
||||
#include "BKE_sound.h"
|
||||
|
|
|
@ -63,7 +63,7 @@
|
|||
#include "BKE_idtype.h"
|
||||
#include "BKE_image_format.h"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_query.hh"
|
||||
#include "BKE_main.hh"
|
||||
#include "BKE_node.hh"
|
||||
#include "BKE_node_runtime.hh"
|
||||
|
@ -400,7 +400,7 @@ static void node_foreach_cache(ID *id,
|
|||
bNodeTree *nodetree = reinterpret_cast<bNodeTree *>(id);
|
||||
IDCacheKey key = {0};
|
||||
key.id_session_uuid = id->session_uuid;
|
||||
key.offset_in_ID = offsetof(bNodeTree, previews);
|
||||
key.identifier = offsetof(bNodeTree, previews);
|
||||
|
||||
/* TODO: see also `direct_link_nodetree()` in `readfile.cc`. */
|
||||
#if 0
|
||||
|
@ -410,7 +410,7 @@ static void node_foreach_cache(ID *id,
|
|||
if (nodetree->type == NTREE_COMPOSIT) {
|
||||
for (bNode *node : nodetree->all_nodes()) {
|
||||
if (node->type == CMP_NODE_MOVIEDISTORTION) {
|
||||
key.offset_in_ID = size_t(BLI_ghashutil_strhash_p(node->name));
|
||||
key.identifier = size_t(BLI_ghashutil_strhash_p(node->name));
|
||||
function_callback(id, &key, static_cast<void **>(&node->storage), 0, user_data);
|
||||
}
|
||||
}
|
||||
|
@ -2529,6 +2529,7 @@ bNode *nodeAddNode(const bContext *C, bNodeTree *ntree, const char *idname)
|
|||
node->runtime = MEM_new<bNodeRuntime>(__func__);
|
||||
BLI_addtail(&ntree->nodes, node);
|
||||
nodeUniqueID(ntree, node);
|
||||
node->ui_order = ntree->all_nodes().size();
|
||||
|
||||
STRNCPY(node->idname, idname);
|
||||
blender::bke::node_set_typeinfo(C, ntree, node, nodeTypeFind(idname));
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
#include "BKE_idprop.h"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_query.hh"
|
||||
#include "BKE_node.hh"
|
||||
#include "BKE_node_tree_interface.hh"
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue