Potential fix for bug #5359:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Sat, 6 Jan 2007 20:16:06 +0000 (20:16 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Sat, 6 Jan 2007 20:16:06 +0000 (20:16 +0000)
Crash leaving editmode related to vertex groups. I couldn't reproduce this,
but suspect somehow multiple deformvert layers were created. Added some
extra checks to avoid that now.

source/blender/blenkernel/BKE_customdata.h
source/blender/blenkernel/intern/customdata.c
source/blender/blenloader/intern/readfile.c

index 03224eaadaf9e8881b78d834db4ab93c0bcfab1d..542837dc3fbc45eaf5b5c7ea345da6237f3410b2 100644 (file)
@@ -221,4 +221,8 @@ const char *CustomData_layertype_name(int type);
 /* make sure the name of layer at index is unique */
 void CustomData_set_layer_unique_name(struct CustomData *data, int index);
 
+/* for file reading compatibility, returns false if the layer was freed,
+   only after this test passes, layer->data should be assigned */
+int CustomData_verify_versions(struct CustomData *data, int index);
+
 #endif
index e93a58bc9510e496b2c5b0f79acd60c40c8335de..b6bcce96ad4ca30f797072b3be2c5d4dc6bb5032 100644 (file)
@@ -567,6 +567,9 @@ static CustomDataLayer *customData_add_layer__internal(CustomData *data,
        int size = typeInfo->size * totelem, flag = 0, index = data->totlayer;
        void *newlayerdata;
 
+       if (!typeInfo->defaultname && CustomData_has_layer(data, type))
+               return &data->layers[CustomData_get_layer_index(data, type)];
+
        if((alloctype == CD_ASSIGN) || (alloctype == CD_REFERENCE)) {
                newlayerdata = layerdata;
        }
@@ -644,7 +647,6 @@ void *CustomData_add_layer_named(CustomData *data, int type, int alloctype,
                            void *layerdata, int totelem, char *name)
 {
        CustomDataLayer *layer;
-       const LayerTypeInfo *typeInfo= layerType_getInfo(type);
        
        layer = customData_add_layer__internal(data, type, alloctype, layerdata,
                                               totelem, name);
@@ -1289,3 +1291,29 @@ void CustomData_set_layer_unique_name(CustomData *data, int index)
        }       
 }
 
+int CustomData_verify_versions(struct CustomData *data, int index)
+{
+       const LayerTypeInfo *typeInfo;
+       CustomDataLayer *layer = &data->layers[index];
+       int i, keeplayer = 1;
+
+       if (layer->type >= CD_NUMTYPES) {
+               keeplayer = 0; /* unknown layer type from future version */
+       }
+       else {
+               typeInfo = layerType_getInfo(layer->type);
+
+               if (!typeInfo->defaultname && (index > 0) &&
+                       data->layers[index-1].type == layer->type)
+                       keeplayer = 0; /* multiple layers of which we only support one */
+       }
+
+       if (!keeplayer) {
+           for (i=index+1; i < data->totlayer; ++i)
+           data->layers[i-1] = data->layers[i];
+               data->totlayer--;
+       }
+
+       return keeplayer;
+}
+
index 8343f8db9adb94b878d9ccca44cf1cb0b9a8230c..e2f11d5011e4c6516267939113209c01002ce4ba 100644 (file)
@@ -2487,15 +2487,10 @@ static void direct_link_customdata(FileData *fd, CustomData *data, int count)
        while (i < data->totlayer) {
                CustomDataLayer *layer = &data->layers[i];
 
-               if (layer->type < CD_NUMTYPES) {
+               if (CustomData_verify_versions(data, i)) {
                        layer->data = newdataadr(fd, layer->data);
                        i++;
                }
-               else {
-                       /* delete layers with unknown type */
-                       layer->data = NULL;
-                       CustomData_free_layers(data, layer->type, 0);
-               }
        }
 }