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:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2009-12-10 17:26:06 +0300
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2009-12-10 17:26:06 +0300
commitacadb8c39f83a4b4112c8c77bac1eb39584ad100 (patch)
tree6e6249a3b1a8ef81bf74efb4dacfb2be8fa37c24 /source/blender/blenkernel/intern
parent6639ba6b867581ece49423f2c92651727fd4552f (diff)
Sculpt Branch:
Revised external multires file saving. Now it is more manual in that you have to specify where to save it, like an image file, but still saved at the same time as the .blend. It would ideally be automatic, but this is difficult to implement, so for now this should at least be more reliable.
Diffstat (limited to 'source/blender/blenkernel/intern')
-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
4 files changed, 521 insertions, 541 deletions
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++)