|
|
|
|
@@ -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
|
|
|
|
|
|
|
|
|
|
@@ -279,38 +280,17 @@ 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 +303,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 +319,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,6 +328,12 @@ 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 ********************** */
|
|
|
|
|
@@ -358,16 +344,21 @@ int DNA_struct_find_nr(SDNA *sdna, const char *str)
|
|
|
|
|
static void init_structDNA(SDNA *sdna, bool do_endian_swap)
|
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
strcpy(str, "SDNA");
|
|
|
|
|
if (*data == *verg) {
|
|
|
|
|
|
|
|
|
|
if (*data != *verg) {
|
|
|
|
|
printf("SDNA error in SDNA file\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
intptr_t nr;
|
|
|
|
|
char *cp;
|
|
|
|
|
|
|
|
|
|
data++;
|
|
|
|
|
|
|
|
|
|
/* load names array */
|
|
|
|
|
@@ -515,11 +506,45 @@ static void init_structDNA(SDNA *sdna, bool do_endian_swap)
|
|
|
|
|
|
|
|
|
|
nr++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
/* second part of gravity problem, setting "gravity" type to void */
|
|
|
|
|
if (gravity_fix > -1) {
|
|
|
|
|
for (intptr_t 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 (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));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#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)) {
|
|
|
|
|
printf("ListBase struct error! Not found.\n");
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* finally pointerlen: use struct ListBase to test it, never change the size of it! */
|
|
|
|
|
sp = findstruct_name(sdna, "ListBase");
|
|
|
|
|
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)) {
|
|
|
|
|
@@ -527,25 +552,6 @@ static void init_structDNA(SDNA *sdna, bool do_endian_swap)
|
|
|
|
|
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++) {
|
|
|
|
|
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++) {
|
|
|
|
|
sp = sdna->structs[nr];
|
|
|
|
|
BLI_ghash_insert(sdna->structs_map, sdna->types[sp[0]], SET_INT_IN_POINTER(nr));
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -557,8 +563,6 @@ SDNA *DNA_sdna_from_data(
|
|
|
|
|
bool do_endian_swap, bool data_alloc)
|
|
|
|
|
{
|
|
|
|
|
SDNA *sdna = MEM_mallocN(sizeof(*sdna), "sdna");
|
|
|
|
|
|
|
|
|
|
sdna->lastfind = 0;
|
|
|
|
|
|
|
|
|
|
sdna->datalen = datalen;
|
|
|
|
|
if (data_alloc) {
|
|
|
|
|
@@ -623,7 +627,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 +644,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 +1046,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 +1065,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 +1103,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 +1145,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 +1154,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 +1179,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 +1237,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 +1279,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 +1288,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) {
|
|
|
|
|
|