diff options
Diffstat (limited to 'source/blender/makesdna')
-rw-r--r-- | source/blender/makesdna/DNA_cloth_types.h | 2 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_genfile.h | 20 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_modifier_types.h | 16 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_sdna_types.h | 11 | ||||
-rw-r--r-- | source/blender/makesdna/intern/CMakeLists.txt | 2 | ||||
-rw-r--r-- | source/blender/makesdna/intern/dna_genfile.c | 307 |
6 files changed, 194 insertions, 164 deletions
diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h index 07bc2478837..d385e303a7c 100644 --- a/source/blender/makesdna/DNA_cloth_types.h +++ b/source/blender/makesdna/DNA_cloth_types.h @@ -42,7 +42,7 @@ * * I've tried to keep similar, if not exact names for the variables as * are presented in the paper. Where I've changed the concept slightly, - * as in stepsPerFrame comapred to the time step in the paper, I've used + * as in stepsPerFrame compared to the time step in the paper, I've used * variables with different names to minimize confusion. */ diff --git a/source/blender/makesdna/DNA_genfile.h b/source/blender/makesdna/DNA_genfile.h index 77877f7bada..0e34792e624 100644 --- a/source/blender/makesdna/DNA_genfile.h +++ b/source/blender/makesdna/DNA_genfile.h @@ -76,13 +76,23 @@ enum eSDNA_StructCompare { struct SDNA *DNA_sdna_from_data( const void *data, const int datalen, - bool do_endian_swap, bool data_alloc); + bool do_endian_swap, bool data_alloc, + const char **r_error_message); void DNA_sdna_free(struct SDNA *sdna); -int DNA_struct_find_nr(struct SDNA *sdna, const char *str); -void DNA_struct_switch_endian(struct SDNA *oldsdna, int oldSDNAnr, char *data); -char *DNA_struct_get_compareflags(struct SDNA *sdna, struct SDNA *newsdna); -void *DNA_struct_reconstruct(struct SDNA *newsdna, struct SDNA *oldsdna, char *compflags, int oldSDNAnr, int blocks, void *data); +/* Access for current Blender versions SDNA*/ +void DNA_sdna_current_init(void); +/* borrowed reference */ +const struct SDNA *DNA_sdna_current_get(void); +void DNA_sdna_current_free(void); + +int DNA_struct_find_nr_ex(const struct SDNA *sdna, const char *str, unsigned int *index_last); +int DNA_struct_find_nr(const struct SDNA *sdna, const char *str); +void DNA_struct_switch_endian(const struct SDNA *oldsdna, int oldSDNAnr, char *data); +char *DNA_struct_get_compareflags(const struct SDNA *sdna, const struct SDNA *newsdna); +void *DNA_struct_reconstruct( + const struct SDNA *newsdna, const struct SDNA *oldsdna, + char *compflags, int oldSDNAnr, int blocks, void *data); int DNA_elem_array_size(const char *str); int DNA_elem_offset(struct SDNA *sdna, const char *stype, const char *vartype, const char *name); diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 5d04fba776f..a6bbb40d826 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -639,8 +639,9 @@ typedef struct BooleanModifierData { struct Object *object; char operation; - char bm_flag, pad[2]; - float threshold; + char solver; + char pad[2]; + float double_threshold; } BooleanModifierData; typedef enum { @@ -649,13 +650,10 @@ typedef enum { eBooleanModifierOp_Difference = 2, } BooleanModifierOp; -/* temp bm_flag (debugging only) */ -enum { - eBooleanModifierBMeshFlag_Enabled = (1 << 0), - eBooleanModifierBMeshFlag_BMesh_Separate = (1 << 1), - eBooleanModifierBMeshFlag_BMesh_NoDissolve = (1 << 2), - eBooleanModifierBMeshFlag_BMesh_NoConnectRegions = (1 << 3), -}; +typedef enum { + eBooleanModifierSolver_Carve = 0, + eBooleanModifierSolver_BMesh = 1, +} BooleanSolver; typedef struct MDefInfluence { int vertex; diff --git a/source/blender/makesdna/DNA_sdna_types.h b/source/blender/makesdna/DNA_sdna_types.h index 791aca77558..bd8f23f30c1 100644 --- a/source/blender/makesdna/DNA_sdna_types.h +++ b/source/blender/makesdna/DNA_sdna_types.h @@ -35,17 +35,17 @@ # # typedef struct SDNA { - const char *data; /* full copy of 'encoded' data */ + const char *data; /* full copy of 'encoded' data (when data_alloc is set, otherwise borrowed). */ int datalen; /* length of data */ bool data_alloc; int nr_names; /* total number of struct members */ - const char **names; /* struct member names */ + const char **names; /* struct member names */ int pointerlen; /* size of a pointer in bytes */ int nr_types; /* number of basic types + struct types */ - char **types; /* type names */ + const char **types; /* type names */ short *typelens; /* type lengths */ int nr_structs; /* number of struct types */ @@ -57,11 +57,6 @@ typedef struct SDNA { struct GHash *structs_map; /* ghash for faster lookups, * requires WITH_DNA_GHASH to be used for now */ - - /* wrong place for this really, its a simple - * cache for findstruct_nr. - */ - int lastfind; } SDNA; # diff --git a/source/blender/makesdna/intern/CMakeLists.txt b/source/blender/makesdna/intern/CMakeLists.txt index 0bb6e866bf4..8c758c33dc5 100644 --- a/source/blender/makesdna/intern/CMakeLists.txt +++ b/source/blender/makesdna/intern/CMakeLists.txt @@ -52,6 +52,8 @@ endif() # SRC_DNA_INC is defined in the parent dir +add_cc_flags_custom_test(makesdna) + add_executable(makesdna ${SRC} ${SRC_DNA_INC}) # Output dna.c diff --git a/source/blender/makesdna/intern/dna_genfile.c b/source/blender/makesdna/intern/dna_genfile.c index 9135d7bab7d..4db98bda7dd 100644 --- a/source/blender/makesdna/intern/dna_genfile.c +++ b/source/blender/makesdna/intern/dna_genfile.c @@ -39,6 +39,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <limits.h> #include "MEM_guardedalloc.h" // for MEM_freeN MEM_mallocN MEM_callocN @@ -133,39 +134,6 @@ * */ -/* ************************* ENDIAN STUFF ********************** */ - -/** - * converts a short between big/little endian. - */ -static short le_short(short temp) -{ - short new; - char *rt = (char *)&temp, *rtn = (char *)&new; - - rtn[0] = rt[1]; - rtn[1] = rt[0]; - - return new; -} - -/** - * converts an int between big/little endian. - */ -static int le_int(int temp) -{ - int new; - char *rt = (char *)&temp, *rtn = (char *)&new; - - rtn[0] = rt[3]; - rtn[1] = rt[2]; - rtn[2] = rt[1]; - rtn[3] = rt[0]; - - return new; -} - - /* ************************* MAKE DNA ********************** */ /* allowed duplicate code from makesdna.c */ @@ -280,37 +248,16 @@ static void printstruct(SDNA *sdna, short strnr) #endif /** - * Returns a pointer to the start of the struct info for the struct with the specified name. - */ -static short *findstruct_name(SDNA *sdna, const char *str) -{ - int a; - short *sp = NULL; - - - for (a = 0; a < sdna->nr_structs; a++) { - - sp = sdna->structs[a]; - - if (strcmp(sdna->types[sp[0]], str) == 0) { - return sp; - } - } - - return NULL; -} - -/** * Returns the index of the struct info for the struct with the specified name. */ -int DNA_struct_find_nr(SDNA *sdna, const char *str) +int DNA_struct_find_nr_ex(const SDNA *sdna, const char *str, unsigned int *index_last) { const short *sp = NULL; - if (sdna->lastfind < sdna->nr_structs) { - sp = sdna->structs[sdna->lastfind]; + if (*index_last < sdna->nr_structs) { + sp = sdna->structs[*index_last]; if (strcmp(sdna->types[sp[0]], str) == 0) { - return sdna->lastfind; + return *index_last; } } @@ -323,7 +270,7 @@ int DNA_struct_find_nr(SDNA *sdna, const char *str) if (index_p) { a = GET_INT_FROM_POINTER(*index_p); - sdna->lastfind = a; + *index_last = a; } else { a = -1; @@ -339,7 +286,7 @@ int DNA_struct_find_nr(SDNA *sdna, const char *str) sp = sdna->structs[a]; if (strcmp(sdna->types[sp[0]], str) == 0) { - sdna->lastfind = a; + *index_last = a; return a; } } @@ -348,26 +295,51 @@ int DNA_struct_find_nr(SDNA *sdna, const char *str) #endif } +int DNA_struct_find_nr(const SDNA *sdna, const char *str) +{ + unsigned int index_last_dummy = UINT_MAX; + return DNA_struct_find_nr_ex(sdna, str, &index_last_dummy); +} + /* ************************* END DIV ********************** */ /* ************************* READ DNA ********************** */ +BLI_INLINE const char *pad_up_4(const char *ptr) +{ + return (const char *)((((uintptr_t)ptr) + 3) & ~3); +} + /** * In sdna->data the data, now we convert that to something understandable */ -static void init_structDNA(SDNA *sdna, bool do_endian_swap) +static bool init_structDNA( + SDNA *sdna, bool do_endian_swap, + const char **r_error_message) { int *data, *verg, gravity_fix = -1; - intptr_t nr; short *sp; - char str[8], *cp; + char str[8]; verg = (int *)str; data = (int *)sdna->data; + /* clear pointers incase of error */ + sdna->names = NULL; + sdna->types = NULL; + sdna->structs = NULL; +#ifdef WITH_DNA_GHASH + sdna->structs_map = NULL; +#endif + strcpy(str, "SDNA"); - if (*data == *verg) { - + if (*data != *verg) { + *r_error_message = "SDNA error in SDNA file"; + return false; + } + else { + const char *cp; + data++; /* load names array */ @@ -375,20 +347,21 @@ static void init_structDNA(SDNA *sdna, bool do_endian_swap) if (*data == *verg) { data++; - if (do_endian_swap) sdna->nr_names = le_int(*data); - else sdna->nr_names = *data; + sdna->nr_names = *data; + if (do_endian_swap) { + BLI_endian_switch_int32(&sdna->nr_names); + } data++; sdna->names = MEM_callocN(sizeof(void *) * sdna->nr_names, "sdnanames"); } else { - printf("NAME error in SDNA file\n"); - return; + *r_error_message = "NAME error in SDNA file"; + return false; } - nr = 0; cp = (char *)data; - while (nr < sdna->nr_names) { + for (int nr = 0; nr < sdna->nr_names; nr++) { sdna->names[nr] = cp; /* "float gravity [3]" was parsed wrong giving both "gravity" and @@ -403,32 +376,31 @@ static void init_structDNA(SDNA *sdna, bool do_endian_swap) while (*cp) cp++; cp++; - nr++; } - nr = (intptr_t)cp; /* prevent BUS error */ - nr = (nr + 3) & ~3; - cp = (char *)nr; + + cp = pad_up_4(cp); /* load type names array */ data = (int *)cp; strcpy(str, "TYPE"); if (*data == *verg) { data++; - - if (do_endian_swap) sdna->nr_types = le_int(*data); - else sdna->nr_types = *data; + + sdna->nr_types = *data; + if (do_endian_swap) { + BLI_endian_switch_int32(&sdna->nr_types); + } data++; sdna->types = MEM_callocN(sizeof(void *) * sdna->nr_types, "sdnatypes"); } else { - printf("TYPE error in SDNA file\n"); - return; + *r_error_message = "TYPE error in SDNA file"; + return false; } - nr = 0; cp = (char *)data; - while (nr < sdna->nr_types) { + for (int nr = 0; nr < sdna->nr_types; nr++) { sdna->types[nr] = cp; /* this is a patch, to change struct names without a conflict with SDNA */ @@ -441,11 +413,9 @@ static void init_structDNA(SDNA *sdna, bool do_endian_swap) while (*cp) cp++; cp++; - nr++; } - nr = (intptr_t)cp; /* prevent BUS error */ - nr = (nr + 3) & ~3; - cp = (char *)nr; + + cp = pad_up_4(cp); /* load typelen array */ data = (int *)cp; @@ -456,20 +426,14 @@ static void init_structDNA(SDNA *sdna, bool do_endian_swap) sdna->typelens = sp; if (do_endian_swap) { - short a, *spo = sp; - - a = sdna->nr_types; - while (a--) { - spo[0] = le_short(spo[0]); - spo++; - } + BLI_endian_switch_int16_array(sp, sdna->nr_types); } sp += sdna->nr_types; } else { - printf("TLEN error in SDNA file\n"); - return; + *r_error_message = "TLEN error in SDNA file"; + return false; } if (sdna->nr_types & 1) sp++; /* prevent BUS error */ @@ -479,74 +443,90 @@ static void init_structDNA(SDNA *sdna, bool do_endian_swap) if (*data == *verg) { data++; - if (do_endian_swap) sdna->nr_structs = le_int(*data); - else sdna->nr_structs = *data; + sdna->nr_structs = *data; + if (do_endian_swap) { + BLI_endian_switch_int32(&sdna->nr_structs); + } data++; sdna->structs = MEM_callocN(sizeof(void *) * sdna->nr_structs, "sdnastrcs"); } else { - printf("STRC error in SDNA file\n"); - return; + *r_error_message = "STRC error in SDNA file"; + return false; } - nr = 0; sp = (short *)data; - while (nr < sdna->nr_structs) { + for (int nr = 0; nr < sdna->nr_structs; nr++) { sdna->structs[nr] = sp; if (do_endian_swap) { short a; - sp[0] = le_short(sp[0]); - sp[1] = le_short(sp[1]); + BLI_endian_switch_int16(&sp[0]); + BLI_endian_switch_int16(&sp[1]); a = sp[1]; sp += 2; while (a--) { - sp[0] = le_short(sp[0]); - sp[1] = le_short(sp[1]); + BLI_endian_switch_int16(&sp[0]); + BLI_endian_switch_int16(&sp[1]); sp += 2; } } else { sp += 2 * sp[1] + 2; } - - nr++; } + } - /* finally pointerlen: use struct ListBase to test it, never change the size of it! */ - sp = findstruct_name(sdna, "ListBase"); - /* weird; i have no memory of that... I think I used sizeof(void *) before... (ton) */ - - sdna->pointerlen = sdna->typelens[sp[0]] / 2; - - if (sp[1] != 2 || (sdna->pointerlen != 4 && sdna->pointerlen != 8)) { - printf("ListBase struct error! Needs it to calculate pointerize.\n"); - exit(1); - /* well, at least sizeof(ListBase) is error proof! (ton) */ - } - + { /* second part of gravity problem, setting "gravity" type to void */ if (gravity_fix > -1) { - for (nr = 0; nr < sdna->nr_structs; nr++) { + for (int nr = 0; nr < sdna->nr_structs; nr++) { sp = sdna->structs[nr]; if (strcmp(sdna->types[sp[0]], "ClothSimSettings") == 0) sp[10] = SDNA_TYPE_VOID; } } + } #ifdef WITH_DNA_GHASH + { /* create a ghash lookup to speed up */ sdna->structs_map = BLI_ghash_str_new_ex("init_structDNA gh", sdna->nr_structs); - for (nr = 0; nr < sdna->nr_structs; nr++) { + for (intptr_t nr = 0; nr < sdna->nr_structs; nr++) { sp = sdna->structs[nr]; - BLI_ghash_insert(sdna->structs_map, sdna->types[sp[0]], SET_INT_IN_POINTER(nr)); + BLI_ghash_insert(sdna->structs_map, (void *)sdna->types[sp[0]], SET_INT_IN_POINTER(nr)); } + } #endif + + /* Calculate 'sdna->pointerlen' */ + { + intptr_t nr = DNA_struct_find_nr(sdna, "ListBase"); + + /* should never happen, only with corrupt file for example */ + if (UNLIKELY(nr == -1)) { + *r_error_message = "ListBase struct error! Not found."; + return false; + } + + /* finally pointerlen: use struct ListBase to test it, never change the size of it! */ + sp = sdna->structs[nr]; + /* weird; i have no memory of that... I think I used sizeof(void *) before... (ton) */ + + sdna->pointerlen = sdna->typelens[sp[0]] / 2; + + if (sp[1] != 2 || (sdna->pointerlen != 4 && sdna->pointerlen != 8)) { + *r_error_message = "ListBase struct error! Needs it to calculate pointerize."; + /* well, at least sizeof(ListBase) is error proof! (ton) */ + return false; + } } + + return true; } /** @@ -554,11 +534,11 @@ static void init_structDNA(SDNA *sdna, bool do_endian_swap) */ SDNA *DNA_sdna_from_data( const void *data, const int datalen, - bool do_endian_swap, bool data_alloc) + bool do_endian_swap, bool data_alloc, + const char **r_error_message) { SDNA *sdna = MEM_mallocN(sizeof(*sdna), "sdna"); - - sdna->lastfind = 0; + const char *error_message = NULL; sdna->datalen = datalen; if (data_alloc) { @@ -571,9 +551,44 @@ SDNA *DNA_sdna_from_data( } sdna->data_alloc = data_alloc; - init_structDNA(sdna, do_endian_swap); - - return sdna; + + if (init_structDNA(sdna, do_endian_swap, &error_message)) { + return sdna; + } + else { + if (r_error_message == NULL) { + fprintf(stderr, "Error decoding blend file SDNA: %s\n", error_message); + } + else { + *r_error_message = error_message; + } + DNA_sdna_free(sdna); + return NULL; + } +} + +/** + * Using globals is acceptable here, the data is read-only and only changes between Blender versions. + * + * So it is safe to create once and reuse. + */ +static SDNA *g_sdna = NULL; + +void DNA_sdna_current_init(void) +{ + g_sdna = DNA_sdna_from_data(DNAstr, DNAlen, false, false, NULL); +} + +const struct SDNA *DNA_sdna_current_get(void) +{ + BLI_assert(g_sdna != NULL); + return g_sdna; +} + +void DNA_sdna_current_free(void) +{ + DNA_sdna_free(g_sdna); + g_sdna = NULL; } /* ******************** END READ DNA ********************** */ @@ -623,7 +638,7 @@ static void recurs_test_compflags(const SDNA *sdna, char *compflags, int structn * - 1 Struct is the same (can be loaded with straight memory copy after any necessary endian conversion) * - 2 Struct is different in some way (needs to be copied/converted field by field) */ -char *DNA_struct_get_compareflags(SDNA *oldsdna, SDNA *newsdna) +char *DNA_struct_get_compareflags(const SDNA *oldsdna, const SDNA *newsdna) { int a, b; const short *sp_old, *sp_new; @@ -640,14 +655,19 @@ char *DNA_struct_get_compareflags(SDNA *oldsdna, SDNA *newsdna) /* we check all structs in 'oldsdna' and compare them with * the structs in 'newsdna' */ + unsigned int newsdna_index_last = 0; for (a = 0; a < oldsdna->nr_structs; a++) { sp_old = oldsdna->structs[a]; /* search for type in cur */ - sp_new = findstruct_name(newsdna, oldsdna->types[sp_old[0]]); - - if (sp_new) { + int sp_new_index = DNA_struct_find_nr_ex(newsdna, oldsdna->types[sp_old[0]], &newsdna_index_last); + + /* The next indices will almost always match */ + newsdna_index_last++; + + if (sp_new_index != -1) { + sp_new = newsdna->structs[sp_new_index]; /* initial assumption */ compflags[a] = SDNA_CMP_NOT_EQUAL; @@ -1037,8 +1057,8 @@ static void reconstruct_elem( * \param cur Where to put converted struct contents */ static void reconstruct_struct( - SDNA *newsdna, - SDNA *oldsdna, + const SDNA *newsdna, + const SDNA *oldsdna, const char *compflags, int oldSDNAnr, @@ -1056,6 +1076,10 @@ static void reconstruct_struct( char *cpo, *cpc; const char *name, *nameo; + unsigned int oldsdna_index_last = UINT_MAX; + unsigned int cursdna_index_last = UINT_MAX; + + if (oldSDNAnr == -1) return; if (curSDNAnr == -1) return; @@ -1090,8 +1114,8 @@ static void reconstruct_struct( cpo = find_elem(oldsdna, type, name, spo, data, &sppo); if (cpo) { - oldSDNAnr = DNA_struct_find_nr(oldsdna, type); - curSDNAnr = DNA_struct_find_nr(newsdna, type); + oldSDNAnr = DNA_struct_find_nr_ex(oldsdna, type, &oldsdna_index_last); + curSDNAnr = DNA_struct_find_nr_ex(newsdna, type, &cursdna_index_last); /* array! */ mul = DNA_elem_array_size(name); @@ -1132,7 +1156,7 @@ static void reconstruct_struct( * \param oldSDNAnr Index of struct info within oldsdna * \param data Struct data */ -void DNA_struct_switch_endian(SDNA *oldsdna, int oldSDNAnr, char *data) +void DNA_struct_switch_endian(const SDNA *oldsdna, int oldSDNAnr, char *data) { /* Recursive! * If element is a struct, call recursive. @@ -1141,6 +1165,7 @@ void DNA_struct_switch_endian(SDNA *oldsdna, int oldSDNAnr, char *data) const short *spo, *spc; char *cur; const char *type, *name; + unsigned int oldsdna_index_last = UINT_MAX; if (oldSDNAnr == -1) return; firststructtypenr = *(oldsdna->structs[0]); @@ -1165,7 +1190,7 @@ void DNA_struct_switch_endian(SDNA *oldsdna, int oldSDNAnr, char *data) /* where does the old data start (is there one?) */ char *cpo = find_elem(oldsdna, type, name, spo, data, NULL); if (cpo) { - oldSDNAnr = DNA_struct_find_nr(oldsdna, type); + oldSDNAnr = DNA_struct_find_nr_ex(oldsdna, type, &oldsdna_index_last); mul = DNA_elem_array_size(name); elena = elen / mul; @@ -1223,7 +1248,9 @@ void DNA_struct_switch_endian(SDNA *oldsdna, int oldSDNAnr, char *data) * \param data Array of struct data * \return An allocated reconstructed struct */ -void *DNA_struct_reconstruct(SDNA *newsdna, SDNA *oldsdna, char *compflags, int oldSDNAnr, int blocks, void *data) +void *DNA_struct_reconstruct( + const SDNA *newsdna, const SDNA *oldsdna, + char *compflags, int oldSDNAnr, int blocks, void *data) { int a, curSDNAnr, curlen = 0, oldlen; const short *spo, *spc; @@ -1263,7 +1290,6 @@ void *DNA_struct_reconstruct(SDNA *newsdna, SDNA *oldsdna, char *compflags, int */ int DNA_elem_offset(SDNA *sdna, const char *stype, const char *vartype, const char *name) { - const int SDNAnr = DNA_struct_find_nr(sdna, stype); const short * const spo = sdna->structs[SDNAnr]; const char * const cp = find_elem(sdna, vartype, name, spo, NULL, NULL); @@ -1273,7 +1299,6 @@ int DNA_elem_offset(SDNA *sdna, const char *stype, const char *vartype, const ch bool DNA_struct_elem_find(SDNA *sdna, const char *stype, const char *vartype, const char *name) { - const int SDNAnr = DNA_struct_find_nr(sdna, stype); if (SDNAnr != -1) { |