GPv3: Tint and Color modifiers #117297
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -8,7 +8,6 @@ from bpy.props import (
|
|||
BoolProperty,
|
||||
EnumProperty,
|
||||
)
|
||||
from bpy_extras.object_utils import object_report_if_active_shape_key_is_locked
|
||||
|
||||
|
||||
class VIEW3D_OT_edit_mesh_extrude_individual_move(Operator):
|
||||
|
@ -22,6 +21,8 @@ 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'}
|
||||
|
||||
|
@ -88,6 +89,8 @@ class VIEW3D_OT_edit_mesh_extrude_move(Operator):
|
|||
|
||||
@staticmethod
|
||||
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'}
|
||||
|
||||
|
@ -187,6 +190,8 @@ class VIEW3D_OT_edit_mesh_extrude_manifold_normal(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'}
|
||||
bpy.ops.mesh.extrude_manifold(
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
@ -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. */
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -587,6 +587,22 @@ static void object_foreach_path(ID *id, BPathForeachPathData *bpath_data)
|
|||
}
|
||||
}
|
||||
|
||||
static void object_foreach_cache(ID *id,
|
||||
IDTypeForeachCacheFunctionCallback function_callback,
|
||||
void *user_data)
|
||||
{
|
||||
Object *ob = reinterpret_cast<Object *>(id);
|
||||
LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
|
||||
if (const ModifierTypeInfo *info = BKE_modifier_get_info(ModifierType(md->type))) {
|
||||
if (info->foreach_cache) {
|
||||
info->foreach_cache(ob, md, [&](const IDCacheKey &cache_key, void **cache_p, uint flags) {
|
||||
function_callback(id, &cache_key, cache_p, flags, user_data);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void object_blend_write(BlendWriter *writer, ID *id, const void *id_address)
|
||||
{
|
||||
Object *ob = (Object *)id;
|
||||
|
@ -1069,7 +1085,7 @@ IDTypeInfo IDType_ID_OB = {
|
|||
/*free_data*/ object_free_data,
|
||||
/*make_local*/ nullptr,
|
||||
/*foreach_id*/ object_foreach_id,
|
||||
/*foreach_cache*/ nullptr,
|
||||
/*foreach_cache*/ object_foreach_cache,
|
||||
/*foreach_path*/ object_foreach_path,
|
||||
/*owner_pointer_get*/ nullptr,
|
||||
|
||||
|
|
|
@ -966,7 +966,7 @@ static void scene_foreach_cache(ID *id,
|
|||
Scene *scene = (Scene *)id;
|
||||
IDCacheKey key{};
|
||||
key.id_session_uuid = id->session_uuid;
|
||||
key.offset_in_ID = offsetof(Scene, eevee.light_cache_data);
|
||||
key.identifier = offsetof(Scene, eevee.light_cache_data);
|
||||
|
||||
function_callback(id,
|
||||
&key,
|
||||
|
@ -2355,7 +2355,7 @@ bool BKE_scene_validate_setscene(Main *bmain, Scene *sce)
|
|||
for (a = 0, sce_iter = sce; sce_iter->set; sce_iter = sce_iter->set, a++) {
|
||||
/* more iterations than scenes means we have a cycle */
|
||||
if (a > totscene) {
|
||||
/* the tested scene gets zero'ed, that's typically current scene */
|
||||
/* The tested scene gets zeroed, that's typically current scene. */
|
||||
sce->set = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -122,7 +122,7 @@ static void sound_foreach_cache(ID *id,
|
|||
bSound *sound = (bSound *)id;
|
||||
IDCacheKey key{};
|
||||
key.id_session_uuid = id->session_uuid;
|
||||
key.offset_in_ID = offsetof(bSound, waveform);
|
||||
key.identifier = offsetof(bSound, waveform);
|
||||
|
||||
function_callback(id, &key, &sound->waveform, 0, user_data);
|
||||
}
|
||||
|
|
|
@ -203,8 +203,7 @@ static void volume_foreach_cache(ID *id,
|
|||
Volume *volume = (Volume *)id;
|
||||
IDCacheKey key = {
|
||||
/*id_session_uuid*/ id->session_uuid,
|
||||
/* This is just some identifier and does not have to be an actual offset. */
|
||||
/*offset_in_ID*/ 1,
|
||||
/*identifier*/ 1,
|
||||
};
|
||||
|
||||
function_callback(id, &key, (void **)&volume->runtime->grids, 0, user_data);
|
||||
|
|
|
@ -187,18 +187,18 @@ static void bicubic_interpolation(
|
|||
}
|
||||
else {
|
||||
if (components == 1) {
|
||||
output[0] = (uchar)(out[0] + 0.5f);
|
||||
output[0] = uchar(out[0] + 0.5f);
|
||||
}
|
||||
else if (components == 3) {
|
||||
output[0] = (uchar)(out[0] + 0.5f);
|
||||
output[1] = (uchar)(out[1] + 0.5f);
|
||||
output[2] = (uchar)(out[2] + 0.5f);
|
||||
output[0] = uchar(out[0] + 0.5f);
|
||||
output[1] = uchar(out[1] + 0.5f);
|
||||
output[2] = uchar(out[2] + 0.5f);
|
||||
}
|
||||
else {
|
||||
output[0] = (uchar)(out[0] + 0.5f);
|
||||
output[1] = (uchar)(out[1] + 0.5f);
|
||||
output[2] = (uchar)(out[2] + 0.5f);
|
||||
output[3] = (uchar)(out[3] + 0.5f);
|
||||
output[0] = uchar(out[0] + 0.5f);
|
||||
output[1] = uchar(out[1] + 0.5f);
|
||||
output[2] = uchar(out[2] + 0.5f);
|
||||
output[3] = uchar(out[3] + 0.5f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -235,7 +235,7 @@ BLI_INLINE void bilinear_interpolation_fl(const float *float_buffer,
|
|||
|
||||
x1 = (int)uf;
|
||||
x2 = x1 + 1;
|
||||
y1 = (int)vf;
|
||||
y1 = int(vf);
|
||||
y2 = y1 + 1;
|
||||
|
||||
const float *row1, *row2, *row3, *row4;
|
||||
|
@ -376,9 +376,9 @@ void BLI_bilinear_interpolation_char(
|
|||
_mm_storeu_ps((float *)xcoord, _mm_castsi128_ps(x1234));
|
||||
_mm_storeu_ps((float *)ycoord, _mm_castsi128_ps(y1234));
|
||||
int sample1 = ((const int *)buffer)[ycoord[0] * (int64_t)width + xcoord[0]];
|
||||
int sample2 = ((const int *)buffer)[ycoord[1] * (int64_t)width + xcoord[1]];
|
||||
int sample3 = ((const int *)buffer)[ycoord[2] * (int64_t)width + xcoord[2]];
|
||||
int sample4 = ((const int *)buffer)[ycoord[3] * (int64_t)width + xcoord[3]];
|
||||
int sample2 = ((const int *)buffer)[ycoord[1] * int64_t(width) + xcoord[1]];
|
||||
int sample3 = ((const int *)buffer)[ycoord[2] * int64_t(width) + xcoord[2]];
|
||||
int sample4 = ((const int *)buffer)[ycoord[3] * int64_t(width) + xcoord[3]];
|
||||
__m128i samples1234 = _mm_set_epi32(sample4, sample3, sample2, sample1);
|
||||
/* Set samples to black for the ones that were actually invalid. */
|
||||
samples1234 = _mm_andnot_si128(invalid_1234, samples1234);
|
||||
|
@ -577,7 +577,7 @@ void BLI_ewa_imp2radangle(
|
|||
*a = sqrtf(A > C ? A : C);
|
||||
*b = 0.0f;
|
||||
*ecc = 1e10f;
|
||||
*th = 0.5f * (atan2f(B, A - C) + (float)M_PI);
|
||||
*th = 0.5f * (atan2f(B, A - C) + float(M_PI));
|
||||
}
|
||||
else {
|
||||
const float AmC = A - C, ApC = A + C, F2 = F * 2.0f;
|
||||
|
@ -594,7 +594,7 @@ void BLI_ewa_imp2radangle(
|
|||
*ecc = *a / *b;
|
||||
}
|
||||
/* Increase theta by `0.5 * pi` (angle of major axis). */
|
||||
*th = 0.5f * (atan2f(B, AmC) + (float)M_PI);
|
||||
*th = 0.5f * (atan2f(B, AmC) + float(M_PI));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -645,15 +645,15 @@ void BLI_ewa_filter(const int width,
|
|||
|
||||
ue = ff * sqrtf(C);
|
||||
ve = ff * sqrtf(A);
|
||||
d = (float)(EWA_MAXIDX + 1) / (F * ff2);
|
||||
d = float(EWA_MAXIDX + 1) / (F * ff2);
|
||||
A *= d;
|
||||
B *= d;
|
||||
C *= d;
|
||||
|
||||
U0 = uv[0] * (float)width;
|
||||
V0 = uv[1] * (float)height;
|
||||
u1 = (int)floorf(U0 - ue);
|
||||
u2 = (int)ceilf(U0 + ue);
|
||||
U0 = uv[0] * float(width);
|
||||
V0 = uv[1] * float(height);
|
||||
u1 = int(floorf(U0 - ue));
|
||||
u2 = int(ceilf(U0 + ue));
|
||||
v1 = (int)floorf(V0 - ve);
|
||||
v2 = (int)ceilf(V0 + ve);
|
||||
|
||||
|
@ -661,17 +661,17 @@ void BLI_ewa_filter(const int width,
|
|||
/* NOTE: if eccentricity gets clamped (see above),
|
||||
* the ue/ve limits can also be lowered accordingly
|
||||
*/
|
||||
if (U0 - (float)u1 > EWA_MAXIDX) {
|
||||
u1 = (int)U0 - EWA_MAXIDX;
|
||||
if (U0 - float(u1) > EWA_MAXIDX) {
|
||||
u1 = int(U0) - EWA_MAXIDX;
|
||||
}
|
||||
if ((float)u2 - U0 > EWA_MAXIDX) {
|
||||
u2 = (int)U0 + EWA_MAXIDX;
|
||||
if (float(u2) - U0 > EWA_MAXIDX) {
|
||||
u2 = int(U0) + EWA_MAXIDX;
|
||||
}
|
||||
if (V0 - (float)v1 > EWA_MAXIDX) {
|
||||
v1 = (int)V0 - EWA_MAXIDX;
|
||||
if (V0 - float(v1) > EWA_MAXIDX) {
|
||||
v1 = int(V0) - EWA_MAXIDX;
|
||||
}
|
||||
if ((float)v2 - V0 > EWA_MAXIDX) {
|
||||
v2 = (int)V0 + EWA_MAXIDX;
|
||||
v2 = int(V0) + EWA_MAXIDX;
|
||||
}
|
||||
|
||||
/* Early output check for cases the whole region is outside of the buffer. */
|
||||
|
@ -683,7 +683,7 @@ void BLI_ewa_filter(const int width,
|
|||
U0 -= 0.5f;
|
||||
V0 -= 0.5f;
|
||||
DDQ = 2.0f * A;
|
||||
U = (float)u1 - U0;
|
||||
U = float(u1) - U0;
|
||||
ac1 = A * (2.0f * U + 1.0f);
|
||||
ac2 = A * U * U;
|
||||
BU = B * U;
|
||||
|
@ -695,9 +695,9 @@ void BLI_ewa_filter(const int width,
|
|||
float DQ = ac1 + B * V;
|
||||
float Q = (C * V + BU) * V + ac2;
|
||||
for (u = u1; u <= u2; u++) {
|
||||
if (Q < (float)(EWA_MAXIDX + 1)) {
|
||||
if (Q < float(EWA_MAXIDX + 1)) {
|
||||
float tc[4];
|
||||
const float wt = EWA_WTS[(Q < 0.0f) ? 0 : (uint)Q];
|
||||
const float wt = EWA_WTS[(Q < 0.0f) ? 0 : uint(Q)];
|
||||
read_pixel_cb(userdata, u, v, tc);
|
||||
madd_v3_v3fl(result, tc, wt);
|
||||
result[3] += use_alpha ? tc[3] * wt : 0.0f;
|
||||
|
|
|
@ -833,13 +833,17 @@ void DepsgraphNodeBuilder::build_object(int base_index,
|
|||
build_texture(object->pd->tex);
|
||||
}
|
||||
|
||||
/* Object dupligroup. */
|
||||
/* Object instancing. */
|
||||
if (object->instance_collection != nullptr) {
|
||||
build_object_instance_collection(object, is_visible);
|
||||
OperationNode *op_node = add_operation_node(
|
||||
&object->id, NodeType::DUPLI, OperationCode::DUPLI);
|
||||
op_node->flag |= OperationFlag::DEPSOP_FLAG_PINNED;
|
||||
|
||||
OperationNode *instancer_node = add_operation_node(
|
||||
&object->id, NodeType::INSTANCING, OperationCode::INSTANCER);
|
||||
instancer_node->flag |= OperationFlag::DEPSOP_FLAG_PINNED;
|
||||
}
|
||||
OperationNode *instance_node = add_operation_node(
|
||||
&object->id, NodeType::INSTANCING, OperationCode::INSTANCE);
|
||||
instance_node->flag |= OperationFlag::DEPSOP_FLAG_PINNED;
|
||||
|
||||
build_object_light_linking(object);
|
||||
|
||||
|
@ -1179,6 +1183,10 @@ void DepsgraphNodeBuilder::build_object_shading(Object *object)
|
|||
NodeType::SHADING,
|
||||
OperationCode::SHADING,
|
||||
[object_cow](::Depsgraph *depsgraph) { BKE_object_eval_shading(depsgraph, object_cow); });
|
||||
|
||||
OperationNode *done_node = add_operation_node(
|
||||
&object->id, NodeType::SHADING, OperationCode::SHADING_DONE);
|
||||
done_node->set_as_exit();
|
||||
}
|
||||
|
||||
void DepsgraphNodeBuilder::build_animdata(ID *id)
|
||||
|
|
|
@ -690,17 +690,9 @@ void DepsgraphRelationBuilder::build_collection(LayerCollection *from_layer_coll
|
|||
const ComponentKey object_hierarchy_key{&object->id, NodeType::HIERARCHY};
|
||||
add_relation(collection_hierarchy_key, object_hierarchy_key, "Collection -> Object hierarchy");
|
||||
|
||||
/* The geometry of a collection depends on the positions of the elements in it. */
|
||||
const OperationKey object_transform_key{
|
||||
&object->id, NodeType::TRANSFORM, OperationCode::TRANSFORM_FINAL};
|
||||
add_relation(object_transform_key, collection_geometry_key, "Collection Geometry");
|
||||
|
||||
/* Only create geometry relations to child objects, if they have a geometry component. */
|
||||
const OperationKey object_geometry_key{
|
||||
&object->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL};
|
||||
if (find_node(object_geometry_key) != nullptr) {
|
||||
add_relation(object_geometry_key, collection_geometry_key, "Collection Geometry");
|
||||
}
|
||||
const OperationKey object_instance_key{
|
||||
&object->id, NodeType::INSTANCING, OperationCode::INSTANCE};
|
||||
add_relation(object_instance_key, collection_geometry_key, "Collection Geometry");
|
||||
|
||||
/* An instance is part of the geometry of the collection. */
|
||||
if (object->type == OB_EMPTY) {
|
||||
|
@ -758,6 +750,10 @@ void DepsgraphRelationBuilder::build_object(Object *object)
|
|||
add_relation(local_transform_key, parent_transform_key, "ObLocal -> ObParent");
|
||||
}
|
||||
|
||||
add_relation(ComponentKey(&object->id, NodeType::TRANSFORM),
|
||||
OperationKey{&object->id, NodeType::INSTANCING, OperationCode::INSTANCE},
|
||||
"Transform -> Instance");
|
||||
|
||||
/* Modifiers. */
|
||||
build_object_modifiers(object);
|
||||
|
||||
|
@ -831,6 +827,8 @@ void DepsgraphRelationBuilder::build_object(Object *object)
|
|||
|
||||
build_object_instance_collection(object);
|
||||
build_object_pointcache(object);
|
||||
|
||||
build_object_shading(object);
|
||||
build_object_light_linking(object);
|
||||
|
||||
/* Synchronization back to original object. */
|
||||
|
@ -1257,31 +1255,47 @@ void DepsgraphRelationBuilder::build_object_instance_collection(Object *object)
|
|||
|
||||
const OperationKey object_transform_final_key(
|
||||
&object->id, NodeType::TRANSFORM, OperationCode::TRANSFORM_FINAL);
|
||||
const ComponentKey duplicator_key(&object->id, NodeType::DUPLI);
|
||||
const OperationKey instancer_key(&object->id, NodeType::INSTANCING, OperationCode::INSTANCER);
|
||||
|
||||
FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_BEGIN (instance_collection, ob, graph_->mode) {
|
||||
const ComponentKey dupli_transform_key(&ob->id, NodeType::TRANSFORM);
|
||||
add_relation(dupli_transform_key, object_transform_final_key, "Dupligroup");
|
||||
|
||||
/* Hook to special component, to ensure proper visibility/evaluation optimizations. */
|
||||
add_relation(dupli_transform_key, duplicator_key, "Dupligroup");
|
||||
const NodeType dupli_geometry_component_type = geometry_tag_to_component(&ob->id);
|
||||
if (dupli_geometry_component_type != NodeType::UNDEFINED) {
|
||||
ComponentKey dupli_geometry_component_key(&ob->id, dupli_geometry_component_type);
|
||||
add_relation(dupli_geometry_component_key, duplicator_key, "Dupligroup");
|
||||
}
|
||||
add_relation(OperationKey(&ob->id, NodeType::INSTANCING, OperationCode::INSTANCE),
|
||||
instancer_key,
|
||||
"Instance -> Instancer");
|
||||
}
|
||||
FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_END;
|
||||
}
|
||||
|
||||
void DepsgraphRelationBuilder::build_object_shading(Object *object)
|
||||
{
|
||||
const OperationKey shading_done_key(&object->id, NodeType::SHADING, OperationCode::SHADING_DONE);
|
||||
|
||||
const OperationKey shading_key(&object->id, NodeType::SHADING, OperationCode::SHADING);
|
||||
add_relation(shading_key, shading_done_key, "Shading -> Done");
|
||||
|
||||
/* Hook up shading component to the instance, so that if the object is instanced by a visible
|
||||
* object the shading component is ensured to be evaluated.
|
||||
* Don't to flushing to avoid re-evaluation of geometry when the object is used as part of a
|
||||
* collection used as a boolean modifier operand. */
|
||||
add_relation(shading_done_key,
|
||||
OperationKey(&object->id, NodeType::INSTANCING, OperationCode::INSTANCE),
|
||||
"Light Linking -> Instance",
|
||||
RELATION_FLAG_NO_FLUSH);
|
||||
}
|
||||
|
||||
void DepsgraphRelationBuilder::build_object_light_linking(Object *emitter)
|
||||
{
|
||||
const ComponentKey hierarchy_key(&emitter->id, NodeType::HIERARCHY);
|
||||
|
||||
const OperationKey shading_done_key(
|
||||
&emitter->id, NodeType::SHADING, OperationCode::SHADING_DONE);
|
||||
const OperationKey light_linking_key(
|
||||
&emitter->id, NodeType::SHADING, OperationCode::LIGHT_LINKING_UPDATE);
|
||||
|
||||
add_relation(hierarchy_key, light_linking_key, "Light Linking From Layer");
|
||||
add_relation(light_linking_key, shading_done_key, "Light Linking -> Shading Done");
|
||||
|
||||
if (emitter->light_linking) {
|
||||
LightLinking &light_linking = *emitter->light_linking;
|
||||
|
@ -2477,6 +2491,10 @@ void DepsgraphRelationBuilder::build_object_data_geometry(Object *object)
|
|||
* evaluated prior to Scene's CoW is ready. */
|
||||
OperationKey scene_key(&scene_->id, NodeType::PARAMETERS, OperationCode::SCENE_EVAL);
|
||||
add_relation(scene_key, obdata_ubereval_key, "CoW Relation", RELATION_FLAG_NO_FLUSH);
|
||||
/* Relation to the instance, so that instancer can use geometry of this object. */
|
||||
add_relation(ComponentKey(&object->id, NodeType::GEOMETRY),
|
||||
OperationKey(&object->id, NodeType::INSTANCING, OperationCode::INSTANCE),
|
||||
"Transform -> Instance");
|
||||
/* Grease Pencil Modifiers. */
|
||||
if (object->greasepencil_modifiers.first != nullptr) {
|
||||
ModifierUpdateDepsgraphContext ctx = {};
|
||||
|
|
|
@ -153,6 +153,8 @@ class DepsgraphRelationBuilder : public DepsgraphBuilder {
|
|||
virtual void build_object_pointcache(Object *object);
|
||||
virtual void build_object_instance_collection(Object *object);
|
||||
|
||||
virtual void build_object_shading(Object *object);
|
||||
|
||||
virtual void build_object_light_linking(Object *emitter);
|
||||
virtual void build_light_linking_collection(Object *emitter, Collection *collection);
|
||||
|
||||
|
|
|
@ -306,6 +306,11 @@ void DepsgraphRelationBuilder::build_rig(Object *object)
|
|||
add_relation(armature_key, pose_init_key, "Data dependency");
|
||||
/* Run cleanup even when there are no bones. */
|
||||
add_relation(pose_init_key, pose_cleanup_key, "Init -> Cleanup");
|
||||
/* Relation to the instance, so that instancer can use pose of this object. */
|
||||
add_relation(ComponentKey(&object->id, NodeType::EVAL_POSE),
|
||||
OperationKey{&object->id, NodeType::INSTANCING, OperationCode::INSTANCE},
|
||||
"Transform -> Instance");
|
||||
|
||||
/* IK Solvers.
|
||||
*
|
||||
* - These require separate processing steps are pose-level to be executed
|
||||
|
|
|
@ -407,7 +407,7 @@ static void deg_debug_graphviz_node(DotExportContext &ctx,
|
|||
case NodeType::OBJECT_FROM_LAYER:
|
||||
case NodeType::HIERARCHY:
|
||||
case NodeType::BATCH_CACHE:
|
||||
case NodeType::DUPLI:
|
||||
case NodeType::INSTANCING:
|
||||
case NodeType::SYNCHRONIZATION:
|
||||
case NodeType::AUDIO:
|
||||
case NodeType::ARMATURE:
|
||||
|
|
|
@ -87,8 +87,8 @@ const char *nodeTypeAsString(NodeType type)
|
|||
return "IMAGE_ANIMATION";
|
||||
case NodeType::BATCH_CACHE:
|
||||
return "BATCH_CACHE";
|
||||
case NodeType::DUPLI:
|
||||
return "DUPLI";
|
||||
case NodeType::INSTANCING:
|
||||
return "INSTANCING";
|
||||
case NodeType::SYNCHRONIZATION:
|
||||
return "SYNCHRONIZATION";
|
||||
case NodeType::AUDIO:
|
||||
|
@ -150,7 +150,7 @@ eDepsSceneComponentType nodeTypeToSceneComponent(NodeType type)
|
|||
case NodeType::POINT_CACHE:
|
||||
case NodeType::IMAGE_ANIMATION:
|
||||
case NodeType::BATCH_CACHE:
|
||||
case NodeType::DUPLI:
|
||||
case NodeType::INSTANCING:
|
||||
case NodeType::SYNCHRONIZATION:
|
||||
case NodeType::UNDEFINED:
|
||||
case NodeType::NUM_TYPES:
|
||||
|
@ -233,7 +233,7 @@ eDepsObjectComponentType nodeTypeToObjectComponent(NodeType type)
|
|||
case NodeType::POINT_CACHE:
|
||||
case NodeType::IMAGE_ANIMATION:
|
||||
case NodeType::BATCH_CACHE:
|
||||
case NodeType::DUPLI:
|
||||
case NodeType::INSTANCING:
|
||||
case NodeType::SYNCHRONIZATION:
|
||||
case NodeType::NTREE_OUTPUT:
|
||||
case NodeType::NTREE_GEOMETRY_PREPROCESS:
|
||||
|
|
|
@ -124,9 +124,9 @@ enum class NodeType {
|
|||
/* Batch Cache Component.
|
||||
* TODO(dfelinto/sergey): rename to make it more generic. */
|
||||
BATCH_CACHE,
|
||||
/* Duplication system. Used to force duplicated objects visible when
|
||||
* when duplicator is visible. */
|
||||
DUPLI,
|
||||
/* Instancing system.
|
||||
* Used to control visibility flags of dependencies. */
|
||||
INSTANCING,
|
||||
/* Synchronization back to original datablock. */
|
||||
SYNCHRONIZATION,
|
||||
/* Node tree output component. */
|
||||
|
|
|
@ -333,7 +333,7 @@ DEG_COMPONENT_NODE_DEFINE(Shading, SHADING, ID_RECALC_SHADING);
|
|||
DEG_COMPONENT_NODE_DEFINE(Transform, TRANSFORM, ID_RECALC_TRANSFORM);
|
||||
DEG_COMPONENT_NODE_DEFINE(ObjectFromLayer, OBJECT_FROM_LAYER, 0);
|
||||
DEG_COMPONENT_NODE_DEFINE(Hierarchy, HIERARCHY, 0);
|
||||
DEG_COMPONENT_NODE_DEFINE(Dupli, DUPLI, 0);
|
||||
DEG_COMPONENT_NODE_DEFINE(Instancing, INSTANCING, 0);
|
||||
DEG_COMPONENT_NODE_DEFINE(Synchronization, SYNCHRONIZATION, 0);
|
||||
DEG_COMPONENT_NODE_DEFINE(Audio, AUDIO, 0);
|
||||
DEG_COMPONENT_NODE_DEFINE(Armature, ARMATURE, 0);
|
||||
|
@ -368,7 +368,7 @@ void deg_register_component_depsnodes()
|
|||
register_node_typeinfo(&DNTI_TRANSFORM);
|
||||
register_node_typeinfo(&DNTI_OBJECT_FROM_LAYER);
|
||||
register_node_typeinfo(&DNTI_HIERARCHY);
|
||||
register_node_typeinfo(&DNTI_DUPLI);
|
||||
register_node_typeinfo(&DNTI_INSTANCING);
|
||||
register_node_typeinfo(&DNTI_SYNCHRONIZATION);
|
||||
register_node_typeinfo(&DNTI_AUDIO);
|
||||
register_node_typeinfo(&DNTI_ARMATURE);
|
||||
|
|
|
@ -202,7 +202,7 @@ DEG_COMPONENT_NODE_DECLARE_GENERIC(ShadingParameters);
|
|||
DEG_COMPONENT_NODE_DECLARE_GENERIC(Transform);
|
||||
DEG_COMPONENT_NODE_DECLARE_NO_COW_TAG_ON_UPDATE(ObjectFromLayer);
|
||||
DEG_COMPONENT_NODE_DECLARE_NO_COW_TAG_ON_UPDATE(Hierarchy);
|
||||
DEG_COMPONENT_NODE_DECLARE_GENERIC(Dupli);
|
||||
DEG_COMPONENT_NODE_DECLARE_GENERIC(Instancing);
|
||||
DEG_COMPONENT_NODE_DECLARE_GENERIC(Synchronization);
|
||||
DEG_COMPONENT_NODE_DECLARE_GENERIC(Audio);
|
||||
DEG_COMPONENT_NODE_DECLARE_GENERIC(Armature);
|
||||
|
|
|
@ -168,6 +168,8 @@ const char *operationCodeAsString(OperationCode opcode)
|
|||
/* Shading. */
|
||||
case OperationCode::SHADING:
|
||||
return "SHADING";
|
||||
case OperationCode::SHADING_DONE:
|
||||
return "SHADING_DONE";
|
||||
case OperationCode::MATERIAL_UPDATE:
|
||||
return "MATERIAL_UPDATE";
|
||||
case OperationCode::LIGHT_UPDATE:
|
||||
|
@ -197,9 +199,11 @@ const char *operationCodeAsString(OperationCode opcode)
|
|||
/* Sequencer. */
|
||||
case OperationCode::SEQUENCES_EVAL:
|
||||
return "SEQUENCES_EVAL";
|
||||
/* instancing/duplication. */
|
||||
case OperationCode::DUPLI:
|
||||
return "DUPLI";
|
||||
/* instancing. */
|
||||
case OperationCode::INSTANCER:
|
||||
return "INSTANCER";
|
||||
case OperationCode::INSTANCE:
|
||||
return "INSTANCE";
|
||||
}
|
||||
BLI_assert_msg(0, "Unhandled operation code, should never happen.");
|
||||
return "UNKNOWN";
|
||||
|
|
|
@ -163,6 +163,7 @@ enum class OperationCode {
|
|||
|
||||
/* Shading. ------------------------------------------------------------- */
|
||||
SHADING,
|
||||
SHADING_DONE,
|
||||
MATERIAL_UPDATE,
|
||||
LIGHT_UPDATE,
|
||||
WORLD_UPDATE,
|
||||
|
@ -197,8 +198,13 @@ enum class OperationCode {
|
|||
|
||||
SEQUENCES_EVAL,
|
||||
|
||||
/* Duplication/instancing system. --------------------------------------- */
|
||||
DUPLI,
|
||||
/* instancing system. --------------------------------------------------- */
|
||||
|
||||
/* Operation on an instancer object. Relations from instanced objects go here. */
|
||||
INSTANCER,
|
||||
|
||||
/* Operation on an object which is being instanced. */
|
||||
INSTANCE,
|
||||
};
|
||||
const char *operationCodeAsString(OperationCode opcode);
|
||||
|
||||
|
|
|
@ -666,7 +666,7 @@ static void text_insert_unicode_confirm(bContext *C, void *arg_block, void *arg_
|
|||
return;
|
||||
}
|
||||
|
||||
uint val = strtoul(edit_string, NULL, 16);
|
||||
uint val = strtoul(edit_string, nullptr, 16);
|
||||
if (val > 31 && val < 0x10FFFF) {
|
||||
Object *obedit = CTX_data_edit_object(C);
|
||||
if (obedit) {
|
||||
|
|
|
@ -782,7 +782,7 @@ void uiPupBlockOperator(bContext *C,
|
|||
|
||||
void UI_popup_block_close(bContext *C, wmWindow *win, uiBlock *block);
|
||||
|
||||
bool UI_popup_block_name_exists(const bScreen *screen, const char *name);
|
||||
bool UI_popup_block_name_exists(const bScreen *screen, blender::StringRef name);
|
||||
|
||||
/* Blocks
|
||||
*
|
||||
|
@ -796,7 +796,7 @@ bool UI_popup_block_name_exists(const bScreen *screen, const char *name);
|
|||
|
||||
uiBlock *UI_block_begin(const bContext *C,
|
||||
ARegion *region,
|
||||
const char *name,
|
||||
std::string name,
|
||||
eUIEmbossType emboss);
|
||||
void UI_block_end_ex(const bContext *C, uiBlock *block, const int xy[2], int r_xy[2]);
|
||||
void UI_block_end(const bContext *C, uiBlock *block);
|
||||
|
|
|
@ -1593,7 +1593,7 @@ static void ui_menu_block_set_keymaps(const bContext *C, uiBlock *block)
|
|||
if (block->rect.xmin != block->rect.xmax) {
|
||||
return;
|
||||
}
|
||||
if (STREQ(block->name, "splash")) {
|
||||
if (block->name == "splash") {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3571,9 +3571,9 @@ void UI_blocklist_free_inactive(const bContext *C, ARegion *region)
|
|||
else {
|
||||
if (region->runtime.block_name_map != nullptr) {
|
||||
uiBlock *b = static_cast<uiBlock *>(
|
||||
BLI_ghash_lookup(region->runtime.block_name_map, block->name));
|
||||
BLI_ghash_lookup(region->runtime.block_name_map, block->name.c_str()));
|
||||
if (b == block) {
|
||||
BLI_ghash_remove(region->runtime.block_name_map, b->name, nullptr, nullptr);
|
||||
BLI_ghash_remove(region->runtime.block_name_map, b->name.c_str(), nullptr, nullptr);
|
||||
}
|
||||
}
|
||||
BLI_remlink(lb, block);
|
||||
|
@ -3594,7 +3594,7 @@ void UI_block_region_set(uiBlock *block, ARegion *region)
|
|||
if (region->runtime.block_name_map == nullptr) {
|
||||
region->runtime.block_name_map = BLI_ghash_str_new(__func__);
|
||||
}
|
||||
oldblock = (uiBlock *)BLI_ghash_lookup(region->runtime.block_name_map, block->name);
|
||||
oldblock = (uiBlock *)BLI_ghash_lookup(region->runtime.block_name_map, block->name.c_str());
|
||||
|
||||
if (oldblock) {
|
||||
oldblock->active = false;
|
||||
|
@ -3604,13 +3604,17 @@ void UI_block_region_set(uiBlock *block, ARegion *region)
|
|||
|
||||
/* at the beginning of the list! for dynamical menus/blocks */
|
||||
BLI_addhead(lb, block);
|
||||
BLI_ghash_reinsert(region->runtime.block_name_map, block->name, block, nullptr, nullptr);
|
||||
BLI_ghash_reinsert(region->runtime.block_name_map,
|
||||
const_cast<char *>(block->name.c_str()),
|
||||
block,
|
||||
nullptr,
|
||||
nullptr);
|
||||
}
|
||||
|
||||
block->oldblock = oldblock;
|
||||
}
|
||||
|
||||
uiBlock *UI_block_begin(const bContext *C, ARegion *region, const char *name, eUIEmbossType emboss)
|
||||
uiBlock *UI_block_begin(const bContext *C, ARegion *region, std::string name, eUIEmbossType emboss)
|
||||
{
|
||||
wmWindow *window = CTX_wm_window(C);
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
|
@ -3636,7 +3640,7 @@ uiBlock *UI_block_begin(const bContext *C, ARegion *region, const char *name, eU
|
|||
STRNCPY(block->display_device, IMB_colormanagement_display_get_default_name());
|
||||
}
|
||||
|
||||
STRNCPY(block->name, name);
|
||||
block->name = std::move(name);
|
||||
|
||||
if (region) {
|
||||
UI_block_region_set(block, region);
|
||||
|
@ -4481,18 +4485,14 @@ static void ui_def_but_rna__menu(bContext *C, uiLayout *layout, void *but_p)
|
|||
}
|
||||
}
|
||||
|
||||
static void ui_def_but_rna__panel_type(bContext *C, uiLayout *layout, void *but_p)
|
||||
static void ui_def_but_rna__panel_type(bContext *C, uiLayout *layout, void *arg)
|
||||
{
|
||||
uiBut *but = static_cast<uiBut *>(but_p);
|
||||
const char *panel_type = static_cast<const char *>(but->func_argN);
|
||||
PanelType *pt = WM_paneltype_find(panel_type, true);
|
||||
if (pt) {
|
||||
ui_item_paneltype_func(C, layout, pt);
|
||||
PanelType *panel_type = static_cast<PanelType *>(arg);
|
||||
if (panel_type) {
|
||||
ui_item_paneltype_func(C, layout, panel_type);
|
||||
}
|
||||
else {
|
||||
char msg[256];
|
||||
SNPRINTF(msg, RPT_("Missing Panel: %s"), panel_type);
|
||||
uiItemL(layout, msg, ICON_NONE);
|
||||
uiItemL(layout, RPT_("Missing Panel"), ICON_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4304,6 +4304,7 @@ static void ui_block_open_begin(bContext *C, uiBut *but, uiHandleButtonData *dat
|
|||
uiBlockHandleCreateFunc handlefunc = nullptr;
|
||||
uiMenuCreateFunc menufunc = nullptr;
|
||||
uiMenuCreateFunc popoverfunc = nullptr;
|
||||
PanelType *popover_panel_type = nullptr;
|
||||
void *arg = nullptr;
|
||||
|
||||
switch (but->type) {
|
||||
|
@ -4319,15 +4320,21 @@ static void ui_block_open_begin(bContext *C, uiBut *but, uiHandleButtonData *dat
|
|||
}
|
||||
break;
|
||||
case UI_BTYPE_MENU:
|
||||
case UI_BTYPE_POPOVER:
|
||||
BLI_assert(but->menu_create_func);
|
||||
if ((but->type == UI_BTYPE_POPOVER) || ui_but_menu_draw_as_popover(but)) {
|
||||
if (ui_but_menu_draw_as_popover(but)) {
|
||||
popoverfunc = but->menu_create_func;
|
||||
const char *idname = static_cast<const char *>(but->func_argN);
|
||||
popover_panel_type = WM_paneltype_find(idname, false);
|
||||
}
|
||||
else {
|
||||
menufunc = but->menu_create_func;
|
||||
arg = but->poin;
|
||||
}
|
||||
arg = but->poin;
|
||||
break;
|
||||
case UI_BTYPE_POPOVER:
|
||||
BLI_assert(but->menu_create_func);
|
||||
popoverfunc = but->menu_create_func;
|
||||
popover_panel_type = reinterpret_cast<PanelType *>(but->poin);
|
||||
break;
|
||||
case UI_BTYPE_COLOR:
|
||||
ui_but_v3_get(but, data->origvec);
|
||||
|
@ -4336,6 +4343,8 @@ static void ui_block_open_begin(bContext *C, uiBut *but, uiHandleButtonData *dat
|
|||
|
||||
if (ui_but_menu_draw_as_popover(but)) {
|
||||
popoverfunc = but->menu_create_func;
|
||||
const char *idname = static_cast<const char *>(but->func_argN);
|
||||
popover_panel_type = WM_paneltype_find(idname, false);
|
||||
}
|
||||
else {
|
||||
handlefunc = ui_block_func_COLOR;
|
||||
|
@ -4364,7 +4373,7 @@ static void ui_block_open_begin(bContext *C, uiBut *but, uiHandleButtonData *dat
|
|||
}
|
||||
}
|
||||
else if (popoverfunc) {
|
||||
data->menu = ui_popover_panel_create(C, data->region, but, popoverfunc, arg);
|
||||
data->menu = ui_popover_panel_create(C, data->region, but, popoverfunc, popover_panel_type);
|
||||
if (but->block->handle) {
|
||||
data->menu->popup = but->block->handle->popup;
|
||||
}
|
||||
|
|
|
@ -530,7 +530,7 @@ struct uiBlock {
|
|||
|
||||
ListBase dynamic_listeners; /* #uiBlockDynamicListener */
|
||||
|
||||
char name[UI_MAX_NAME_STR];
|
||||
std::string name;
|
||||
|
||||
float winmat[4][4];
|
||||
|
||||
|
@ -979,8 +979,11 @@ uiPopupBlockHandle *ui_popup_menu_create(
|
|||
|
||||
/* `interface_region_popover.cc` */
|
||||
|
||||
uiPopupBlockHandle *ui_popover_panel_create(
|
||||
bContext *C, ARegion *butregion, uiBut *but, uiMenuCreateFunc menu_func, void *arg);
|
||||
uiPopupBlockHandle *ui_popover_panel_create(bContext *C,
|
||||
ARegion *butregion,
|
||||
uiBut *but,
|
||||
uiMenuCreateFunc menu_func,
|
||||
const PanelType *panel_type);
|
||||
|
||||
/* `interface_region_menu_pie.cc` */
|
||||
|
||||
|
|
|
@ -2455,10 +2455,9 @@ int ui_handler_panel_region(bContext *C,
|
|||
if (panel == nullptr || panel->type == nullptr) {
|
||||
continue;
|
||||
}
|
||||
/* We can't expand or collapse panels without headers, they would disappear. */
|
||||
if (panel->type->flag & PANEL_TYPE_NO_HEADER) {
|
||||
continue;
|
||||
}
|
||||
/* We can't expand or collapse panels without headers, they would disappear. Layout panels can
|
||||
* be expanded and collpased though. */
|
||||
const bool has_panel_header = !(panel->type->flag & PANEL_TYPE_NO_HEADER);
|
||||
|
||||
int mx = event->xy[0];
|
||||
int my = event->xy[1];
|
||||
|
@ -2466,7 +2465,7 @@ int ui_handler_panel_region(bContext *C,
|
|||
|
||||
const uiPanelMouseState mouse_state = ui_panel_mouse_state_get(block, panel, mx, my);
|
||||
|
||||
if (mouse_state != PANEL_MOUSE_OUTSIDE) {
|
||||
if (has_panel_header && mouse_state != PANEL_MOUSE_OUTSIDE) {
|
||||
/* Mark panels that have been interacted with so their expansion
|
||||
* doesn't reset when property search finishes. */
|
||||
SET_FLAG_FROM_TEST(panel->flag, UI_panel_is_closed(panel), PNL_CLOSED);
|
||||
|
@ -2489,7 +2488,7 @@ int ui_handler_panel_region(bContext *C,
|
|||
continue;
|
||||
}
|
||||
|
||||
if (mouse_state == PANEL_MOUSE_INSIDE_HEADER) {
|
||||
if (has_panel_header && mouse_state == PANEL_MOUSE_INSIDE_HEADER) {
|
||||
/* All mouse clicks inside panel headers should return in break. */
|
||||
if (ELEM(event->type, EVT_RETKEY, EVT_PADENTER, LEFTMOUSE)) {
|
||||
retval = WM_UI_HANDLER_BREAK;
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "DNA_userdef_types.h"
|
||||
|
||||
#include "BLI_ghash.h"
|
||||
#include "BLI_hash.hh"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_math_vector.h"
|
||||
#include "BLI_rect.h"
|
||||
|
@ -42,6 +43,8 @@
|
|||
#include "interface_intern.hh"
|
||||
#include "interface_regions_intern.hh"
|
||||
|
||||
using blender::StringRef;
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Utility Functions
|
||||
* \{ */
|
||||
|
@ -86,25 +89,19 @@ int ui_but_menu_step(uiBut *but, int direction)
|
|||
* \note This is stored for each unique menu title.
|
||||
* \{ */
|
||||
|
||||
static uint ui_popup_string_hash(const char *str, const bool use_sep)
|
||||
static uint ui_popup_string_hash(const StringRef str, const bool use_sep)
|
||||
{
|
||||
/* sometimes button contains hotkey, sometimes not, strip for proper compare */
|
||||
int hash;
|
||||
const char *delimit = use_sep ? strrchr(str, UI_SEP_CHAR) : nullptr;
|
||||
const size_t sep_index = use_sep ? str.find_first_of(UI_SEP_CHAR) : StringRef::not_found;
|
||||
const StringRef before_hotkey = sep_index == StringRef::not_found ? str :
|
||||
str.substr(0, sep_index);
|
||||
|
||||
if (delimit) {
|
||||
hash = BLI_ghashutil_strhash_n(str, delimit - str);
|
||||
}
|
||||
else {
|
||||
hash = BLI_ghashutil_strhash(str);
|
||||
}
|
||||
|
||||
return hash;
|
||||
return blender::get_default_hash(before_hotkey);
|
||||
}
|
||||
|
||||
uint ui_popup_menu_hash(const char *str)
|
||||
uint ui_popup_menu_hash(const StringRef str)
|
||||
{
|
||||
return BLI_ghashutil_strhash(str);
|
||||
return blender::get_default_hash(str);
|
||||
}
|
||||
|
||||
/* but == nullptr read, otherwise set */
|
||||
|
@ -124,7 +121,7 @@ static uiBut *ui_popup_menu_memory__internal(uiBlock *block, uiBut *but)
|
|||
|
||||
if (but) {
|
||||
/* set */
|
||||
mem[hash_mod] = ui_popup_string_hash(but->str.c_str(), but->flag & UI_BUT_HAS_SEP_CHAR);
|
||||
mem[hash_mod] = ui_popup_string_hash(but->str, but->flag & UI_BUT_HAS_SEP_CHAR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -136,8 +133,7 @@ static uiBut *ui_popup_menu_memory__internal(uiBlock *block, uiBut *but)
|
|||
if (ELEM(but_iter->type, UI_BTYPE_LABEL, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE)) {
|
||||
continue;
|
||||
}
|
||||
if (mem[hash_mod] ==
|
||||
ui_popup_string_hash(but_iter->str.c_str(), but_iter->flag & UI_BUT_HAS_SEP_CHAR))
|
||||
if (mem[hash_mod] == ui_popup_string_hash(but_iter->str, but_iter->flag & UI_BUT_HAS_SEP_CHAR))
|
||||
{
|
||||
return but_iter;
|
||||
}
|
||||
|
@ -169,7 +165,7 @@ struct uiPopupMenu {
|
|||
ARegion *butregion;
|
||||
|
||||
/* Menu hash is created from this, to keep a memory of recently opened menus. */
|
||||
const char *title;
|
||||
StringRef title;
|
||||
|
||||
int mx, my;
|
||||
bool popup, slideout;
|
||||
|
@ -183,8 +179,8 @@ struct uiPopupMenu {
|
|||
*/
|
||||
static void ui_popup_menu_create_block(bContext *C,
|
||||
uiPopupMenu *pup,
|
||||
const char *title,
|
||||
const char *block_name)
|
||||
const StringRef title,
|
||||
const StringRef block_name)
|
||||
{
|
||||
const uiStyle *style = UI_style_get_dpi();
|
||||
|
||||
|
@ -198,7 +194,7 @@ static void ui_popup_menu_create_block(bContext *C,
|
|||
* for the same storage of the menu memory. Using idname instead (or in combination with the
|
||||
* label) for the hash could be looked at to solve this. */
|
||||
pup->block->flag |= UI_BLOCK_POPUP_MEMORY;
|
||||
if (title && title[0]) {
|
||||
if (!title.is_empty()) {
|
||||
pup->block->puphash = ui_popup_menu_hash(title);
|
||||
}
|
||||
pup->layout = UI_block_layout(
|
||||
|
@ -767,11 +763,11 @@ void UI_popup_block_close(bContext *C, wmWindow *win, uiBlock *block)
|
|||
}
|
||||
}
|
||||
|
||||
bool UI_popup_block_name_exists(const bScreen *screen, const char *name)
|
||||
bool UI_popup_block_name_exists(const bScreen *screen, const blender::StringRef name)
|
||||
{
|
||||
LISTBASE_FOREACH (const ARegion *, region, &screen->regionbase) {
|
||||
LISTBASE_FOREACH (const uiBlock *, block, ®ion->uiblocks) {
|
||||
if (STREQ(block->name, name)) {
|
||||
if (block->name == name) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ struct uiPopover {
|
|||
wmEventHandler_Keymap *keymap_handler;
|
||||
|
||||
uiMenuCreateFunc menu_func;
|
||||
void *menu_arg;
|
||||
const PanelType *menu_arg;
|
||||
|
||||
/* Size in pixels (ui scale applied). */
|
||||
int ui_size_x;
|
||||
|
@ -119,7 +119,7 @@ static uiBlock *ui_block_func_POPOVER(bContext *C, uiPopupBlockHandle *handle, v
|
|||
|
||||
if (pup->menu_func) {
|
||||
pup->block->handle = handle;
|
||||
pup->menu_func(C, pup->layout, pup->menu_arg);
|
||||
pup->menu_func(C, pup->layout, const_cast<PanelType *>(pup->menu_arg));
|
||||
pup->block->handle = nullptr;
|
||||
}
|
||||
|
||||
|
@ -239,12 +239,14 @@ static void ui_block_free_func_POPOVER(void *arg_pup)
|
|||
MEM_freeN(pup);
|
||||
}
|
||||
|
||||
uiPopupBlockHandle *ui_popover_panel_create(
|
||||
bContext *C, ARegion *butregion, uiBut *but, uiMenuCreateFunc menu_func, void *arg)
|
||||
uiPopupBlockHandle *ui_popover_panel_create(bContext *C,
|
||||
ARegion *butregion,
|
||||
uiBut *but,
|
||||
uiMenuCreateFunc menu_func,
|
||||
const PanelType *panel_type)
|
||||
{
|
||||
wmWindow *window = CTX_wm_window(C);
|
||||
const uiStyle *style = UI_style_get_dpi();
|
||||
const PanelType *panel_type = (PanelType *)arg;
|
||||
|
||||
/* Create popover, buttons are created from callback. */
|
||||
uiPopover *pup = MEM_cnew<uiPopover>(__func__);
|
||||
|
@ -261,7 +263,7 @@ uiPopupBlockHandle *ui_popover_panel_create(
|
|||
}
|
||||
|
||||
pup->menu_func = menu_func;
|
||||
pup->menu_arg = arg;
|
||||
pup->menu_arg = panel_type;
|
||||
|
||||
#ifdef USE_UI_POPOVER_ONCE
|
||||
{
|
||||
|
|
|
@ -10,9 +10,11 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "BLI_string_ref.hh"
|
||||
|
||||
/* interface_region_menu_popup.cc */
|
||||
|
||||
uint ui_popup_menu_hash(const char *str);
|
||||
uint ui_popup_menu_hash(blender::StringRef str);
|
||||
|
||||
/* interface_regions.cc */
|
||||
|
||||
|
|
|
@ -801,14 +801,15 @@ static MenuSearch_Data *menu_items_from_ui_create(bContext *C,
|
|||
}
|
||||
|
||||
if (region) {
|
||||
BLI_ghash_remove(region->runtime.block_name_map, sub_block->name, nullptr, nullptr);
|
||||
BLI_ghash_remove(
|
||||
region->runtime.block_name_map, sub_block->name.c_str(), nullptr, nullptr);
|
||||
BLI_remlink(®ion->uiblocks, sub_block);
|
||||
}
|
||||
UI_block_free(nullptr, sub_block);
|
||||
}
|
||||
}
|
||||
if (region) {
|
||||
BLI_ghash_remove(region->runtime.block_name_map, block->name, nullptr, nullptr);
|
||||
BLI_ghash_remove(region->runtime.block_name_map, block->name.c_str(), nullptr, nullptr);
|
||||
BLI_remlink(®ion->uiblocks, block);
|
||||
}
|
||||
UI_block_free(nullptr, block);
|
||||
|
|
|
@ -289,6 +289,9 @@ static bool compare_node_depth(const bNode *a, const bNode *b)
|
|||
void tree_draw_order_update(bNodeTree &ntree)
|
||||
{
|
||||
Array<bNode *> sort_nodes = ntree.all_nodes();
|
||||
std::sort(sort_nodes.begin(), sort_nodes.end(), [](bNode *a, bNode *b) {
|
||||
return a->ui_order < b->ui_order;
|
||||
});
|
||||
std::stable_sort(sort_nodes.begin(), sort_nodes.end(), compare_node_depth);
|
||||
for (const int i : sort_nodes.index_range()) {
|
||||
sort_nodes[i]->ui_order = i;
|
||||
|
@ -324,8 +327,8 @@ static Array<uiBlock *> node_uiblocks_init(const bContext &C, const Span<bNode *
|
|||
Array<uiBlock *> blocks(nodes.size());
|
||||
/* Add node uiBlocks in drawing order - prevents events going to overlapping nodes. */
|
||||
for (const int i : nodes.index_range()) {
|
||||
const std::string block_name = "node_" + std::string(nodes[i]->name);
|
||||
blocks[i] = UI_block_begin(&C, CTX_wm_region(&C), block_name.c_str(), UI_EMBOSS);
|
||||
std::string block_name = "node_" + std::string(nodes[i]->name);
|
||||
blocks[i] = UI_block_begin(&C, CTX_wm_region(&C), std::move(block_name), UI_EMBOSS);
|
||||
/* This cancels events for background nodes. */
|
||||
UI_block_flag_enable(blocks[i], UI_BLOCK_CLIP_EVENTS);
|
||||
}
|
||||
|
|
|
@ -1891,7 +1891,7 @@ static bNode *node_find_frame_to_attach(ARegion ®ion, bNodeTree &ntree, const
|
|||
|
||||
for (bNode *frame : tree_draw_order_calc_nodes_reversed(ntree)) {
|
||||
/* skip selected, those are the nodes we want to attach */
|
||||
if ((frame->type != NODE_FRAME) || (frame->flag & NODE_SELECT)) {
|
||||
if (!frame->is_frame() || (frame->flag & NODE_SELECT)) {
|
||||
continue;
|
||||
}
|
||||
if (BLI_rctf_isect_pt_v(&frame->runtime->totr, cursor)) {
|
||||
|
@ -1913,6 +1913,8 @@ static int node_attach_invoke(bContext *C, wmOperator * /*op*/, const wmEvent *e
|
|||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
bool changed = false;
|
||||
|
||||
for (bNode *node : tree_draw_order_calc_nodes_reversed(*snode.edittree)) {
|
||||
if (!(node->flag & NODE_SELECT)) {
|
||||
continue;
|
||||
|
@ -1925,6 +1927,11 @@ static int node_attach_invoke(bContext *C, wmOperator * /*op*/, const wmEvent *e
|
|||
|
||||
if (node->parent == nullptr) {
|
||||
nodeAttachNode(&ntree, node, frame);
|
||||
changed = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (node->parent == frame) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1936,27 +1943,26 @@ static int node_attach_invoke(bContext *C, wmOperator * /*op*/, const wmEvent *e
|
|||
|
||||
nodeDetachNode(&ntree, node);
|
||||
nodeAttachNode(&ntree, node, frame);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
tree_draw_order_update(ntree);
|
||||
WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, nullptr);
|
||||
if (changed) {
|
||||
tree_draw_order_update(ntree);
|
||||
WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, nullptr);
|
||||
}
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void NODE_OT_attach(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Attach Nodes";
|
||||
ot->description = "Attach active node to a frame";
|
||||
ot->idname = "NODE_OT_attach";
|
||||
|
||||
/* api callbacks */
|
||||
|
||||
ot->invoke = node_attach_invoke;
|
||||
ot->poll = ED_operator_node_editable;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
|
||||
#include "WM_api.hh"
|
||||
|
||||
namespace blender::ed::transform {
|
||||
|
||||
struct TransCustomDataNode {
|
||||
View2DEdgePanData edgepan_data;
|
||||
|
||||
|
@ -49,8 +51,8 @@ static void create_transform_data_for_node(TransData &td,
|
|||
const float dpi_fac)
|
||||
{
|
||||
/* account for parents (nested nodes) */
|
||||
const blender::float2 node_offset = {node.offsetx, node.offsety};
|
||||
blender::float2 loc = blender::bke::nodeToView(&node, blender::math::round(node_offset));
|
||||
const float2 node_offset = {node.offsetx, node.offsety};
|
||||
float2 loc = bke::nodeToView(&node, math::round(node_offset));
|
||||
loc *= dpi_fac;
|
||||
|
||||
/* use top-left corner as the transform origin for nodes */
|
||||
|
@ -94,8 +96,6 @@ static bool is_node_parent_select(const bNode *node)
|
|||
|
||||
static void createTransNodeData(bContext * /*C*/, TransInfo *t)
|
||||
{
|
||||
using namespace blender;
|
||||
using namespace blender::ed;
|
||||
SpaceNode *snode = static_cast<SpaceNode *>(t->area->spacedata.first);
|
||||
bNodeTree *node_tree = snode->edittree;
|
||||
if (!node_tree) {
|
||||
|
@ -152,8 +152,6 @@ static void createTransNodeData(bContext * /*C*/, TransInfo *t)
|
|||
|
||||
static void node_snap_grid_apply(TransInfo *t)
|
||||
{
|
||||
using namespace blender;
|
||||
|
||||
if (!(transform_snap_is_active(t) &&
|
||||
(t->tsnap.mode & (SCE_SNAP_TO_INCREMENT | SCE_SNAP_TO_GRID))))
|
||||
{
|
||||
|
@ -195,7 +193,6 @@ static void node_snap_grid_apply(TransInfo *t)
|
|||
|
||||
static void flushTransNodes(TransInfo *t)
|
||||
{
|
||||
using namespace blender::ed;
|
||||
const float dpi_fac = UI_SCALE_FAC;
|
||||
SpaceNode *snode = static_cast<SpaceNode *>(t->area->spacedata.first);
|
||||
|
||||
|
@ -234,16 +231,16 @@ static void flushTransNodes(TransInfo *t)
|
|||
TransData2D *td2d = &tc->data_2d[i];
|
||||
bNode *node = static_cast<bNode *>(td->extra);
|
||||
|
||||
blender::float2 loc;
|
||||
float2 loc;
|
||||
add_v2_v2v2(loc, td2d->loc, offset);
|
||||
|
||||
/* Weirdo - but the node system is a mix of free 2d elements and DPI sensitive UI. */
|
||||
loc /= dpi_fac;
|
||||
|
||||
/* account for parents (nested nodes) */
|
||||
const blender::float2 node_offset = {node->offsetx, node->offsety};
|
||||
const blender::float2 new_node_location = loc - blender::math::round(node_offset);
|
||||
const blender::float2 location = blender::bke::nodeFromView(node->parent, new_node_location);
|
||||
const float2 node_offset = {node->offsetx, node->offsety};
|
||||
const float2 new_node_location = loc - math::round(node_offset);
|
||||
const float2 location = bke::nodeFromView(node->parent, new_node_location);
|
||||
node->locx = location.x;
|
||||
node->locy = location.y;
|
||||
}
|
||||
|
@ -268,7 +265,6 @@ static void flushTransNodes(TransInfo *t)
|
|||
|
||||
static void special_aftertrans_update__node(bContext *C, TransInfo *t)
|
||||
{
|
||||
using namespace blender::ed;
|
||||
Main *bmain = CTX_data_main(C);
|
||||
SpaceNode *snode = (SpaceNode *)t->area->spacedata.first;
|
||||
bNodeTree *ntree = snode->edittree;
|
||||
|
@ -306,9 +302,11 @@ static void special_aftertrans_update__node(bContext *C, TransInfo *t)
|
|||
|
||||
/** \} */
|
||||
|
||||
} // namespace blender::ed::transform
|
||||
|
||||
TransConvertTypeInfo TransConvertType_Node = {
|
||||
/*flags*/ (T_POINTS | T_2D_EDIT),
|
||||
/*create_trans_data*/ createTransNodeData,
|
||||
/*recalc_data*/ flushTransNodes,
|
||||
/*special_aftertrans_update*/ special_aftertrans_update__node,
|
||||
/*create_trans_data*/ blender::ed::transform::createTransNodeData,
|
||||
/*recalc_data*/ blender::ed::transform::flushTransNodes,
|
||||
/*special_aftertrans_update*/ blender::ed::transform::special_aftertrans_update__node,
|
||||
};
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace blender::geometry {
|
|||
*
|
||||
* \param iterations: Number of times to repeat the smoothing.
|
||||
* \param smooth_ends: Smooth the first and last value.
|
||||
* \param keep_shape: Changes the gaussian kernal to avoid severe deformations.
|
||||
* \param keep_shape: Changes the gaussian kernel to avoid severe deformations.
|
||||
* \param is_cyclic: Propagate smoothing across the ends of the input as if they were connected.
|
||||
*/
|
||||
void gaussian_blur_1D(const GSpan src,
|
||||
|
|
|
@ -166,7 +166,7 @@ static void sample_image(const ImBuf *source, float u, float v, T *r_sample)
|
|||
/* BLI_bilinear_interpolation functions use `floor(uv)` and `floor(uv)+1`
|
||||
* texels. For proper mapping between pixel and texel spaces, need to
|
||||
* subtract 0.5. Same for bicubic. */
|
||||
if constexpr (Filter == IMB_FILTER_BILINEAR || Filter == IMB_FILTER_BICUBIC) {
|
||||
if constexpr (ELEM(Filter, IMB_FILTER_BILINEAR, IMB_FILTER_BICUBIC)) {
|
||||
u -= 0.5f;
|
||||
v -= 0.5f;
|
||||
}
|
||||
|
|
|
@ -667,6 +667,62 @@ int rna_ShapeKey_data_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr)
|
|||
return false;
|
||||
}
|
||||
|
||||
static void rna_ShapeKey_points_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
|
||||
{
|
||||
Key *key = rna_ShapeKey_find_key(ptr->owner_id);
|
||||
KeyBlock *kb = (KeyBlock *)ptr->data;
|
||||
int tot = kb->totelem;
|
||||
|
||||
if (GS(key->from->name) == ID_CU_LEGACY) {
|
||||
/* Legacy curves have only curve points and bezier points. */
|
||||
tot = 0;
|
||||
}
|
||||
rna_iterator_array_begin(iter, (void *)kb->data, key->elemsize, tot, 0, nullptr);
|
||||
}
|
||||
|
||||
static int rna_ShapeKey_points_length(PointerRNA *ptr)
|
||||
{
|
||||
Key *key = rna_ShapeKey_find_key(ptr->owner_id);
|
||||
KeyBlock *kb = (KeyBlock *)ptr->data;
|
||||
int tot = kb->totelem;
|
||||
|
||||
if (GS(key->from->name) == ID_CU_LEGACY) {
|
||||
/* Legacy curves have only curve points and bezier points. */
|
||||
tot = 0;
|
||||
}
|
||||
|
||||
return tot;
|
||||
}
|
||||
|
||||
int rna_ShapeKey_points_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr)
|
||||
{
|
||||
Key *key = rna_ShapeKey_find_key(ptr->owner_id);
|
||||
KeyBlock *kb = (KeyBlock *)ptr->data;
|
||||
int elemsize = key->elemsize;
|
||||
char *databuf = static_cast<char *>(kb->data);
|
||||
|
||||
memset(r_ptr, 0, sizeof(*r_ptr));
|
||||
|
||||
if (index < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (GS(key->from->name) == ID_CU_LEGACY) {
|
||||
/* Legacy curves have only curve points and bezier points. */
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
if (index < kb->totelem) {
|
||||
r_ptr->owner_id = ptr->owner_id;
|
||||
r_ptr->type = &RNA_ShapeKeyPoint;
|
||||
r_ptr->data = databuf + elemsize * index;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static char *rna_ShapeKey_path(const PointerRNA *ptr)
|
||||
{
|
||||
const KeyBlock *kb = (KeyBlock *)ptr->data;
|
||||
|
@ -807,13 +863,13 @@ static void rna_def_keydata(BlenderRNA *brna)
|
|||
PropertyRNA *prop;
|
||||
|
||||
srna = RNA_def_struct(brna, "ShapeKeyPoint", nullptr);
|
||||
RNA_def_struct_sdna(srna, "vec3f");
|
||||
RNA_def_struct_ui_text(srna, "Shape Key Point", "Point in a shape key");
|
||||
RNA_def_struct_path_func(srna, "rna_ShapeKeyPoint_path");
|
||||
|
||||
prop = RNA_def_property(srna, "co", PROP_FLOAT, PROP_TRANSLATION);
|
||||
RNA_def_property_float_sdna(prop, nullptr, "x");
|
||||
RNA_def_property_array(prop, 3);
|
||||
RNA_def_property_float_funcs(
|
||||
prop, "rna_ShapeKeyPoint_co_get", "rna_ShapeKeyPoint_co_set", nullptr);
|
||||
RNA_def_property_ui_text(prop, "Location", "");
|
||||
RNA_def_property_update(prop, 0, "rna_Key_update_data");
|
||||
|
||||
|
@ -954,7 +1010,7 @@ static void rna_def_keyblock(BlenderRNA *brna)
|
|||
RNA_def_property_update(prop, 0, "rna_Key_update_data");
|
||||
|
||||
prop = RNA_def_property(srna, "lock_shape", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", KEYBLOCK_LOCKED_SHAPE);
|
||||
RNA_def_property_boolean_sdna(prop, nullptr, "flag", KEYBLOCK_LOCKED_SHAPE);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Lock Shape", "Protect the shape key from accidental sculpting and editing");
|
||||
RNA_def_property_ui_icon(prop, ICON_UNLOCKED, 1);
|
||||
|
@ -992,6 +1048,25 @@ static void rna_def_keyblock(BlenderRNA *brna)
|
|||
nullptr,
|
||||
nullptr);
|
||||
|
||||
prop = RNA_def_property(srna, "points", PROP_COLLECTION, PROP_NONE);
|
||||
RNA_def_property_collection_sdna(prop, nullptr, "data", nullptr);
|
||||
RNA_def_property_struct_type(prop, "ShapeKeyPoint");
|
||||
RNA_def_property_override_flag(prop, PROPOVERRIDE_IGNORE);
|
||||
RNA_def_property_ui_text(prop,
|
||||
"Points",
|
||||
"Optimized access to shape keys point data, when using "
|
||||
"foreach_get/foreach_set accessors. "
|
||||
"(Warning: Does not support legacy Curve shape keys)");
|
||||
RNA_def_property_collection_funcs(prop,
|
||||
"rna_ShapeKey_points_begin",
|
||||
"rna_iterator_array_next",
|
||||
"rna_iterator_array_end",
|
||||
"rna_iterator_array_get",
|
||||
"rna_ShapeKey_points_length",
|
||||
"rna_ShapeKey_points_lookup_int",
|
||||
nullptr,
|
||||
nullptr);
|
||||
|
||||
/* XXX multi-dim dynamic arrays are very badly supported by (py)rna currently,
|
||||
* those are defined for the day it works better, for now user will get a 1D tuple.
|
||||
*/
|
||||
|
|
|
@ -284,4 +284,5 @@ ModifierTypeInfo modifierType_Armature = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ nullptr,
|
||||
/*blend_read*/ blend_read,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -1104,4 +1104,5 @@ ModifierTypeInfo modifierType_Array = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ nullptr,
|
||||
/*blend_read*/ nullptr,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -444,4 +444,5 @@ ModifierTypeInfo modifierType_Bevel = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ blend_write,
|
||||
/*blend_read*/ blend_read,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -702,4 +702,5 @@ ModifierTypeInfo modifierType_Boolean = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ nullptr,
|
||||
/*blend_read*/ nullptr,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -329,4 +329,5 @@ ModifierTypeInfo modifierType_Build = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ nullptr,
|
||||
/*blend_read*/ nullptr,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -541,4 +541,5 @@ ModifierTypeInfo modifierType_Cast = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ nullptr,
|
||||
/*blend_read*/ nullptr,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -304,4 +304,5 @@ ModifierTypeInfo modifierType_Cloth = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ nullptr,
|
||||
/*blend_read*/ nullptr,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -316,4 +316,5 @@ ModifierTypeInfo modifierType_Collision = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ nullptr,
|
||||
/*blend_read*/ blend_read,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -858,4 +858,5 @@ ModifierTypeInfo modifierType_CorrectiveSmooth = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ blend_write,
|
||||
/*blend_read*/ blend_read,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -222,4 +222,5 @@ ModifierTypeInfo modifierType_Curve = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ nullptr,
|
||||
/*blend_read*/ nullptr,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -531,4 +531,5 @@ ModifierTypeInfo modifierType_DataTransfer = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ nullptr,
|
||||
/*blend_read*/ nullptr,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -305,4 +305,5 @@ ModifierTypeInfo modifierType_Decimate = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ nullptr,
|
||||
/*blend_read*/ nullptr,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -474,4 +474,5 @@ ModifierTypeInfo modifierType_Displace = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ nullptr,
|
||||
/*blend_read*/ nullptr,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -223,4 +223,5 @@ ModifierTypeInfo modifierType_DynamicPaint = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ nullptr,
|
||||
/*blend_read*/ nullptr,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -192,4 +192,5 @@ ModifierTypeInfo modifierType_EdgeSplit = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ nullptr,
|
||||
/*blend_read*/ nullptr,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -1247,4 +1247,5 @@ ModifierTypeInfo modifierType_Explode = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ nullptr,
|
||||
/*blend_read*/ blend_read,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -263,4 +263,5 @@ ModifierTypeInfo modifierType_Fluid = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ nullptr,
|
||||
/*blend_read*/ nullptr,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -332,4 +332,5 @@ ModifierTypeInfo modifierType_GreasePencilOpacity = {
|
|||
/*panel_register*/ blender::panel_register,
|
||||
/*blend_write*/ blender::blend_write,
|
||||
/*blend_read*/ blender::blend_read,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -185,4 +185,5 @@ ModifierTypeInfo modifierType_GreasePencilSubdiv = {
|
|||
/*panel_register*/ blender::panel_register,
|
||||
/*blend_write*/ blender::blend_write,
|
||||
/*blend_read*/ blender::blend_read,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -574,4 +574,5 @@ ModifierTypeInfo modifierType_Hook = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ blend_write,
|
||||
/*blend_read*/ blend_read,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -884,4 +884,5 @@ ModifierTypeInfo modifierType_LaplacianDeform = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ blend_write,
|
||||
/*blend_read*/ blend_read,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -584,4 +584,5 @@ ModifierTypeInfo modifierType_LaplacianSmooth = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ nullptr,
|
||||
/*blend_read*/ nullptr,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -195,4 +195,5 @@ ModifierTypeInfo modifierType_Lattice = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ nullptr,
|
||||
/*blend_read*/ nullptr,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -830,4 +830,5 @@ ModifierTypeInfo modifierType_Mask = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ nullptr,
|
||||
/*blend_read*/ nullptr,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -226,4 +226,5 @@ ModifierTypeInfo modifierType_MeshToVolume = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ nullptr,
|
||||
/*blend_read*/ nullptr,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -407,4 +407,5 @@ ModifierTypeInfo modifierType_MeshCache = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ nullptr,
|
||||
/*blend_read*/ nullptr,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -648,4 +648,5 @@ ModifierTypeInfo modifierType_MeshDeform = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ blend_write,
|
||||
/*blend_read*/ blend_read,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -462,4 +462,5 @@ ModifierTypeInfo modifierType_MeshSequenceCache = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ nullptr,
|
||||
/*blend_read*/ blend_read,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -270,4 +270,5 @@ ModifierTypeInfo modifierType_Mirror = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ nullptr,
|
||||
/*blend_read*/ nullptr,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -513,4 +513,5 @@ ModifierTypeInfo modifierType_Multires = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ nullptr,
|
||||
/*blend_read*/ nullptr,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -2294,4 +2294,5 @@ ModifierTypeInfo modifierType_Nodes = {
|
|||
/*panel_register*/ blender::panel_register,
|
||||
/*blend_write*/ blender::blend_write,
|
||||
/*blend_read*/ blender::blend_read,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -55,4 +55,5 @@ ModifierTypeInfo modifierType_None = {
|
|||
/*panel_register*/ nullptr,
|
||||
/*blend_write*/ nullptr,
|
||||
/*blend_read*/ nullptr,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -749,4 +749,5 @@ ModifierTypeInfo modifierType_NormalEdit = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ nullptr,
|
||||
/*blend_read*/ nullptr,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -723,4 +723,5 @@ ModifierTypeInfo modifierType_Ocean = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ nullptr,
|
||||
/*blend_read*/ blend_read,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -670,4 +670,5 @@ ModifierTypeInfo modifierType_ParticleInstance = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ nullptr,
|
||||
/*blend_read*/ nullptr,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -296,4 +296,5 @@ ModifierTypeInfo modifierType_ParticleSystem = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ nullptr,
|
||||
/*blend_read*/ blend_read,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -294,4 +294,5 @@ ModifierTypeInfo modifierType_Remesh = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ nullptr,
|
||||
/*blend_read*/ nullptr,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -1174,4 +1174,5 @@ ModifierTypeInfo modifierType_Screw = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ nullptr,
|
||||
/*blend_read*/ nullptr,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -136,4 +136,5 @@ ModifierTypeInfo modifierType_ShapeKey = {
|
|||
/*panel_register*/ nullptr,
|
||||
/*blend_write*/ nullptr,
|
||||
/*blend_read*/ nullptr,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -243,4 +243,5 @@ ModifierTypeInfo modifierType_Shrinkwrap = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ nullptr,
|
||||
/*blend_read*/ nullptr,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -564,4 +564,5 @@ ModifierTypeInfo modifierType_SimpleDeform = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ nullptr,
|
||||
/*blend_read*/ nullptr,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -2101,4 +2101,5 @@ ModifierTypeInfo modifierType_Skin = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ nullptr,
|
||||
/*blend_read*/ nullptr,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -248,4 +248,5 @@ ModifierTypeInfo modifierType_Smooth = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ nullptr,
|
||||
/*blend_read*/ nullptr,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -123,4 +123,5 @@ ModifierTypeInfo modifierType_Softbody = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ nullptr,
|
||||
/*blend_read*/ nullptr,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -296,4 +296,5 @@ ModifierTypeInfo modifierType_Solidify = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ nullptr,
|
||||
/*blend_read*/ nullptr,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -517,4 +517,5 @@ ModifierTypeInfo modifierType_Subsurf = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ nullptr,
|
||||
/*blend_read*/ blend_read,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -234,4 +234,5 @@ ModifierTypeInfo modifierType_Surface = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ nullptr,
|
||||
/*blend_read*/ blend_read,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -1745,4 +1745,5 @@ ModifierTypeInfo modifierType_SurfaceDeform = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ blend_write,
|
||||
/*blend_read*/ blend_read,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -162,4 +162,5 @@ ModifierTypeInfo modifierType_Triangulate = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ nullptr,
|
||||
/*blend_read*/ nullptr,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -381,4 +381,5 @@ ModifierTypeInfo modifierType_UVProject = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ nullptr,
|
||||
/*blend_read*/ nullptr,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -337,4 +337,5 @@ ModifierTypeInfo modifierType_UVWarp = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ nullptr,
|
||||
/*blend_read*/ nullptr,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -345,4 +345,5 @@ ModifierTypeInfo modifierType_VolumeDisplace = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ nullptr,
|
||||
/*blend_read*/ nullptr,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -229,4 +229,5 @@ ModifierTypeInfo modifierType_VolumeToMesh = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ nullptr,
|
||||
/*blend_read*/ nullptr,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -503,4 +503,5 @@ ModifierTypeInfo modifierType_Warp = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ blend_write,
|
||||
/*blend_read*/ blend_read,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -452,4 +452,5 @@ ModifierTypeInfo modifierType_Wave = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ nullptr,
|
||||
/*blend_read*/ nullptr,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -664,4 +664,5 @@ ModifierTypeInfo modifierType_WeightedNormal = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ nullptr,
|
||||
/*blend_read*/ nullptr,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
|
@ -420,4 +420,5 @@ ModifierTypeInfo modifierType_WeightVGEdit = {
|
|||
/*panel_register*/ panel_register,
|
||||
/*blend_write*/ blend_write,
|
||||
/*blend_read*/ blend_read,
|
||||
/*foreach_cache*/ nullptr,
|
||||
};
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue