GPv3: Tint and Color modifiers #117297

Merged
Lukas Tönne merged 20 commits from LukasTonne/blender:gp3-color-modifier into main 2024-01-19 16:59:49 +01:00
109 changed files with 676 additions and 232 deletions
Showing only changes of commit 818167bc19 - Show all commits

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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(

View File

@ -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);

View File

@ -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. */

View File

@ -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) {

View File

@ -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};

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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));

View File

@ -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,

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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;

View File

@ -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)

View File

@ -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 = {};

View File

@ -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);

View File

@ -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

View File

@ -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:

View File

@ -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:

View File

@ -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. */

View File

@ -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);

View File

@ -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);

View File

@ -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";

View File

@ -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);

View File

@ -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) {

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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` */

View File

@ -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;

View File

@ -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, &region->uiblocks) {
if (STREQ(block->name, name)) {
if (block->name == name) {
return true;
}
}

View File

@ -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
{

View File

@ -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 */

View File

@ -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(&region->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(&region->uiblocks, block);
}
UI_block_free(nullptr, block);

View File

@ -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);
}

View File

@ -1891,7 +1891,7 @@ static bNode *node_find_frame_to_attach(ARegion &region, 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;
}

View File

@ -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,
};

View File

@ -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,

View File

@ -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;
}

View File

@ -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.
*/

View File

@ -284,4 +284,5 @@ ModifierTypeInfo modifierType_Armature = {
/*panel_register*/ panel_register,
/*blend_write*/ nullptr,
/*blend_read*/ blend_read,
/*foreach_cache*/ nullptr,
};

View File

@ -1104,4 +1104,5 @@ ModifierTypeInfo modifierType_Array = {
/*panel_register*/ panel_register,
/*blend_write*/ nullptr,
/*blend_read*/ nullptr,
/*foreach_cache*/ nullptr,
};

View File

@ -444,4 +444,5 @@ ModifierTypeInfo modifierType_Bevel = {
/*panel_register*/ panel_register,
/*blend_write*/ blend_write,
/*blend_read*/ blend_read,
/*foreach_cache*/ nullptr,
};

View File

@ -702,4 +702,5 @@ ModifierTypeInfo modifierType_Boolean = {
/*panel_register*/ panel_register,
/*blend_write*/ nullptr,
/*blend_read*/ nullptr,
/*foreach_cache*/ nullptr,
};

View File

@ -329,4 +329,5 @@ ModifierTypeInfo modifierType_Build = {
/*panel_register*/ panel_register,
/*blend_write*/ nullptr,
/*blend_read*/ nullptr,
/*foreach_cache*/ nullptr,
};

View File

@ -541,4 +541,5 @@ ModifierTypeInfo modifierType_Cast = {
/*panel_register*/ panel_register,
/*blend_write*/ nullptr,
/*blend_read*/ nullptr,
/*foreach_cache*/ nullptr,
};

View File

@ -304,4 +304,5 @@ ModifierTypeInfo modifierType_Cloth = {
/*panel_register*/ panel_register,
/*blend_write*/ nullptr,
/*blend_read*/ nullptr,
/*foreach_cache*/ nullptr,
};

View File

@ -316,4 +316,5 @@ ModifierTypeInfo modifierType_Collision = {
/*panel_register*/ panel_register,
/*blend_write*/ nullptr,
/*blend_read*/ blend_read,
/*foreach_cache*/ nullptr,
};

View File

@ -858,4 +858,5 @@ ModifierTypeInfo modifierType_CorrectiveSmooth = {
/*panel_register*/ panel_register,
/*blend_write*/ blend_write,
/*blend_read*/ blend_read,
/*foreach_cache*/ nullptr,
};

View File

@ -222,4 +222,5 @@ ModifierTypeInfo modifierType_Curve = {
/*panel_register*/ panel_register,
/*blend_write*/ nullptr,
/*blend_read*/ nullptr,
/*foreach_cache*/ nullptr,
};

View File

@ -531,4 +531,5 @@ ModifierTypeInfo modifierType_DataTransfer = {
/*panel_register*/ panel_register,
/*blend_write*/ nullptr,
/*blend_read*/ nullptr,
/*foreach_cache*/ nullptr,
};

View File

@ -305,4 +305,5 @@ ModifierTypeInfo modifierType_Decimate = {
/*panel_register*/ panel_register,
/*blend_write*/ nullptr,
/*blend_read*/ nullptr,
/*foreach_cache*/ nullptr,
};

View File

@ -474,4 +474,5 @@ ModifierTypeInfo modifierType_Displace = {
/*panel_register*/ panel_register,
/*blend_write*/ nullptr,
/*blend_read*/ nullptr,
/*foreach_cache*/ nullptr,
};

View File

@ -223,4 +223,5 @@ ModifierTypeInfo modifierType_DynamicPaint = {
/*panel_register*/ panel_register,
/*blend_write*/ nullptr,
/*blend_read*/ nullptr,
/*foreach_cache*/ nullptr,
};

View File

@ -192,4 +192,5 @@ ModifierTypeInfo modifierType_EdgeSplit = {
/*panel_register*/ panel_register,
/*blend_write*/ nullptr,
/*blend_read*/ nullptr,
/*foreach_cache*/ nullptr,
};

View File

@ -1247,4 +1247,5 @@ ModifierTypeInfo modifierType_Explode = {
/*panel_register*/ panel_register,
/*blend_write*/ nullptr,
/*blend_read*/ blend_read,
/*foreach_cache*/ nullptr,
};

View File

@ -263,4 +263,5 @@ ModifierTypeInfo modifierType_Fluid = {
/*panel_register*/ panel_register,
/*blend_write*/ nullptr,
/*blend_read*/ nullptr,
/*foreach_cache*/ nullptr,
};

View File

@ -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,
};

View File

@ -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,
};

View File

@ -574,4 +574,5 @@ ModifierTypeInfo modifierType_Hook = {
/*panel_register*/ panel_register,
/*blend_write*/ blend_write,
/*blend_read*/ blend_read,
/*foreach_cache*/ nullptr,
};

View File

@ -884,4 +884,5 @@ ModifierTypeInfo modifierType_LaplacianDeform = {
/*panel_register*/ panel_register,
/*blend_write*/ blend_write,
/*blend_read*/ blend_read,
/*foreach_cache*/ nullptr,
};

View File

@ -584,4 +584,5 @@ ModifierTypeInfo modifierType_LaplacianSmooth = {
/*panel_register*/ panel_register,
/*blend_write*/ nullptr,
/*blend_read*/ nullptr,
/*foreach_cache*/ nullptr,
};

View File

@ -195,4 +195,5 @@ ModifierTypeInfo modifierType_Lattice = {
/*panel_register*/ panel_register,
/*blend_write*/ nullptr,
/*blend_read*/ nullptr,
/*foreach_cache*/ nullptr,
};

View File

@ -830,4 +830,5 @@ ModifierTypeInfo modifierType_Mask = {
/*panel_register*/ panel_register,
/*blend_write*/ nullptr,
/*blend_read*/ nullptr,
/*foreach_cache*/ nullptr,
};

View File

@ -226,4 +226,5 @@ ModifierTypeInfo modifierType_MeshToVolume = {
/*panel_register*/ panel_register,
/*blend_write*/ nullptr,
/*blend_read*/ nullptr,
/*foreach_cache*/ nullptr,
};

View File

@ -407,4 +407,5 @@ ModifierTypeInfo modifierType_MeshCache = {
/*panel_register*/ panel_register,
/*blend_write*/ nullptr,
/*blend_read*/ nullptr,
/*foreach_cache*/ nullptr,
};

View File

@ -648,4 +648,5 @@ ModifierTypeInfo modifierType_MeshDeform = {
/*panel_register*/ panel_register,
/*blend_write*/ blend_write,
/*blend_read*/ blend_read,
/*foreach_cache*/ nullptr,
};

View File

@ -462,4 +462,5 @@ ModifierTypeInfo modifierType_MeshSequenceCache = {
/*panel_register*/ panel_register,
/*blend_write*/ nullptr,
/*blend_read*/ blend_read,
/*foreach_cache*/ nullptr,
};

View File

@ -270,4 +270,5 @@ ModifierTypeInfo modifierType_Mirror = {
/*panel_register*/ panel_register,
/*blend_write*/ nullptr,
/*blend_read*/ nullptr,
/*foreach_cache*/ nullptr,
};

View File

@ -513,4 +513,5 @@ ModifierTypeInfo modifierType_Multires = {
/*panel_register*/ panel_register,
/*blend_write*/ nullptr,
/*blend_read*/ nullptr,
/*foreach_cache*/ nullptr,
};

View File

@ -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,
};

View File

@ -55,4 +55,5 @@ ModifierTypeInfo modifierType_None = {
/*panel_register*/ nullptr,
/*blend_write*/ nullptr,
/*blend_read*/ nullptr,
/*foreach_cache*/ nullptr,
};

View File

@ -749,4 +749,5 @@ ModifierTypeInfo modifierType_NormalEdit = {
/*panel_register*/ panel_register,
/*blend_write*/ nullptr,
/*blend_read*/ nullptr,
/*foreach_cache*/ nullptr,
};

View File

@ -723,4 +723,5 @@ ModifierTypeInfo modifierType_Ocean = {
/*panel_register*/ panel_register,
/*blend_write*/ nullptr,
/*blend_read*/ blend_read,
/*foreach_cache*/ nullptr,
};

View File

@ -670,4 +670,5 @@ ModifierTypeInfo modifierType_ParticleInstance = {
/*panel_register*/ panel_register,
/*blend_write*/ nullptr,
/*blend_read*/ nullptr,
/*foreach_cache*/ nullptr,
};

View File

@ -296,4 +296,5 @@ ModifierTypeInfo modifierType_ParticleSystem = {
/*panel_register*/ panel_register,
/*blend_write*/ nullptr,
/*blend_read*/ blend_read,
/*foreach_cache*/ nullptr,
};

View File

@ -294,4 +294,5 @@ ModifierTypeInfo modifierType_Remesh = {
/*panel_register*/ panel_register,
/*blend_write*/ nullptr,
/*blend_read*/ nullptr,
/*foreach_cache*/ nullptr,
};

View File

@ -1174,4 +1174,5 @@ ModifierTypeInfo modifierType_Screw = {
/*panel_register*/ panel_register,
/*blend_write*/ nullptr,
/*blend_read*/ nullptr,
/*foreach_cache*/ nullptr,
};

View File

@ -136,4 +136,5 @@ ModifierTypeInfo modifierType_ShapeKey = {
/*panel_register*/ nullptr,
/*blend_write*/ nullptr,
/*blend_read*/ nullptr,
/*foreach_cache*/ nullptr,
};

View File

@ -243,4 +243,5 @@ ModifierTypeInfo modifierType_Shrinkwrap = {
/*panel_register*/ panel_register,
/*blend_write*/ nullptr,
/*blend_read*/ nullptr,
/*foreach_cache*/ nullptr,
};

View File

@ -564,4 +564,5 @@ ModifierTypeInfo modifierType_SimpleDeform = {
/*panel_register*/ panel_register,
/*blend_write*/ nullptr,
/*blend_read*/ nullptr,
/*foreach_cache*/ nullptr,
};

View File

@ -2101,4 +2101,5 @@ ModifierTypeInfo modifierType_Skin = {
/*panel_register*/ panel_register,
/*blend_write*/ nullptr,
/*blend_read*/ nullptr,
/*foreach_cache*/ nullptr,
};

View File

@ -248,4 +248,5 @@ ModifierTypeInfo modifierType_Smooth = {
/*panel_register*/ panel_register,
/*blend_write*/ nullptr,
/*blend_read*/ nullptr,
/*foreach_cache*/ nullptr,
};

View File

@ -123,4 +123,5 @@ ModifierTypeInfo modifierType_Softbody = {
/*panel_register*/ panel_register,
/*blend_write*/ nullptr,
/*blend_read*/ nullptr,
/*foreach_cache*/ nullptr,
};

View File

@ -296,4 +296,5 @@ ModifierTypeInfo modifierType_Solidify = {
/*panel_register*/ panel_register,
/*blend_write*/ nullptr,
/*blend_read*/ nullptr,
/*foreach_cache*/ nullptr,
};

View File

@ -517,4 +517,5 @@ ModifierTypeInfo modifierType_Subsurf = {
/*panel_register*/ panel_register,
/*blend_write*/ nullptr,
/*blend_read*/ blend_read,
/*foreach_cache*/ nullptr,
};

View File

@ -234,4 +234,5 @@ ModifierTypeInfo modifierType_Surface = {
/*panel_register*/ panel_register,
/*blend_write*/ nullptr,
/*blend_read*/ blend_read,
/*foreach_cache*/ nullptr,
};

View File

@ -1745,4 +1745,5 @@ ModifierTypeInfo modifierType_SurfaceDeform = {
/*panel_register*/ panel_register,
/*blend_write*/ blend_write,
/*blend_read*/ blend_read,
/*foreach_cache*/ nullptr,
};

View File

@ -162,4 +162,5 @@ ModifierTypeInfo modifierType_Triangulate = {
/*panel_register*/ panel_register,
/*blend_write*/ nullptr,
/*blend_read*/ nullptr,
/*foreach_cache*/ nullptr,
};

View File

@ -381,4 +381,5 @@ ModifierTypeInfo modifierType_UVProject = {
/*panel_register*/ panel_register,
/*blend_write*/ nullptr,
/*blend_read*/ nullptr,
/*foreach_cache*/ nullptr,
};

View File

@ -337,4 +337,5 @@ ModifierTypeInfo modifierType_UVWarp = {
/*panel_register*/ panel_register,
/*blend_write*/ nullptr,
/*blend_read*/ nullptr,
/*foreach_cache*/ nullptr,
};

View File

@ -345,4 +345,5 @@ ModifierTypeInfo modifierType_VolumeDisplace = {
/*panel_register*/ panel_register,
/*blend_write*/ nullptr,
/*blend_read*/ nullptr,
/*foreach_cache*/ nullptr,
};

View File

@ -229,4 +229,5 @@ ModifierTypeInfo modifierType_VolumeToMesh = {
/*panel_register*/ panel_register,
/*blend_write*/ nullptr,
/*blend_read*/ nullptr,
/*foreach_cache*/ nullptr,
};

View File

@ -503,4 +503,5 @@ ModifierTypeInfo modifierType_Warp = {
/*panel_register*/ panel_register,
/*blend_write*/ blend_write,
/*blend_read*/ blend_read,
/*foreach_cache*/ nullptr,
};

View File

@ -452,4 +452,5 @@ ModifierTypeInfo modifierType_Wave = {
/*panel_register*/ panel_register,
/*blend_write*/ nullptr,
/*blend_read*/ nullptr,
/*foreach_cache*/ nullptr,
};

View File

@ -664,4 +664,5 @@ ModifierTypeInfo modifierType_WeightedNormal = {
/*panel_register*/ panel_register,
/*blend_write*/ nullptr,
/*blend_read*/ nullptr,
/*foreach_cache*/ nullptr,
};

View File

@ -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