Core: Increase MAX_ID_NAME length from 66 to 258 (Blender 5.0)
Change the maximum data-block name from 64 to 256 bytes by increasing MAX_ID_NAME value. Also increase a few related non-ID data name max size, essentially the action slots identifiers, as these are the primary key used to match an Action's slot to an ID by name. Other sub-data (bones, modifiers, etc.) lengths are not modified here, as these can be made actual dynamic strings in the future, while keeping (a reasonable level of) forward compatibility, during the course of Blender 5 release cycles. Implements #137608. Co-authored-by: Bastien Montagne <bastien@blender.org> Pull Request: https://projects.blender.org/blender/blender/pulls/137196
This commit is contained in:
committed by
Bastien Montagne
parent
09af302457
commit
fdaaea6328
@@ -113,6 +113,13 @@ def _read_blend_rend_chunk_from_file(blendfile, filepath):
|
||||
|
||||
scene_name = blendfile.read(64)
|
||||
sizeof_data_left -= 64
|
||||
if b'\0' not in scene_name:
|
||||
if sizeof_data_left >= 192:
|
||||
# Assume new, up to 256 bytes name.
|
||||
scene_name += blendfile.read(192)
|
||||
sizeof_data_left -= 192
|
||||
if b'\0' not in scene_name:
|
||||
scene_name = scene_name[:-1] + b'\0'
|
||||
|
||||
scene_name = scene_name[:scene_name.index(b'\0')]
|
||||
# It's possible old blend files are not UTF8 compliant, use `surrogateescape`.
|
||||
|
||||
@@ -1130,14 +1130,25 @@ TEST_F(ActionLayersTest, conversion_to_layered)
|
||||
ASSERT_TRUE(bag->fcurve_array[0]->modifiers.first == nullptr);
|
||||
ASSERT_TRUE(bag->fcurve_array[1]->modifiers.first != nullptr);
|
||||
|
||||
Action *long_name_action = BKE_id_new<Action>(
|
||||
bmain, "name_for_an_action_that_is_exactly_64_chars_which_is_MAX_ID_NAME");
|
||||
constexpr char id_name_max[] =
|
||||
"name_for_an_action_that_is_exactly_255_bytes_MAX_ID_NAME-3______"
|
||||
"name_for_an_action_that_is_exactly_255_bytes_MAX_ID_NAME-3______"
|
||||
"name_for_an_action_that_is_exactly_255_bytes_MAX_ID_NAME-3______"
|
||||
"name_for_an_action_that_is_exactly_255_bytes_MAX_ID_NAME-3_____";
|
||||
BLI_STATIC_ASSERT(std::string::traits_type::length(id_name_max) == MAX_ID_NAME - 2 - 1,
|
||||
"Wrong 'max length' name");
|
||||
Action *long_name_action = BKE_id_new<Action>(bmain, id_name_max);
|
||||
action_fcurve_ensure_legacy(bmain, long_name_action, "Long", nullptr, {"location", 0});
|
||||
/* The long name is shortened to make space for "_layered". */
|
||||
constexpr char id_name_max_converted[] =
|
||||
"name_for_an_action_that_is_exactly_255_bytes_MAX_ID_NAME-3______"
|
||||
"name_for_an_action_that_is_exactly_255_bytes_MAX_ID_NAME-3______"
|
||||
"name_for_an_action_that_is_exactly_255_bytes_MAX_ID_NAME-3______"
|
||||
"name_for_an_action_that_is_exactly_255_bytes_MAX_ID_NAM_layered";
|
||||
BLI_STATIC_ASSERT(std::string::traits_type::length(id_name_max_converted) == MAX_ID_NAME - 2 - 1,
|
||||
"Wrong 'max length' name");
|
||||
converted = convert_to_layered_action(*bmain, *long_name_action);
|
||||
/* AC gets added automatically by Blender, the long name is shortened to make space for
|
||||
* "_layered". */
|
||||
EXPECT_STREQ(converted->id.name,
|
||||
"ACname_for_an_action_that_is_exactly_64_chars_which_is_MA_layered");
|
||||
EXPECT_STREQ(BKE_id_name(converted->id), id_name_max_converted);
|
||||
}
|
||||
|
||||
TEST_F(ActionLayersTest, conversion_to_layered_action_groups)
|
||||
|
||||
@@ -299,7 +299,7 @@ void AS_asset_library_remap_ids(const blender::bke::id::IDRemapper &mappings);
|
||||
* \param r_name: Returns the ID name on success. Optional (passing null is allowed).
|
||||
*/
|
||||
void AS_asset_full_path_explode_from_weak_ref(const AssetWeakReference *asset_reference,
|
||||
char r_path_buffer[1090 /* FILE_MAX_LIBEXTRA */],
|
||||
char r_path_buffer[1282 /* FILE_MAX_LIBEXTRA */],
|
||||
char **r_dir,
|
||||
char **r_group,
|
||||
char **r_name);
|
||||
|
||||
@@ -103,7 +103,7 @@ void AS_asset_library_remap_ids(const bke::id::IDRemapper &mappings)
|
||||
}
|
||||
|
||||
void AS_asset_full_path_explode_from_weak_ref(const AssetWeakReference *asset_reference,
|
||||
char r_path_buffer[1090 /* FILE_MAX_LIBEXTRA */],
|
||||
char r_path_buffer[1282 /* FILE_MAX_LIBEXTRA */],
|
||||
char **r_dir,
|
||||
char **r_group,
|
||||
char **r_name)
|
||||
@@ -129,7 +129,7 @@ void AS_asset_full_path_explode_from_weak_ref(const AssetWeakReference *asset_re
|
||||
BLI_assert(!exploded->group_component.is_empty());
|
||||
BLI_assert(!exploded->name_component.is_empty());
|
||||
|
||||
BLI_strncpy(r_path_buffer, exploded->full_path->c_str(), 1090 /* #FILE_MAX_LIBEXTRA. */);
|
||||
BLI_strncpy(r_path_buffer, exploded->full_path->c_str(), 1282 /* #FILE_MAX_LIBEXTRA. */);
|
||||
|
||||
if (!exploded->dir_component.is_empty()) {
|
||||
r_path_buffer[exploded->dir_component.size()] = '\0';
|
||||
|
||||
@@ -132,7 +132,7 @@ std::string AssetRepresentation::full_library_path() const
|
||||
{
|
||||
std::string asset_path = full_path();
|
||||
|
||||
char blend_path[/*FILE_MAX_LIBEXTRA*/ 1090];
|
||||
char blend_path[/*FILE_MAX_LIBEXTRA*/ 1282];
|
||||
if (!BKE_blendfile_library_path_explode(asset_path.c_str(), blend_path, nullptr, nullptr)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
/* Blender file format version. */
|
||||
#define BLENDER_FILE_VERSION BLENDER_VERSION
|
||||
#define BLENDER_FILE_SUBVERSION 21
|
||||
#define BLENDER_FILE_SUBVERSION 22
|
||||
|
||||
/* Minimum Blender version that supports reading file written with the current
|
||||
* version. Older Blender versions will test this and cancel loading the file, showing a warning to
|
||||
|
||||
@@ -788,8 +788,8 @@ void BKE_main_lib_objects_recalc_all(Main *bmain);
|
||||
*/
|
||||
void BKE_main_id_repair_duplicate_names_listbase(Main *bmain, ListBase *lb);
|
||||
|
||||
#define MAX_ID_FULL_NAME (64 + 64 + 3 + 1) /* 64 is MAX_ID_NAME - 2 */
|
||||
#define MAX_ID_FULL_NAME_UI (MAX_ID_FULL_NAME + 3) /* Adds `keycode` two letters at beginning. */
|
||||
#define MAX_ID_FULL_NAME (256 + 256 + 3 + 1) /* 256 is MAX_ID_NAME - 2 */
|
||||
#define MAX_ID_FULL_NAME_UI (MAX_ID_FULL_NAME + 3) /* Adds 'keycode' two letters at beginning. */
|
||||
/**
|
||||
* Generate full name of the data-block (without ID code, but with library if any).
|
||||
*
|
||||
|
||||
@@ -125,6 +125,11 @@ static std::string asset_blendfile_path_for_save(const bUserAssetLibrary &user_l
|
||||
std::min(sizeof(base_name_filesafe), size_t(base_name.size() + 1)));
|
||||
BLI_path_make_safe_filename(base_name_filesafe);
|
||||
|
||||
/* FIXME: MAX_ID_NAME & FILE_MAXFILE
|
||||
*
|
||||
* This already does not respect the FILE_MAXFILE max length of filenames for the final filepath
|
||||
* it seems?
|
||||
*/
|
||||
{
|
||||
const std::string filepath = root_path + SEP + base_name_filesafe + BLENDER_ASSET_FILE_SUFFIX;
|
||||
if (!BLI_is_file(filepath.c_str())) {
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
|
||||
#include "DNA_ID.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace blender::bke::tests {
|
||||
|
||||
struct LibIDMainSortTestContext {
|
||||
@@ -163,13 +165,27 @@ TEST(lib_id_main_unique_name, local_ids_rename_existing_never)
|
||||
STRNCPY(future_name, "OB_BBBB");
|
||||
EXPECT_FALSE(BKE_main_namemap_get_unique_name(*ctx.bmain, *id_c, future_name));
|
||||
EXPECT_STREQ(future_name, "OB_BBBB");
|
||||
constexpr char long_name[] =
|
||||
"OB_BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
|
||||
"BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
|
||||
"BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
|
||||
"BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB";
|
||||
BLI_STATIC_ASSERT(std::string::traits_type::length(long_name) == MAX_ID_NAME - 2 - 1,
|
||||
"Wrong 'max length' name");
|
||||
constexpr char long_name_shorten[] =
|
||||
"OB_BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
|
||||
"BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
|
||||
"BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
|
||||
"BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB";
|
||||
BLI_STATIC_ASSERT(std::string::traits_type::length(long_name_shorten) == MAX_ID_NAME - 2 - 2,
|
||||
"Wrong 'max length' name");
|
||||
/* Name too long, needs to be truncated. */
|
||||
STRNCPY(future_name, "OB_BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB");
|
||||
STRNCPY(future_name, long_name);
|
||||
change_name(ctx.bmain, id_a, future_name, IDNewNameMode::RenameExistingNever);
|
||||
EXPECT_STREQ(id_a->name + 2, future_name);
|
||||
EXPECT_STREQ(future_name, "OB_BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB");
|
||||
EXPECT_STREQ(future_name, long_name);
|
||||
EXPECT_TRUE(BKE_main_namemap_get_unique_name(*ctx.bmain, *id_c, future_name));
|
||||
EXPECT_STREQ(future_name, "OB_BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB");
|
||||
EXPECT_STREQ(future_name, long_name_shorten);
|
||||
}
|
||||
|
||||
TEST(lib_id_main_unique_name, local_ids_rename_existing_always)
|
||||
@@ -303,7 +319,7 @@ TEST(lib_id_main_unique_name, linked_ids_1)
|
||||
static void change_name_global(Main *bmain, ID *id, const char *name)
|
||||
{
|
||||
BKE_main_namemap_remove_id(*bmain, *id);
|
||||
BLI_strncpy(id->name + 2, name, MAX_NAME);
|
||||
BLI_strncpy(id->name + 2, name, MAX_ID_NAME - 2);
|
||||
|
||||
BKE_main_global_namemap_get_unique_name(*bmain, *id, id->name + 2);
|
||||
|
||||
@@ -415,17 +431,45 @@ TEST(lib_id_main_unique_name, ids_sorted_by_default_with_libraries)
|
||||
TEST(lib_id_main_unique_name, name_too_long_handling)
|
||||
{
|
||||
LibIDMainSortTestContext ctx;
|
||||
const char *name_a = "Long_Name_That_Does_Not_Fit_Into_Max_Name_Limit_And_Should_Get_Truncated";
|
||||
const char *name_b = "Another_Long_Name_That_Does_Not_Fit_And_Has_A_Number_Suffix.123456";
|
||||
const char *name_c = "Name_That_Has_Too_Long_Number_Suffix.1234567890";
|
||||
constexpr char name_a[] =
|
||||
"Long_Name_That_Does_Not_Fit_Into_Max_Name_Limit_And_Should_Get_Truncated_"
|
||||
"Long_Name_That_Does_Not_Fit_Into_Max_Name_Limit_And_Should_Get_Truncated_"
|
||||
"Long_Name_That_Does_Not_Fit_Into_Max_Name_Limit_And_Should_Get_Truncated_"
|
||||
"Long_Name_That_Does_Not_Fit_Into_Max_Name_Limit_And_Should_Get_Truncated";
|
||||
BLI_STATIC_ASSERT(std::string::traits_type::length(name_a) > MAX_ID_NAME - 2,
|
||||
"Wrong 'max length' name");
|
||||
constexpr char name_a_shorten[] =
|
||||
"Long_Name_That_Does_Not_Fit_Into_Max_Name_Limit_And_Should_Get_Truncated_"
|
||||
"Long_Name_That_Does_Not_Fit_Into_Max_Name_Limit_And_Should_Get_Truncated_"
|
||||
"Long_Name_That_Does_Not_Fit_Into_Max_Name_Limit_And_Should_Get_Truncated_"
|
||||
"Long_Name_That_Does_Not_Fit_Into_Max";
|
||||
BLI_STATIC_ASSERT(std::string::traits_type::length(name_a_shorten) == MAX_ID_NAME - 2 - 1,
|
||||
"Wrong 'max length' name");
|
||||
constexpr char name_b[] =
|
||||
"Another_Long_Name_That_Does_Not_Fit_And_Has_A_Number_Suffix_____"
|
||||
"Another_Long_Name_That_Does_Not_Fit_And_Has_A_Number_Suffix_____"
|
||||
"Another_Long_Name_That_Does_Not_Fit_And_Has_A_Number_Suffix_____"
|
||||
"Another_Long_Name_That_Does_Not_Fit_And_Has_A_Number_Suffix.123456";
|
||||
BLI_STATIC_ASSERT(std::string::traits_type::length(name_b) > MAX_ID_NAME - 2,
|
||||
"Wrong 'max length' name");
|
||||
constexpr char name_b_shorten[] =
|
||||
"Another_Long_Name_That_Does_Not_Fit_And_Has_A_Number_Suffix_____"
|
||||
"Another_Long_Name_That_Does_Not_Fit_And_Has_A_Number_Suffix_____"
|
||||
"Another_Long_Name_That_Does_Not_Fit_And_Has_A_Number_Suffix_____"
|
||||
"Another_Long_Name_That_Does_Not_Fit_And_Has_A_Number_Suffix.123";
|
||||
BLI_STATIC_ASSERT(std::string::traits_type::length(name_b_shorten) == MAX_ID_NAME - 2 - 1,
|
||||
"Wrong 'max length' name");
|
||||
constexpr char name_c[] = "Name_That_Has_Too_Long_Number_Suffix.1234567890";
|
||||
BLI_STATIC_ASSERT(std::string::traits_type::length(name_c) < MAX_ID_NAME - 2,
|
||||
"Wrong 'max length' name");
|
||||
|
||||
ID *id_a = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, name_a));
|
||||
ID *id_b = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, name_b));
|
||||
ID *id_c = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, name_c));
|
||||
|
||||
EXPECT_STREQ(id_a->name + 2, "Long_Name_That_Does_Not_Fit_Into_Max_Name_Limit_And_Should_Get_");
|
||||
EXPECT_STREQ(id_b->name + 2, "Another_Long_Name_That_Does_Not_Fit_And_Has_A_Number_Suffix.123");
|
||||
EXPECT_STREQ(id_c->name + 2, "Name_That_Has_Too_Long_Number_Suffix.1234567890"); /* Unchanged */
|
||||
EXPECT_STREQ(BKE_id_name(*id_a), name_a_shorten);
|
||||
EXPECT_STREQ(BKE_id_name(*id_b), name_b_shorten);
|
||||
EXPECT_STREQ(BKE_id_name(*id_c), name_c); /* Unchanged */
|
||||
|
||||
EXPECT_TRUE(BKE_main_namemap_validate(*ctx.bmain));
|
||||
|
||||
|
||||
@@ -133,6 +133,12 @@ void BLI_path_sequence_encode(char *path,
|
||||
{
|
||||
BLI_string_debug_size(path, path_maxncpy);
|
||||
|
||||
/* FIXME: MAX_ID_NAME & FILE_MAXFILE
|
||||
*
|
||||
* As this function directly works on a full file path (typically a FILE_MAX long char buffer),
|
||||
* and does not perform any check on the filename part of the path, it can easily generate final
|
||||
* paths containing a filename longer than the max supported length (FILE_MAXFILE).
|
||||
*/
|
||||
BLI_snprintf(path, path_maxncpy, "%s%.*d%s", head, numlen, std::max(0, pic), tail);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,8 +12,8 @@ struct bContext;
|
||||
struct uiLayout;
|
||||
|
||||
/* names */
|
||||
#define UI_MAX_DRAW_STR 400
|
||||
#define UI_MAX_NAME_STR 128
|
||||
#define UI_MAX_DRAW_STR 550
|
||||
#define UI_MAX_NAME_STR 256
|
||||
#define UI_MAX_SHORTCUT_STR 64
|
||||
|
||||
/* Menu Callbacks */
|
||||
|
||||
@@ -153,6 +153,12 @@ static wmOperatorStatus brush_asset_save_as_exec(bContext *C, wmOperator *op)
|
||||
|
||||
/* Determine file path to save to. */
|
||||
PropertyRNA *name_prop = RNA_struct_find_property(op->ptr, "name");
|
||||
/* FIXME: MAX_ID_NAME & FILE_MAXFILE
|
||||
*
|
||||
* This `name` should be `MAX_ID_NAME - 2` long.
|
||||
*
|
||||
* This name might also be used as filename for the saved asset, thus hitting the size issue
|
||||
* between ID names and file names (FILE_MAXFILE). */
|
||||
char name[MAX_NAME] = "";
|
||||
if (RNA_property_is_set(op->ptr, name_prop)) {
|
||||
RNA_property_string_get(op->ptr, name_prop, name);
|
||||
|
||||
@@ -82,7 +82,7 @@ void filelist_init_icons();
|
||||
void filelist_free_icons();
|
||||
void filelist_file_get_full_path(const FileList *filelist,
|
||||
const FileDirEntry *file,
|
||||
char r_filepath[/*FILE_MAX_LIBEXTRA*/ 1090]);
|
||||
char r_filepath[/*FILE_MAX_LIBEXTRA*/ 1282]);
|
||||
bool filelist_file_is_preview_pending(const FileList *filelist, const FileDirEntry *file);
|
||||
/**
|
||||
* \return True if a new preview request was pushed, false otherwise (e.g. because the preview is
|
||||
@@ -121,7 +121,7 @@ bool filelist_is_dir(const FileList *filelist, const char *path);
|
||||
/**
|
||||
* May modify in place given `dirpath`, which is expected to be #FILE_MAX_LIBEXTRA length.
|
||||
*/
|
||||
void filelist_setdir(FileList *filelist, char dirpath[/*FILE_MAX_LIBEXTRA*/ 1090]);
|
||||
void filelist_setdir(FileList *filelist, char dirpath[/*FILE_MAX_LIBEXTRA*/ 1282]);
|
||||
|
||||
/**
|
||||
* Limited version of full update done by space_file's file_refresh(),
|
||||
|
||||
@@ -1364,6 +1364,17 @@ static void draw_selected_name(
|
||||
char frame[16];
|
||||
} info_buffers;
|
||||
|
||||
/* Info can contain:
|
||||
* - 1 frame number `(7 + 2)`.
|
||||
* - 1 collection name `(MAX_ID_NAME - 2 + 3)`.
|
||||
* - 1 object name `(MAX_ID_NAME - 2)`.
|
||||
* - 1 object data name `(MAX_ID_NAME - 2)`.
|
||||
* - 2 non-ID data names (bones, shapekeys...) `(MAX_NAME * 2)`.
|
||||
* - 2 BREAD_CRUMB_SEPARATOR(s) `(6)`.
|
||||
* - 1 SHAPE_KEY_PINNED marker and a trailing '\0' `(9+1)` - translated, so give some room!
|
||||
* - 1 marker name `(MAX_NAME + 3)`.
|
||||
*/
|
||||
|
||||
SNPRINTF(info_buffers.frame, "(%d)", cfra);
|
||||
info_array[i++] = info_buffers.frame;
|
||||
|
||||
@@ -1377,15 +1388,6 @@ static void draw_selected_name(
|
||||
}
|
||||
}
|
||||
|
||||
/* Info can contain:
|
||||
* - A frame `(7 + 2)`.
|
||||
* - A collection name `(MAX_NAME + 3)`.
|
||||
* - 3 object names `(MAX_NAME)`.
|
||||
* - 2 BREAD_CRUMB_SEPARATOR(s) `(6)`.
|
||||
* - A SHAPE_KEY_PINNED marker and a trailing '\0' `(9+1)` - translated, so give some room!
|
||||
* - A marker name `(MAX_NAME + 3)`.
|
||||
*/
|
||||
|
||||
/* get name of marker on current frame (if available) */
|
||||
const char *markern = BKE_scene_find_marker_name(scene, cfra);
|
||||
|
||||
@@ -1477,9 +1479,12 @@ static void draw_selected_name(
|
||||
}
|
||||
|
||||
BLI_assert(i < int(ARRAY_SIZE(info_array)));
|
||||
char info[300];
|
||||
/* It's expected there will be enough room for the buffer (if not, increase it). */
|
||||
|
||||
char info[MAX_ID_NAME * 4];
|
||||
/* It's expected there will be enough room for the whole string in the the buffer. If not,
|
||||
* increase it. */
|
||||
BLI_assert(BLI_string_len_array(info_array, i) < sizeof(info));
|
||||
|
||||
BLI_string_join_array(info, sizeof(info), info_array, i);
|
||||
|
||||
*yoffset -= VIEW3D_OVERLAY_LINEHEIGHT;
|
||||
|
||||
@@ -359,8 +359,8 @@ enum {
|
||||
* provides a common handle to place all data in double-linked lists.
|
||||
*/
|
||||
|
||||
/* 2 characters for ID code and 64 for actual name */
|
||||
#define MAX_ID_NAME 66
|
||||
/* 2 characters for ID code and 256 for actual name */
|
||||
#define MAX_ID_NAME 258
|
||||
|
||||
/** #ID_Runtime_Remap.status */
|
||||
enum {
|
||||
@@ -412,7 +412,15 @@ typedef struct ID {
|
||||
/** If the ID is an asset, this pointer is set. Owning pointer. */
|
||||
struct AssetMetaData *asset_data;
|
||||
|
||||
char name[/*MAX_ID_NAME*/ 66];
|
||||
/**
|
||||
* Main identifier for this data-block. Must be unique within the ID name-space (defined by its
|
||||
* type, and owning #Library).
|
||||
*
|
||||
* The first two bytes are always the #ID_Type code of the data-block's type.
|
||||
*
|
||||
* One critical usage is to reference external linked data. */
|
||||
char name[/*MAX_ID_NAME*/ 258];
|
||||
|
||||
/**
|
||||
* ID_FLAG_... flags report on status of the data-block this ID belongs to
|
||||
* (persistent, saved to and read from .blend).
|
||||
@@ -531,7 +539,7 @@ typedef struct LibraryWeakReference {
|
||||
char library_filepath[/*FILE_MAX*/ 1024];
|
||||
|
||||
/** May be different from the current local ID name. */
|
||||
char library_id_name[/*MAX_ID_NAME*/ 66];
|
||||
char library_id_name[/*MAX_ID_NAME*/ 258];
|
||||
|
||||
char _pad[2];
|
||||
} LibraryWeakReference;
|
||||
|
||||
@@ -1184,7 +1184,7 @@ typedef struct ActionSlot {
|
||||
*
|
||||
* \see #AnimData::slot_name
|
||||
*/
|
||||
char identifier[/*MAX_ID_NAME*/ 66];
|
||||
char identifier[/*MAX_ID_NAME*/ 258];
|
||||
|
||||
/**
|
||||
* Type of ID-block that this slot is intended for.
|
||||
|
||||
@@ -441,7 +441,7 @@ typedef struct NlaStrip {
|
||||
* \note Most code should not write to this field directly, but use functions from
|
||||
* `blender::animrig::nla` instead, see ANIM_nla.hh.
|
||||
*/
|
||||
char last_slot_identifier[66]; /* MAX_ID_NAME */
|
||||
char last_slot_identifier[/* MAX_ID_NAME */ 258];
|
||||
char _pad0[2];
|
||||
|
||||
/** F-Curves for controlling this strip's influence and timing */ /* TODO: move out? */
|
||||
@@ -677,7 +677,7 @@ typedef struct AnimData {
|
||||
*
|
||||
* \see #ActionSlot::name
|
||||
*/
|
||||
char last_slot_identifier[66]; /* MAX_ID_NAME */
|
||||
char last_slot_identifier[/* MAX_ID_NAME */ 258];
|
||||
uint8_t _pad0[2];
|
||||
|
||||
/**
|
||||
@@ -686,7 +686,7 @@ typedef struct AnimData {
|
||||
*/
|
||||
bAction *tmpact;
|
||||
int32_t tmp_slot_handle;
|
||||
char tmp_last_slot_identifier[66]; /* MAX_ID_NAME */
|
||||
char tmp_last_slot_identifier[/* MAX_ID_NAME */ 258];
|
||||
uint8_t _pad1[2];
|
||||
|
||||
/* nla-tracks */
|
||||
|
||||
@@ -303,7 +303,7 @@ typedef struct bActionConstraint {
|
||||
float eval_time; /* Only used when flag ACTCON_USE_EVAL_TIME is set. */
|
||||
struct bAction *act;
|
||||
int32_t action_slot_handle;
|
||||
char last_slot_identifier[/*MAX_ID_NAME*/ 66];
|
||||
char last_slot_identifier[/*MAX_ID_NAME*/ 258];
|
||||
char _pad1[2];
|
||||
char subtarget[/*MAX_NAME*/ 64];
|
||||
} bActionConstraint;
|
||||
|
||||
@@ -396,10 +396,10 @@ typedef struct FileSelectParams {
|
||||
/**
|
||||
* Directory.
|
||||
*
|
||||
* \note #FILE_MAX_LIBEXTRA == `1024 + 66`, this is for extreme case when 1023 length path
|
||||
* \note #FILE_MAX_LIBEXTRA == `1024 + 258`, this is for extreme case when 1023 length path
|
||||
* needs to be linked in, where `foo.blend/Armature` need adding.
|
||||
*/
|
||||
char dir[/*FILE_MAX_LIBEXTRA*/ 1090];
|
||||
char dir[/*FILE_MAX_LIBEXTRA*/ 1282];
|
||||
char file[/*FILE_MAXFILE*/ 256];
|
||||
|
||||
char renamefile[/*FILE_MAXFILE*/ 256];
|
||||
|
||||
@@ -1034,6 +1034,11 @@ static void render_result_exr_file_cache_path(Scene *sce,
|
||||
root = root_buf;
|
||||
}
|
||||
|
||||
/* FIXME: MAX_ID_NAME & FILE_MAXFILE
|
||||
*
|
||||
* If #filename is already long (it is initialized from the blend-file name itself), adding the
|
||||
* scene name can cause the file name to be truncated.
|
||||
*/
|
||||
SNPRINTF(filename_full, "cached_RR_%s_%s_%s.exr", filename, sce->id.name + 2, path_hexdigest);
|
||||
|
||||
BLI_path_join(r_path, FILE_CACHE_MAX, root, filename_full);
|
||||
|
||||
BIN
tests/files/io_tests/fbx/max2025-longnames.fbx
(Stored with Git LFS)
BIN
tests/files/io_tests/fbx/max2025-longnames.fbx
(Stored with Git LFS)
Binary file not shown.
@@ -135,7 +135,7 @@
|
||||
-0.210 0.000 0.978 0.000
|
||||
- props: int:MaxHandle=3
|
||||
- anim act:Take 001 slot:OBArmature blend:REPLACE drivers:0
|
||||
- Obj 'Box_With_A_Long_Name_To_Test_Importer_Handling_Of_Names_That_A' MESH data:'Mesh.002' par:'Armature'
|
||||
- Obj 'Box_With_A_Long_Name_To_Test_Importer_Handling_Of_Names_That_Are_Too_Long_To_Fit_Box_With_A_Long_Name_To_Test_Importer_Handling_Of_Names_That_Are_Too_Long_To_Fit_Box_With_A_Long_Name_To_Test_Importer_Handling_Of_Names_That_Are_Too_Long_To_Fit_Box_With_A_' MESH data:'Mesh.002' par:'Armature'
|
||||
- pos 0.679, 0.000, 15.811
|
||||
- rot -1.571, 0.000, 0.000 (XYZ)
|
||||
- scl 1.000, 1.000, 1.000
|
||||
@@ -144,7 +144,7 @@
|
||||
- 1 modifiers
|
||||
- ARMATURE 'Armature'
|
||||
- props: int:MaxHandle=10
|
||||
- Obj 'Box_With_A_Long_Name_To_Test_Importer_Handling_Of_Names_That_Ar' MESH data:'Mesh' par:'Armature'
|
||||
- Obj 'Box_With_A_Long_Name_To_Test_Importer_Handling_Of_Names_That_Are_Too_Long_To_Fit_Box_With_A_Long_Name_To_Test_Importer_Handling_Of_Names_That_Are_Too_Long_To_Fit_Box_With_A_Long_Name_To_Test_Importer_Handling_Of_Names_That_Are_Too_Long_To_Fit_Box_With_A_L' MESH data:'Mesh' par:'Armature'
|
||||
- pos 0.679, 0.000, -0.945
|
||||
- rot -1.571, 0.000, 0.000 (XYZ)
|
||||
- scl 1.000, 1.000, 1.000
|
||||
@@ -153,17 +153,17 @@
|
||||
- 1 modifiers
|
||||
- ARMATURE 'Armature'
|
||||
- props: int:MaxHandle=2
|
||||
- Obj 'Box_Yellow_That_Is_Animated_And_Also_With_A_Long_Name_Let_Us_Se' MESH data:'Mesh.003'
|
||||
- Obj 'Box_Yellow_That_Is_Animated_And_Also_With_A_Long_Name_Let_Us_See_What_Happens_Here_Box_Yellow_That_Is_Animated_And_Also_With_A_Long_Name_Let_Us_See_What_Happens_Here_Box_Yellow_That_Is_Animated_And_Also_With_A_Long_Name_Let_Us_See_What_Happens_Here_Box_Ye' MESH data:'Mesh.003'
|
||||
- pos -0.261, -0.829, 0.000
|
||||
- rot 0.000, 0.000, 0.000 (XYZ)
|
||||
- scl 0.025, 0.025, 0.025
|
||||
- anim act:Take 001 slot:OBBox_Yellow_That_Is_Animated_And_Also_With_A_Long_Name_Let_Us_Se blend:REPLACE drivers:0
|
||||
- anim act:Take 001 slot:OBBox_Yellow_That_Is_Animated_And_Also_With_A_Long_Name_Let_Us_See_What_Happens_Here_Box_Yellow_That_Is_Animated_And_Also_With_A_Long_Name_Let_Us_See_What_Happens_Here_Box_Yellow_That_Is_Animated_And_Also_With_A_Long_Name_Let_Us_See_What_Happens_Here_Box_Ye blend:REPLACE drivers:0
|
||||
- props: int:MaxHandle=14
|
||||
- Obj 'Point_Light_Object_Color_Blue_Light_Color_Animated_With_A_Long_' LIGHT data:'Light'
|
||||
- Obj 'Point_Light_Object_Color_Blue_Light_Color_Animated_With_A_Long_Name_Here_Point_Light_Object_Color_Blue_Light_Color_Animated_With_A_Long_Name_Here_Point_Light_Object_Color_Blue_Light_Color_Animated_With_A_Long_Name_Here_Point_Light_Object_Color_Blue_Light_' LIGHT data:'Light'
|
||||
- pos 0.567, -0.741, 0.000
|
||||
- rot 0.000, 0.000, 0.000 (XYZ)
|
||||
- scl 0.025, 0.025, 0.025
|
||||
- anim act:Take 001 slot:OBPoint_Light_Object_Color_Blue_Light_Color_Animated_With_A_Long_ blend:REPLACE drivers:0
|
||||
- anim act:Take 001 slot:OBPoint_Light_Object_Color_Blue_Light_Color_Animated_With_A_Long_Name_Here_Point_Light_Object_Color_Blue_Light_Color_Animated_With_A_Long_Name_Here_Point_Light_Object_Color_Blue_Light_Color_Animated_With_A_Long_Name_Here_Point_Light_Object_Color_Blue_Light_ blend:REPLACE drivers:0
|
||||
- props: int:MaxHandle=15
|
||||
- Obj 'Sphere_Parented_To_Bone' MESH data:'Mesh.001' par:'Armature' par_type:BONE par_bone:'Likewise_Here_Is_A_Bone_With_A_Long_Name_To_See_What_Happen.002'
|
||||
- pos 6.099, -21.143, 2.790
|
||||
@@ -224,7 +224,7 @@
|
||||
- fcu 'pose.bones["Likewise_Here_Is_A_Bone_With_A_Long_Name_To_See_What_Happen.003"].rotation_quaternion[1]' smooth:CONT_ACCEL extra:CONSTANT keyframes:2 grp:'Likewise_Here_Is_A_Bone_With_A_Long_Name_To_See_What_Happen.003'
|
||||
- (1.000, 0.000) lh:(-0.667, 0.000 AUTO_CLAMPED) rh:(2.667, 0.000 AUTO_CLAMPED)
|
||||
- (6.000, 0.000) lh:(4.333, 0.000 AUTO_CLAMPED) rh:(7.667, 0.000 AUTO_CLAMPED)
|
||||
- Channelbag slot 'OBBox_Yellow_That_Is_Animated_And_Also_With_A_Long_Name_Let_Us_Se' curves:9
|
||||
- Channelbag slot 'OBBox_Yellow_That_Is_Animated_And_Also_With_A_Long_Name_Let_Us_See_What_Happens_Here_Box_Yellow_That_Is_Animated_And_Also_With_A_Long_Name_Let_Us_See_What_Happens_Here_Box_Yellow_That_Is_Animated_And_Also_With_A_Long_Name_Let_Us_See_What_Happens_Here_Box_Ye' curves:9
|
||||
- fcu 'location[0]' smooth:CONT_ACCEL extra:CONSTANT keyframes:2 grp:'Box_Yellow_That_Is_Animated_And_Also_With_A_Long_Name_Let_Us_Se'
|
||||
- (1.000, -0.261) lh:(0.000, -0.261 AUTO_CLAMPED) rh:(2.000, -0.261 AUTO_CLAMPED)
|
||||
- (4.000, 0.211) lh:(3.000, 0.211 AUTO_CLAMPED) rh:(5.000, 0.211 AUTO_CLAMPED)
|
||||
@@ -252,7 +252,7 @@
|
||||
- fcu 'scale[2]' smooth:CONT_ACCEL extra:CONSTANT keyframes:2 grp:'Box_Yellow_That_Is_Animated_And_Also_With_A_Long_Name_Let_Us_Se'
|
||||
- (1.000, 0.025) lh:(0.000, 0.025 AUTO_CLAMPED) rh:(2.000, 0.025 AUTO_CLAMPED)
|
||||
- (4.000, 0.025) lh:(3.000, 0.025 AUTO_CLAMPED) rh:(5.000, 0.025 AUTO_CLAMPED)
|
||||
- Channelbag slot 'OBPoint_Light_Object_Color_Blue_Light_Color_Animated_With_A_Long_' curves:9
|
||||
- Channelbag slot 'OBPoint_Light_Object_Color_Blue_Light_Color_Animated_With_A_Long_Name_Here_Point_Light_Object_Color_Blue_Light_Color_Animated_With_A_Long_Name_Here_Point_Light_Object_Color_Blue_Light_Color_Animated_With_A_Long_Name_Here_Point_Light_Object_Color_Blue_Light_' curves:9
|
||||
- fcu 'location[0]' smooth:CONT_ACCEL extra:CONSTANT keyframes:2 grp:'Point_Light_Object_Color_Blue_Light_Color_Animated_With_A_Long_'
|
||||
- (1.000, 0.567) lh:(-0.667, 0.567 AUTO_CLAMPED) rh:(2.667, 0.567 AUTO_CLAMPED)
|
||||
- (6.000, 1.148) lh:(4.333, 1.148 AUTO_CLAMPED) rh:(7.667, 1.148 AUTO_CLAMPED)
|
||||
|
||||
BIN
tests/files/io_tests/obj/invalid_syntax.obj
(Stored with Git LFS)
BIN
tests/files/io_tests/obj/invalid_syntax.obj
(Stored with Git LFS)
Binary file not shown.
@@ -1,5 +1,5 @@
|
||||
==== Meshes: 1
|
||||
- Mesh 'ObjectWithAReallyLongNameToCheckHowImportHandlesNamesThatAreLon' vtx:3 face:1 loop:3 edge:3
|
||||
- Mesh 'ObjectWithAReallyLongNameToCheckHowImportHandlesNamesThatAreLongerThanBlenderCanHandleObjectWithAReallyLongNameToCheckHowImportHandlesNamesThatAreLongerThanBlenderCanHandleObjectWithAReallyLongNameToCheckHowImportHandlesNamesThatAreLongerThanBlenderCanHan' vtx:3 face:1 loop:3 edge:3
|
||||
- 0 1 2
|
||||
- 0/2 0/1 1/2
|
||||
- attr 'position' FLOAT_VECTOR POINT
|
||||
@@ -22,7 +22,7 @@
|
||||
- (1.000, 0.750)
|
||||
|
||||
==== Objects: 1
|
||||
- Obj 'ObjectWithAReallyLongNameToCheckHowImportHandlesNamesThatAreLon' MESH data:'ObjectWithAReallyLongNameToCheckHowImportHandlesNamesThatAreLon'
|
||||
- Obj 'ObjectWithAReallyLongNameToCheckHowImportHandlesNamesThatAreLongerThanBlenderCanHandleObjectWithAReallyLongNameToCheckHowImportHandlesNamesThatAreLongerThanBlenderCanHandleObjectWithAReallyLongNameToCheckHowImportHandlesNamesThatAreLongerThanBlenderCanHan' MESH data:'ObjectWithAReallyLongNameToCheckHowImportHandlesNamesThatAreLongerThanBlenderCanHandleObjectWithAReallyLongNameToCheckHowImportHandlesNamesThatAreLongerThanBlenderCanHandleObjectWithAReallyLongNameToCheckHowImportHandlesNamesThatAreLongerThanBlenderCanHan'
|
||||
- pos 0.000, 0.000, 0.000
|
||||
- rot 1.571, 0.000, 0.000 (XYZ)
|
||||
- scl 1.000, 1.000, 1.000
|
||||
|
||||
@@ -68,24 +68,36 @@ class ActionSlotCreationTest(unittest.TestCase):
|
||||
self.action.slots.new('UNSPECIFIED', "Bob")
|
||||
|
||||
def test_long_identifier(self):
|
||||
# Test a 65-character identifier, using a 63-character name. This is the
|
||||
# maximum length allowed (the DNA field is MAX_ID_NAME=66 long, which
|
||||
# Test a 257-character identifier, using a 255-character name. This is the
|
||||
# maximum length allowed (the DNA field is MAX_ID_NAME=258 long, which
|
||||
# includes the trailing zero byte).
|
||||
long_but_ok_name = "This name is so long! It might look long, but it is just right!"
|
||||
long_but_ok_name = (
|
||||
"This name is so long! It might look long, but it is just right! "
|
||||
"This name is so long! It might look long, but it is just right! "
|
||||
"This name is so long! It might look long, but it is just right! "
|
||||
"This name is so long! It might look long, but it is just right!"
|
||||
)
|
||||
assert (len(long_but_ok_name) == 255)
|
||||
slot_ok = self.action.slots.new('OBJECT', long_but_ok_name)
|
||||
self.assertEqual(long_but_ok_name, slot_ok.name_display, "this name should fit")
|
||||
self.assertEqual('OB' + long_but_ok_name, slot_ok.identifier, "this identifier should fit")
|
||||
|
||||
# Test one character more.
|
||||
too_long_name = "This name is so long! It might look long, and that it is indeed."
|
||||
too_long_name_truncated = too_long_name[:63]
|
||||
too_long_name = (
|
||||
"This name is so long! It might look long, and that it is indeed."
|
||||
"This name is so long! It might look long, and that it is indeed."
|
||||
"This name is so long! It might look long, and that it is indeed."
|
||||
"This name is so long! It might look long, and that it is indeed."
|
||||
)
|
||||
assert (len(too_long_name) == 256)
|
||||
too_long_name_truncated = too_long_name[:255]
|
||||
slot_long = self.action.slots.new('OBJECT', too_long_name)
|
||||
self.assertEqual(too_long_name_truncated, slot_long.name_display, "this name should be truncated")
|
||||
self.assertEqual('OB' + too_long_name_truncated, slot_long.identifier, "this identifier should be truncated")
|
||||
|
||||
# Test with different trailing character.
|
||||
other_long_name = "This name is so long! It might look long, and that it is indeed!"
|
||||
truncated_and_unique = other_long_name[:59] + ".001"
|
||||
other_long_name = too_long_name[:-1] + "!"
|
||||
truncated_and_unique = other_long_name[:251] + ".001"
|
||||
slot_long2 = self.action.slots.new('OBJECT', too_long_name)
|
||||
self.assertEqual(truncated_and_unique, slot_long2.name_display,
|
||||
"this name should be truncated and made unique")
|
||||
|
||||
Reference in New Issue
Block a user