Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_btex.h64
-rw-r--r--source/blender/blenkernel/BKE_customdata.h10
-rw-r--r--source/blender/blenkernel/BKE_customdata_file.h59
-rw-r--r--source/blender/blenkernel/BKE_utildefines.h10
-rw-r--r--source/blender/blenkernel/intern/btex.c482
-rw-r--r--source/blender/blenkernel/intern/customdata.c125
-rw-r--r--source/blender/blenkernel/intern/customdata_file.c446
-rw-r--r--source/blender/blenkernel/intern/multires.c9
8 files changed, 594 insertions, 611 deletions
diff --git a/source/blender/blenkernel/BKE_btex.h b/source/blender/blenkernel/BKE_btex.h
deleted file mode 100644
index cb73fd160d7..00000000000
--- a/source/blender/blenkernel/BKE_btex.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * $Id$
- *
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-#ifndef BKE_BTEX_H
-#define BKE_BTEX_H
-
-#define BTEX_TYPE_IMAGE 0
-#define BTEX_TYPE_MESH 1
-
-#define BTEX_LAYER_NAME_MAX 64
-
-typedef struct BTex BTex;
-typedef struct BTexLayer BTexLayer;
-
-/* Create/Free */
-
-BTex *btex_create(int type);
-void btex_free(BTex *btex);
-
-/* File read/write/remove */
-
-int btex_read_open(BTex *btex, char *filename);
-int btex_read_layer(BTex *btex, BTexLayer *blay);
-int btex_read_data(BTex *btex, int size, void *data);
-void btex_read_close(BTex *btex);
-
-int btex_write_open(BTex *btex, char *filename);
-int btex_write_layer(BTex *btex, BTexLayer *blay);
-int btex_write_data(BTex *btex, int size, void *data);
-void btex_write_close(BTex *btex);
-
-void btex_remove(char *filename);
-
-/* Layers */
-
-BTexLayer *btex_layer_find(BTex *btex, int type, char *name);
-BTexLayer *btex_layer_add(BTex *btex, int type, char *name);
-void btex_layer_remove(BTex *btex, BTexLayer *blay);
-
-/* Mesh */
-
-void btex_mesh_set_grids(BTex *btex, int totgrid, int gridsize, int datasize);
-
-#endif /* BKE_BTEX_H */
-
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h
index 5ce4b396f0e..5f13e702343 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -32,6 +32,7 @@
#ifndef BKE_CUSTOMDATA_H
#define BKE_CUSTOMDATA_H
+struct ID;
struct CustomData;
struct CustomDataLayer;
typedef unsigned int CustomDataMask;
@@ -282,16 +283,15 @@ void CustomData_bmesh_init_pool(struct CustomData *data, int allocsize);
/* External file storage */
void CustomData_external_add(struct CustomData *data,
- int type, const char *name, int totelem);
+ struct ID *id, int type, int totelem, const char *filename);
void CustomData_external_remove(struct CustomData *data,
- int type, int totelem);
-void CustomData_external_remove_object(struct CustomData *data);
+ struct ID *id, int type, int totelem);
int CustomData_external_test(struct CustomData *data, int type);
void CustomData_external_write(struct CustomData *data,
- CustomDataMask mask, int totelem, int free);
+ struct ID *id, CustomDataMask mask, int totelem, int free);
void CustomData_external_read(struct CustomData *data,
- CustomDataMask mask, int totelem);
+ struct ID *id, CustomDataMask mask, int totelem);
#endif
diff --git a/source/blender/blenkernel/BKE_customdata_file.h b/source/blender/blenkernel/BKE_customdata_file.h
new file mode 100644
index 00000000000..5cbff193cd3
--- /dev/null
+++ b/source/blender/blenkernel/BKE_customdata_file.h
@@ -0,0 +1,59 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef BKE_CUSTOMDATA_FILE_H
+#define BKE_CUSTOMDATA_FILE_H
+
+#define CDF_TYPE_IMAGE 0
+#define CDF_TYPE_MESH 1
+
+#define CDF_LAYER_NAME_MAX 64
+
+typedef struct CDataFile CDataFile;
+typedef struct CDataFileLayer CDataFileLayer;
+
+/* Create/Free */
+
+CDataFile *cdf_create(int type);
+void cdf_free(CDataFile *cdf);
+
+/* File read/write/remove */
+
+int cdf_read_open(CDataFile *cdf, char *filename);
+int cdf_read_layer(CDataFile *cdf, CDataFileLayer *blay);
+int cdf_read_data(CDataFile *cdf, int size, void *data);
+void cdf_read_close(CDataFile *cdf);
+
+int cdf_write_open(CDataFile *cdf, char *filename);
+int cdf_write_layer(CDataFile *cdf, CDataFileLayer *blay);
+int cdf_write_data(CDataFile *cdf, int size, void *data);
+void cdf_write_close(CDataFile *cdf);
+
+void cdf_remove(char *filename);
+
+/* Layers */
+
+CDataFileLayer *cdf_layer_find(CDataFile *cdf, int type, char *name);
+CDataFileLayer *cdf_layer_add(CDataFile *cdf, int type, char *name, size_t datasize);
+
+#endif /* BKE_CUSTOMDATA_FILE_H */
+
diff --git a/source/blender/blenkernel/BKE_utildefines.h b/source/blender/blenkernel/BKE_utildefines.h
index c0ed8430177..c052af775f2 100644
--- a/source/blender/blenkernel/BKE_utildefines.h
+++ b/source/blender/blenkernel/BKE_utildefines.h
@@ -168,7 +168,15 @@
#define ENDB MAKE_ID('E','N','D','B')
-/* This one rotates the bytes in an int */
+/* This one rotates the bytes in an int64, int (32) and short (16) */
+#define SWITCH_INT64(a) { \
+ char s_i, *p_i; \
+ p_i= (char *)&(a); \
+ s_i=p_i[0]; p_i[0]=p_i[7]; p_i[7]=s_i; \
+ s_i=p_i[1]; p_i[1]=p_i[6]; p_i[6]=s_i; \
+ s_i=p_i[2]; p_i[2]=p_i[5]; p_i[5]=s_i; \
+ s_i=p_i[3]; p_i[3]=p_i[4]; p_i[4]=s_i; }
+
#define SWITCH_INT(a) { \
char s_i, *p_i; \
p_i= (char *)&(a); \
diff --git a/source/blender/blenkernel/intern/btex.c b/source/blender/blenkernel/intern/btex.c
deleted file mode 100644
index 363e515f6e2..00000000000
--- a/source/blender/blenkernel/intern/btex.c
+++ /dev/null
@@ -1,482 +0,0 @@
-/*
- * $Id$
- *
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "MEM_guardedalloc.h"
-
-#include "BLI_fileops.h"
-#include "BLI_string.h"
-
-#include "BKE_btex.h"
-#include "BKE_global.h"
-#include "BKE_utildefines.h"
-
-/************************* File Format Definitions ***************************/
-
-#define BTEX_ENDIAN_LITTLE 0
-#define BTEX_ENDIAN_BIG 1
-
-#define BTEX_DATA_FLOAT 0
-
-typedef struct BTexHeader {
- char ID[4]; /* "BTEX" */
- char endian; /* little, big */
- char version; /* non-compatible versions */
- char subversion; /* compatible sub versions */
- char pad; /* padding */
-
- int structbytes; /* size of this struct in bytes */
- int type; /* image, mesh */
- int totlayer; /* number of layers in the file */
-} BTexHeader;
-
-typedef struct BTexImageHeader {
- int structbytes; /* size of this struct in bytes */
- int width; /* image width */
- int height; /* image height */
- int tile_size; /* tile size (required power of 2) */
-} BTexImageHeader;
-
-typedef struct BTexMeshHeader {
- int structbytes; /* size of this struct in bytes */
- int totgrid; /* number of grids */
- int gridsize; /* width of grids */
-} BTexMeshHeader;
-
-struct BTexLayer {
- int structbytes; /* size of this struct in bytes */
- int datatype; /* only float for now */
- int datasize; /* size of data in layer */
- int type; /* layer type */
- char name[BTEX_LAYER_NAME_MAX]; /* layer name */
-};
-
-/**************************** Other Definitions ******************************/
-
-#define BTEX_VERSION 0
-#define BTEX_SUBVERSION 0
-#define BTEX_TILE_SIZE 64
-
-struct BTex {
- int type;
-
- BTexHeader header;
- union {
- BTexImageHeader image;
- BTexMeshHeader mesh;
- } btype;
-
- BTexLayer *layer;
- int totlayer;
-
- FILE *readf;
- FILE *writef;
- int switchendian;
- size_t dataoffset;
-};
-
-/********************************* Create/Free *******************************/
-
-static int btex_endian(void)
-{
- if(ENDIAN_ORDER == L_ENDIAN)
- return BTEX_ENDIAN_LITTLE;
- else
- return BTEX_ENDIAN_BIG;
-}
-
-/*static int btex_data_type_size(int datatype)
-{
- if(datatype == BTEX_DATA_FLOAT)
- return sizeof(float);
-
- return 0;
-}*/
-
-BTex *btex_create(int type)
-{
- BTex *btex= MEM_callocN(sizeof(BTex), "BTex");
-
- btex->type= type;
-
- return btex;
-}
-
-void btex_free(BTex *btex)
-{
- btex_read_close(btex);
- btex_write_close(btex);
-
- if(btex->layer)
- MEM_freeN(btex->layer);
-
- MEM_freeN(btex);
-}
-
-/********************************* Read/Write ********************************/
-
-static int btex_read_header(BTex *btex)
-{
- BTexHeader *header;
- BTexImageHeader *image;
- BTexMeshHeader *mesh;
- BTexLayer *layer;
- FILE *f= btex->readf;
- size_t offset = 0;
- int a;
-
- header= &btex->header;
-
- if(!fread(header, sizeof(BTexHeader), 1, btex->readf))
- return 0;
-
- if(memcmp(header->ID, "BTEX", sizeof(header->ID)) != 0)
- return 0;
- if(header->version > BTEX_VERSION)
- return 0;
-
- btex->switchendian= header->endian != btex_endian();
- header->endian= btex_endian();
-
- if(btex->switchendian) {
- SWITCH_INT(header->type);
- SWITCH_INT(header->totlayer);
- SWITCH_INT(header->structbytes);
- }
-
- if(!ELEM(header->type, BTEX_TYPE_IMAGE, BTEX_TYPE_MESH))
- return 0;
-
- offset += header->structbytes;
- header->structbytes= sizeof(BTexHeader);
-
- if(fseek(f, offset, SEEK_SET) != 0)
- return 0;
-
- if(header->type == BTEX_TYPE_IMAGE) {
- image= &btex->btype.image;
- if(!fread(image, sizeof(BTexImageHeader), 1, f))
- return 0;
-
- if(btex->switchendian) {
- SWITCH_INT(image->width);
- SWITCH_INT(image->height);
- SWITCH_INT(image->tile_size);
- SWITCH_INT(image->structbytes);
- }
-
- offset += image->structbytes;
- image->structbytes= sizeof(BTexImageHeader);
- }
- else if(header->type == BTEX_TYPE_MESH) {
- mesh= &btex->btype.mesh;
- if(!fread(mesh, sizeof(BTexMeshHeader), 1, f))
- return 0;
-
- if(btex->switchendian) {
- SWITCH_INT(mesh->totgrid);
- SWITCH_INT(mesh->gridsize);
- SWITCH_INT(mesh->structbytes);
- }
-
- offset += mesh->structbytes;
- mesh->structbytes= sizeof(BTexMeshHeader);
- }
-
- if(fseek(f, offset, SEEK_SET) != 0)
- return 0;
-
- btex->layer= MEM_callocN(sizeof(BTexLayer)*header->totlayer, "BTexLayer");
- btex->totlayer= header->totlayer;
-
- for(a=0; a<header->totlayer; a++) {
- layer= &btex->layer[a];
-
- if(!fread(layer, sizeof(BTexLayer), 1, f))
- return 0;
-
- if(btex->switchendian) {
- SWITCH_INT(layer->type);
- SWITCH_INT(layer->datatype);
- SWITCH_INT(layer->datasize);
- SWITCH_INT(layer->structbytes);
- }
-
- if(layer->datatype != BTEX_DATA_FLOAT)
- return 0;
-
- offset += layer->structbytes;
- layer->structbytes= sizeof(BTexLayer);
-
- if(fseek(f, offset, SEEK_SET) != 0)
- return 0;
- }
-
- btex->dataoffset= offset;
-
- return 1;
-}
-
-static int btex_write_header(BTex *btex)
-{
- BTexHeader *header;
- BTexImageHeader *image;
- BTexMeshHeader *mesh;
- BTexLayer *layer;
- FILE *f= btex->writef;
- int a;
-
- header= &btex->header;
-
- if(!fwrite(header, sizeof(BTexHeader), 1, f))
- return 0;
-
- if(header->type == BTEX_TYPE_IMAGE) {
- image= &btex->btype.image;
- if(!fwrite(image, sizeof(BTexImageHeader), 1, f))
- return 0;
- }
- else if(header->type == BTEX_TYPE_MESH) {
- mesh= &btex->btype.mesh;
- if(!fwrite(mesh, sizeof(BTexMeshHeader), 1, f))
- return 0;
- }
-
- for(a=0; a<header->totlayer; a++) {
- layer= &btex->layer[a];
-
- if(!fwrite(layer, sizeof(BTexLayer), 1, f))
- return 0;
- }
-
- return 1;
-}
-
-int btex_read_open(BTex *btex, char *filename)
-{
- FILE *f;
-
- f= fopen(filename, "rb");
- if(!f)
- return 0;
-
- btex->readf= f;
-
- if(!btex_read_header(btex)) {
- btex_read_close(btex);
- return 0;
- }
-
- if(btex->header.type != btex->type) {
- btex_read_close(btex);
- return 0;
- }
-
- return 1;
-}
-
-int btex_read_layer(BTex *btex, BTexLayer *blay)
-{
- size_t offset;
- int a;
-
- /* seek to right location in file */
- offset= btex->dataoffset;
- for(a=0; a<btex->totlayer; a++) {
- if(&btex->layer[a] == blay)
- break;
- else
- offset += btex->layer[a].datasize;
- }
-
- return (fseek(btex->readf, offset, SEEK_SET) == 0);
-}
-
-int btex_read_data(BTex *btex, int size, void *data)
-{
- float *fdata;
- int a;
-
- /* read data */
- if(!fread(data, size, 1, btex->readf))
- return 0;
-
- /* switch endian if necessary */
- if(btex->switchendian) {
- fdata= data;
-
- for(a=0; a<size/sizeof(float); a++)
- SWITCH_INT(fdata[a])
- }
-
- return 1;
-}
-
-void btex_read_close(BTex *btex)
-{
- if(btex->readf) {
- fclose(btex->readf);
- btex->readf= NULL;
- }
-}
-
-int btex_write_open(BTex *btex, char *filename)
-{
- BTexHeader *header;
- BTexImageHeader *image;
- BTexMeshHeader *mesh;
- FILE *f;
-
- f= fopen(filename, "wb");
- if(!f)
- return 0;
-
- btex->writef= f;
-
- /* fill header */
- header= &btex->header;
- strcpy(header->ID, "BTEX");
- header->endian= btex_endian();
- header->version= BTEX_VERSION;
- header->subversion= BTEX_SUBVERSION;
-
- header->structbytes= sizeof(BTexHeader);
- header->type= btex->type;
- header->totlayer= btex->totlayer;
-
- if(btex->type == BTEX_TYPE_IMAGE) {
- /* fill image header */
- image= &btex->btype.image;
- image->structbytes= sizeof(BTexImageHeader);
- image->tile_size= BTEX_TILE_SIZE;
- }
- else if(btex->type == BTEX_TYPE_MESH) {
- /* fill mesh header */
- mesh= &btex->btype.mesh;
- mesh->structbytes= sizeof(BTexMeshHeader);
- }
-
- btex_write_header(btex);
-
- return 1;
-}
-
-int btex_write_layer(BTex *btex, BTexLayer *blay)
-{
- return 1;
-}
-
-int btex_write_data(BTex *btex, int size, void *data)
-{
- /* write data */
- if(!fwrite(data, size, 1, btex->writef))
- return 0;
-
- return 1;
-}
-
-void btex_write_close(BTex *btex)
-{
- if(btex->writef) {
- fclose(btex->writef);
- btex->writef= NULL;
- }
-}
-
-void btex_remove(char *filename)
-{
- BLI_delete(filename, 0, 0);
-}
-
-/********************************** Layers ***********************************/
-
-BTexLayer *btex_layer_find(BTex *btex, int type, char *name)
-{
- BTexLayer *layer;
- int a;
-
- for(a=0; a<btex->totlayer; a++) {
- layer= &btex->layer[a];
-
- if(layer->type == type && strcmp(layer->name, name) == 0)
- return layer;
- }
-
- return NULL;
-}
-
-BTexLayer *btex_layer_add(BTex *btex, int type, char *name)
-{
- BTexLayer *newlayer, *layer;
-
- /* expand array */
- newlayer= MEM_callocN(sizeof(BTexLayer)*(btex->totlayer+1), "BTexLayer");
- memcpy(newlayer, btex->layer, sizeof(BTexLayer)*btex->totlayer);
- btex->layer= newlayer;
-
- btex->totlayer++;
-
- /* fill in new layer */
- layer= &btex->layer[btex->totlayer-1];
- layer->structbytes= sizeof(BTexLayer);
- layer->datatype= BTEX_DATA_FLOAT;
- layer->type= type;
- BLI_strncpy(layer->name, name, BTEX_LAYER_NAME_MAX);
-
- return layer;
-}
-
-void btex_layer_remove(BTex *btex, BTexLayer *layer)
-{
- BTexLayer *newlayer;
- int index= layer - btex->layer;
-
- /* expand array */
- newlayer= MEM_callocN(sizeof(BTexLayer)*(btex->totlayer-1), "BTexLayer");
- if(index > 0)
- memcpy(newlayer, btex->layer, sizeof(BTexLayer)*index);
- if(index+1 < btex->totlayer)
- memcpy(newlayer+index, btex->layer+index+1, sizeof(BTexLayer)*(btex->totlayer-(index+1)));
- btex->layer= newlayer;
-
- btex->totlayer--;
-}
-
-/********************************* Mesh **************************************/
-
-void btex_mesh_set_grids(BTex *btex, int totgrid, int gridsize, int datasize)
-{
- BTexLayer *layer;
- int a;
-
- btex->btype.mesh.totgrid= totgrid;
- btex->btype.mesh.gridsize= gridsize;
-
- for(a=0; a<btex->totlayer; a++) {
- layer= &btex->layer[a];
- layer->datasize= datasize;
- }
-}
-
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index f9997708a50..d9e85d5d412 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -48,8 +48,8 @@
#include "BLI_mempool.h"
#include "BLI_string.h"
-#include "BKE_btex.h"
#include "BKE_customdata.h"
+#include "BKE_customdata_file.h"
#include "BKE_global.h"
#include "BKE_utildefines.h"
@@ -95,11 +95,14 @@ typedef struct LayerTypeInfo {
default is assumed to be all zeros */
void (*set_default)(void *data, int count);
- /* a function to read data from a btex file */
- int (*read)(BTex *btex, void *data, int count);
+ /* a function to read data from a cdf file */
+ int (*read)(CDataFile *cdf, void *data, int count);
- /* a function to write data to a btex file */
- int (*write)(BTex *btex, void *data, int count);
+ /* a function to write data to a cdf file */
+ int (*write)(CDataFile *cdf, void *data, int count);
+
+ /* a function to determine file size */
+ size_t (*filesize)(CDataFile *cdf, void *data, int count);
} LayerTypeInfo;
static void layerCopy_mdeformvert(const void *source, void *dest,
@@ -550,7 +553,7 @@ static void layerFree_mdisps(void *data, int count, int size)
}
}
-static int layerRead_mdisps(BTex *btex, void *data, int count)
+static int layerRead_mdisps(CDataFile *cdf, void *data, int count)
{
MDisps *d = data;
int i;
@@ -559,7 +562,7 @@ static int layerRead_mdisps(BTex *btex, void *data, int count)
if(!d[i].disps)
d[i].disps = MEM_callocN(sizeof(float)*3*d[i].totdisp, "mdisps read");
- if(!btex_read_data(btex, d[i].totdisp*3*sizeof(float), d[i].disps)) {
+ if(!cdf_read_data(cdf, d[i].totdisp*3*sizeof(float), d[i].disps)) {
printf("failed to read %d/%d %d\n", i, count, d[i].totdisp);
return 0;
}
@@ -568,13 +571,13 @@ static int layerRead_mdisps(BTex *btex, void *data, int count)
return 1;
}
-static int layerWrite_mdisps(BTex *btex, void *data, int count)
+static int layerWrite_mdisps(CDataFile *cdf, void *data, int count)
{
MDisps *d = data;
int i;
for(i = 0; i < count; ++i) {
- if(!btex_write_data(btex, d[i].totdisp*3*sizeof(float), d[i].disps)) {
+ if(!cdf_write_data(cdf, d[i].totdisp*3*sizeof(float), d[i].disps)) {
printf("failed to write %d/%d %d\n", i, count, d[i].totdisp);
return 0;
}
@@ -583,6 +586,18 @@ static int layerWrite_mdisps(BTex *btex, void *data, int count)
return 1;
}
+static size_t layerFilesize_mdisps(CDataFile *cdf, void *data, int count)
+{
+ MDisps *d = data;
+ size_t size = 0;
+ int i;
+
+ for(i = 0; i < count; ++i)
+ size += d[i].totdisp*3*sizeof(float);
+
+ return size;
+}
+
/* --------- */
static void layerDefault_mloopcol(void *data, int count)
@@ -776,7 +791,7 @@ 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},
+ layerFree_mdisps, layerInterp_mdisps, layerSwap_mdisps, NULL, layerRead_mdisps, layerWrite_mdisps, layerFilesize_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,
@@ -838,8 +853,6 @@ void CustomData_merge(const struct CustomData *source, struct CustomData *dest,
CustomDataLayer *layer, *newlayer;
int i, type, number = 0, lasttype = -1, lastactive = 0, lastrender = 0, lastclone = 0, lastmask = 0;
- CustomData_external_read(dest, mask, totelem);
-
for(i = 0; i < source->totlayer; ++i) {
layer = &source->layers[i];
typeInfo = layerType_getInfo(layer->type);
@@ -2297,18 +2310,20 @@ int CustomData_verify_versions(struct CustomData *data, int index)
/****************************** External Files *******************************/
-static void customdata_external_filename(char filename[FILE_MAX], CustomDataExternal *external)
+static void customdata_external_filename(char filename[FILE_MAX], ID *id, CustomDataExternal *external)
{
+ char *path = (id->lib)? id->lib->filename: G.sce;
+
BLI_strncpy(filename, external->filename, FILE_MAX);
- BLI_convertstringcode(filename, G.sce);
+ BLI_convertstringcode(filename, path);
}
-void CustomData_external_read(CustomData *data, CustomDataMask mask, int totelem)
+void CustomData_external_read(CustomData *data, ID *id, CustomDataMask mask, int totelem)
{
CustomDataExternal *external= data->external;
CustomDataLayer *layer;
- BTex *btex;
- BTexLayer *blay;
+ CDataFile *cdf;
+ CDataFileLayer *blay;
char filename[FILE_MAX];
const LayerTypeInfo *typeInfo;
int i, update = 0;
@@ -2329,10 +2344,10 @@ void CustomData_external_read(CustomData *data, CustomDataMask mask, int totelem
if(!update)
return;
- customdata_external_filename(filename, external);
+ customdata_external_filename(filename, id, external);
- btex= btex_create(BTEX_TYPE_MESH);
- if(!btex_read_open(btex, filename))
+ cdf= cdf_create(CDF_TYPE_MESH);
+ if(!cdf_read_open(cdf, filename))
return;
for(i=0; i<data->totlayer; i++) {
@@ -2342,11 +2357,11 @@ void CustomData_external_read(CustomData *data, CustomDataMask mask, int totelem
if(!(mask & (1<<layer->type)));
else if(layer->flag & CD_FLAG_IN_MEMORY);
else if((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->read) {
- blay= btex_layer_find(btex, layer->type, layer->name);
+ blay= cdf_layer_find(cdf, layer->type, layer->name);
if(blay) {
- if(btex_read_layer(btex, blay)) {
- if(typeInfo->read(btex, layer->data, totelem));
+ if(cdf_read_layer(cdf, blay)) {
+ if(typeInfo->read(cdf, layer->data, totelem));
else break;
layer->flag |= CD_FLAG_IN_MEMORY;
}
@@ -2356,16 +2371,16 @@ void CustomData_external_read(CustomData *data, CustomDataMask mask, int totelem
}
}
- btex_read_close(btex);
- btex_free(btex);
+ cdf_read_close(cdf);
+ cdf_free(cdf);
}
-void CustomData_external_write(CustomData *data, CustomDataMask mask, int totelem, int free)
+void CustomData_external_write(CustomData *data, ID *id, CustomDataMask mask, int totelem, int free)
{
CustomDataExternal *external= data->external;
CustomDataLayer *layer;
- BTex *btex;
- BTexLayer *blay;
+ CDataFile *cdf;
+ CDataFileLayer *blay;
const LayerTypeInfo *typeInfo;
int i, update = 0;
char filename[FILE_MAX];
@@ -2385,20 +2400,21 @@ void CustomData_external_write(CustomData *data, CustomDataMask mask, int totele
if(!update)
return;
- CustomData_external_read(data, mask, totelem);
+ CustomData_external_read(data, id, mask, totelem);
- btex= btex_create(BTEX_TYPE_MESH);
+ cdf= cdf_create(CDF_TYPE_MESH);
for(i=0; i<data->totlayer; i++) {
layer = &data->layers[i];
typeInfo = layerType_getInfo(layer->type);
- if((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->write)
- btex_layer_add(btex, layer->type, layer->name);
+ if((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->filesize)
+ cdf_layer_add(cdf, layer->type, layer->name,
+ typeInfo->filesize(cdf, layer->data, totelem));
}
- customdata_external_filename(filename, external);
- if(!btex_write_open(btex, filename))
+ customdata_external_filename(filename, id, external);
+ if(!cdf_write_open(cdf, filename))
return;
for(i=0; i<data->totlayer; i++) {
@@ -2406,10 +2422,10 @@ void CustomData_external_write(CustomData *data, CustomDataMask mask, int totele
typeInfo = layerType_getInfo(layer->type);
if((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->write) {
- blay= btex_layer_find(btex, layer->type, layer->name);
+ blay= cdf_layer_find(cdf, layer->type, layer->name);
- if(btex_write_layer(btex, blay)) {
- if(typeInfo->write(btex, layer->data, totelem));
+ if(cdf_write_layer(cdf, blay)) {
+ if(typeInfo->write(cdf, layer->data, totelem));
else break;
}
else
@@ -2418,7 +2434,7 @@ void CustomData_external_write(CustomData *data, CustomDataMask mask, int totele
}
if(i != data->totlayer) {
- btex_free(btex);
+ cdf_free(cdf);
return;
}
@@ -2435,11 +2451,11 @@ void CustomData_external_write(CustomData *data, CustomDataMask mask, int totele
}
}
- btex_write_close(btex);
- btex_free(btex);
+ cdf_write_close(cdf);
+ cdf_free(cdf);
}
-void CustomData_external_add(CustomData *data, int type, const char *name, int totelem)
+void CustomData_external_add(CustomData *data, ID *id, int type, int totelem, const char *filename)
{
CustomDataExternal *external= data->external;
CustomDataLayer *layer;
@@ -2454,23 +2470,20 @@ void CustomData_external_add(CustomData *data, int type, const char *name, int t
return;
if(!external) {
- char hex[MAX_ID_NAME*2];
-
external= MEM_callocN(sizeof(CustomDataExternal), "CustomDataExternal");
- BLI_strhex(hex, sizeof(hex), name);
- BLI_snprintf(external->filename, sizeof(external->filename), "//%s_mesh.btex", hex);
+ BLI_strncpy(external->filename, filename, sizeof(external->filename));
data->external= external;
}
layer->flag |= CD_FLAG_EXTERNAL|CD_FLAG_IN_MEMORY;
}
-void CustomData_external_remove(CustomData *data, int type, int totelem)
+void CustomData_external_remove(CustomData *data, ID *id, int type, int totelem)
{
CustomDataExternal *external= data->external;
CustomDataLayer *layer;
- char filename[FILE_MAX];
- int layer_index, i, remove_file;
+ //char filename[FILE_MAX];
+ int layer_index; // i, remove_file;
layer_index = CustomData_get_active_layer_index(data, type);
if(layer_index < 0) return;
@@ -2482,20 +2495,22 @@ void CustomData_external_remove(CustomData *data, int type, int totelem)
if(layer->flag & CD_FLAG_EXTERNAL) {
if(!(layer->flag & CD_FLAG_IN_MEMORY))
- CustomData_external_read(data, (1<<layer->type), totelem);
+ CustomData_external_read(data, id, (1<<layer->type), totelem);
layer->flag &= ~CD_FLAG_EXTERNAL;
+#if 0
remove_file= 1;
for(i=0; i<data->totlayer; i++)
if(data->layers[i].flag & CD_FLAG_EXTERNAL)
remove_file= 0;
if(remove_file) {
- customdata_external_filename(filename, external);
- btex_remove(filename);
+ customdata_external_filename(filename, id, external);
+ cdf_remove(filename);
CustomData_external_free(data);
}
+#endif
}
}
@@ -2511,7 +2526,8 @@ int CustomData_external_test(CustomData *data, int type)
return (layer->flag & CD_FLAG_EXTERNAL);
}
-void CustomData_external_remove_object(CustomData *data)
+#if 0
+void CustomData_external_remove_object(CustomData *data, ID *id)
{
CustomDataExternal *external= data->external;
char filename[FILE_MAX];
@@ -2519,8 +2535,9 @@ void CustomData_external_remove_object(CustomData *data)
if(!external)
return;
- customdata_external_filename(filename, external);
- btex_remove(filename);
+ customdata_external_filename(filename, id, external);
+ cdf_remove(filename);
CustomData_external_free(data);
}
+#endif
diff --git a/source/blender/blenkernel/intern/customdata_file.c b/source/blender/blenkernel/intern/customdata_file.c
new file mode 100644
index 00000000000..b58ada878de
--- /dev/null
+++ b/source/blender/blenkernel/intern/customdata_file.c
@@ -0,0 +1,446 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_fileops.h"
+#include "BLI_string.h"
+
+#include "BKE_customdata_file.h"
+#include "BKE_global.h"
+#include "BKE_utildefines.h"
+
+/************************* File Format Definitions ***************************/
+
+#define CDF_ENDIAN_LITTLE 0
+#define CDF_ENDIAN_BIG 1
+
+#define CDF_DATA_FLOAT 0
+
+typedef struct CDataFileHeader {
+ char ID[4]; /* "BCDF" */
+ char endian; /* little, big */
+ char version; /* non-compatible versions */
+ char subversion; /* compatible sub versions */
+ char pad; /* padding */
+
+ int structbytes; /* size of this struct in bytes */
+ int type; /* image, mesh */
+ int totlayer; /* number of layers in the file */
+} CDataFileHeader;
+
+typedef struct CDataFileImageHeader {
+ int structbytes; /* size of this struct in bytes */
+ int width; /* image width */
+ int height; /* image height */
+ int tile_size; /* tile size (required power of 2) */
+} CDataFileImageHeader;
+
+typedef struct CDataFileMeshHeader {
+ int structbytes; /* size of this struct in bytes */
+} CDataFileMeshHeader;
+
+struct CDataFileLayer {
+ int structbytes; /* size of this struct in bytes */
+ int datatype; /* only float for now */
+ uint64_t datasize; /* size of data in layer */
+ int type; /* layer type */
+ char name[CDF_LAYER_NAME_MAX]; /* layer name */
+};
+
+/**************************** Other Definitions ******************************/
+
+#define CDF_VERSION 0
+#define CDF_SUBVERSION 0
+#define CDF_TILE_SIZE 64
+
+struct CDataFile {
+ int type;
+
+ CDataFileHeader header;
+ union {
+ CDataFileImageHeader image;
+ CDataFileMeshHeader mesh;
+ } btype;
+
+ CDataFileLayer *layer;
+ int totlayer;
+
+ FILE *readf;
+ FILE *writef;
+ int switchendian;
+ size_t dataoffset;
+};
+
+/********************************* Create/Free *******************************/
+
+static int cdf_endian(void)
+{
+ if(ENDIAN_ORDER == L_ENDIAN)
+ return CDF_ENDIAN_LITTLE;
+ else
+ return CDF_ENDIAN_BIG;
+}
+
+/*static int cdf_data_type_size(int datatype)
+{
+ if(datatype == CDF_DATA_FLOAT)
+ return sizeof(float);
+
+ return 0;
+}*/
+
+CDataFile *cdf_create(int type)
+{
+ CDataFile *cdf= MEM_callocN(sizeof(CDataFile), "CDataFile");
+
+ cdf->type= type;
+
+ return cdf;
+}
+
+void cdf_free(CDataFile *cdf)
+{
+ cdf_read_close(cdf);
+ cdf_write_close(cdf);
+
+ if(cdf->layer)
+ MEM_freeN(cdf->layer);
+
+ MEM_freeN(cdf);
+}
+
+/********************************* Read/Write ********************************/
+
+static int cdf_read_header(CDataFile *cdf)
+{
+ CDataFileHeader *header;
+ CDataFileImageHeader *image;
+ CDataFileMeshHeader *mesh;
+ CDataFileLayer *layer;
+ FILE *f= cdf->readf;
+ size_t offset = 0;
+ int a;
+
+ header= &cdf->header;
+
+ if(!fread(header, sizeof(CDataFileHeader), 1, cdf->readf))
+ return 0;
+
+ if(memcmp(header->ID, "BCDF", sizeof(header->ID)) != 0)
+ return 0;
+ if(header->version > CDF_VERSION)
+ return 0;
+
+ cdf->switchendian= header->endian != cdf_endian();
+ header->endian= cdf_endian();
+
+ if(cdf->switchendian) {
+ SWITCH_INT(header->type);
+ SWITCH_INT(header->totlayer);
+ SWITCH_INT(header->structbytes);
+ }
+
+ if(!ELEM(header->type, CDF_TYPE_IMAGE, CDF_TYPE_MESH))
+ return 0;
+
+ offset += header->structbytes;
+ header->structbytes= sizeof(CDataFileHeader);
+
+ if(fseek(f, offset, SEEK_SET) != 0)
+ return 0;
+
+ if(header->type == CDF_TYPE_IMAGE) {
+ image= &cdf->btype.image;
+ if(!fread(image, sizeof(CDataFileImageHeader), 1, f))
+ return 0;
+
+ if(cdf->switchendian) {
+ SWITCH_INT(image->width);
+ SWITCH_INT(image->height);
+ SWITCH_INT(image->tile_size);
+ SWITCH_INT(image->structbytes);
+ }
+
+ offset += image->structbytes;
+ image->structbytes= sizeof(CDataFileImageHeader);
+ }
+ else if(header->type == CDF_TYPE_MESH) {
+ mesh= &cdf->btype.mesh;
+ if(!fread(mesh, sizeof(CDataFileMeshHeader), 1, f))
+ return 0;
+
+ if(cdf->switchendian)
+ SWITCH_INT(mesh->structbytes);
+
+ offset += mesh->structbytes;
+ mesh->structbytes= sizeof(CDataFileMeshHeader);
+ }
+
+ if(fseek(f, offset, SEEK_SET) != 0)
+ return 0;
+
+ cdf->layer= MEM_callocN(sizeof(CDataFileLayer)*header->totlayer, "CDataFileLayer");
+ cdf->totlayer= header->totlayer;
+
+ for(a=0; a<header->totlayer; a++) {
+ layer= &cdf->layer[a];
+
+ if(!fread(layer, sizeof(CDataFileLayer), 1, f))
+ return 0;
+
+ if(cdf->switchendian) {
+ SWITCH_INT(layer->type);
+ SWITCH_INT(layer->datatype);
+ SWITCH_INT64(layer->datasize);
+ SWITCH_INT(layer->structbytes);
+ }
+
+ if(layer->datatype != CDF_DATA_FLOAT)
+ return 0;
+
+ offset += layer->structbytes;
+ layer->structbytes= sizeof(CDataFileLayer);
+
+ if(fseek(f, offset, SEEK_SET) != 0)
+ return 0;
+ }
+
+ cdf->dataoffset= offset;
+
+ return 1;
+}
+
+static int cdf_write_header(CDataFile *cdf)
+{
+ CDataFileHeader *header;
+ CDataFileImageHeader *image;
+ CDataFileMeshHeader *mesh;
+ CDataFileLayer *layer;
+ FILE *f= cdf->writef;
+ int a;
+
+ header= &cdf->header;
+
+ if(!fwrite(header, sizeof(CDataFileHeader), 1, f))
+ return 0;
+
+ if(header->type == CDF_TYPE_IMAGE) {
+ image= &cdf->btype.image;
+ if(!fwrite(image, sizeof(CDataFileImageHeader), 1, f))
+ return 0;
+ }
+ else if(header->type == CDF_TYPE_MESH) {
+ mesh= &cdf->btype.mesh;
+ if(!fwrite(mesh, sizeof(CDataFileMeshHeader), 1, f))
+ return 0;
+ }
+
+ for(a=0; a<header->totlayer; a++) {
+ layer= &cdf->layer[a];
+
+ if(!fwrite(layer, sizeof(CDataFileLayer), 1, f))
+ return 0;
+ }
+
+ return 1;
+}
+
+int cdf_read_open(CDataFile *cdf, char *filename)
+{
+ FILE *f;
+
+ f= fopen(filename, "rb");
+ if(!f)
+ return 0;
+
+ cdf->readf= f;
+
+ if(!cdf_read_header(cdf)) {
+ cdf_read_close(cdf);
+ return 0;
+ }
+
+ if(cdf->header.type != cdf->type) {
+ cdf_read_close(cdf);
+ return 0;
+ }
+
+ return 1;
+}
+
+int cdf_read_layer(CDataFile *cdf, CDataFileLayer *blay)
+{
+ size_t offset;
+ int a;
+
+ /* seek to right location in file */
+ offset= cdf->dataoffset;
+ for(a=0; a<cdf->totlayer; a++) {
+ if(&cdf->layer[a] == blay)
+ break;
+ else
+ offset += cdf->layer[a].datasize;
+ }
+
+ return (fseek(cdf->readf, offset, SEEK_SET) == 0);
+}
+
+int cdf_read_data(CDataFile *cdf, int size, void *data)
+{
+ float *fdata;
+ int a;
+
+ /* read data */
+ if(!fread(data, size, 1, cdf->readf))
+ return 0;
+
+ /* switch endian if necessary */
+ if(cdf->switchendian) {
+ fdata= data;
+
+ for(a=0; a<size/sizeof(float); a++)
+ SWITCH_INT(fdata[a])
+ }
+
+ return 1;
+}
+
+void cdf_read_close(CDataFile *cdf)
+{
+ if(cdf->readf) {
+ fclose(cdf->readf);
+ cdf->readf= NULL;
+ }
+}
+
+int cdf_write_open(CDataFile *cdf, char *filename)
+{
+ CDataFileHeader *header;
+ CDataFileImageHeader *image;
+ CDataFileMeshHeader *mesh;
+ FILE *f;
+
+ f= fopen(filename, "wb");
+ if(!f)
+ return 0;
+
+ cdf->writef= f;
+
+ /* fill header */
+ header= &cdf->header;
+ strcpy(header->ID, "BCDF");
+ header->endian= cdf_endian();
+ header->version= CDF_VERSION;
+ header->subversion= CDF_SUBVERSION;
+
+ header->structbytes= sizeof(CDataFileHeader);
+ header->type= cdf->type;
+ header->totlayer= cdf->totlayer;
+
+ if(cdf->type == CDF_TYPE_IMAGE) {
+ /* fill image header */
+ image= &cdf->btype.image;
+ image->structbytes= sizeof(CDataFileImageHeader);
+ image->tile_size= CDF_TILE_SIZE;
+ }
+ else if(cdf->type == CDF_TYPE_MESH) {
+ /* fill mesh header */
+ mesh= &cdf->btype.mesh;
+ mesh->structbytes= sizeof(CDataFileMeshHeader);
+ }
+
+ cdf_write_header(cdf);
+
+ return 1;
+}
+
+int cdf_write_layer(CDataFile *cdf, CDataFileLayer *blay)
+{
+ return 1;
+}
+
+int cdf_write_data(CDataFile *cdf, int size, void *data)
+{
+ /* write data */
+ if(!fwrite(data, size, 1, cdf->writef))
+ return 0;
+
+ return 1;
+}
+
+void cdf_write_close(CDataFile *cdf)
+{
+ if(cdf->writef) {
+ fclose(cdf->writef);
+ cdf->writef= NULL;
+ }
+}
+
+void cdf_remove(char *filename)
+{
+ BLI_delete(filename, 0, 0);
+}
+
+/********************************** Layers ***********************************/
+
+CDataFileLayer *cdf_layer_find(CDataFile *cdf, int type, char *name)
+{
+ CDataFileLayer *layer;
+ int a;
+
+ for(a=0; a<cdf->totlayer; a++) {
+ layer= &cdf->layer[a];
+
+ if(layer->type == type && strcmp(layer->name, name) == 0)
+ return layer;
+ }
+
+ return NULL;
+}
+
+CDataFileLayer *cdf_layer_add(CDataFile *cdf, int type, char *name, size_t datasize)
+{
+ CDataFileLayer *newlayer, *layer;
+
+ /* expand array */
+ newlayer= MEM_callocN(sizeof(CDataFileLayer)*(cdf->totlayer+1), "CDataFileLayer");
+ memcpy(newlayer, cdf->layer, sizeof(CDataFileLayer)*cdf->totlayer);
+ cdf->layer= newlayer;
+
+ cdf->totlayer++;
+
+ /* fill in new layer */
+ layer= &cdf->layer[cdf->totlayer-1];
+ layer->structbytes= sizeof(CDataFileLayer);
+ layer->datatype= CDF_DATA_FLOAT;
+ layer->datasize= datasize;
+ layer->type= type;
+ BLI_strncpy(layer->name, name, CDF_LAYER_NAME_MAX);
+
+ return layer;
+}
+
diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c
index 8a76d659d5f..20ba360a231 100644
--- a/source/blender/blenkernel/intern/multires.c
+++ b/source/blender/blenkernel/intern/multires.c
@@ -41,7 +41,6 @@
#include "BLI_blenlib.h"
#include "BLI_pbvh.h"
-#include "BKE_btex.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_customdata.h"
#include "BKE_depsgraph.h"
@@ -250,7 +249,7 @@ void multiresModifier_del_levels(struct MultiresModifierData *mmd, struct Object
int levels = mmd->totlvl - lvl;
MDisps *mdisps;
- CustomData_external_read(&me->fdata, CD_MASK_MDISPS, me->totface);
+ CustomData_external_read(&me->fdata, &me->id, CD_MASK_MDISPS, me->totface);
mdisps= CustomData_get_layer(&me->fdata, CD_MDISPS);
multires_force_update(ob);
@@ -286,7 +285,7 @@ void multiresModifier_del_levels(struct MultiresModifierData *mmd, struct Object
}
}
else {
- CustomData_external_remove(&me->fdata, CD_MDISPS, me->totface);
+ CustomData_external_remove(&me->fdata, &me->id, CD_MDISPS, me->totface);
CustomData_free_layer_active(&me->fdata, CD_MDISPS, me->totface);
}
}
@@ -538,7 +537,7 @@ static void multiresModifier_update(DerivedMesh *dm)
ob = ccgdm->multires.ob;
me = ccgdm->multires.ob->data;
mmd = ccgdm->multires.mmd;
- CustomData_external_read(&me->fdata, CD_MASK_MDISPS, me->totface);
+ CustomData_external_read(&me->fdata, &me->id, CD_MASK_MDISPS, me->totface);
mdisps = CustomData_get_layer(&me->fdata, CD_MDISPS);
if(mdisps) {
@@ -690,7 +689,7 @@ struct DerivedMesh *multires_dm_create_from_derived(MultiresModifierData *mmd, i
memcpy(subGridData[i], gridData[i], sizeof(DMGridData)*gridSize*gridSize);
}
- CustomData_external_read(&me->fdata, CD_MASK_MDISPS, me->totface);
+ CustomData_external_read(&me->fdata, &me->id, CD_MASK_MDISPS, me->totface);
multiresModifier_disp_run(result, ob->data, 0, 0, subGridData, mmd->totlvl);
for(i = 0; i < numGrids; i++)