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/intern/customdata.c')
-rw-r--r--source/blender/blenkernel/intern/customdata.c627
1 files changed, 561 insertions, 66 deletions
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index d7cc5376e21..f0b93212766 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -44,19 +44,25 @@
#include "DNA_meshdata_types.h"
#include "DNA_ID.h"
+#include "BLI_utildefines.h"
#include "BLI_blenlib.h"
#include "BLI_linklist.h"
#include "BLI_math.h"
#include "BLI_mempool.h"
+#include "BLI_cellalloc.h"
#include "BLI_utildefines.h"
#include "BKE_customdata.h"
#include "BKE_customdata_file.h"
#include "BKE_global.h"
#include "BKE_main.h"
-#include "BKE_utildefines.h"
#include "BKE_multires.h"
+#include "bmesh.h"
+
+#include <math.h>
+#include <string.h>
+
/* number of layers to add when growing a CustomData object */
#define CUSTOMDATA_GROW 5
@@ -99,6 +105,14 @@ typedef struct LayerTypeInfo {
default is assumed to be all zeros */
void (*set_default)(void *data, int count);
+ /* functions necassary for geometry collapse*/
+ int (*equal)(void *data1, void *data2);
+ void (*multiply)(void *data, float fac);
+ void (*initminmax)(void *min, void *max);
+ void (*add)(void *data1, void *data2);
+ void (*dominmax)(void *data1, void *min, void *max);
+ void (*copyvalue)(void *source, void *dest);
+
/* a function to read data from a cdf file */
int (*read)(CDataFile *cdf, void *data, int count);
@@ -125,7 +139,7 @@ static void layerCopy_mdeformvert(const void *source, void *dest,
MDeformVert *dvert = (MDeformVert *)((char *)dest + i * size);
if(dvert->totweight) {
- MDeformWeight *dw = MEM_callocN(dvert->totweight * sizeof(*dw),
+ MDeformWeight *dw = BLI_cellalloc_calloc(dvert->totweight * sizeof(*dw),
"layerCopy_mdeformvert dw");
memcpy(dw, dvert->dw, dvert->totweight * sizeof(*dw));
@@ -144,7 +158,7 @@ static void layerFree_mdeformvert(void *data, int count, int size)
MDeformVert *dvert = (MDeformVert *)((char *)data + i * size);
if(dvert->dw) {
- MEM_freeN(dvert->dw);
+ BLI_cellalloc_free(dvert->dw);
dvert->dw = NULL;
dvert->totweight = 0;
}
@@ -153,7 +167,7 @@ static void layerFree_mdeformvert(void *data, int count, int size)
static void linklist_free_simple(void *link)
{
- MEM_freeN(link);
+ BLI_cellalloc_free(link);
}
static void layerInterp_mdeformvert(void **sources, float *weights,
@@ -186,7 +200,7 @@ static void layerInterp_mdeformvert(void **sources, float *weights,
/* if this def_nr is not in the list, add it */
if(!node) {
- MDeformWeight *tmp_dw = MEM_callocN(sizeof(*tmp_dw),
+ MDeformWeight *tmp_dw = BLI_cellalloc_calloc(sizeof(*tmp_dw),
"layerInterp_mdeformvert tmp_dw");
tmp_dw->def_nr = dw->def_nr;
tmp_dw->weight = dw->weight * interp_weight;
@@ -197,10 +211,10 @@ static void layerInterp_mdeformvert(void **sources, float *weights,
}
/* now we know how many unique deform weights there are, so realloc */
- if(dvert->dw) MEM_freeN(dvert->dw);
+ if(dvert->dw) BLI_cellalloc_free(dvert->dw);
if(totweight) {
- dvert->dw = MEM_callocN(sizeof(*dvert->dw) * totweight,
+ dvert->dw = BLI_cellalloc_calloc(sizeof(*dvert->dw) * totweight,
"layerInterp_mdeformvert dvert->dw");
dvert->totweight = totweight;
@@ -331,6 +345,24 @@ static void layerDefault_tface(void *data, int count)
tf[i] = default_tf;
}
+static void layerCopy_propFloat(const void *source, void *dest,
+ int count)
+{
+ memcpy(dest, source, sizeof(MFloatProperty)*count);
+}
+
+static void layerCopy_propInt(const void *source, void *dest,
+ int count)
+{
+ memcpy(dest, source, sizeof(MIntProperty)*count);
+}
+
+static void layerCopy_propString(const void *source, void *dest,
+ int count)
+{
+ memcpy(dest, source, sizeof(MStringProperty)*count);
+}
+
static void layerCopy_origspace_face(const void *source, void *dest, int count)
{
const OrigSpaceFace *source_tf = (const OrigSpaceFace*)source;
@@ -419,22 +451,39 @@ static void layerSwap_mdisps(void *data, const int *ci)
/* happens when face changed vertex count in edit mode
if it happened, just forgot displacement */
- MEM_freeN(s->disps);
+ BLI_cellalloc_free(s->disps);
s->totdisp= (s->totdisp/corners)*nverts;
- s->disps= MEM_callocN(s->totdisp*sizeof(float)*3, "mdisp swap");
+ s->disps= BLI_cellalloc_calloc(s->totdisp*sizeof(float)*3, "mdisp swap");
return;
}
- d= MEM_callocN(sizeof(float) * 3 * s->totdisp, "mdisps swap");
+ d= BLI_cellalloc_calloc(sizeof(float) * 3 * s->totdisp, "mdisps swap");
for(S = 0; S < corners; S++)
memcpy(d + cornersize*S, s->disps + cornersize*ci[S], cornersize*3*sizeof(float));
- MEM_freeN(s->disps);
+ BLI_cellalloc_free(s->disps);
s->disps= d;
}
}
+#if 1 /* BMESH_TODO: place holder function, dont actually interp */
+static void layerInterp_mdisps(void **sources, float *UNUSED(weights),
+ float *UNUSED(sub_weights), int UNUSED(count), void *dest)
+{
+ MDisps *d = dest;
+
+ /* happens when flipping normals of newly created mesh */
+ if(!d->totdisp) {
+ d->totdisp = ((MDisps*)sources[0])->totdisp;
+ }
+
+ if (!d->disps && d->totdisp)
+ d->disps = BLI_cellalloc_calloc(sizeof(float)*3*d->totdisp, "blank mdisps in layerInterp_mdisps");
+}
+
+#else // BMESH_TODO
+
static void layerInterp_mdisps(void **sources, float *UNUSED(weights),
float *sub_weights, int count, void *dest)
{
@@ -547,6 +596,7 @@ static void layerInterp_mdisps(void **sources, float *UNUSED(weights),
MEM_freeN(d->disps);
d->disps = disps;
}
+#endif // BMESH_TODO
static void layerCopy_mdisps(const void *source, void *dest, int count)
{
@@ -556,7 +606,7 @@ static void layerCopy_mdisps(const void *source, void *dest, int count)
for(i = 0; i < count; ++i) {
if(s[i].disps) {
- d[i].disps = MEM_dupallocN(s[i].disps);
+ d[i].disps = BLI_cellalloc_dupalloc(s[i].disps);
d[i].totdisp = s[i].totdisp;
}
else {
@@ -569,6 +619,10 @@ static void layerCopy_mdisps(const void *source, void *dest, int count)
static void layerValidate_mdisps(void *data, int sub_elements)
{
+#if 1 /*BMESH_TODO*/
+ (void)data;
+ (void)sub_elements;
+#else
MDisps *disps = data;
if(disps->disps) {
int corners = multires_mdisp_corners(disps);
@@ -576,9 +630,10 @@ static void layerValidate_mdisps(void *data, int sub_elements)
if(corners != sub_elements) {
MEM_freeN(disps->disps);
disps->totdisp = disps->totdisp / corners * sub_elements;
- disps->disps = MEM_callocN(3*disps->totdisp*sizeof(float), "layerValidate_mdisps");
+ disps->disps = BLI_cellalloc_calloc(3*disps->totdisp*sizeof(float), "layerValidate_mdisps");
}
}
+#endif
}
static void layerFree_mdisps(void *data, int count, int UNUSED(size))
@@ -588,7 +643,7 @@ static void layerFree_mdisps(void *data, int count, int UNUSED(size))
for(i = 0; i < count; ++i) {
if(d[i].disps)
- MEM_freeN(d[i].disps);
+ BLI_cellalloc_free(d[i].disps);
d[i].disps = NULL;
d[i].totdisp = 0;
}
@@ -601,7 +656,7 @@ static int layerRead_mdisps(CDataFile *cdf, void *data, int count)
for(i = 0; i < count; ++i) {
if(!d[i].disps)
- d[i].disps = MEM_callocN(sizeof(float)*3*d[i].totdisp, "mdisps read");
+ d[i].disps = BLI_cellalloc_calloc(sizeof(float)*3*d[i].totdisp, "mdisps read");
if(!cdf_read_data(cdf, d[i].totdisp*3*sizeof(float), d[i].disps)) {
printf("failed to read multires displacement %d/%d %d\n", i, count, d[i].totdisp);
@@ -640,10 +695,83 @@ static size_t layerFilesize_mdisps(CDataFile *UNUSED(cdf), void *data, int count
}
/* --------- */
+static void layerCopyValue_mloopcol(void *source, void *dest)
+{
+ MLoopCol *m1 = source, *m2 = dest;
+
+ m2->r = m1->r;
+ m2->g = m1->g;
+ m2->b = m1->b;
+ m2->a = m1->a;
+}
+
+static int layerEqual_mloopcol(void *data1, void *data2)
+{
+ MLoopCol *m1 = data1, *m2 = data2;
+ float r, g, b, a;
+
+ r = m1->r - m2->r;
+ g = m1->g - m2->g;
+ b = m1->b - m2->b;
+ a = m1->a - m2->a;
+
+ return r*r + g*g + b*b + a*a < 0.001;
+}
+
+static void layerMultiply_mloopcol(void *data, float fac)
+{
+ MLoopCol *m = data;
+
+ m->r = (float)m->r * fac;
+ m->g = (float)m->g * fac;
+ m->b = (float)m->b * fac;
+ m->a = (float)m->a * fac;
+}
+
+static void layerAdd_mloopcol(void *data1, void *data2)
+{
+ MLoopCol *m = data1, *m2 = data2;
+
+ m->r += m2->r;
+ m->g += m2->g;
+ m->b += m2->b;
+ m->a += m2->a;
+}
+
+static void layerDoMinMax_mloopcol(void *data, void *vmin, void *vmax)
+{
+ MLoopCol *m = data;
+ MLoopCol *min = vmin, *max = vmax;
+
+ if (m->r < min->r) min->r = m->r;
+ if (m->g < min->g) min->g = m->g;
+ if (m->b < min->b) min->b = m->b;
+ if (m->a < min->a) min->a = m->a;
+
+ if (m->r > max->r) max->r = m->r;
+ if (m->g > max->g) max->g = m->g;
+ if (m->b > max->b) max->b = m->b;
+ if (m->a > max->a) max->a = m->a;
+}
+
+static void layerInitMinMax_mloopcol(void *vmin, void *vmax)
+{
+ MLoopCol *min = vmin, *max = vmax;
+
+ min->r = 255;
+ min->g = 255;
+ min->b = 255;
+ min->a = 255;
+
+ max->r = 0;
+ max->g = 0;
+ max->b = 0;
+ max->a = 0;
+}
static void layerDefault_mloopcol(void *data, int count)
{
- static MLoopCol default_mloopcol = {255,255,255,255};
+ MLoopCol default_mloopcol = {255,255,255,255};
MLoopCol *mlcol = (MLoopCol*)data;
int i;
for(i = 0; i < count; i++)
@@ -695,6 +823,56 @@ static void layerInterp_mloopcol(void **sources, float *weights,
mc->g = (int)col.g;
mc->b = (int)col.b;
}
+
+static void layerCopyValue_mloopuv(void *source, void *dest)
+{
+ MLoopUV *luv1 = source, *luv2 = dest;
+
+ luv2->uv[0] = luv1->uv[0];
+ luv2->uv[1] = luv1->uv[1];
+}
+
+static int layerEqual_mloopuv(void *data1, void *data2)
+{
+ MLoopUV *luv1 = data1, *luv2 = data2;
+ float u, v;
+
+ u = luv1->uv[0] - luv2->uv[0];
+ v = luv1->uv[1] - luv2->uv[1];
+
+ return u*u + v*v < 0.00001;
+}
+
+static void layerMultiply_mloopuv(void *data, float fac)
+{
+ MLoopUV *luv = data;
+
+ luv->uv[0] *= fac;
+ luv->uv[1] *= fac;
+}
+
+static void layerInitMinMax_mloopuv(void *vmin, void *vmax)
+{
+ MLoopUV *min = vmin, *max = vmax;
+
+ INIT_MINMAX2(min->uv, max->uv);
+}
+
+static void layerDoMinMax_mloopuv(void *data, void *vmin, void *vmax)
+{
+ MLoopUV *min = vmin, *max = vmax, *luv = data;
+
+ DO_MINMAX2(luv->uv, min->uv, max->uv);
+}
+
+static void layerAdd_mloopuv(void *data1, void *data2)
+{
+ MLoopUV *l1 = data1, *l2 = data2;
+
+ l1->uv[0] += l2->uv[0];
+ l1->uv[1] += l2->uv[1];
+}
+
static void layerInterp_mloopuv(void **sources, float *weights,
float *sub_weights, int count, void *dest)
{
@@ -802,7 +980,48 @@ static void layerDefault_mcol(void *data, int count)
mcol[i] = default_mcol;
}
+static void layerInterp_bweight(void **sources, float *weights,
+ float *UNUSED(sub_weights), int count, void *dest)
+{
+ float *f = dest, *src;
+ float **in = (float **)sources;
+ int i;
+
+ if(count <= 0) return;
+
+ *f = 0.0f;
+
+ for(i = 0; i < count; ++i) {
+ float weight = weights ? weights[i] : 1.0f;
+
+ src = in[i];
+ *f += *src * weight;
+ }
+}
+
+static void layerInterp_shapekey(void **sources, float *weights,
+ float *UNUSED(sub_weights), int count, void *dest)
+{
+ float *co = dest, *src;
+ float **in = (float **)sources;
+ int i;
+ if(count <= 0) return;
+
+ memset(co, 0, sizeof(float)*3);
+
+ for(i = 0; i < count; ++i) {
+ float weight = weights ? weights[i] : 1.0f;
+
+ src = in[i];
+ co[0] += src[0] * weight;
+ co[1] += src[1] * weight;
+ co[2] += src[2] * weight;
+ }
+}
+
+/* note, these numbered comments below are copied from trunk,
+ * while _most_ match, some at the end need adding and are out of sync */
static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
/* 0: CD_MVERT */
@@ -828,15 +1047,15 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
{sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
/* 8: CD_NORMAL */
/* 3 floats per normal vector */
- {sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
- /* 9: CD_FLAGS */
- {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
+ {sizeof(float)*3, "vec3f", 1, NULL, NULL, NULL, NULL, NULL, NULL},
+ /* 9: CD_POLYINDEX */
+ {sizeof(int), "MIntProperty", 1, NULL, NULL, NULL, NULL, NULL, NULL},
/* 10: CD_PROP_FLT */
- {sizeof(MFloatProperty), "MFloatProperty",1,"Float",NULL,NULL,NULL,NULL},
+ {sizeof(MFloatProperty), "MFloatProperty",1,"Float", layerCopy_propFloat,NULL,NULL,NULL},
/* 11: CD_PROP_INT */
- {sizeof(MIntProperty), "MIntProperty",1,"Int",NULL,NULL,NULL,NULL},
+ {sizeof(MIntProperty), "MIntProperty",1,"Int",layerCopy_propInt,NULL,NULL,NULL},
/* 12: CD_PROP_STR */
- {sizeof(MStringProperty), "MStringProperty",1,"String",NULL,NULL,NULL,NULL},
+ {sizeof(MStringProperty), "MStringProperty",1,"String",layerCopy_propString,NULL,NULL,NULL},
/* 13: CD_ORIGSPACE */
{sizeof(OrigSpaceFace), "OrigSpaceFace", 1, "UVTex", layerCopy_origspace_face, NULL,
layerInterp_origspace_face, layerSwap_origspace_face, layerDefault_origspace_face},
@@ -845,58 +1064,80 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
/* 15: CD_MTEXPOLY */
{sizeof(MTexPoly), "MTexPoly", 1, "Face Texture", NULL, NULL, NULL, NULL, NULL},
/* 16: CD_MLOOPUV */
- {sizeof(MLoopUV), "MLoopUV", 1, "UV coord", NULL, NULL, layerInterp_mloopuv, NULL, NULL},
+ {sizeof(MLoopUV), "MLoopUV", 1, "UV coord", NULL, NULL, layerInterp_mloopuv, NULL, NULL,
+ layerEqual_mloopuv, layerMultiply_mloopuv, layerInitMinMax_mloopuv,
+ layerAdd_mloopuv, layerDoMinMax_mloopuv, layerCopyValue_mloopuv},
/* 17: CD_MLOOPCOL */
- {sizeof(MLoopCol), "MLoopCol", 1, "Col", NULL, NULL, layerInterp_mloopcol, NULL, layerDefault_mloopcol},
- /* 18: CD_TANGENT */
+ {sizeof(MLoopCol), "MLoopCol", 1, "Col", NULL, NULL, layerInterp_mloopcol, NULL,
+ layerDefault_mloopcol, layerEqual_mloopcol, layerMultiply_mloopcol, layerInitMinMax_mloopcol,
+ layerAdd_mloopcol, layerDoMinMax_mloopcol, layerCopyValue_mloopcol},
{sizeof(float)*4*4, "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
/* 19: CD_MDISPS */
{sizeof(MDisps), "MDisps", 1, NULL, layerCopy_mdisps,
- layerFree_mdisps, layerInterp_mdisps, layerSwap_mdisps, NULL, layerRead_mdisps, layerWrite_mdisps,
- layerFilesize_mdisps, layerValidate_mdisps},
+ layerFree_mdisps, layerInterp_mdisps, layerSwap_mdisps, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL,
+ layerRead_mdisps, layerWrite_mdisps, layerFilesize_mdisps, layerValidate_mdisps},
/* 20: CD_WEIGHT_MCOL */
{sizeof(MCol)*4, "MCol", 4, "WeightCol", NULL, NULL, layerInterp_mcol,
layerSwap_mcol, layerDefault_mcol},
+ {sizeof(MPoly), "MPoly", 1, "NGon Face", NULL, NULL, NULL, NULL, NULL},
+ {sizeof(MLoop), "MLoop", 1, "NGon Face-Vertex", NULL, NULL, NULL, NULL, NULL},
+ {sizeof(float)*3, "", 0, "ClothOrco", NULL, NULL, layerInterp_shapekey},
/* 21: CD_ID_MCOL */
{sizeof(MCol)*4, "MCol", 4, "IDCol", NULL, NULL, layerInterp_mcol,
layerSwap_mcol, layerDefault_mcol},
- /* 22: CD_TEXTURE_MCOL */
- {sizeof(MCol)*4, "MCol", 4, "TexturedCol", NULL, NULL, layerInterp_mcol,
+ {sizeof(MCol)*4, "MCol", 4, "TextureCol", NULL, NULL, layerInterp_mcol,
layerSwap_mcol, layerDefault_mcol},
- /* 23: CD_CLOTH_ORCO */
- {sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
+ {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
+ {sizeof(float)*3, "", 0, "ShapeKey", NULL, NULL, layerInterp_shapekey},
+ {sizeof(float), "", 0, "BevelWeight", NULL, NULL, layerInterp_bweight},
+ {sizeof(float), "", 0, "SubSurfCrease", NULL, NULL, layerInterp_bweight},
+ {sizeof(MLoopCol), "MLoopCol", 1, "WeightLoopCol", NULL, NULL, layerInterp_mloopcol, NULL,
+ layerDefault_mloopcol, layerEqual_mloopcol, layerMultiply_mloopcol, layerInitMinMax_mloopcol,
+ layerAdd_mloopcol, layerDoMinMax_mloopcol, layerCopyValue_mloopcol},
/* 24: CD_RECAST */
{sizeof(MRecast), "MRecast", 1,"Recast",NULL,NULL,NULL,NULL}
};
+/* note, numbers are from trunk and need updating for bmesh */
+
static const char *LAYERTYPENAMES[CD_NUMTYPES] = {
- /* 0-4 */ "CDMVert", "CDMSticky", "CDMDeformVert", "CDMEdge", "CDMFace",
- /* 5-9 */ "CDMTFace", "CDMCol", "CDOrigIndex", "CDNormal", "CDFlags",
- /* 10-14 */ "CDMFloatProperty", "CDMIntProperty","CDMStringProperty", "CDOrigSpace", "CDOrco",
- /* 15-19 */ "CDMTexPoly", "CDMLoopUV", "CDMloopCol", "CDTangent", "CDMDisps",
- /* 20-24 */"CDWeightMCol", "CDIDMCol", "CDTextureMCol", "CDClothOrco", "CDMRecast"
+ /* 0-4 */ "CDMVert", "CDMSticky", "CDMDeformVert", "CDMEdge", "CDMFace", "CDMTFace",
+ /* 5-9 */ "CDMCol", "CDOrigIndex", "CDNormal", "CDPolyIndex","CDMFloatProperty",
+ /* 10-14 */ "CDMIntProperty","CDMStringProperty", "CDOrigSpace", "CDOrco", "CDMTexPoly", "CDMLoopUV",
+ /* 15-19 */ "CDMloopCol", "CDTangent", "CDMDisps", "CDWeightMCol", "CDMPoly",
+ /* 20-24 */ "CDMLoop", "CDMClothOrco", "CDMLoopCol", "CDIDCol", "CDTextureCol",
+ /* ?-? */ "CDShapeKeyIndex", "CDShapeKey", "CDBevelWeight", "CDSubSurfCrease", "CDMRecast"
};
+
const CustomDataMask CD_MASK_BAREMESH =
- CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE;
+ CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE | CD_MASK_MLOOP | CD_MASK_MPOLY | CD_MASK_BWEIGHT;
const CustomDataMask CD_MASK_MESH =
CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE |
CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MCOL |
- CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR | CD_MASK_MDISPS | CD_MASK_RECAST;
+ CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR | CD_MASK_MDISPS |
+ CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MPOLY | CD_MASK_MLOOP |
+ CD_MASK_MTEXPOLY | CD_MASK_NORMAL | CD_MASK_MDISPS | CD_MASK_RECAST;
const CustomDataMask CD_MASK_EDITMESH =
- CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE |
- CD_MASK_MCOL|CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR | CD_MASK_MDISPS | CD_MASK_RECAST;
+ CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MLOOPUV |
+ CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY | CD_MASK_SHAPE_KEYINDEX |
+ CD_MASK_MCOL|CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR |
+ CD_MASK_MDISPS | CD_MASK_SHAPEKEY | CD_MASK_RECAST;
const CustomDataMask CD_MASK_DERIVEDMESH =
CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE |
- CD_MASK_MCOL | CD_MASK_ORIGINDEX | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_CLOTH_ORCO |
- CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORCO | CD_MASK_TANGENT | CD_MASK_WEIGHT_MCOL | CD_MASK_RECAST;
-const CustomDataMask CD_MASK_BMESH =
- CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR;
+ CD_MASK_MCOL | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_CLOTH_ORCO |
+ CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY | CD_MASK_WEIGHT_MLOOPCOL |
+ CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORCO | CD_MASK_TANGENT |
+ CD_MASK_WEIGHT_MCOL | CD_MASK_NORMAL | CD_MASK_SHAPEKEY | CD_MASK_RECAST |
+ CD_MASK_ORIGINDEX | CD_MASK_POLYINDEX;
+const CustomDataMask CD_MASK_BMESH = CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY |
+ CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_PROP_FLT | CD_MASK_PROP_INT |
+ CD_MASK_PROP_STR | CD_MASK_SHAPEKEY | CD_MASK_SHAPE_KEYINDEX | CD_MASK_MDISPS;
const CustomDataMask CD_MASK_FACECORNERS =
CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_MTEXPOLY | CD_MASK_MLOOPUV |
CD_MASK_MLOOPCOL;
-
static const LayerTypeInfo *layerType_getInfo(int type)
{
if(type < 0 || type >= CD_NUMTYPES) return NULL;
@@ -917,11 +1158,28 @@ static void customData_update_offsets(CustomData *data);
static CustomDataLayer *customData_add_layer__internal(CustomData *data,
int type, int alloctype, void *layerdata, int totelem, const char *name);
+void CustomData_update_typemap(CustomData *data)
+{
+ int i, lasttype = -1;
+
+ for (i=0; i<CD_NUMTYPES; i++) {
+ data->typemap[i] = -1;
+ }
+
+ for (i=0; i<data->totlayer; i++) {
+ if (data->layers[i].type != lasttype) {
+ data->typemap[data->layers[i].type] = i;
+ }
+ lasttype = data->layers[i].type;
+ }
+}
+
void CustomData_merge(const struct CustomData *source, struct CustomData *dest,
CustomDataMask mask, int alloctype, int totelem)
{
/*const LayerTypeInfo *typeInfo;*/
CustomDataLayer *layer, *newlayer;
+ void *data;
int i, type, number = 0, lasttype = -1, lastactive = 0, lastrender = 0, lastclone = 0, lastmask = 0, lastflag = 0;
for(i = 0; i < source->totlayer; ++i) {
@@ -946,14 +1204,27 @@ void CustomData_merge(const struct CustomData *source, struct CustomData *dest,
else if(!((int)mask & (int)(1 << (int)type))) continue;
else if(number < CustomData_number_of_layers(dest, type)) continue;
+ switch (alloctype) {
+ case CD_ASSIGN:
+ case CD_REFERENCE:
+ case CD_DUPLICATE:
+ data = layer->data;
+ break;
+ default:
+ data = NULL;
+ break;
+ }
+
if((alloctype == CD_ASSIGN) && (lastflag & CD_FLAG_NOFREE))
newlayer = customData_add_layer__internal(dest, type, CD_REFERENCE,
- layer->data, totelem, layer->name);
+ data, totelem, layer->name);
else
newlayer = customData_add_layer__internal(dest, type, alloctype,
- layer->data, totelem, layer->name);
+ data, totelem, layer->name);
if(newlayer) {
+ newlayer->uid = layer->uid;
+
newlayer->active = lastactive;
newlayer->active_rnd = lastrender;
newlayer->active_clone = lastclone;
@@ -961,6 +1232,8 @@ void CustomData_merge(const struct CustomData *source, struct CustomData *dest,
newlayer->flag |= lastflag & (CD_FLAG_EXTERNAL|CD_FLAG_IN_MEMORY);
}
}
+
+ CustomData_update_typemap(dest);
}
void CustomData_copy(const struct CustomData *source, struct CustomData *dest,
@@ -1025,6 +1298,7 @@ static void customData_update_offsets(CustomData *data)
}
data->totsize = offset;
+ CustomData_update_typemap(data);
}
int CustomData_get_layer_index(const CustomData *data, int type)
@@ -1038,6 +1312,17 @@ int CustomData_get_layer_index(const CustomData *data, int type)
return -1;
}
+int CustomData_get_layer_index_n(const struct CustomData *data, int type, int n)
+{
+ int i;
+
+ for(i=0; i < data->totlayer; ++i)
+ if(data->layers[i].type == type)
+ return i + n;
+
+ return -1;
+}
+
int CustomData_get_named_layer_index(const CustomData *data, int type, const char *name)
{
int i;
@@ -1051,11 +1336,12 @@ int CustomData_get_named_layer_index(const CustomData *data, int type, const cha
int CustomData_get_active_layer_index(const CustomData *data, int type)
{
- int i;
+ if (!data->totlayer)
+ return -1;
- for(i=0; i < data->totlayer; ++i)
- if(data->layers[i].type == type)
- return i + data->layers[i].active;
+ if (data->typemap[type] != -1) {
+ return data->typemap[type] + data->layers[data->typemap[type]].active;
+ }
return -1;
}
@@ -1242,6 +1528,13 @@ static CustomDataLayer *customData_add_layer__internal(CustomData *data,
int size = typeInfo->size * totelem, flag = 0, index = data->totlayer;
void *newlayerdata;
+ /* Passing a layerdata to copy from with an alloctype that won't copy is
+ most likely a bug */
+ BLI_assert(!layerdata ||
+ (alloctype == CD_ASSIGN) ||
+ (alloctype == CD_DUPLICATE) ||
+ (alloctype == CD_REFERENCE));
+
if (!typeInfo->defaultname && CustomData_has_layer(data, type))
return &data->layers[CustomData_get_layer_index(data, type)];
@@ -1254,7 +1547,7 @@ static CustomDataLayer *customData_add_layer__internal(CustomData *data,
return NULL;
}
- if (alloctype == CD_DUPLICATE) {
+ if (alloctype == CD_DUPLICATE && layerdata) {
if(typeInfo->copy)
typeInfo->copy(layerdata, newlayerdata, totelem);
else
@@ -1284,6 +1577,7 @@ static CustomDataLayer *customData_add_layer__internal(CustomData *data,
data->layers[index].type = type;
data->layers[index].flag = flag;
data->layers[index].data = newlayerdata;
+
if(name || (name=typeInfo->defaultname)) {
BLI_strncpy(data->layers[index].name, name, 32);
CustomData_set_layer_unique_name(data, index);
@@ -1316,6 +1610,7 @@ void *CustomData_add_layer(CustomData *data, int type, int alloctype,
layer = customData_add_layer__internal(data, type, alloctype, layerdata,
totelem, typeInfo->defaultname);
+ CustomData_update_typemap(data);
if(layer)
return layer->data;
@@ -1331,6 +1626,7 @@ void *CustomData_add_layer_named(CustomData *data, int type, int alloctype,
layer = customData_add_layer__internal(data, type, alloctype, layerdata,
totelem, name);
+ CustomData_update_typemap(data);
if(layer)
return layer->data;
@@ -1369,6 +1665,7 @@ int CustomData_free_layer(CustomData *data, int type, int totelem, int index)
customData_resize(data, -CUSTOMDATA_GROW);
customData_update_offsets(data);
+ CustomData_update_typemap(data);
return 1;
}
@@ -1469,7 +1766,7 @@ void CustomData_free_temporary(CustomData *data, int totelem)
}
void CustomData_set_only_copy(const struct CustomData *data,
- CustomDataMask mask)
+ CustomDataMask mask)
{
int i;
@@ -1478,6 +1775,16 @@ void CustomData_set_only_copy(const struct CustomData *data,
data->layers[i].flag |= CD_FLAG_NOCOPY;
}
+void CustomData_copy_elements(int type, void *source, void *dest, int count)
+{
+ const LayerTypeInfo *typeInfo = layerType_getInfo(type);
+
+ if (typeInfo->copy)
+ typeInfo->copy(source, dest, count);
+ else
+ memcpy(dest, source, typeInfo->size*count);
+}
+
void CustomData_copy_data(const CustomData *source, CustomData *dest,
int source_index, int dest_index, int count)
{
@@ -1509,7 +1816,12 @@ void CustomData_copy_data(const CustomData *source, CustomData *dest,
src_offset = source_index * typeInfo->size;
dest_offset = dest_index * typeInfo->size;
-
+
+ if (!src_data || !dest_data) {
+ printf("eek! null data in CustomData_copy_data!\n");
+ continue;
+ }
+
if(typeInfo->copy)
typeInfo->copy(src_data + src_offset,
dest_data + dest_offset,
@@ -1637,6 +1949,19 @@ void *CustomData_get(const CustomData *data, int index, int type)
return (char *)data->layers[layer_index].data + offset;
}
+void *CustomData_get_n(const CustomData *data, int type, int index, int n)
+{
+ int layer_index;
+ int offset;
+
+ /* get the layer index of the first layer of type */
+ layer_index = data->typemap[type];
+ if(layer_index < 0) return NULL;
+
+ offset = layerType_getInfo(type)->size * index;
+ return (char *)data->layers[layer_index+n].data + offset;
+}
+
void *CustomData_get_layer(const CustomData *data, int type)
{
/* get the layer index of the active layer of type */
@@ -1664,6 +1989,20 @@ void *CustomData_get_layer_named(const struct CustomData *data, int type,
return data->layers[layer_index].data;
}
+
+int CustomData_set_layer_name(const CustomData *data, int type, int n, const char *name)
+{
+ /* get the layer index of the first layer of type */
+ int layer_index = CustomData_get_layer_index_n(data, type, n);
+
+ if(layer_index < 0) return 0;
+ if (!name) return 0;
+
+ strcpy(data->layers[layer_index].name, name);
+
+ return 1;
+}
+
void *CustomData_set_layer(const CustomData *data, int type, void *ptr)
{
/* get the layer index of the first layer of type */
@@ -1983,33 +2322,97 @@ void CustomData_from_em_block(const CustomData *source, CustomData *dest,
/*Bmesh functions*/
/*needed to convert to/from different face reps*/
-void CustomData_to_bmeshpoly(CustomData *fdata, CustomData *pdata, CustomData *ldata)
+void CustomData_to_bmeshpoly(CustomData *fdata, CustomData *pdata, CustomData *ldata,
+ int totloop, int totpoly)
{
int i;
for(i=0; i < fdata->totlayer; i++){
if(fdata->layers[i].type == CD_MTFACE){
- CustomData_add_layer(pdata, CD_MTEXPOLY, CD_CALLOC, &(fdata->layers[i].name), 0);
- CustomData_add_layer(ldata, CD_MLOOPUV, CD_CALLOC, &(fdata->layers[i].name), 0);
+ CustomData_add_layer_named(pdata, CD_MTEXPOLY, CD_CALLOC, NULL, totpoly, fdata->layers[i].name);
+ CustomData_add_layer_named(ldata, CD_MLOOPUV, CD_CALLOC, NULL, totloop, fdata->layers[i].name);
}
else if(fdata->layers[i].type == CD_MCOL)
- CustomData_add_layer(ldata, CD_MLOOPCOL, CD_CALLOC, &(fdata->layers[i].name), 0);
- }
+ CustomData_add_layer_named(ldata, CD_MLOOPCOL, CD_CALLOC, NULL, totloop, fdata->layers[i].name);
+ else if(fdata->layers[i].type == CD_MDISPS)
+ CustomData_add_layer_named(ldata, CD_MDISPS, CD_CALLOC, NULL, totloop, fdata->layers[i].name);
+ }
}
-void CustomData_from_bmeshpoly(CustomData *fdata, CustomData *pdata, CustomData *ldata, int total){
+void CustomData_from_bmeshpoly(CustomData *fdata, CustomData *pdata, CustomData *ldata, int total)
+{
int i;
for(i=0; i < pdata->totlayer; i++){
if(pdata->layers[i].type == CD_MTEXPOLY)
- CustomData_add_layer(fdata, CD_MTFACE, CD_CALLOC, &(pdata->layers[i].name), total);
+ CustomData_add_layer_named(fdata, CD_MTFACE, CD_CALLOC, NULL, total, pdata->layers[i].name);
}
for(i=0; i < ldata->totlayer; i++){
if(ldata->layers[i].type == CD_MLOOPCOL)
- CustomData_add_layer(fdata, CD_MCOL, CD_CALLOC, &(ldata->layers[i].name), total);
+ CustomData_add_layer_named(fdata, CD_MCOL, CD_CALLOC, NULL, total, ldata->layers[i].name);
+ if (ldata->layers[i].type == CD_WEIGHT_MLOOPCOL)
+ CustomData_add_layer_named(fdata, CD_WEIGHT_MCOL, CD_CALLOC, NULL, total, ldata->layers[i].name);
}
}
-void CustomData_bmesh_init_pool(CustomData *data, int allocsize){
- if(data->totlayer)data->pool = BLI_mempool_create(data->totsize, allocsize, allocsize, 0);
+void CustomData_bmesh_init_pool(CustomData *data, int allocsize)
+{
+ /* Dispose old pools before calling here to avoid leaks */
+ BLI_assert(data->pool == NULL);
+
+ /* If there are no layers, no pool is needed just yet */
+ if (data->totlayer) {
+ data->pool = BLI_mempool_create(data->totsize, allocsize, allocsize, 1, 0);
+ }
+}
+
+void CustomData_bmesh_merge(CustomData *source, CustomData *dest,
+ int mask, int alloctype, BMesh *bm, int type)
+{
+ BMHeader *h;
+ BMIter iter;
+ CustomData destold = *dest;
+ void *tmp;
+ int t;
+
+ CustomData_merge(source, dest, mask, alloctype, 0);
+ CustomData_bmesh_init_pool(dest, 512);
+
+ switch (type) {
+ case BM_VERT:
+ t = BM_VERTS_OF_MESH; break;
+ case BM_EDGE:
+ t = BM_EDGES_OF_MESH; break;
+ case BM_LOOP:
+ t = BM_LOOPS_OF_FACE; break;
+ case BM_FACE:
+ t = BM_FACES_OF_MESH; break;
+ default: /* should never happen */
+ BLI_assert(!"invalid type given");
+ t = BM_VERTS_OF_MESH;
+ }
+
+ if (t != BM_LOOPS_OF_FACE) {
+ /*ensure all current elements follow new customdata layout*/
+ BM_ITER(h, &iter, bm, t, NULL) {
+ CustomData_bmesh_copy_data(&destold, dest, h->data, &tmp);
+ CustomData_bmesh_free_block(&destold, &h->data);
+ h->data = tmp;
+ }
+ } else {
+ BMFace *f;
+ BMLoop *l;
+ BMIter liter;
+
+ /*ensure all current elements follow new customdata layout*/
+ BM_ITER(f, &iter, bm, BM_FACES_OF_MESH, NULL) {
+ BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, f) {
+ CustomData_bmesh_copy_data(&destold, dest, l->head.data, &tmp);
+ CustomData_bmesh_free_block(&destold, &l->head.data);
+ l->head.data = tmp;
+ }
+ }
+ }
+
+ if (destold.pool) BLI_mempool_destroy(destold.pool);
}
void CustomData_bmesh_free_block(CustomData *data, void **block)
@@ -2029,7 +2432,9 @@ void CustomData_bmesh_free_block(CustomData *data, void **block)
}
}
- BLI_mempool_free(data->pool, *block);
+ if (data->totsize)
+ BLI_mempool_free(data->pool, *block);
+
*block = NULL;
}
@@ -2040,7 +2445,7 @@ static void CustomData_bmesh_alloc_block(CustomData *data, void **block)
CustomData_bmesh_free_block(data, block);
if (data->totsize > 0)
- *block = BLI_mempool_calloc(data->pool);
+ *block = BLI_mempool_alloc(data->pool);
else
*block = NULL;
}
@@ -2113,6 +2518,82 @@ void *CustomData_bmesh_get_n(const CustomData *data, void *block, int type, int
return (char *)block + data->layers[layer_index+n].offset;
}
+/*gets from the layer at physical index n, note: doesn't check type.*/
+void *CustomData_bmesh_get_layer_n(const CustomData *data, void *block, int n)
+{
+ if(n < 0 || n >= data->totlayer) return NULL;
+
+ return (char *)block + data->layers[n].offset;
+}
+
+int CustomData_layer_has_math(struct CustomData *data, int layern)
+{
+ const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[layern].type);
+
+ if (typeInfo->equal && typeInfo->add && typeInfo->multiply &&
+ typeInfo->initminmax && typeInfo->dominmax) return 1;
+
+ return 0;
+}
+
+/*copies the "value" (e.g. mloopuv uv or mloopcol colors) from one block to
+ another, while not overwriting anything else (e.g. flags)*/
+void CustomData_data_copy_value(int type, void *source, void *dest)
+{
+ const LayerTypeInfo *typeInfo = layerType_getInfo(type);
+
+ if(!dest) return;
+
+ if(typeInfo->copyvalue)
+ typeInfo->copyvalue(source, dest);
+ else
+ memcpy(dest, source, typeInfo->size);
+}
+
+int CustomData_data_equals(int type, void *data1, void *data2)
+{
+ const LayerTypeInfo *typeInfo = layerType_getInfo(type);
+
+ if (typeInfo->equal)
+ return typeInfo->equal(data1, data2);
+ else return !memcmp(data1, data2, typeInfo->size);
+}
+
+void CustomData_data_initminmax(int type, void *min, void *max)
+{
+ const LayerTypeInfo *typeInfo = layerType_getInfo(type);
+
+ if (typeInfo->initminmax)
+ typeInfo->initminmax(min, max);
+}
+
+
+void CustomData_data_dominmax(int type, void *data, void *min, void *max)
+{
+ const LayerTypeInfo *typeInfo = layerType_getInfo(type);
+
+ if (typeInfo->dominmax)
+ typeInfo->dominmax(data, min, max);
+}
+
+
+void CustomData_data_multiply(int type, void *data, float fac)
+{
+ const LayerTypeInfo *typeInfo = layerType_getInfo(type);
+
+ if (typeInfo->multiply)
+ typeInfo->multiply(data, fac);
+}
+
+
+void CustomData_data_add(int type, void *data1, void *data2)
+{
+ const LayerTypeInfo *typeInfo = layerType_getInfo(type);
+
+ if (typeInfo->add)
+ typeInfo->add(data1, data2);
+}
+
void CustomData_bmesh_set(const CustomData *data, void *block, int type, void *source)
{
void *dest = CustomData_bmesh_get(data, block, type);
@@ -2139,6 +2620,19 @@ void CustomData_bmesh_set_n(CustomData *data, void *block, int type, int n, void
memcpy(dest, source, typeInfo->size);
}
+void CustomData_bmesh_set_layer_n(CustomData *data, void *block, int n, void *source)
+{
+ void *dest = CustomData_bmesh_get_layer_n(data, block, n);
+ const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[n].type);
+
+ if(!dest) return;
+
+ if(typeInfo->copy)
+ typeInfo->copy(source, dest, 1);
+ else
+ memcpy(dest, source, typeInfo->size);
+}
+
void CustomData_bmesh_interp(CustomData *data, void **src_blocks, float *weights,
float *sub_weights, int count, void *dest_block)
{
@@ -2184,6 +2678,7 @@ void CustomData_bmesh_set_default(CustomData *data, void **block)
if(typeInfo->set_default)
typeInfo->set_default((char*)*block + offset, 1);
+ else memset((char*)*block + offset, 0, typeInfo->size);
}
}