New customdata layer callback: validate
authorSergey Sharybin <sergey.vfx@gmail.com>
Sun, 2 Jan 2011 17:08:25 +0000 (17:08 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Sun, 2 Jan 2011 17:08:25 +0000 (17:08 +0000)
Used to validate displacement allocation size after face copying
to match face vertex and displacement corners count.

source/blender/blenkernel/BKE_customdata.h
source/blender/blenkernel/intern/customdata.c
source/blender/editors/mesh/editmesh.c
source/blender/editors/mesh/editmesh_tools.c

index fb079d4..e911832 100644 (file)
@@ -144,6 +144,7 @@ void CustomData_em_copy_data(const struct CustomData *source,
 void CustomData_bmesh_copy_data(const struct CustomData *source, 
                                                        struct CustomData *dest,void *src_block, 
                                                        void **dest_block);
+void CustomData_em_validate_data(struct CustomData *data, void *block, int sub_elements);
 
 /* frees data in a CustomData object
  * return 1 on success, 0 on failure
index ee34775..2d4e65f 100644 (file)
@@ -104,6 +104,11 @@ typedef struct LayerTypeInfo {
 
        /* a function to determine file size */
        size_t (*filesize)(CDataFile *cdf, void *data, int count);
+
+       /* a function to validate layer contents depending on
+        * sub-elements count
+        */
+       void (*validate)(void *source, int sub_elements);
 } LayerTypeInfo;
 
 static void layerCopy_mdeformvert(const void *source, void *dest,
@@ -517,6 +522,20 @@ static void layerCopy_mdisps(const void *source, void *dest, int count)
        }
 }
 
+static void layerValidate_mdisps(void *data, int sub_elements)
+{
+       MDisps *disps = data;
+       if(disps->disps) {
+               int corners = multires_mdisp_corners(disps);
+
+               if(corners != sub_elements) {
+                       MEM_freeN(disps->disps);
+                       disps->totdisp = disps->totdisp / corners * sub_elements;
+                       disps->disps = MEM_callocN(3*disps->totdisp*sizeof(float), "layerValidate_mdisps");
+               }
+       }
+}
+
 static void layerFree_mdisps(void *data, int count, int UNUSED(size))
 {
        int i;
@@ -768,7 +787,8 @@ const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
        {sizeof(MLoopCol), "MLoopCol", 1, "Col", NULL, NULL, layerInterp_mloopcol, NULL, layerDefault_mloopcol},
        {sizeof(float)*3*4, "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
        {sizeof(MDisps), "MDisps", 1, NULL, layerCopy_mdisps,
-        layerFree_mdisps, layerInterp_mdisps, layerSwap_mdisps, NULL, layerRead_mdisps, layerWrite_mdisps, layerFilesize_mdisps},
+        layerFree_mdisps, layerInterp_mdisps, layerSwap_mdisps, NULL, layerRead_mdisps, layerWrite_mdisps,
+        layerFilesize_mdisps, layerValidate_mdisps},
        {sizeof(MCol)*4, "MCol", 4, "WeightCol", NULL, NULL, layerInterp_mcol,
         layerSwap_mcol, layerDefault_mcol},
         {sizeof(MCol)*4, "MCol", 4, "IDCol", NULL, NULL, layerInterp_mcol,
@@ -1691,6 +1711,18 @@ void CustomData_em_copy_data(const CustomData *source, CustomData *dest,
        }
 }
 
+void CustomData_em_validate_data(CustomData *data, void *block, int sub_elements)
+{
+       int i;
+       for(i = 0; i < data->totlayer; i++) {
+               const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[i].type);
+               char *leayer_data = (char*)block + data->layers[i].offset;
+
+               if(typeInfo->validate)
+                       typeInfo->validate(leayer_data, sub_elements);
+       }
+}
+
 void *CustomData_em_get(const CustomData *data, void *block, int type)
 {
        int layer_index;
index 2a66e95..5f7ccd1 100644 (file)
@@ -380,6 +380,7 @@ EditFace *addfacelist(EditMesh *em, EditVert *v1, EditVert *v2, EditVert *v3, Ed
                efa->mat_nr= example->mat_nr;
                efa->flag= example->flag;
                CustomData_em_copy_data(&em->fdata, &em->fdata, example->data, &efa->data);
+               CustomData_em_validate_data(&em->fdata, efa->data, efa->v4 ? 4 : 3);
        }
        else {
                efa->mat_nr= em->mat_nr;
index 7c3262f..d00b5ac 100644 (file)
@@ -1519,6 +1519,7 @@ static void facecopy(EditMesh *em, EditFace *source, EditFace *target)
        if (target->v4)
                interp_weights_face_v3( w[3],v1, v2, v3, v4, target->v4->co);
 
+       CustomData_em_validate_data(&em->fdata, target->data, target->v4 ? 4 : 3);
        CustomData_em_interp(&em->fdata, &source->data, NULL, (float*)w, 1, target->data);
 }