diff options
19 files changed, 749 insertions, 638 deletions
diff --git a/release/scripts/ui/properties_data_modifier.py b/release/scripts/ui/properties_data_modifier.py index 8194027bae6..97c8f603273 100644 --- a/release/scripts/ui/properties_data_modifier.py +++ b/release/scripts/ui/properties_data_modifier.py @@ -438,7 +438,6 @@ class DATA_PT_modifiers(DataButtonsPanel): col.prop(md, "levels", text="Preview") col.prop(md, "sculpt_levels", text="Sculpt") col.prop(md, "render_levels", text="Render") - col.prop(md, "optimal_display") if wide_ui: col = split.column() @@ -446,9 +445,20 @@ class DATA_PT_modifiers(DataButtonsPanel): col.enabled = ob.mode != 'EDIT' col.operator("object.multires_subdivide", text="Subdivide") col.operator("object.multires_higher_levels_delete", text="Delete Higher") + col.prop(md, "optimal_display") + + layout.separator() + + col = layout.column() row = col.row() - row.enabled = md.total_levels > 0 - row.prop(md, "external") + if md.external: + row.operator("object.multires_pack_external", text="Pack External") + row.label() + row = col.row() + row.prop(md, "filename", text="") + else: + row.operator("object.multires_save_external", text="Save External...") + row.label() def PARTICLE_INSTANCE(self, layout, ob, md, wide_ui): layout.prop(md, "object") 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++) diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index bc0db6d4cd1..280b9ffc182 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -1457,13 +1457,13 @@ static void write_mdisps(WriteData *wd, int count, MDisps *mdlist, int external) } } -static void write_customdata(WriteData *wd, int count, CustomData *data, int partial_type, int partial_count) +static void write_customdata(WriteData *wd, ID *id, int count, CustomData *data, int partial_type, int partial_count) { int i; - /* write external customdata */ + /* write external customdata (not for undo) */ if(data->external && !wd->current) - CustomData_external_write(data, CD_MASK_MESH, count, 0); + CustomData_external_write(data, id, CD_MASK_MESH, count, 0); writestruct(wd, DATA, "CustomDataLayer", data->maxlayer, data->layers); @@ -1515,16 +1515,16 @@ static void write_meshs(WriteData *wd, ListBase *idbase) writedata(wd, DATA, sizeof(void *)*mesh->totcol, mesh->mat); if(mesh->pv) { - write_customdata(wd, mesh->pv->totvert, &mesh->vdata, -1, 0); - write_customdata(wd, mesh->pv->totedge, &mesh->edata, + write_customdata(wd, &mesh->id, mesh->pv->totvert, &mesh->vdata, -1, 0); + write_customdata(wd, &mesh->id, mesh->pv->totedge, &mesh->edata, CD_MEDGE, mesh->totedge); - write_customdata(wd, mesh->pv->totface, &mesh->fdata, + write_customdata(wd, &mesh->id, mesh->pv->totface, &mesh->fdata, CD_MFACE, mesh->totface); } else { - write_customdata(wd, mesh->totvert, &mesh->vdata, -1, 0); - write_customdata(wd, mesh->totedge, &mesh->edata, -1, 0); - write_customdata(wd, mesh->totface, &mesh->fdata, -1, 0); + write_customdata(wd, &mesh->id, mesh->totvert, &mesh->vdata, -1, 0); + write_customdata(wd, &mesh->id, mesh->totedge, &mesh->edata, -1, 0); + write_customdata(wd, &mesh->id, mesh->totface, &mesh->fdata, -1, 0); } /* PMV data */ diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index c87210d6070..848855da1b0 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -143,6 +143,8 @@ void OBJECT_OT_modifier_convert(struct wmOperatorType *ot); void OBJECT_OT_modifier_copy(struct wmOperatorType *ot); void OBJECT_OT_multires_subdivide(struct wmOperatorType *ot); void OBJECT_OT_multires_higher_levels_delete(struct wmOperatorType *ot); +void OBJECT_OT_multires_save_external(struct wmOperatorType *ot); +void OBJECT_OT_multires_pack_external(struct wmOperatorType *ot); void OBJECT_OT_meshdeform_bind(struct wmOperatorType *ot); void OBJECT_OT_explode_refresh(struct wmOperatorType *ot); diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index 76c0f297999..a0fa0efec0a 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -44,6 +44,7 @@ #include "BLI_math.h" #include "BLI_listbase.h" #include "BLI_string.h" +#include "BLI_util.h" #include "BKE_action.h" #include "BKE_curve.h" @@ -794,21 +795,105 @@ static int multires_subdivide_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -static int multires_subdivide_poll(bContext *C) -{ - PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_MultiresModifier); - ID *id= ptr.id.data; - return (ptr.data && id && !id->lib); -} - void OBJECT_OT_multires_subdivide(wmOperatorType *ot) { ot->name= "Multires Subdivide"; ot->description= "Add a new level of subdivision."; ot->idname= "OBJECT_OT_multires_subdivide"; + ot->poll= multires_poll; ot->exec= multires_subdivide_exec; - ot->poll= multires_subdivide_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/****************** multires save external operator *********************/ + +static int multires_save_external_exec(bContext *C, wmOperator *op) +{ + PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_MultiresModifier); + Object *ob= ptr.id.data; + Mesh *me= (ob)? ob->data: op->customdata; + char path[FILE_MAX]; + + if(CustomData_external_test(&me->fdata, CD_MDISPS)) + return OPERATOR_CANCELLED; + + RNA_string_get(op->ptr, "path", path); + if(G.save_over) + BLI_makestringcode(G.sce, path); /* make relative */ + + CustomData_external_add(&me->fdata, &me->id, CD_MDISPS, me->totface, path); + CustomData_external_write(&me->fdata, &me->id, CD_MASK_MESH, me->totface, 0); + + return OPERATOR_FINISHED; +} + +static int multires_save_external_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_MultiresModifier); + Object *ob= ptr.id.data; + Mesh *me= ob->data; + char path[FILE_MAX]; + + if(CustomData_external_test(&me->fdata, CD_MDISPS)) + return OPERATOR_CANCELLED; + + if(RNA_property_is_set(op->ptr, "path")) + return multires_save_external_exec(C, op); + + op->customdata= me; + + BLI_snprintf(path, sizeof(path), "//%s.btx", me->id.name+2); + RNA_string_set(op->ptr, "path", path); + + WM_event_add_fileselect(C, op); + + return OPERATOR_RUNNING_MODAL; +} + +void OBJECT_OT_multires_save_external(wmOperatorType *ot) +{ + ot->name= "Multires Save External"; + ot->description= "Save displacements to an external file."; + ot->idname= "OBJECT_OT_multires_save_external"; + + ot->poll= multires_poll; + ot->exec= multires_save_external_exec; + ot->invoke= multires_save_external_invoke; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + WM_operator_properties_filesel(ot, FOLDERFILE|BTXFILE, FILE_SPECIAL); +} + +/****************** multires pack operator *********************/ + +static int multires_pack_external_exec(bContext *C, wmOperator *op) +{ + PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_MultiresModifier); + Object *ob= ptr.id.data; + Mesh *me= ob->data; + + if(!CustomData_external_test(&me->fdata, CD_MDISPS)) + return OPERATOR_CANCELLED; + + // XXX don't remove.. + CustomData_external_remove(&me->fdata, &me->id, CD_MDISPS, me->totface); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_multires_pack_external(wmOperatorType *ot) +{ + ot->name= "Multires Pack External"; + ot->description= "Pack displacements from an external file."; + ot->idname= "OBJECT_OT_multires_pack_external"; + + ot->poll= multires_poll; + ot->exec= multires_pack_external_exec; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 13b1155d616..7376b5aa939 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -136,6 +136,8 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_modifier_copy); WM_operatortype_append(OBJECT_OT_multires_subdivide); WM_operatortype_append(OBJECT_OT_multires_higher_levels_delete); + WM_operatortype_append(OBJECT_OT_multires_save_external); + WM_operatortype_append(OBJECT_OT_multires_pack_external); WM_operatortype_append(OBJECT_OT_meshdeform_bind); WM_operatortype_append(OBJECT_OT_explode_refresh); diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c index a1f9a9fd250..93bedd0b866 100644 --- a/source/blender/editors/space_file/file_draw.c +++ b/source/blender/editors/space_file/file_draw.c @@ -310,6 +310,8 @@ static int get_file_icon(struct direntry *file) return ICON_FILE_SOUND; else if (file->flags & FTFONTFILE) return ICON_FILE_FONT; + else if (file->flags & BTXFILE) + return ICON_FILE_BLANK; else return ICON_FILE_BLANK; } diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index 640f365b073..81aa63dcad9 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -871,6 +871,8 @@ void filelist_setfiletypes(struct FileList* filelist, short has_quicktime) || BLI_testextensie(file->relname, ".otf") || BLI_testextensie(file->relname, ".otc")) { file->flags |= FTFONTFILE; + } else if(BLI_testextensie(file->relname, ".btx")) { + file->flags |= BTXFILE; } else if (has_quicktime){ if( BLI_testextensie(file->relname, ".int") || BLI_testextensie(file->relname, ".inta") diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c index d681a58b276..bf580545455 100644 --- a/source/blender/editors/space_file/filesel.c +++ b/source/blender/editors/space_file/filesel.c @@ -161,6 +161,8 @@ short ED_fileselect_set_params(SpaceFile *sfile) params->filter |= RNA_boolean_get(op->ptr, "filter_text") ? TEXTFILE : 0; if(RNA_struct_find_property(op->ptr, "filter_folder")) params->filter |= RNA_boolean_get(op->ptr, "filter_folder") ? FOLDERFILE : 0; + if(RNA_struct_find_property(op->ptr, "filter_btx")) + params->filter |= RNA_boolean_get(op->ptr, "filter_btx") ? BTXFILE : 0; if (params->filter != 0) params->flag |= FILE_FILTER; diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 7a76417fe4b..83181d10df5 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -667,6 +667,7 @@ enum FileSortTypeE { #define TEXTFILE 512 #define MOVIEFILE_ICON 1024 /* movie file that preview can't load */ #define FOLDERFILE 2048 /* represents folders for filtering */ +#define BTXFILE 4096 /* SpaceImage->dt_uv */ #define SI_UVDT_OUTLINE 0 diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index ae02489537f..5a534a8ce14 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -357,15 +357,29 @@ static int rna_MultiresModifier_external_get(PointerRNA *ptr) return CustomData_external_test(&me->fdata, CD_MDISPS); } -static void rna_MultiresModifier_external_set(PointerRNA *ptr, int value) +static void rna_MultiresModifier_filename_get(PointerRNA *ptr, char *value) { Object *ob= (Object*)ptr->id.data; - Mesh *me= ob->data; + CustomDataExternal *external= ((Mesh*)ob->data)->fdata.external; + + BLI_strncpy(value, (external)? external->filename: "", sizeof(external->filename)); +} + +static void rna_MultiresModifier_filename_set(PointerRNA *ptr, const char *value) +{ + Object *ob= (Object*)ptr->id.data; + CustomDataExternal *external= ((Mesh*)ob->data)->fdata.external; + + if(external) + BLI_strncpy(external->filename, value, sizeof(external->filename)); +} + +static int rna_MultiresModifier_filename_length(PointerRNA *ptr) +{ + Object *ob= (Object*)ptr->id.data; + CustomDataExternal *external= ((Mesh*)ob->data)->fdata.external; - if(CustomData_external_test(&me->fdata, CD_MDISPS) && !value) - CustomData_external_remove(&me->fdata, CD_MDISPS, me->totface); - else if(!CustomData_external_test(&me->fdata, CD_MDISPS) && value) - CustomData_external_add(&me->fdata, CD_MDISPS, me->id.name+2, me->totface); + return strlen((external)? external->filename: ""); } static int rna_MultiresModifier_external_editable(PointerRNA *ptr) @@ -580,10 +594,16 @@ static void rna_def_modifier_multires(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Total Levels", "Number of subdivisions for which displacements are stored."); prop= RNA_def_property(srna, "external", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_funcs(prop, "rna_MultiresModifier_external_get", "rna_MultiresModifier_external_set"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_boolean_funcs(prop, "rna_MultiresModifier_external_get", NULL); RNA_def_property_editable_func(prop, "rna_MultiresModifier_external_editable"); RNA_def_property_ui_text(prop, "External", "Store multires displacements outside the .blend file, to save memory."); + prop= RNA_def_property(srna, "filename", PROP_STRING, PROP_FILEPATH); + RNA_def_property_string_funcs(prop, "rna_MultiresModifier_filename_get", "rna_MultiresModifier_filename_length", "rna_MultiresModifier_filename_set"); + RNA_def_property_ui_text(prop, "Filename", "Path to external displacements file."); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + prop= RNA_def_property(srna, "optimal_display", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", eMultiresModifierFlag_ControlEdges); RNA_def_property_ui_text(prop, "Optimal Display", "Skip drawing/rendering of interior subdivided edges"); diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 8c819c1e3a0..751785a417a 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -680,6 +680,8 @@ void WM_operator_properties_filesel(wmOperatorType *ot, int filter, short type) RNA_def_property_flag(prop, PROP_HIDDEN); prop= RNA_def_boolean(ot->srna, "filter_text", (filter & TEXTFILE), "Filter text files", ""); RNA_def_property_flag(prop, PROP_HIDDEN); + prop= RNA_def_boolean(ot->srna, "filter_btx", (filter & BTXFILE), "Filter btx files", ""); + RNA_def_property_flag(prop, PROP_HIDDEN); prop= RNA_def_boolean(ot->srna, "filter_folder", (filter & FOLDERFILE), "Filter folders", ""); RNA_def_property_flag(prop, PROP_HIDDEN); |