diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2006-12-21 16:47:27 +0300 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2006-12-21 16:47:27 +0300 |
commit | 47bc3d1208c48903f53728d17d3acbb1ccbd06cb (patch) | |
tree | eca808294b88940590b8dc7e9693acc20ef2048f | |
parent | edccdf934018264002c034906e8a287d12b7ead7 (diff) |
Added names to UV and vertex color layers, and display them as a list.
Added support for multiple UVs in the render engine. This also involved
changing the way faces are stored, to allow data to be added optionally
per 256 faces, same as the existing system for vertices.
A UV layer can be specified in the Map Input panel and the Geometry node
by name. Leaving this field blank will default to the active UV layer.
Also added sharing of face selection and hiding between UV layers, and at
the same time improved syncing with editmode selection and hiding.
Still to do:
- Multi UV support for fastshade.
- Multires and NMesh preservation of multiple UV sets.
39 files changed, 972 insertions, 475 deletions
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h index 3f133adc68a..b20e60c9442 100644 --- a/source/blender/blenkernel/BKE_customdata.h +++ b/source/blender/blenkernel/BKE_customdata.h @@ -166,6 +166,7 @@ void *CustomData_em_get(const struct CustomData *data, void *block, int type); void *CustomData_get_layer(const struct CustomData *data, int type); void *CustomData_get_layer_n(const struct CustomData *data, int type, int n); +int CustomData_get_layer_index(const struct CustomData *data, int type); int CustomData_get_active_layer_index(const struct CustomData *data, int type); /* copies the data from source to the data element at index in the first @@ -206,4 +207,7 @@ int CustomData_sizeof(int type); /* get the name of a layer type */ const char *CustomData_layertype_name(int type); +/* make sure the name of layer at index is unique */ +void CustomData_set_layer_unique_name(struct CustomData *data, int index); + #endif diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index 586c6db972b..2567595171c 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -34,6 +34,7 @@ #include "BKE_customdata.h" +#include "BLI_blenlib.h" #include "BLI_linklist.h" #include "DNA_customdata_types.h" @@ -52,6 +53,7 @@ typedef struct LayerTypeInfo { int size; /* the memory size of one element of this layer's data */ char *structname; /* name of the struct used, for file writing */ int structnum; /* number of structs per element, for file writing */ + char *defaultname; /* default layer name */ /* a function to copy count elements of this layer's data * (deep copy if appropriate) @@ -351,22 +353,22 @@ static void layerDefault_mcol(void *data, int count) } const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = { - {sizeof(MVert), "MVert", 1, NULL, NULL, NULL, NULL, NULL}, - {sizeof(MSticky), "MSticky", 1, NULL, NULL, layerInterp_msticky, NULL, + {sizeof(MVert), "MVert", 1, NULL, NULL, NULL, NULL, NULL, NULL}, + {sizeof(MSticky), "MSticky", 1, NULL, NULL, NULL, layerInterp_msticky, NULL, NULL}, - {sizeof(MDeformVert), "MDeformVert", 1, layerCopy_mdeformvert, + {sizeof(MDeformVert), "MDeformVert", 1, NULL, layerCopy_mdeformvert, layerFree_mdeformvert, layerInterp_mdeformvert, NULL, NULL}, - {sizeof(MEdge), "MEdge", 1, NULL, NULL, NULL, NULL, NULL}, - {sizeof(MFace), "MFace", 1, NULL, NULL, NULL, NULL, NULL}, - {sizeof(MTFace), "MTFace", 1, layerCopy_tface, NULL, + {sizeof(MEdge), "MEdge", 1, NULL, NULL, NULL, NULL, NULL, NULL}, + {sizeof(MFace), "MFace", 1, NULL, NULL, NULL, NULL, NULL, NULL}, + {sizeof(MTFace), "MTFace", 1, "UVTex", layerCopy_tface, NULL, layerInterp_tface, layerSwap_tface, layerDefault_tface}, /* 4 MCol structs per face */ - {sizeof(MCol)*4, "MCol", 4, NULL, NULL, layerInterp_mcol, + {sizeof(MCol)*4, "MCol", 4, "Col", NULL, NULL, layerInterp_mcol, layerSwap_mcol, layerDefault_mcol}, - {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL}, + {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL}, /* 3 floats per normal vector */ - {sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL}, - {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL}, + {sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL}, + {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL}, }; const char *LAYERTYPENAMES[CD_NUMTYPES] = { @@ -403,7 +405,7 @@ static const char *layerType_getName(int type) static void customData_update_offsets(CustomData *data); static CustomDataLayer *customData_add_layer__internal(CustomData *data, - int type, int alloctype, void *layerdata, int totelem); + int type, int alloctype, void *layerdata, int totelem, const char *name); void CustomData_merge(const struct CustomData *source, struct CustomData *dest, CustomDataMask mask, int alloctype, int totelem) @@ -432,10 +434,10 @@ void CustomData_merge(const struct CustomData *source, struct CustomData *dest, if((alloctype == CD_ASSIGN) && (layer->flag & CD_FLAG_NOFREE)) newlayer = customData_add_layer__internal(dest, type, CD_REFERENCE, - layer->data, totelem); + layer->data, totelem, layer->name); else newlayer = customData_add_layer__internal(dest, type, alloctype, - layer->data, totelem); + layer->data, totelem, layer->name); if(newlayer) newlayer->active = lastactive; @@ -493,7 +495,7 @@ static void customData_update_offsets(CustomData *data) data->totsize = offset; } -static int CustomData_get_layer_index(const struct CustomData *data, int type) +int CustomData_get_layer_index(const CustomData *data, int type) { int i; @@ -550,7 +552,7 @@ static int customData_resize(CustomData *data, int amount) } static CustomDataLayer *customData_add_layer__internal(CustomData *data, - int type, int alloctype, void *layerdata, int totelem) + int type, int alloctype, void *layerdata, int totelem, const char *name) { const LayerTypeInfo *typeInfo= layerType_getInfo(type); int size = typeInfo->size * totelem, flag = 0, index = data->totlayer; @@ -586,6 +588,8 @@ static CustomDataLayer *customData_add_layer__internal(CustomData *data, } } + data->totlayer++; + /* keep layers ordered by type */ for( ; index > 0 && data->layers[index - 1].type > type; --index) data->layers[index] = data->layers[index - 1]; @@ -594,13 +598,18 @@ static CustomDataLayer *customData_add_layer__internal(CustomData *data, data->layers[index].flag = flag; data->layers[index].data = newlayerdata; + if(name) { + strcpy(data->layers[index].name, name); + CustomData_set_layer_unique_name(data, index); + } + else + data->layers[index].name[0] = '\0'; + if(index > 0 && data->layers[index-1].type == type) data->layers[index].active = data->layers[index-1].active; else data->layers[index].active = 0; - data->totlayer++; - customData_update_offsets(data); return &data->layers[index]; @@ -610,9 +619,10 @@ void *CustomData_add_layer(CustomData *data, int type, int alloctype, void *layerdata, int totelem) { CustomDataLayer *layer; + const LayerTypeInfo *typeInfo= layerType_getInfo(type); layer = customData_add_layer__internal(data, type, alloctype, layerdata, - totelem); + totelem, typeInfo->defaultname); if(layer) return layer->data; @@ -1195,3 +1205,53 @@ const char *CustomData_layertype_name(int type) { return layerType_getName(type); } + +void CustomData_set_layer_unique_name(CustomData *data, int index) +{ + char tempname[64]; + int number, i, type; + char *dot, *name; + CustomDataLayer *layer, *nlayer= &data->layers[index]; + const LayerTypeInfo *typeInfo= layerType_getInfo(nlayer->type); + + if (!typeInfo->defaultname) + return; + + type = nlayer->type; + name = nlayer->name; + + if (name[0] == '\0') + BLI_strncpy(nlayer->name, typeInfo->defaultname, sizeof(nlayer->name)); + + /* see if there is a duplicate */ + for(i=0; i<data->totlayer; i++) { + layer = &data->layers[i]; + + if(i!=index && layer->type==type && strcmp(layer->name, name)==0) + break; + } + + if(i == data->totlayer) + return; + + /* strip off the suffix */ + dot = strchr(nlayer->name, '.'); + if(dot) *dot=0; + + for(number=1; number <=999; number++) { + sprintf(tempname, "%s.%03d", nlayer->name, number); + + for(i=0; i<data->totlayer; i++) { + layer = &data->layers[i]; + + if(i!=index && layer->type==type && strcmp(layer->name, tempname)==0) + break; + } + + if(i == data->totlayer) { + BLI_strncpy(nlayer->name, tempname, sizeof(nlayer->name)); + return; + } + } +} + diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index 62c8d53d15a..0e69607d1bb 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -282,7 +282,6 @@ void count_displist(ListBase *lb, int *totvert, int *totface) static ShadeInput shi; static void init_fastshade_shadeinput(void) { - memset(&shi, 0, sizeof(ShadeInput)); shi.lay= G.scene->lay; shi.view[2]= -1.0f; @@ -311,15 +310,19 @@ void fastshade_free_render(void) } } -static void fastshade(float *co, float *nor, float *orco, float *uv, Material *ma, char *col1, char *col2, char *vertcol) +static void fastshade(float *co, float *nor, float *orco, float *uv, char *uvname, Material *ma, char *col1, char *col2, char *vertcol, char *colname) { ShadeResult shr; int a; if(vertcol) { - shi.vcol[0]= ((float)vertcol[3])/255.0f; - shi.vcol[1]= ((float)vertcol[2])/255.0f; - shi.vcol[2]= ((float)vertcol[1])/255.0f; + shi.col[0].col[0]= ((float)vertcol[3])/255.0f; + shi.col[0].col[1]= ((float)vertcol[2])/255.0f; + shi.col[0].col[2]= ((float)vertcol[1])/255.0f; + shi.col[0].name= colname; + shi.totcol= 1; + + VECCOPY(shi.vcol, shi.col[0].col); } VECCOPY(shi.co, co); @@ -343,12 +346,15 @@ static void fastshade(float *co, float *nor, float *orco, float *uv, Material *m } if(ma->texco & TEXCO_UV) { if(uv) { - shi.uv[0]= 2.0f*uv[0]-1.0f; - shi.uv[1]= 2.0f*uv[1]-1.0f; + shi.uv[0].uv[0]= 2.0f*uv[0]-1.0f; + shi.uv[0].uv[1]= 2.0f*uv[1]-1.0f; + shi.uv[0].uv[2]= 1.0f; } else { - VECCOPY(shi.uv, shi.lo); + VECCOPY(shi.uv[0].uv, shi.lo); } + shi.uv[0].name = uvname; + shi.totuv= 1; } if(ma->texco & TEXCO_OBJECT) { VECCOPY(shi.co, shi.lo); @@ -449,7 +455,8 @@ static void mesh_create_shadedColors(Render *re, Object *ob, int onlyForMesh, un MTFace *mtface; unsigned int *col1, *col2; float *orco, *vnors, *nors, imat[3][3], mat[4][4], vec[3]; - int a, i, need_orco, totface, totvert; + int a, i, need_orco, totface, totvert, layerindex; + char *uvname= "", *colname= ""; CustomDataMask dataMask = CD_MASK_BAREMESH | CD_MASK_MCOL | CD_MASK_MTFACE | CD_MASK_NORMAL; @@ -470,6 +477,15 @@ static void mesh_create_shadedColors(Render *re, Object *ob, int onlyForMesh, un totvert = dm->getNumVerts(dm); totface = dm->getNumFaces(dm); + if (mcol) { + layerindex= CustomData_get_active_layer_index(&dm->faceData, CD_MCOL); + colname= dm->faceData.layers[layerindex].name; + } + if (mtface) { + layerindex= CustomData_get_active_layer_index(&dm->faceData, CD_MTFACE); + uvname= dm->faceData.layers[layerindex].name; + } + if (onlyForMesh) { col1 = *col1_r; col2 = NULL; @@ -546,7 +562,7 @@ static void mesh_create_shadedColors(Render *re, Object *ob, int onlyForMesh, un vec[0]+= 0.001*vn[0]; vec[1]+= 0.001*vn[1]; vec[2]+= 0.001*vn[2]; - fastshade(vec, vn, orco?&orco[vidx[j]*3]:mv->co, uv, ma, col1, col2, mcol); + fastshade(vec, vn, orco?&orco[vidx[j]*3]:mv->co, uv, uvname, ma, col1, col2, mcol, colname); } } MEM_freeN(vnors); @@ -566,7 +582,7 @@ void shadeMeshMCol(Object *ob, Mesh *me) Render *re= fastshade_get_render(); mesh_create_shadedColors(re, ob, 1, (unsigned int **)&me->mcol, NULL); - + /* swap bytes */ for(cp= (char *)me->mcol, a= 4*me->totface; a>0; a--, cp+=4) { SWAP(char, cp[0], cp[3]); @@ -646,7 +662,7 @@ void shadeDispList(Base *base) VECCOPY(vec, fp); Mat4MulVecfl(mat, vec); - fastshade(vec, n1, fp, NULL, ma, (char *)col1, NULL, NULL); + fastshade(vec, n1, fp, NULL, "", ma, (char *)col1, NULL, NULL, ""); fp+= 3; col1++; } @@ -667,7 +683,7 @@ void shadeDispList(Base *base) n1[2]= imat[2][0]*nor[0]+imat[2][1]*nor[1]+imat[2][2]*nor[2]; Normalise(n1); - fastshade(vec, n1, fp, NULL, ma, (char *)col1, NULL, NULL); + fastshade(vec, n1, fp, NULL, "", ma, (char *)col1, NULL, NULL, ""); fp+= 3; nor+= 3; col1++; } @@ -705,7 +721,7 @@ void shadeDispList(Base *base) n1[2]= imat[2][0]*nor[0]+imat[2][1]*nor[1]+imat[2][2]*nor[2]; Normalise(n1); - fastshade(vec, n1, fp, NULL, ma, (char *)col1, NULL, NULL); + fastshade(vec, n1, fp, NULL, "", ma, (char *)col1, NULL, NULL, ""); fp+= 3; col1++; nor+= 3; } diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index d10ff6c6d33..59dcccc1f8d 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -785,6 +785,8 @@ bNode *nodeAddNodeType(bNodeTree *ntree, int type, bNodeTree *ngroup) node->storage= curvemapping_add(3, -1.0f, -1.0f, 1.0f, 1.0f); else if(type==SH_NODE_CURVE_RGB) node->storage= curvemapping_add(4, 0.0f, 0.0f, 1.0f, 1.0f); + else if(type==SH_NODE_GEOMETRY) + node->storage= MEM_callocN(sizeof(NodeGeometry), "NodeGeometry"); } else if(ntree->type==NTREE_COMPOSIT) { if(type==CMP_NODE_VALTORGB) diff --git a/source/blender/blenkernel/intern/node_shaders.c b/source/blender/blenkernel/intern/node_shaders.c index dbdca2edcb6..f332873de49 100644 --- a/source/blender/blenkernel/intern/node_shaders.c +++ b/source/blender/blenkernel/intern/node_shaders.c @@ -188,13 +188,25 @@ static void node_shader_exec_geom(void *data, bNode *node, bNodeStack **in, bNod { if(data) { ShadeInput *shi= ((ShaderCallData *)data)->shi; + ShadeInputUV *suv= &shi->uv[0]; + NodeGeometry *ngeo= (NodeGeometry*)node->storage; + int i; + + if(ngeo->uvname[0]) { + for(i = 0; i < shi->totuv; i++) { + if(strcmp(shi->uv[i].name, ngeo->uvname)==0) { + suv= &shi->uv[i]; + break; + } + } + } /* out: global, local, view, orco, uv, normal */ VECCOPY(out[GEOM_OUT_GLOB]->vec, shi->gl); VECCOPY(out[GEOM_OUT_LOCAL]->vec, shi->co); VECCOPY(out[GEOM_OUT_VIEW]->vec, shi->view); VECCOPY(out[GEOM_OUT_ORCO]->vec, shi->lo); - VECCOPY(out[GEOM_OUT_UV]->vec, shi->uv); + VECCOPY(out[GEOM_OUT_UV]->vec, suv->uv); VECCOPY(out[GEOM_OUT_NORMAL]->vec, shi->vno); if(shi->osatex) { @@ -206,7 +218,7 @@ static void node_shader_exec_geom(void *data, bNode *node, bNodeStack **in, bNod out[GEOM_OUT_VIEW]->datatype= NS_OSA_VALUES; out[GEOM_OUT_ORCO]->data= shi->dxlo; out[GEOM_OUT_ORCO]->datatype= NS_OSA_VECTORS; - out[GEOM_OUT_UV]->data= shi->dxuv; + out[GEOM_OUT_UV]->data= suv->dxuv; out[GEOM_OUT_UV]->datatype= NS_OSA_VECTORS; out[GEOM_OUT_NORMAL]->data= shi->dxno; out[GEOM_OUT_NORMAL]->datatype= NS_OSA_VECTORS; @@ -218,11 +230,11 @@ static void node_shader_exec_geom(void *data, bNode *node, bNodeStack **in, bNod static bNodeType sh_node_geom= { /* type code */ SH_NODE_GEOMETRY, /* name */ "Geometry", - /* width+range */ 90, 40, 100, - /* class+opts */ NODE_CLASS_INPUT, 0, + /* width+range */ 120, 80, 160, + /* class+opts */ NODE_CLASS_INPUT, NODE_OPTIONS, /* input sock */ NULL, /* output sock */ sh_node_geom_out, - /* storage */ "", + /* storage */ "NodeGeometry", /* execfunc */ node_shader_exec_geom }; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 48eb6ae8e55..0330883b2f9 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -4203,10 +4203,11 @@ static void sort_shape_fix(Main *main) static void customdata_version_242(Mesh *me) { + CustomDataLayer *layer; MTFace *mtf; MCol *mcol; TFace *tf; - int a; + int a, mtfacen, mcoln; if (!me->vdata.totlayer) { CustomData_add_layer(&me->vdata, CD_MVERT, CD_ASSIGN, me->mvert, me->totvert); @@ -4256,6 +4257,25 @@ static void customdata_version_242(Mesh *me) me->tface= NULL; } + for (a=0, mtfacen=0, mcoln=0; a < me->fdata.totlayer; a++) { + layer= &me->fdata.layers[a]; + + if (layer->type == CD_MTFACE) { + if (layer->name[0] == 0) { + if (mtfacen == 0) strcpy(layer->name, "UVTex"); + else sprintf(layer->name, "UVTex.%.3d", mtfacen); + } + mtfacen++; + } + else if (layer->type == CD_MCOL) { + if (layer->name[0] == 0) { + if (mcoln == 0) strcpy(layer->name, "Col"); + else sprintf(layer->name, "Col.%.3d", mcoln); + } + mcoln++; + } + } + mesh_update_customdata_pointers(me); } diff --git a/source/blender/include/BDR_editface.h b/source/blender/include/BDR_editface.h index edb54325ff4..84c1e09d058 100644 --- a/source/blender/include/BDR_editface.h +++ b/source/blender/include/BDR_editface.h @@ -57,5 +57,8 @@ void set_texturepaint(void); void get_same_uv(void); void seam_mark_clear_tface(short mode); +void select_mface_from_tface(struct Mesh *me); +void select_tface_from_mface(struct Mesh *me); + #endif /* BDR_EDITFACE_H */ diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h index 83111f58c67..d8930f8a098 100644 --- a/source/blender/makesdna/DNA_customdata_types.h +++ b/source/blender/makesdna/DNA_customdata_types.h @@ -38,6 +38,7 @@ typedef struct CustomDataLayer { int offset; /* in editmode, offset of layer in block */ int flag; /* general purpose flag */ int active; /* number of the active layer of this type */ + char name[32]; /* layer name */ void *data; /* layer data */ } CustomDataLayer; @@ -85,4 +86,8 @@ typedef struct CustomData { /* indicates the layer is only temporary, also implies no copy */ #define CD_FLAG_TEMPORARY ((1<<2)|CD_FLAG_NOCOPY) +/* Limits */ +#define MAX_MTFACE 4 +#define MAX_MCOL 4 + #endif diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 5e899dce0f6..db7db374dcc 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -213,5 +213,9 @@ typedef struct NodeChroma { float key[4]; } NodeChroma; +typedef struct NodeGeometry { + char uvname[32]; +} NodeGeometry; + #endif diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h index eae2a07ec6e..3fbe85818c2 100644 --- a/source/blender/makesdna/DNA_texture_types.h +++ b/source/blender/makesdna/DNA_texture_types.h @@ -51,6 +51,7 @@ typedef struct MTex { short texco, mapto, maptoneg, blendtype; struct Object *object; struct Tex *tex; + char uvname[32]; char projx, projy, projz, mapping; float ofs[3], size[3]; diff --git a/source/blender/radiosity/intern/source/radrender.c b/source/blender/radiosity/intern/source/radrender.c index d75b2536c1e..d0472a834af 100644 --- a/source/blender/radiosity/intern/source/radrender.c +++ b/source/blender/radiosity/intern/source/radrender.c @@ -95,7 +95,7 @@ static VlakRen *findshoot_rr(Render *re) maxenergy= 0.0; for(a=0; a<re->totvlak; a++) { - if((a & 255)==0) vlr= re->blovl[a>>8]; else vlr++; + if((a & 255)==0) vlr= re->vlaknodes[a>>8].vlak; else vlr++; if(vlr->radface) { rf= vlr->radface; rf->flag &= ~RAD_SHOOT; @@ -129,7 +129,7 @@ static void backface_test_rr(Render *re, VlakRen *shoot) /* backface testing */ for(a=0; a<re->totvlak; a++) { - if((a & 255)==0) vlr= re->blovl[a>>8]; else vlr++; + if((a & 255)==0) vlr= re->vlaknodes[a>>8].vlak; else vlr++; if(vlr->radface) { if(vlr!=shoot) { rf= vlr->radface; @@ -151,7 +151,7 @@ static void clear_backface_test_rr(Render *re) /* backface flag clear */ for(a=0; a<re->totvlak; a++) { - if((a & 255)==0) vlr= re->blovl[a>>8]; else vlr++; + if((a & 255)==0) vlr= re->vlaknodes[a>>8].vlak; else vlr++; if(vlr->radface) { rf= vlr->radface; @@ -208,7 +208,7 @@ static void makeformfactors_rr(Render *re, VlakRen *shoot) fp= RG.formfactors; for(a=0; a<re->totvlak; a++) { - if((a & 255)==0) vlr= re->blovl[a>>8]; else vlr++; + if((a & 255)==0) vlr= re->vlaknodes[a>>8].vlak; else vlr++; if(vlr->radface) { rf= vlr->radface; @@ -236,7 +236,7 @@ static void applyformfactors_rr(Render *re, VlakRen *shoot) fp= RG.formfactors; for(a=0; a<re->totvlak; a++) { - if((a & 255)==0) vlr= re->blovl[a>>8]; else vlr++; + if((a & 255)==0) vlr= re->vlaknodes[a>>8].vlak; else vlr++; if(vlr->radface) { rf= vlr->radface; @@ -327,7 +327,7 @@ static void initradfaces(Render *re) /* count first for fast malloc */ for(a=0; a<re->totvlak; a++) { - if((a & 255)==0) vlr= re->blovl[a>>8]; else vlr++; + if((a & 255)==0) vlr= re->vlaknodes[a>>8].vlak; else vlr++; if(vlr->mat->mode & MA_RADIO) { if(vlr->mat->emit > 0.0) { @@ -343,7 +343,7 @@ printf(" Rad elems: %d emittors %d\n", RG.totelem, RG.totpatch); /* make/init radfaces */ rf=radfaces= MEM_callocN(RG.totelem*sizeof(RadFace), "radfaces"); for(a=0; a<re->totvlak; a++) { - if((a & 255)==0) vlr= re->blovl[a>>8]; else vlr++; + if((a & 255)==0) vlr= re->vlaknodes[a>>8].vlak; else vlr++; if(vlr->mat->mode & MA_RADIO) { @@ -419,7 +419,7 @@ static void make_vertex_rad_values(Render *re) /* accumulate vertexcolors */ for(a=0; a<re->totvlak; a++) { - if((a & 255)==0) vlr= re->blovl[a>>8]; else vlr++; + if((a & 255)==0) vlr= re->vlaknodes[a>>8].vlak; else vlr++; if(vlr->radface) { rf= vlr->radface; diff --git a/source/blender/render/extern/include/RE_shader_ext.h b/source/blender/render/extern/include/RE_shader_ext.h index 398e85a60e2..81660d23656 100644 --- a/source/blender/render/extern/include/RE_shader_ext.h +++ b/source/blender/render/extern/include/RE_shader_ext.h @@ -74,6 +74,16 @@ struct ShadeInputCopy { int mode; /* base material mode (OR-ed result of entire node tree) */ }; +typedef struct ShadeInputUV { + float dxuv[3], dyuv[3], uv[3]; + char *name; +} ShadeInputUV; + +typedef struct ShadeInputCol { + float col[3]; + char *name; +} ShadeInputCol; + /* localized renderloop data */ typedef struct ShadeInput { @@ -112,13 +122,17 @@ typedef struct ShadeInput float layerfac; /* texture coordinates */ - float lo[3], gl[3], uv[3], ref[3], orn[3], winco[3], sticky[3], vcol[3], rad[3]; + float lo[3], gl[3], ref[3], orn[3], winco[3], sticky[3], vcol[3], rad[3]; float refcol[4], displace[3]; float strand, tang[3], stress, winspeed[4]; + + ShadeInputUV uv[4]; /* 4 = MAX_MTFACE */ + ShadeInputCol col[4]; /* 4 = MAX_MCOL */ + int totuv, totcol; /* dx/dy OSA coordinates */ float dxco[3], dyco[3]; - float dxlo[3], dylo[3], dxgl[3], dygl[3], dxuv[3], dyuv[3]; + float dxlo[3], dylo[3], dxgl[3], dygl[3]; float dxref[3], dyref[3], dxorn[3], dyorn[3]; float dxno[3], dyno[3], dxview, dyview; float dxlv[3], dylv[3]; diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h index 4a3b0324143..609c391d599 100644 --- a/source/blender/render/intern/include/render_types.h +++ b/source/blender/render/intern/include/render_types.h @@ -45,6 +45,7 @@ struct Object; struct MemArena; struct VertTableNode; +struct VlakTableNode; struct Octree; struct GHash; @@ -158,16 +159,18 @@ struct Render int vertnodeslen; struct VertTableNode *vertnodes; + int vlaknodeslen; + struct VlakTableNode *vlaknodes; int blohalen; struct HaloRen **bloha; - int blovllen; - struct VlakRen **blovl; ListBase objecttable; - + struct Image *backbuf, *bakebuf; struct GHash *orco_hash; + ListBase customdata_names; + /* arena for allocating data for use during render, for * example dynamic TFaces to go in the VlakRen structure. */ @@ -259,12 +262,11 @@ typedef struct VlakRen { unsigned int lay; float n[3]; struct Material *mat; - struct MTFace *tface; - unsigned int *vcol; char snproj, puno; char flag, ec; RadFace *radface; Object *ob; + int index; } VlakRen; typedef struct HaloRen diff --git a/source/blender/render/intern/include/renderdatabase.h b/source/blender/render/intern/include/renderdatabase.h index 6f52a13f6e6..75aea05fee2 100644 --- a/source/blender/render/intern/include/renderdatabase.h +++ b/source/blender/render/intern/include/renderdatabase.h @@ -36,6 +36,9 @@ struct VertRen; struct HaloRen; struct Material; struct Render; +struct MCol; +struct MTFace; +struct CustomData; #define RE_QUAD_MASK 0x7FFFFFF #define RE_QUAD_OFFS 0x8000000 @@ -51,9 +54,25 @@ typedef struct VertTableNode { float *winspeed; } VertTableNode; +typedef struct VlakTableNode { + struct VlakRen *vlak; + struct MTFace **mtface; + struct MCol **mcol; + int totmtface, totmcol; + struct CustomDataNames **names; +} VlakTableNode; + +typedef struct CustomDataNames{ + struct CustomDataNames *next, *prev; + + char (*mtface)[32]; + char (*mcol)[32]; +} CustomDataNames; + /* renderdatabase.c */ void free_renderdata_tables(struct Render *re); void free_renderdata_vertnodes(struct VertTableNode *vertnodes); +void free_renderdata_vlaknodes(struct VlakTableNode *vlaknodes); void set_normalflags(Render *re); void project_renderdata(struct Render *re, void (*projectfunc)(float *, float mat[][4], float *), int do_pano, float xoffs); @@ -74,7 +93,13 @@ float *RE_vertren_get_strand(struct Render *re, struct VertRen *ver, int verify) float *RE_vertren_get_tangent(struct Render *re, struct VertRen *ver, int verify); float *RE_vertren_get_winspeed(struct Render *re, struct VertRen *ver, int verify); -VertRen *RE_vertren_copy(struct Render *re, struct VertRen *ver); +struct MTFace *RE_vlakren_get_tface(struct Render *re, VlakRen *ren, int n, char **name, int verify); +struct MCol *RE_vlakren_get_mcol(struct Render *re, VlakRen *ren, int n, char **name, int verify); + +struct VertRen *RE_vertren_copy(struct Render *re, struct VertRen *ver); +struct VlakRen *RE_vlakren_copy(struct Render *re, struct VlakRen *vlr); + +void RE_vlakren_set_customdata_names(struct Render *re, struct CustomData *data); /* haloren->type: flags */ #define HA_ONLYSKY 1 diff --git a/source/blender/render/intern/include/shading.h b/source/blender/render/intern/include/shading.h index 6c8f20673ed..902899bce94 100644 --- a/source/blender/render/intern/include/shading.h +++ b/source/blender/render/intern/include/shading.h @@ -32,14 +32,15 @@ struct LampRen; /* shadeinput.c */ +#define RE_MAX_OSA 16 /* needed to calculate shadow and AO for an entire pixel */ typedef struct ShadeSample { int tot; /* amount of shi in use, can be 1 for not FULL_OSA */ /* could be malloced once */ - ShadeInput shi[16]; /* RE_MAX_OSA */ - ShadeResult shr[16]; /* RE_MAX_OSA */ + ShadeInput shi[RE_MAX_OSA]; + ShadeResult shr[RE_MAX_OSA]; int samplenr; /* counter, detect shadow-reuse for shaders */ } ShadeSample; diff --git a/source/blender/render/intern/include/texture.h b/source/blender/render/intern/include/texture.h index 6c7d12c4c8c..9175145869c 100644 --- a/source/blender/render/intern/include/texture.h +++ b/source/blender/render/intern/include/texture.h @@ -62,7 +62,7 @@ void do_lamp_tex(LampRen *la, float *lavec, struct ShadeInput *shi, float *colf) void init_render_textures(Render *re); -void render_realtime_texture(struct ShadeInput *shi); +void render_realtime_texture(struct ShadeInput *shi, struct Image *ima); /* imagetexture.h */ diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 650eba5fef0..6b431fbecff 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -434,7 +434,7 @@ static void calc_edge_stress(Render *re, Mesh *me, int startvert, int startvlak) /* gets tangent from tface or orco */ static void calc_tangent_vector(Render *re, VlakRen *vlr) { - MTFace *tface= vlr->tface; + MTFace *tface= RE_vlakren_get_tface(re, vlr, 0, NULL, 0); VertRen *v1=vlr->v1, *v2=vlr->v2, *v3=vlr->v3, *v4=vlr->v4; float tang[3], tangv[3], ct[3], e1[3], e2[3], *tav; float *uv1, *uv2, *uv3, *uv4; @@ -1627,37 +1627,33 @@ static void init_render_mball(Render *re, Object *ob) /* ------------------------------------------------------------------------- */ /* convert */ +static int vlakren_customdata_layer_num(int n, int active) +{ + /* make the active layer the first */ + if (n == active) return 0; + else if (n < active) return n+1; + else return n; +} + struct edgesort { int v1, v2; - int has_mcol; - MTFace *tface; - float uv1[2], uv2[2]; - unsigned int mcol1, mcol2; + int f; + int i1, i2; }; /* edges have to be added with lowest index first for sorting */ -static void to_edgesort(struct edgesort *ed, int i1, int i2, int v1, int v2, unsigned int *mcol, MTFace *tface) +static void to_edgesort(struct edgesort *ed, int i1, int i2, int v1, int v2, int f) { - if(v1<v2) { - ed->v1= v1; ed->v2= v2; - } - else { - ed->v1= v2; ed->v2= v1; + if(v1>v2) { + SWAP(int, v1, v2); SWAP(int, i1, i2); } - /* copy color and tface, edges use different ordering */ - ed->tface= tface; - if(tface) { - ed->uv1[0]= tface->uv[i1][0]; - ed->uv1[1]= tface->uv[i1][1]; - ed->uv2[0]= tface->uv[i2][0]; - ed->uv2[1]= tface->uv[i2][1]; - } - ed->has_mcol= mcol!=NULL; - if(mcol) { - ed->mcol1= mcol[i1]; - ed->mcol2= mcol[i2]; - } + + ed->v1= v1; + ed->v2= v2; + ed->i1= i1; + ed->i2= i2; + ed->f = f; } static int vergedgesort(const void *v1, const void *v2) @@ -1687,72 +1683,83 @@ static struct edgesort *make_mesh_edge_lookup(DerivedMesh *dm, int *totedgesort) if(mcol==NULL && tface==NULL) return NULL; - /* make sorted table with edges and and tface/mcol pointers in it */ + /* make sorted table with edges and face indices in it */ for(a= totface, mf= mface; a>0; a--, mf++) { if(mf->v4) totedge+=4; else if(mf->v3) totedge+=3; } - if(totedge==0) return NULL; + + if(totedge==0) + return NULL; ed= edsort= MEM_callocN(totedge*sizeof(struct edgesort), "edgesort"); - for(a= totface, mf= mface; a>0; a--, mf++) { - if(mface->v4 || mface->v3) { - to_edgesort(ed++, 0, 1, mf->v1, mf->v2, mcol, tface); - to_edgesort(ed++, 1, 2, mf->v2, mf->v3, mcol, tface); - if(mf->v4) { - to_edgesort(ed++, 2, 3, mf->v3, mf->v4, mcol, tface); - to_edgesort(ed++, 3, 0, mf->v4, mf->v1, mcol, tface); - } - else if(mf->v3) { - to_edgesort(ed++, 2, 3, mf->v3, mf->v1, mcol, tface); - } + for(a=0, mf=mface; a<totface; a++, mf++) { + to_edgesort(ed++, 0, 1, mf->v1, mf->v2, a); + to_edgesort(ed++, 1, 2, mf->v2, mf->v3, a); + if(mf->v4) { + to_edgesort(ed++, 2, 3, mf->v3, mf->v4, a); + to_edgesort(ed++, 3, 0, mf->v4, mf->v1, a); } - if(mcol) mcol+=4; - if(tface) tface++; + else if(mf->v3) + to_edgesort(ed++, 2, 3, mf->v3, mf->v1, a); } qsort(edsort, totedge, sizeof(struct edgesort), vergedgesort); *totedgesort= totedge; + return edsort; } -static void use_mesh_edge_lookup(Render *re, MEdge *medge, VlakRen *vlr, struct edgesort *edgetable, int totedge) +static void use_mesh_edge_lookup(Render *re, DerivedMesh *dm, MEdge *medge, VlakRen *vlr, struct edgesort *edgetable, int totedge) { struct edgesort ed, *edp; + CustomDataLayer *layer; + MTFace *mtface, *mtf; + MCol *mcol, *mc; + int index, mtfn, mcn, n; + char *name; if(medge->v1 < medge->v2) { - ed.v1= medge->v1; ed.v2= medge->v2; + ed.v1= medge->v1; + ed.v2= medge->v2; } else { - ed.v1= medge->v2; ed.v2= medge->v1; + ed.v1= medge->v2; + ed.v2= medge->v1; } edp= bsearch(&ed, edgetable, totedge, sizeof(struct edgesort), vergedgesort); + + /* since edges have different index ordering, we have to duplicate mcol and tface */ if(edp) { - /* since edges have different index ordering, we have to duplicate mcol and tface */ - if(edp->tface) { - vlr->tface= BLI_memarena_alloc(re->memArena, sizeof(MTFace)); - memcpy(vlr->tface, edp->tface, sizeof(MTFace)); - - if(edp->v1==medge->v1) { - memcpy(vlr->tface->uv[0], edp->uv1, 2*sizeof(float)); - memcpy(vlr->tface->uv[1], edp->uv2, 2*sizeof(float)); + mtfn= mcn= 0; + + for(index=0; index<dm->faceData.totlayer; index++) { + layer= &dm->faceData.layers[index]; + name= layer->name; + + if(layer->type == CD_MTFACE && mtfn < MAX_MTFACE) { + mtface= &((MTFace*)layer->data)[edp->f]; + n= vlakren_customdata_layer_num(mtfn++, layer->active); + mtf= RE_vlakren_get_tface(re, vlr, n, &name, 1); + + *mtf= *mtface; + + memcpy(mtf->uv[0], mtface->uv[edp->i1], sizeof(float)*2); + memcpy(mtf->uv[1], mtface->uv[edp->i2], sizeof(float)*2); + memcpy(mtf->uv[2], mtface->uv[1], sizeof(float)*2); + memcpy(mtf->uv[3], mtface->uv[1], sizeof(float)*2); } - else { - memcpy(vlr->tface->uv[0], edp->uv2, 2*sizeof(float)); - memcpy(vlr->tface->uv[1], edp->uv1, 2*sizeof(float)); + else if(layer->type == CD_MCOL && mcn < MAX_MCOL) { + mcol= &((MCol*)layer->data)[edp->f*4]; + n= vlakren_customdata_layer_num(mcn++, layer->active); + mc= RE_vlakren_get_mcol(re, vlr, n, &name, 1); + + mc[0]= mcol[edp->i1]; + mc[1]= mc[2]= mc[3]= mcol[edp->i2]; } - memcpy(vlr->tface->uv[2], vlr->tface->uv[1], 2*sizeof(float)); - memcpy(vlr->tface->uv[3], vlr->tface->uv[1], 2*sizeof(float)); - } - if(edp->has_mcol) { - vlr->vcol= BLI_memarena_alloc(re->memArena, sizeof(MCol)*4); - vlr->vcol[0]= edp->mcol1; - vlr->vcol[1]= edp->mcol2; - vlr->vcol[2]= vlr->vcol[1]; - vlr->vcol[3]= vlr->vcol[1]; } } } @@ -1768,7 +1775,6 @@ static void init_render_mesh(Render *re, Object *ob, Object *par, int only_verts MSticky *ms = NULL; PartEff *paf; DerivedMesh *dm; - unsigned int *vertcol; float xn, yn, zn, imat[3][3], mat[4][4]; //nor[3], float *orco=0; int a, a1, ok, need_orco=0, need_stress=0, need_tangent=0, totvlako, totverto, vertofs; @@ -1899,6 +1905,8 @@ static void init_render_mesh(Render *re, Object *ob, Object *par, int only_verts } if(!only_verts) { + /* store customdata names, because DerivedMesh is freed */ + RE_vlakren_set_customdata_names(re, &dm->faceData); /* still to do for keys: the correct local texture coordinate */ @@ -1927,14 +1935,10 @@ static void init_render_mesh(Render *re, Object *ob, Object *par, int only_verts } if(ok) { - MTFace *tface= NULL; - end= dm->getNumFaces(dm); mface= dm->getFaceArray(dm); - tface= dm->getFaceDataArray(dm, CD_MTFACE); - vertcol= dm->getFaceDataArray(dm, CD_MCOL); - for(a=0; a<end; a++) { + for(a=0; a<end; a++, mface++) { int v1, v2, v3, v4, flag; if( mface->mat_nr==a1 ) { @@ -1981,19 +1985,31 @@ static void init_render_mesh(Render *re, Object *ob, Object *par, int only_verts if(len==0) re->totvlak--; else { - if(tface) { - vlr->tface= BLI_memarena_alloc(re->memArena, sizeof(MTFace)); - memcpy(vlr->tface, tface, sizeof(MTFace)); - } - if (vertcol) { - vlr->vcol= BLI_memarena_alloc(re->memArena, sizeof(int)*4); - memcpy(vlr->vcol, vertcol+4*a, sizeof(int)*4); + CustomDataLayer *layer; + MTFace *mtface, *mtf; + MCol *mcol, *mc; + int index, mtfn= 0, mcn= 0, n; + char *name; + + for(index=0; index<dm->faceData.totlayer; index++) { + layer= &dm->faceData.layers[index]; + name= layer->name; + + if(layer->type == CD_MTFACE && mtfn < MAX_MTFACE) { + n= vlakren_customdata_layer_num(mtfn++, layer->active); + mtf= RE_vlakren_get_tface(re, vlr, n, &name, 1); + mtface= (MTFace*)layer->data; + *mtf= mtface[a]; + } + else if(layer->type == CD_MCOL && mcn < MAX_MCOL) { + n= vlakren_customdata_layer_num(mcn++, layer->active); + mc= RE_vlakren_get_mcol(re, vlr, n, &name, 1); + mcol= (MCol*)layer->data; + memcpy(mc, &mcol[a*4], sizeof(MCol)*4); + } } } } - - mface++; - if(tface) tface++; } } } @@ -2025,7 +2041,7 @@ static void init_render_mesh(Render *re, Object *ob, Object *par, int only_verts vlr->v4= NULL; if(edgetable) { - use_mesh_edge_lookup(re, medge, vlr, edgetable, totedge); + use_mesh_edge_lookup(re, dm, medge, vlr, edgetable, totedge); } xn= -(v0->no[0]+v1->no[0]); @@ -2935,11 +2951,6 @@ void RE_Database_Free(Render *re) /* FREE */ - if(re->memArena) { - BLI_memarena_free(re->memArena); - re->memArena = NULL; - } - for(lar= re->lampren.first; lar; lar= lar->next) { freeshadowbuf(lar); if(lar->jitter) MEM_freeN(lar->jitter); @@ -2991,6 +3002,10 @@ void RE_Database_Free(Render *re) if((re->r.scemode & R_PREVIEWBUTS)==0) BKE_image_free_all_textures(); + if(re->memArena) { + BLI_memarena_free(re->memArena); + re->memArena = NULL; + } } /* per face check if all samples should be taken. @@ -3081,8 +3096,7 @@ static void check_non_flat_quads(Render *re) if(ABS(xn) < 0.999995 ) { // checked on noisy fractal grid float d1, d2; - vlr1= RE_findOrAddVlak(re, re->totvlak++); - *vlr1= *vlr; + vlr1= RE_vlakren_copy(re, vlr); vlr1->flag |= R_FACE_SPLIT; /* split direction based on vnorms */ @@ -3117,10 +3131,6 @@ static void check_non_flat_quads(Render *re) /* new normals */ CalcNormFloat(vlr->v3->co, vlr->v2->co, vlr->v1->co, vlr->n); CalcNormFloat(vlr1->v3->co, vlr1->v2->co, vlr1->v1->co, vlr1->n); - - /* so later UV can be pulled from original tface, look for R_DIVIDE_24 for direction */ - vlr1->tface=vlr->tface; - } /* clear the flag when not divided */ else vlr->flag &= ~R_DIVIDE_24; @@ -3914,7 +3924,7 @@ void RE_Database_Baking(Render *re, Scene *scene, int type) unsigned int lay; re->scene= scene; - + /* renderdata setup and exceptions */ re->r= scene->r; re->r.mode &= ~R_OSA; @@ -4110,15 +4120,34 @@ static short test_for_displace(Render *re, Object *ob) return 0; } -static void displace_render_vert(Render *re, ShadeInput *shi, VertRen *vr, float *scale) +static void displace_render_vert(Render *re, ShadeInput *shi, VertRen *vr, int vindex, float *scale) { + MTFace *tface; short texco= shi->mat->texco; float sample=0; + char *name; + int i; + /* shi->co is current render coord, just make sure at least some vector is here */ VECCOPY(shi->co, vr->co); /* vertex normal is used for textures type 'col' and 'var' */ VECCOPY(shi->vn, vr->n); - + + if (texco & TEXCO_UV) { + shi->totuv= 0; + + for (i=0; (tface=RE_vlakren_get_tface(re, shi->vlr, i, &name, 0)); i++) { + ShadeInputUV *suv= &shi->uv[i]; + + /* shi.uv needs scale correction from tface uv */ + suv->uv[0]= 2*tface->uv[vindex][0]-1.0f; + suv->uv[1]= 2*tface->uv[vindex][1]-1.0f; + suv->uv[2]= 0.0f; + suv->name= name; + shi->totuv++; + } + } + /* set all rendercoords, 'texco' is an ORed value for all textures needed */ if ((texco & TEXCO_ORCO) && (vr->orco)) { VECCOPY(shi->lo, vr->orco); @@ -4173,55 +4202,26 @@ static void displace_render_vert(Render *re, ShadeInput *shi, VertRen *vr, float static void displace_render_face(Render *re, VlakRen *vlr, float *scale) { ShadeInput shi; - // VertRen vr; - // float samp1,samp2, samp3, samp4, xn; - short hasuv=0; + /* set up shadeinput struct for multitex() */ - shi.osatex= 0; /* signal not to use dx[] and dy[] texture AA vectors */ shi.vlr= vlr; /* current render face */ shi.mat= vlr->mat; /* current input material */ - - /* UV coords must come from face */ - hasuv = vlr->tface && (shi.mat->texco & TEXCO_UV); - if (hasuv) shi.uv[2]=0.0f; - /* I don't think this is used, but seting it just in case */ - /* Displace the verts, flag is set when done */ - if (! (vlr->v1->flag)){ - if (hasuv) { - shi.uv[0] = 2*vlr->tface->uv[0][0]-1.0f; /* shi.uv and tface->uv are */ - shi.uv[1]= 2*vlr->tface->uv[0][1]-1.0f; /* scalled differently */ - } - displace_render_vert(re, &shi, vlr->v1, scale); - } - - if (! (vlr->v2->flag)) { - if (hasuv) { - shi.uv[0] = 2*vlr->tface->uv[1][0]-1.0f; - shi.uv[1]= 2*vlr->tface->uv[1][1]-1.0f; - } - displace_render_vert(re, &shi, vlr->v2, scale); - } - - if (! (vlr->v3->flag)) { - if (hasuv) { - shi.uv[0] = 2*vlr->tface->uv[2][0]-1.0f; - shi.uv[1]= 2*vlr->tface->uv[2][1]-1.0f; - } - displace_render_vert(re, &shi, vlr->v3, scale); - } + if (!vlr->v1->flag) + displace_render_vert(re, &shi, vlr->v1,0, scale); + if (!vlr->v2->flag) + displace_render_vert(re, &shi, vlr->v2, 1, scale); + + if (!vlr->v3->flag) + displace_render_vert(re, &shi, vlr->v3, 2, scale); + if (vlr->v4) { - if (! (vlr->v4->flag)) { - if (hasuv) { - shi.uv[0] = 2*vlr->tface->uv[3][0]-1.0f; - shi.uv[1]= 2*vlr->tface->uv[3][1]-1.0f; - } - displace_render_vert(re, &shi, vlr->v4, scale); - } - /* We want to split the quad along the opposite verts that are */ + if (!vlr->v4->flag) + displace_render_vert(re, &shi, vlr->v4, 3, scale); + /* closest in displace value. This will help smooth edges. */ if ( fabs(vlr->v1->accum - vlr->v3->accum) > fabs(vlr->v2->accum - vlr->v4->accum)) vlr->flag |= R_DIVIDE_24; @@ -4235,7 +4235,6 @@ static void displace_render_face(Render *re, VlakRen *vlr, float *scale) else { CalcNormFloat(vlr->v3->co, vlr->v2->co, vlr->v1->co, vlr->n); } - } @@ -4261,7 +4260,7 @@ static void do_displacement(Render *re, Object *ob, int startface, int numface, vr= RE_findOrAddVert(re, i); vr->flag= 0; } - + for(i=startface; i<startface+numface; i++){ vlr=RE_findOrAddVlak(re, i); displace_render_face(re, vlr, scale); diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c index 782308a65ec..684651ca97b 100644 --- a/source/blender/render/intern/source/envmap.c +++ b/source/blender/render/intern/source/envmap.c @@ -154,8 +154,9 @@ static Render *envmap_render_copy(Render *re, EnvMap *env) envre->vertnodes= re->vertnodes; envre->blohalen= re->blohalen; envre->bloha= re->bloha; - envre->blovllen= re->blovllen; - envre->blovl= re->blovl; + envre->vlaknodeslen= re->vlaknodeslen; + envre->vlaknodes= re->vlaknodes; + envre->customdata_names= re->customdata_names; envre->oc= re->oc; return envre; @@ -173,8 +174,9 @@ static void envmap_free_render_copy(Render *envre) envre->vertnodes= NULL; envre->blohalen= 0; envre->bloha= NULL; - envre->blovllen= 0; - envre->blovl= NULL; + envre->vlaknodeslen= 0; + envre->vlaknodes= NULL; + envre->customdata_names.first= envre->customdata_names.last= NULL; envre->oc.adrbranch= NULL; envre->oc.adrnode= NULL; @@ -258,7 +260,7 @@ static void env_rotate_scene(Render *re, float mat[][4], int mode) } for(a=0; a<re->totvlak; a++) { - if((a & 255)==0) vlr= re->blovl[a>>8]; + if((a & 255)==0) vlr= re->vlaknodes[a>>8].vlak; else vlr++; xn= vlr->n[0]; @@ -321,7 +323,7 @@ static void env_layerflags(Render *re, unsigned int notlay) notlay= ~notlay; for(a=0; a<re->totvlak; a++) { - if((a & 255)==0) vlr= re->blovl[a>>8]; + if((a & 255)==0) vlr= re->vlaknodes[a>>8].vlak; else vlr++; if((vlr->lay & notlay)==0) vlr->flag &= ~R_VISIBLE; @@ -334,7 +336,7 @@ static void env_hideobject(Render *re, Object *ob) int a; for(a=0; a<re->totvlak; a++) { - if((a & 255)==0) vlr= re->blovl[a>>8]; + if((a & 255)==0) vlr= re->vlaknodes[a>>8].vlak; else vlr++; if(vlr->ob == ob) vlr->flag &= ~R_VISIBLE; } diff --git a/source/blender/render/intern/source/ray.c b/source/blender/render/intern/source/ray.c index 41fa2dbbf16..d6090cad4de 100644 --- a/source/blender/render/intern/source/ray.c +++ b/source/blender/render/intern/source/ray.c @@ -49,6 +49,7 @@ #include "render_types.h" #include "renderpipeline.h" #include "rendercore.h" +#include "renderdatabase.h" #include "pixelblending.h" #include "pixelshading.h" #include "shading.h" @@ -490,7 +491,7 @@ void makeoctree(Render *re) /* first min max octree space */ for(v=0;v<re->totvlak;v++) { - if((v & 255)==0) vlr= re->blovl[v>>8]; + if((v & 255)==0) vlr= re->vlaknodes[v>>8].vlak; else vlr++; if(vlr->mat->mode & MA_TRACEBLE) { if((vlr->mat->mode & MA_WIRE)==0) { @@ -533,7 +534,7 @@ void makeoctree(Render *re) if((v & 255)==0) { double time= PIL_check_seconds_timer(); - vlr= re->blovl[v>>8]; + vlr= re->vlaknodes[v>>8].vlak; if(re->test_break()) break; if(time-lasttime>1.0f) { diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index 0ebd778754e..e6ace571156 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -404,11 +404,11 @@ static void add_filt_passes(RenderLayer *rl, int curmask, int rectx, int offset, break; case SCE_PASS_UV: /* box filter only, gauss will screwup UV too much */ - if(shi->uv[2]!=0.0f) { + if(shi->uv[0].uv[2]!=0.0f) { float mult= (float)count_mask(curmask)/(float)R.osa; fp= rpass->rect + 3*offset; - fp[0]+= mult*(0.5f + 0.5f*shi->uv[0]); - fp[1]+= mult*(0.5f + 0.5f*shi->uv[1]); + fp[0]+= mult*(0.5f + 0.5f*shi->uv[0].uv[0]); + fp[1]+= mult*(0.5f + 0.5f*shi->uv[0].uv[1]); fp[2]+= mult; } break; @@ -481,8 +481,8 @@ static void add_passes(RenderLayer *rl, int offset, ShadeInput *shi, ShadeResult col= shr->nor; break; case SCE_PASS_UV: - uvcol[0]= 0.5f + 0.5f*shi->uv[0]; - uvcol[1]= 0.5f + 0.5f*shi->uv[1]; + uvcol[0]= 0.5f + 0.5f*shi->uv[0].uv[0]; + uvcol[1]= 0.5f + 0.5f*shi->uv[0].uv[1]; uvcol[2]= 1.0f; col= uvcol; break; @@ -1443,6 +1443,7 @@ static void do_bake_shade(void *handle, int x, int y, float u, float v) static int get_next_bake_face(BakeShade *bs) { VlakRen *vlr; + MTFace *tface; static int v= 0, vdone= 0; if(bs==NULL) { @@ -1457,8 +1458,10 @@ static int get_next_bake_face(BakeShade *bs) vlr= RE_findOrAddVlak(&R, v); if(vlr->ob->flag & SELECT) { - if(vlr->tface && vlr->tface->tpage) { - Image *ima= vlr->tface->tpage; + tface= RE_vlakren_get_tface(&R, vlr, 0, NULL, 0); + + if(tface && tface->tpage) { + Image *ima= tface->tpage; ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL); float vec[4]= {0.0f, 0.0f, 0.0f, 0.0f}; @@ -1509,7 +1512,7 @@ static int get_next_bake_face(BakeShade *bs) static void shade_tface(BakeShade *bs) { VlakRen *vlr= bs->vlr; - MTFace *tface= vlr->tface; + MTFace *tface= RE_vlakren_get_tface(&R, vlr, 0, NULL, 0); Image *ima= tface->tpage; float vec[4][2]; int a, i1, i2, i3; diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c index e5c7d8c60a4..cf4e2a1b006 100644 --- a/source/blender/render/intern/source/renderdatabase.c +++ b/source/blender/render/intern/source/renderdatabase.c @@ -28,7 +28,7 @@ /* * Storage, retrieval and query of render specific data. * - * All data from a Blender scene is converter by the renderconverter/ + * All data from a Blender scene is converted by the renderconverter/ * into a special format that is used by the render module to make * images out of. These functions interface to the render-specific * database. @@ -40,7 +40,7 @@ * offset in a 256-entry block. * * - If the 256-entry block entry has an entry in the - * vertnodes/bloha/blovl array of the current block, the i-th entry in + * vertnodes/vlaknodes/bloha array of the current block, the i-th entry in * that block is allocated to this entry. * * - If the entry has no block allocated for it yet, memory is @@ -62,12 +62,14 @@ #include "BLI_arithb.h" #include "BLI_blenlib.h" +#include "BLI_memarena.h" #include "DNA_material_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_texture_types.h" +#include "BKE_customdata.h" #include "BKE_texture.h" #include "RE_render_ext.h" /* externtex */ @@ -80,10 +82,11 @@ /* ------------------------------------------------------------------------- */ -/* More dynamic allocation of options for render vertices, so we dont +/* More dynamic allocation of options for render vertices and faces, so we dont have to reserve this space inside vertices. - Important; vertices should have been created already (to get tables checked) - that's a reason why the calls demand VertRen * as arg, not the index */ + Important; vertices and faces, should have been created already (to get tables + checked) that's a reason why the calls demand VertRen/VlakRen * as arg, not + the index */ /* NOTE! the hardcoded table size 256 is used still in code for going quickly over vertices/faces */ @@ -94,6 +97,8 @@ #define RE_TANGENT_ELEMS 3 #define RE_STRESS_ELEMS 1 #define RE_WINSPEED_ELEMS 4 +#define RE_MTFACE_ELEMS 1 +#define RE_MCOL_ELEMS 4 float *RE_vertren_get_sticky(Render *re, VertRen *ver, int verify) { @@ -268,6 +273,207 @@ VertRen *RE_findOrAddVert(Render *re, int nr) return v; } +/* ------------------------------------------------------------------------ */ + +MTFace *RE_vlakren_get_tface(Render *re, VlakRen *vlr, int n, char **name, int verify) +{ + VlakTableNode *node; + int nr= vlr->index>>8, vlakindex= (vlr->index&255); + int index= (n<<8) + vlakindex; + + node= &re->vlaknodes[nr]; + + if(verify) { + if(n>=node->totmtface) { + MTFace **mtface= node->mtface; + int size= size= (n+1)*256; + + node->mtface= MEM_callocN(size*sizeof(MTFace*), "Vlak mtface"); + + if(mtface) { + size= node->totmtface*256; + memcpy(node->mtface, mtface, size*sizeof(MTFace*)); + MEM_freeN(mtface); + } + + node->totmtface= n+1; + + if (!node->names) { + size= sizeof(*node->names)*256; + node->names= MEM_callocN(size, "Vlak names"); + } + } + + if(node->mtface[index]==NULL) { + node->mtface[index]= BLI_memarena_alloc(re->memArena, + sizeof(MTFace)*RE_MTFACE_ELEMS); + + node->names[vlakindex]= re->customdata_names.last; + } + } + else { + if(n>=node->totmtface || node->mtface[index]==NULL) + return NULL; + + if(name) *name= node->names[vlakindex]->mtface[n]; + } + + return node->mtface[index]; +} + +MCol *RE_vlakren_get_mcol(Render *re, VlakRen *vlr, int n, char **name, int verify) +{ + VlakTableNode *node; + int nr= vlr->index>>8, vlakindex= (vlr->index&255); + int index= (n<<8) + vlakindex; + + node= &re->vlaknodes[nr]; + + if(verify) { + if(n>=node->totmcol) { + MCol **mcol= node->mcol; + int size= (n+1)*256; + + node->mcol= MEM_callocN(size*sizeof(MCol*), "Vlak mcol"); + + if(mcol) { + size= node->totmcol*256; + memcpy(node->mcol, mcol, size*sizeof(MCol*)); + MEM_freeN(mcol); + } + + node->totmcol= n+1; + + if (!node->names) { + size= sizeof(*node->names)*256; + node->names= MEM_callocN(size, "Vlak names"); + } + } + + if(node->mcol[index]==NULL) { + node->mcol[index]= BLI_memarena_alloc(re->memArena, + sizeof(MCol)*RE_MCOL_ELEMS); + + node->names[vlakindex]= re->customdata_names.last; + } + } + else { + if(n>=node->totmcol || node->mcol[index]==NULL) + return NULL; + + if(name) *name= node->names[vlakindex]->mcol[n]; + } + + return node->mcol[index]; +} + +VlakRen *RE_vlakren_copy(Render *re, VlakRen *vlr) +{ + VlakRen *vlr1 = RE_findOrAddVlak(re, re->totvlak++); + MTFace *mtface, *mtface1; + MCol *mcol, *mcol1; + int i, index = vlr1->index; + char *name; + + *vlr1= *vlr; + vlr1->index= index; + + for (i=0; (mtface=RE_vlakren_get_tface(re, vlr, i, &name, 0)) != NULL; i++) { + mtface1= RE_vlakren_get_tface(re, vlr1, i, &name, 1); + memcpy(mtface1, mtface, sizeof(MTFace)*RE_MTFACE_ELEMS); + } + + for (i=0; (mcol=RE_vlakren_get_mcol(re, vlr, i, &name, 0)) != NULL; i++) { + mcol1= RE_vlakren_get_mcol(re, vlr1, i, &name, 1); + memcpy(mcol1, mcol, sizeof(MCol)*RE_MCOL_ELEMS); + } + + return vlr1; +} + +static int vlakren_remap_layer_num(int n, int active) +{ + /* make the active layer the first */ + if (n == active) return 0; + else if (n < active) return n+1; + else return n; +} + +void RE_vlakren_set_customdata_names(Render *re, CustomData *data) +{ + /* CustomData layer names are stored per object here, because the + DerivedMesh which stores the layers is freed */ + + CustomDataNames *cdn= MEM_callocN(sizeof(*cdn), "CustomDataNames"); + CustomDataLayer *layer; + int numlayers, i, mtfn, mcn, n; + + BLI_addtail(&re->customdata_names, cdn); + + if (CustomData_has_layer(data, CD_MTFACE)) { + numlayers= CustomData_number_of_layers(data, CD_MTFACE); + cdn->mtface= MEM_callocN(sizeof(*cdn->mtface)*numlayers, "mtfacenames"); + } + + if (CustomData_has_layer(data, CD_MCOL)) { + numlayers= CustomData_number_of_layers(data, CD_MCOL); + cdn->mcol= MEM_callocN(sizeof(*cdn->mcol)*numlayers, "mcolnames"); + } + + for (i=0, mtfn=0, mcn=0; i < data->totlayer; i++) { + layer= &data->layers[i]; + + if (layer->type == CD_MTFACE) { + n= vlakren_remap_layer_num(mtfn++, layer->active); + strcpy(cdn->mtface[n], layer->name); + } + else if (layer->type == CD_MCOL) { + n= vlakren_remap_layer_num(mcn++, layer->active); + strcpy(cdn->mcol[n], layer->name); + } + } +} + +VlakRen *RE_findOrAddVlak(Render *re, int nr) +{ + VlakTableNode *temp; + VlakRen *v; + int a; + + if(nr<0) { + printf("error in findOrAddVlak: %d\n",nr); + return re->vlaknodes[0].vlak; + } + a= nr>>8; + + if (a>=re->vlaknodeslen-1){ /* Need to allocate more columns..., and keep last element NULL for free loop */ + temp= re->vlaknodes; + + re->vlaknodes= MEM_mallocN(sizeof(VlakTableNode)*(re->vlaknodeslen+TABLEINITSIZE) , "vlaknodes"); + if(temp) memcpy(re->vlaknodes, temp, re->vlaknodeslen*sizeof(VlakTableNode)); + memset(re->vlaknodes+re->vlaknodeslen, 0, TABLEINITSIZE*sizeof(VlakTableNode)); + + re->vlaknodeslen+=TABLEINITSIZE; /*Does this really need to be power of 2?*/ + if(temp) MEM_freeN(temp); + } + + v= re->vlaknodes[a].vlak; + + if(v==NULL) { + int i; + + v= (VlakRen *)MEM_callocN(256*sizeof(VlakRen),"findOrAddVlak"); + re->vlaknodes[a].vlak= v; + + for(i= (nr & 0xFFFFFF00), a=0; a<256; a++, i++) + v[a].index= i; + } + v+= (nr & 255); + return v; +} + +/* ------------------------------------------------------------------------ */ + void RE_addRenderObject(Render *re, Object *ob, Object *par, int index, int sve, int eve, int sfa, int efa) { ObjectRen *obr= MEM_mallocN(sizeof(ObjectRen), "object render struct"); @@ -306,22 +512,33 @@ void free_renderdata_vertnodes(VertTableNode *vertnodes) } MEM_freeN(vertnodes); - } -void free_renderdata_tables(Render *re) +void free_renderdata_vlaknodes(VlakTableNode *vlaknodes) { - int a=0; + int a; - if(re->blovl) { - for(a=0; re->blovl[a]; a++) - MEM_freeN(re->blovl[a]); + if(vlaknodes==NULL) return; + + for(a=0; vlaknodes[a].vlak; a++) { + MEM_freeN(vlaknodes[a].vlak); - MEM_freeN(re->blovl); - re->blovl= NULL; - re->blovllen= 0; + if(vlaknodes[a].mtface) + MEM_freeN(vlaknodes[a].mtface); + if(vlaknodes[a].mcol) + MEM_freeN(vlaknodes[a].mcol); + if(vlaknodes[a].names) + MEM_freeN(vlaknodes[a].names); } + MEM_freeN(vlaknodes); +} + +void free_renderdata_tables(Render *re) +{ + int a=0; + CustomDataNames *cdn; + if(re->bloha) { for(a=0; re->bloha[a]; a++) MEM_freeN(re->bloha[a]); @@ -336,7 +553,21 @@ void free_renderdata_tables(Render *re) re->vertnodes= NULL; re->vertnodeslen= 0; } - + + if(re->vlaknodes) { + free_renderdata_vlaknodes(re->vlaknodes); + re->vlaknodes= NULL; + re->vlaknodeslen= 0; + } + + for(cdn=re->customdata_names.first; cdn; cdn=cdn->next) { + if(cdn->mtface) + MEM_freeN(cdn->mtface); + if(cdn->mcol) + MEM_freeN(cdn->mcol); + } + + BLI_freelistN(&re->customdata_names); BLI_freelistN(&re->objecttable); } @@ -375,41 +606,6 @@ HaloRen *RE_findOrAddHalo(Render *re, int nr) return h; } -/* ------------------------------------------------------------------------ */ - -VlakRen *RE_findOrAddVlak(Render *re, int nr) -{ - VlakRen *v, **temp; - int a; - - if(nr<0) { - printf("error in findOrAddVlak: %d\n",nr); - return re->blovl[0]; - } - a= nr>>8; - - if (a>=re->blovllen-1){ /* Need to allocate more columns..., and keep last element NULL for free loop */ - // printf("Allocating %i more face groups. %i total.\n", - // TABLEINITSIZE, re->blovllen+TABLEINITSIZE ); - temp= re->blovl; - - re->blovl=(VlakRen**)MEM_callocN(sizeof(void*)*(re->blovllen+TABLEINITSIZE) , "Blovl"); - if(temp) memcpy(re->blovl, temp, re->blovllen*sizeof(void*)); - memset(&(re->blovl[re->blovllen]), 0, TABLEINITSIZE*sizeof(void*)); - re->blovllen+=TABLEINITSIZE; /*Does this really need to be power of 2?*/ - if(temp) MEM_freeN(temp); - } - - v= re->blovl[a]; - - if(v==NULL) { - v= (VlakRen *)MEM_callocN(256*sizeof(VlakRen),"findOrAddVlak"); - re->blovl[a]= v; - } - v+= (nr & 255); - return v; -} - /* ------------------------------------------------------------------------- */ HaloRen *RE_inithalo(Render *re, Material *ma, float *vec, float *vec1, @@ -667,7 +863,7 @@ void project_renderdata(Render *re, void (*projectfunc)(float *, float mat[][4], /* set flags at 0 if clipped away */ for(a=0; a<re->totvlak; a++) { - if((a & 255)==0) vlr= re->blovl[a>>8]; + if((a & 255)==0) vlr= re->vlaknodes[a>>8].vlak; else vlr++; vlr->flag |= R_VISIBLE; @@ -690,7 +886,7 @@ void set_normalflags(Render *re) /* switch normal 'snproj' values (define which axis is the optimal one for calculations) */ for(a1=0; a1<re->totvlak; a1++) { - if((a1 & 255)==0) vlr= re->blovl[a1>>8]; + if((a1 & 255)==0) vlr= re->vlaknodes[a1>>8].vlak; else vlr++; /* abuse of this flag... this is code that just sets face normal in direction of camera */ diff --git a/source/blender/render/intern/source/shadbuf.c b/source/blender/render/intern/source/shadbuf.c index b4653f5b3d2..3c6975c2a67 100644 --- a/source/blender/render/intern/source/shadbuf.c +++ b/source/blender/render/intern/source/shadbuf.c @@ -302,7 +302,7 @@ static void shadowbuf_autoclip(Render *re, LampRen *lar) /* set clip in vertices when face visible */ for(a=0; a<re->totvlak; a++) { - if((a & 255)==0) vlr= re->blovl[a>>8]; + if((a & 255)==0) vlr= re->vlaknodes[a>>8].vlak; else vlr++; /* note; these conditions are copied from zbuffer_shadow() */ @@ -317,7 +317,7 @@ static void shadowbuf_autoclip(Render *re, LampRen *lar) vlr->v2->clip= 1; vlr->v3->clip= 1; if(vlr->v4) vlr->v4->clip= 1; - } + } } /* calculate min and max */ @@ -1424,7 +1424,7 @@ static void isb_bsp_fillfaces(Render *re, LampRen *lar, ISBBranch *root) for(a=0; a<re->totvlak; a++) { - if((a & 255)==0) vlr= re->blovl[a>>8]; + if((a & 255)==0) vlr= re->vlaknodes[a>>8].vlak; else vlr++; /* note, these conditions are copied in shadowbuf_autoclip() */ diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c index 9bf5f5a5207..c1bc3108eb4 100644 --- a/source/blender/render/intern/source/shadeinput.c +++ b/source/blender/render/intern/source/shadeinput.c @@ -638,23 +638,38 @@ void shade_input_set_shade_texco(ShadeInput *shi) if((texco & TEXCO_UV) || (mode & (MA_VERTEXCOL|MA_VERTEXCOLP|MA_FACETEXTURE))) { VlakRen *vlr= shi->vlr; - int j1=shi->i1, j2=shi->i2, j3=shi->i3; - + MTFace *tface; + MCol *mcol; + char *name; + int i, j1=shi->i1, j2=shi->i2, j3=shi->i3; + /* uv and vcols are not copied on split, so set them according vlr divide flag */ vlr_set_uv_indices(vlr, &j1, &j2, &j3); - + + shi->totuv= 0; + shi->totcol= 0; + if(mode & (MA_VERTEXCOL|MA_VERTEXCOLP)) { - - if(vlr->vcol) { + for (i=0; (mcol=RE_vlakren_get_mcol(&R, vlr, i, &name, 0)); i++) { + ShadeInputCol *scol= &shi->col[i]; char *cp1, *cp2, *cp3; - cp1= (char *)(vlr->vcol+j1); - cp2= (char *)(vlr->vcol+j2); - cp3= (char *)(vlr->vcol+j3); + shi->totcol++; + scol->name= name; + + cp1= (char *)(mcol+j1); + cp2= (char *)(mcol+j2); + cp3= (char *)(mcol+j3); - shi->vcol[0]= (l*((float)cp3[3]) - u*((float)cp1[3]) - v*((float)cp2[3]))/255.0f; - shi->vcol[1]= (l*((float)cp3[2]) - u*((float)cp1[2]) - v*((float)cp2[2]))/255.0f; - shi->vcol[2]= (l*((float)cp3[1]) - u*((float)cp1[1]) - v*((float)cp2[1]))/255.0f; + scol->col[0]= (l*((float)cp3[3]) - u*((float)cp1[3]) - v*((float)cp2[3]))/255.0f; + scol->col[1]= (l*((float)cp3[2]) - u*((float)cp1[2]) - v*((float)cp2[2]))/255.0f; + scol->col[2]= (l*((float)cp3[1]) - u*((float)cp1[1]) - v*((float)cp2[1]))/255.0f; + } + + if(shi->totcol) { + shi->vcol[0]= shi->col[0].col[0]; + shi->vcol[1]= shi->col[0].col[1]; + shi->vcol[2]= shi->col[0].col[2]; } else { shi->vcol[0]= 0.0f; @@ -662,17 +677,22 @@ void shade_input_set_shade_texco(ShadeInput *shi) shi->vcol[2]= 0.0f; } } - if(vlr->tface) { + + for (i=0; (tface=RE_vlakren_get_tface(&R, vlr, i, &name, 0)); i++) { + ShadeInputUV *suv= &shi->uv[i]; float *uv1, *uv2, *uv3; + + shi->totuv++; + suv->name= name; - uv1= vlr->tface->uv[j1]; - uv2= vlr->tface->uv[j2]; - uv3= vlr->tface->uv[j3]; - - shi->uv[0]= -1.0f + 2.0f*(l*uv3[0]-u*uv1[0]-v*uv2[0]); - shi->uv[1]= -1.0f + 2.0f*(l*uv3[1]-u*uv1[1]-v*uv2[1]); - shi->uv[2]= 1.0f; /* texture.c assumes there are 3 coords, also to indicate it is real UV for passes */ + uv1= tface->uv[j1]; + uv2= tface->uv[j2]; + uv3= tface->uv[j3]; + suv->uv[0]= -1.0f + 2.0f*(l*uv3[0]-u*uv1[0]-v*uv2[0]); + suv->uv[1]= -1.0f + 2.0f*(l*uv3[1]-u*uv1[1]-v*uv2[1]); + suv->uv[2]= 1.0f; /* texture.c assumes there are 3 coords, also to indicate it is real UV for passes */ + if(shi->osatex) { float duv[2]; @@ -680,29 +700,34 @@ void shade_input_set_shade_texco(ShadeInput *shi) duv[0]= shi->dx_u; duv[1]= shi->dx_v; - shi->dxuv[0]= 2.0f*(dl*uv3[0]-duv[0]*uv1[0]-duv[1]*uv2[0]); - shi->dxuv[1]= 2.0f*(dl*uv3[1]-duv[0]*uv1[1]-duv[1]*uv2[1]); + suv->dxuv[0]= 2.0f*(dl*uv3[0]-duv[0]*uv1[0]-duv[1]*uv2[0]); + suv->dxuv[1]= 2.0f*(dl*uv3[1]-duv[0]*uv1[1]-duv[1]*uv2[1]); dl= shi->dy_u+shi->dy_v; duv[0]= shi->dy_u; duv[1]= shi->dy_v; - shi->dyuv[0]= 2.0f*(dl*uv3[0]-duv[0]*uv1[0]-duv[1]*uv2[0]); - shi->dyuv[1]= 2.0f*(dl*uv3[1]-duv[0]*uv1[1]-duv[1]*uv2[1]); + suv->dyuv[0]= 2.0f*(dl*uv3[0]-duv[0]*uv1[0]-duv[1]*uv2[0]); + suv->dyuv[1]= 2.0f*(dl*uv3[1]-duv[0]*uv1[1]-duv[1]*uv2[1]); } - if(mode & MA_FACETEXTURE) { + + if((mode & MA_FACETEXTURE) && i==0) { if((mode & (MA_VERTEXCOL|MA_VERTEXCOLP))==0) { shi->vcol[0]= 1.0f; shi->vcol[1]= 1.0f; shi->vcol[2]= 1.0f; } - if(vlr->tface) render_realtime_texture(shi); + if(tface && tface->tpage) + render_realtime_texture(shi, tface->tpage); } } - else { - shi->uv[0]= 2.0f*(u+.5f); - shi->uv[1]= 2.0f*(v+.5f); - shi->uv[2]= 0.0f; /* texture.c assumes there are 3 coords, also to indicate it is no real UV for passes */ + + if(shi->totuv == 0) { + ShadeInputUV *suv= &shi->uv[0]; + + suv->uv[0]= 2.0f*(u+.5f); + suv->uv[1]= 2.0f*(v+.5f); + suv->uv[2]= 0.0f; /* texture.c assumes there are 3 coords, also to indicate it is no real UV for passes */ if(mode & MA_FACETEXTURE) { /* no tface? set at 1.0f */ @@ -842,7 +867,6 @@ void shade_input_set_shade_texco(ShadeInput *shi) /* ****************** ShadeSample ************************************** */ - /* initialize per part, not per pixel! */ void shade_input_initialize(ShadeInput *shi, RenderPart *pa, RenderLayer *rl, int sample) { @@ -877,7 +901,6 @@ void shade_sample_initialize(ShadeSample *ssamp, RenderPart *pa, RenderLayer *rl ssamp->samplenr= 0; /* counter, detect shadow-reuse for shaders */ } - /* Do AO or (future) GI */ void shade_samples_do_AO(ShadeSample *ssamp) { diff --git a/source/blender/render/intern/source/shadeoutput.c b/source/blender/render/intern/source/shadeoutput.c index b53954c8ace..8837b933fa3 100644 --- a/source/blender/render/intern/source/shadeoutput.c +++ b/source/blender/render/intern/source/shadeoutput.c @@ -822,14 +822,8 @@ void shade_color(ShadeInput *shi, ShadeResult *shr) shi->b= shi->vcol[2]; } - if(ma->texco) { - if(ma->mode & (MA_VERTEXCOLP|MA_FACETEXTURE)) { - shi->r= shi->vcol[0]; - shi->g= shi->vcol[1]; - shi->b= shi->vcol[2]; - } + if(ma->texco) do_material_tex(shi); - } if(ma->fresnel_tra!=0.0f) shi->alpha*= fresnel_fac(shi->view, shi->vn, ma->fresnel_tra_i, ma->fresnel_tra); diff --git a/source/blender/render/intern/source/texture.c b/source/blender/render/intern/source/texture.c index 3860ca1f4c4..643b4c9338f 100644 --- a/source/blender/render/intern/source/texture.c +++ b/source/blender/render/intern/source/texture.c @@ -1416,7 +1416,21 @@ void do_material_tex(ShadeInput *shi) co= shi->gl; dx= shi->dxco; dy= shi->dyco; } else if(mtex->texco==TEXCO_UV) { - co= shi->uv; dx= shi->dxuv; dy= shi->dyuv; + ShadeInputUV *suv= &shi->uv[0]; + int i; + + if(mtex->uvname[0] != 0) { + for(i = 0; i < shi->totuv; i++) { + if(strcmp(shi->uv[i].name, mtex->uvname)==0) { + suv= &shi->uv[i]; + break; + } + } + } + + co= suv->uv; + dx= suv->dxuv; + dy= suv->dyuv; } else if(mtex->texco==TEXCO_WINDOW) { co= shi->winco; dx= shi->dxwin; dy= shi->dywin; @@ -2366,15 +2380,14 @@ int externtex(MTex *mtex, float *vec, float *tin, float *tr, float *tg, float *t /* ------------------------------------------------------------------------- */ -void render_realtime_texture(ShadeInput *shi) +void render_realtime_texture(ShadeInput *shi, Image *ima) { TexResult texr; - Image *ima; static Tex tex1, tex2; // threadsafe static int firsttime= 1; Tex *tex; float texvec[3], dx[2], dy[2]; - + if(firsttime) { firsttime= 0; default_tex(&tex1); @@ -2385,27 +2398,23 @@ void render_realtime_texture(ShadeInput *shi) if(shi->ys & 1) tex= &tex1; else tex= &tex2; // threadsafe - ima = shi->vlr->tface->tpage; - if(ima) { - - texvec[0]= 0.5+0.5*shi->uv[0]; - texvec[1]= 0.5+0.5*shi->uv[1]; - if(shi->osatex) { - dx[0]= 0.5*shi->dxuv[0]; - dx[1]= 0.5*shi->dxuv[1]; - dy[0]= 0.5*shi->dyuv[0]; - dy[1]= 0.5*shi->dyuv[1]; - } - - texr.nor= NULL; - - if(shi->osatex) imagewraposa(tex, ima, NULL, texvec, dx, dy, &texr); - else imagewrap(tex, ima, NULL, texvec, &texr); - - shi->vcol[0]*= texr.tr; - shi->vcol[1]*= texr.tg; - shi->vcol[2]*= texr.tb; + texvec[0]= 0.5+0.5*shi->uv[0].uv[0]; + texvec[1]= 0.5+0.5*shi->uv[0].uv[1]; + if(shi->osatex) { + dx[0]= 0.5*shi->uv[0].dxuv[0]; + dx[1]= 0.5*shi->uv[0].dxuv[1]; + dy[0]= 0.5*shi->uv[0].dyuv[0]; + dy[1]= 0.5*shi->uv[0].dyuv[1]; } + + texr.nor= NULL; + + if(shi->osatex) imagewraposa(tex, ima, NULL, texvec, dx, dy, &texr); + else imagewrap(tex, ima, NULL, texvec, &texr); + + shi->vcol[0]*= texr.tr; + shi->vcol[1]*= texr.tg; + shi->vcol[2]*= texr.tb; } /* eof */ diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c index 44fbd782214..e934fcf2c29 100644 --- a/source/blender/render/intern/source/zbuf.c +++ b/source/blender/render/intern/source/zbuf.c @@ -1756,7 +1756,7 @@ void zbuffer_solid(RenderPart *pa, unsigned int lay, short layflag) for(v=0; v<R.totvlak; v++) { - if((v & 255)==0) vlr= R.blovl[v>>8]; + if((v & 255)==0) vlr= R.vlaknodes[v>>8].vlak; else vlr++; if((vlr->flag & R_VISIBLE)) { @@ -1919,7 +1919,7 @@ void RE_zbufferall_radio(struct RadView *vw, RNode **rg_elem, int rg_totelem, Re int totface=0; for(a=0; a<re->totvlak; a++) { - if((a & 255)==0) vlr= re->blovl[a>>8]; else vlr++; + if((a & 255)==0) vlr= re->vlaknodes[a>>8].vlak; else vlr++; if(vlr->radface) { rf= vlr->radface; @@ -1979,7 +1979,7 @@ void zbuffer_shadow(Render *re, LampRen *lar, int *rectz, int size, float jitx, for(a=0; a<re->totvlak; a++) { - if((a & 255)==0) vlr= re->blovl[a>>8]; + if((a & 255)==0) vlr= re->vlaknodes[a>>8].vlak; else vlr++; /* note, these conditions are copied in shadowbuf_autoclip() */ @@ -2588,7 +2588,7 @@ static int zbuffer_abuf(RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, un for(v=0; v<R.totvlak; v++) { if((v & 255)==0) - vlr= R.blovl[v>>8]; + vlr= R.vlaknodes[v>>8].vlak; else vlr++; if(vlr->mat!=ma) { diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 537ae7d6a68..75c44e9b399 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -671,32 +671,90 @@ void do_common_editbuts(unsigned short event) // old name, is a mix of object an /* *************************** MESH ******************************** */ -static void customdata_buttons(uiBlock *block, CustomData *data, int type, int *activep, int setevt, int newevt, int delevt, char *label, char *shortlabel, char *browsetip, char *newtip, char *deltip, int x, int y) +static void verify_customdata_name_func(void *data1, void *data2) +{ + CustomData *data= (CustomData*)data1; + CustomDataLayer *layer= (CustomDataLayer*)data2; + + CustomData_set_layer_unique_name(data, layer - data->layers); +} + +static void delete_customdata_layer(void *data1, void *data2) +{ + Mesh *me= (Mesh*)data1; + CustomData *data= (G.obedit)? &G.editMesh->fdata: &me->fdata; + CustomDataLayer *layer= (CustomDataLayer*)data2; + int type= layer->type; + int index= CustomData_get_layer_index(data, type); + + CustomData_set_layer_active(data, type, layer - &data->layers[index]); + + if(G.obedit) { + EM_free_data_layer(data, type); + } + else if(me) { + CustomData_free_layer(data, type, me->totface); + mesh_update_customdata_pointers(me); + } + + if(!CustomData_has_layer(data, type)) { + if(type == CD_MCOL && (G.f & G_VERTEXPAINT)) + G.f &= ~G_VERTEXPAINT; /* get out of vertexpaint mode */ + if(type == CD_MTFACE && (G.f & G_FACESELECT)) + set_faceselect(); /* get out of faceselect mode */ + } + + DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA); + + if(type == CD_MTFACE) + BIF_undo_push("Delete UV Texture"); + else if(type == CD_MCOL) + BIF_undo_push("Delete Vertex Color"); + + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWIMAGE, 0); + allqueue(REDRAWBUTSEDIT, 0); +} + +static int customdata_buttons(uiBlock *block, Mesh *me, CustomData *data, int type, int *activep, int setevt, int newevt, char *label, char *shortlabel, char *browsetip, char *newtip, char *deltip, int x, int y) { CustomDataLayer *layer; - int i, count= 0; + uiBut *but; + int i, count= CustomData_number_of_layers(data, type); + + if(count >= MAX_MTFACE) { + uiDefBut(block, LABEL, 0, label, x,y,220,19, 0, 0.0, 0, 0, 0, ""); + } + else { + uiDefBut(block, LABEL, 0, label, x,y,140,19, 0, 0.0, 0, 0, 0, ""); + uiBlockBeginAlign(block); + uiDefBut(block, BUT, newevt, "New", x+140,y,80,19, 0,0,0,0,0, newtip); + uiBlockEndAlign(block); + } - *activep = 1; + y -= (count)? 24: 19; - for (i=0; i<data->totlayer; i++) { + uiBlockBeginAlign(block); + for (count=1, i=0; i<data->totlayer; i++) { layer= &data->layers[i]; if(layer->type == type) { - if(count == layer->active) - *activep = count+1; + *activep= layer->active + 1; + + uiDefButI(block, ROW, setevt, "", x,y,25,19, activep, 1.0, count, 0, 0, "Set active UV texture layer"); + but=uiDefBut(block, TEX, setevt, "", x+25,y,170,19, layer->name, 0.0, 31.0, 0, 0, "UV texture layer name"); + uiButSetFunc(but, verify_customdata_name_func, data, layer); + but= uiDefIconBut(block, BUT, B_NOP, VICON_X, x+195,y,25,19, NULL, 0.0, 0.0, 0.0, 0.0, "Delete UV texture layer"); + uiButSetFunc(but, delete_customdata_layer, me, layer); + + count++; + y -= 19; } } - - uiBlockBeginAlign(block); - if (count == 0) - uiDefBut(block, LABEL, 0, label, x,y,140,20, 0, 0.0, 0, 0, 0, ""); - else - uiDefButI(block, NUM, setevt, shortlabel, x,y,140,20, activep, 1, count, 0, 0, browsetip); - - uiDefBut(block, BUT, newevt, "New", x+140,y,52,20, 0,0,0,0,0, newtip); - uiDefBut(block, BUT, delevt, "Delete", x+182,y,68,20, 0,0,0,0,0, deltip); uiBlockEndAlign(block); + + return y; } static void editing_panel_mesh_type(Object *ob, Mesh *me) @@ -705,62 +763,65 @@ static void editing_panel_mesh_type(Object *ob, Mesh *me) uiBut *but; float val; CustomData *fdata; + int yco; block= uiNewBlock(&curarea->uiblocks, "editing_panel_mesh_type", UI_EMBOSS, UI_HELV, curarea->win); if( uiNewPanel(curarea, block, "Mesh", "Editing", 320, 0, 318, 204)==0) return; uiBlockBeginAlign(block); - uiDefButBitS(block, TOG, ME_AUTOSMOOTH, REDRAWVIEW3D, "Auto Smooth",10,180,154,19, &me->flag, 0, 0, 0, 0, "Treats all set-smoothed faces with angles less than Degr: as 'smooth' during render"); - uiDefButS(block, NUM, B_DIFF, "Degr:", 10,160,154,19, &me->smoothresh, 1, 80, 0, 0, "Defines maximum angle between face normals that 'Auto Smooth' will operate on"); + uiDefButBitS(block, TOG, ME_AUTOSMOOTH, REDRAWVIEW3D, "Auto Smooth",10,180,170,19, &me->flag, 0, 0, 0, 0, "Treats all set-smoothed faces with angles less than Degr: as 'smooth' during render"); + uiDefButS(block, NUM, B_DIFF, "Degr:", 10,160,170,19, &me->smoothresh, 1, 80, 0, 0, "Defines maximum angle between face normals that 'Auto Smooth' will operate on"); uiBlockEndAlign(block); /* Retopo */ if(G.obedit) { uiBlockBeginAlign(block); - but= uiDefButBitC(block,TOG,1,B_NOP, "Retopo", 10,130,154,19, &G.editMesh->retopo_mode, 0,0,0,0, "Turn on the re-topology tool"); + but= uiDefButBitC(block,TOG,1,B_NOP, "Retopo", 10,130,170,19, &G.editMesh->retopo_mode, 0,0,0,0, "Turn on the re-topology tool"); uiButSetFunc(but,retopo_toggle,ob,me); if(G.editMesh->retopo_mode) { - but= uiDefButBitC(block,TOG,2,B_NOP,"Paint", 10,110,50,19, &G.editMesh->retopo_mode,0,0,0,0, ""); + but= uiDefButBitC(block,TOG,2,B_NOP,"Paint", 10,110,55,19, &G.editMesh->retopo_mode,0,0,0,0, ""); uiButSetFunc(but,retopo_paint_toggle,ob,me); - but= uiDefBut(block,BUT,B_NOP,"Retopo All", 60,110,104,19, 0,0,0,0,0, "Apply the re-topology tool to all selected vertices"); + but= uiDefBut(block,BUT,B_NOP,"Retopo All", 65,110,115,19, 0,0,0,0,0, "Apply the re-topology tool to all selected vertices"); uiButSetFunc(but,retopo_do_all,ob,me); } uiBlockEndAlign(block); } - uiBlockSetCol(block, TH_AUTO); - - uiDefIDPoinBut(block, test_meshpoin_but, ID_ME, B_REDR, "TexMesh: ", 180,180,230,19, &me->texcomesh, "Derive texture coordinates from another mesh."); + uiBlockBeginAlign(block); + uiDefBut(block, BUT,B_DOCENTRE, "Centre", 10, 80, 65, 19, 0, 0, 0, 0, 0, "Shifts object data to be centered about object's origin"); + uiDefBut(block, BUT,B_DOCENTRENEW, "Centre New", 75, 80, 105, 19, 0, 0, 0, 0, 0, "Shifts object's origin to center of object data"); + uiDefBut(block, BUT,B_DOCENTRECURSOR, "Centre Cursor", 10, 60, 170, 19, 0, 0, 0, 0, 0, "Shifts object's origin to cursor location"); + uiBlockEndAlign(block); - fdata= (G.obedit)? &G.editMesh->fdata: &me->fdata; - customdata_buttons(block, fdata, CD_MCOL, &actmcol, B_SETMCOL, - B_NEWMCOL, B_DELMCOL, "Vert Color", "Vert Color:", - "Sets active vertex color layer", "Creates a new vertex color layer", - "Removes the current vertex color layer", 10, 60); + uiBlockBeginAlign(block); + uiDefButBitS(block, TOG, ME_TWOSIDED, REDRAWVIEW3D, "Double Sided", 10,30,170,19, &me->flag, 0, 0, 0, 0, "Render/display the mesh as double or single sided"); + uiDefButBitS(block, TOG, ME_NOPUNOFLIP, REDRAWVIEW3D, "No V.Normal Flip", 10,10,170,19, &me->flag, 0, 0, 0, 0, "Disables flipping of vertexnormals during render"); + uiBlockEndAlign(block); - customdata_buttons(block, fdata, CD_MTFACE, &acttface, B_SETTFACE, - B_NEWTFACE, B_DELTFACE, "UV Texture", "UV Texture:", - "Set active UV texture", "Creates a new UV texture layer", - "Removes the current UV texture layer", 10, 35); + uiDefIDPoinBut(block, test_meshpoin_but, ID_ME, B_REDR, "TexMesh: ", 190,180,220,19, &me->texcomesh, "Derive texture coordinates from another mesh."); - uiBlockBeginAlign(block); if(me->msticky) val= 1.0; else val= 0.0; - uiDefBut(block, LABEL, 0, "Sticky", 10,10,140,20, 0, val, 0, 0, 0, ""); + uiDefBut(block, LABEL, 0, "Sticky", 190,155,140,19, 0, val, 0, 0, 0, ""); + uiBlockBeginAlign(block); if(me->msticky==NULL) { - uiDefBut(block, BUT, B_MAKESTICKY, "Make", 150,10,110,20, 0, 0, 0, 0, 0, "Creates Sticky coordinates from the current camera view background picture"); + uiDefBut(block, BUT, B_MAKESTICKY, "Make", 330,155, 80,19, 0, 0, 0, 0, 0, "Creates Sticky coordinates from the current camera view background picture"); } - else uiDefBut(block, BUT, B_DELSTICKY, "Delete", 150,10,110,20, 0, 0, 0, 0, 0, "Deletes Sticky texture coordinates"); + else uiDefBut(block, BUT, B_DELSTICKY, "Delete", 330,155, 80,19, 0, 0, 0, 0, 0, "Deletes Sticky texture coordinates"); uiBlockEndAlign(block); - uiBlockBeginAlign(block); - uiDefBut(block, BUT,B_DOCENTRE, "Centre", 275, 95, 130, 19, 0, 0, 0, 0, 0, "Shifts object data to be centered about object's origin"); - uiDefBut(block, BUT,B_DOCENTRENEW, "Centre New", 275, 75, 130, 19, 0, 0, 0, 0, 0, "Shifts object's origin to center of object data"); - uiDefBut(block, BUT,B_DOCENTRECURSOR, "Centre Cursor", 275, 55, 130, 19, 0, 0, 0, 0, 0, "Shifts object's origin to cursor location"); + fdata= (G.obedit)? &G.editMesh->fdata: &me->fdata; + yco= customdata_buttons(block, me, fdata, CD_MTFACE, &acttface, + B_SETTFACE, B_NEWTFACE, "UV Texture", "UV Texture:", + "Set active UV texture", "Creates a new UV texture layer", + "Removes the current UV texture layer", 190, 130); - uiBlockBeginAlign(block); - uiDefButBitS(block, TOG, ME_TWOSIDED, REDRAWVIEW3D, "Double Sided", 275,30,130,19, &me->flag, 0, 0, 0, 0, "Render/display the mesh as double or single sided"); - uiDefButBitS(block, TOG, ME_NOPUNOFLIP, REDRAWVIEW3D, "No V.Normal Flip",275,10,130,19, &me->flag, 0, 0, 0, 0, "Disables flipping of vertexnormals during render"); - uiBlockEndAlign(block); + yco= customdata_buttons(block, me, fdata, CD_MCOL, &actmcol, + B_SETMCOL, B_NEWMCOL, "Vertex Color", "Vertex Color:", + "Sets active vertex color layer", "Creates a new vertex color layer", + "Removes the current vertex color layer", 190, yco-5); + + if(yco < 0) + uiNewPanelHeight(block, 204 - yco); } /* *************************** MODIFIERS ******************************** */ @@ -3601,11 +3662,13 @@ void do_meshbuts(unsigned short event) if(me->msticky) { CustomData_free_layer(&me->vdata, CD_MSTICKY, me->totvert); me->msticky= NULL; + BIF_undo_push("Delete Sticky"); } allqueue(REDRAWBUTSEDIT, 0); break; case B_MAKESTICKY: RE_make_sticky(); + BIF_undo_push("Make Sticky"); allqueue(REDRAWBUTSEDIT, 0); break; @@ -3634,22 +3697,7 @@ void do_meshbuts(unsigned short event) } DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); - allqueue(REDRAWVIEW3D, 0); - allqueue(REDRAWBUTSEDIT, 0); - break; - case B_DELMCOL: - if(G.obedit) { - EM_free_data_layer(&em->fdata, CD_MCOL); - } - else if(me) { - CustomData_free_layer(&me->fdata, CD_MCOL, me->totface); - me->mcol= CustomData_get_layer(&me->fdata, CD_MCOL); - } - - if((me && me->mcol == NULL) && (G.f & G_VERTEXPAINT)) - G.f &= ~G_VERTEXPAINT; /* get out of vertexpaint mode */ - - DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + BIF_undo_push("New Vertex Color"); allqueue(REDRAWVIEW3D, 0); allqueue(REDRAWBUTSEDIT, 0); break; @@ -3660,6 +3708,7 @@ void do_meshbuts(unsigned short event) mesh_update_customdata_pointers(me); DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + BIF_undo_push("Set Active Vertex Color"); allqueue(REDRAWVIEW3D, 0); allqueue(REDRAWBUTSEDIT, 0); } @@ -3686,34 +3735,28 @@ void do_meshbuts(unsigned short event) } DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + BIF_undo_push("New UV Texture"); allqueue(REDRAWVIEW3D, 0); allqueue(REDRAWBUTSEDIT, 0); - break; - case B_DELTFACE: - if(G.obedit) { - EM_free_data_layer(&em->fdata, CD_MTFACE); - } - else if(me) { - CustomData_free_layer(&me->fdata, CD_MTFACE, me->totface); - me->mtface= CustomData_get_layer(&me->fdata, CD_MTFACE); - } - - if((me && me->mtface == NULL) && (G.f & G_FACESELECT)) - set_faceselect(); /* get out of vertexpaint mode */ - - DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); - allqueue(REDRAWVIEW3D, 0); - allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWIMAGE, 0); break; case B_SETTFACE: if (G.obedit || me) { + if (G.f & G_FACESELECT) + select_mface_from_tface(me); + CustomData *fdata= (G.obedit)? &em->fdata: &me->fdata; CustomData_set_layer_active(fdata, CD_MTFACE, acttface-1); mesh_update_customdata_pointers(me); + if (G.f & G_FACESELECT) + select_tface_from_mface(me); + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + BIF_undo_push("Set Active UV Texture"); allqueue(REDRAWVIEW3D, 0); allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWIMAGE, 0); } break; diff --git a/source/blender/src/buttons_shading.c b/source/blender/src/buttons_shading.c index 8557cea5468..6998f8ec19b 100644 --- a/source/blender/src/buttons_shading.c +++ b/source/blender/src/buttons_shading.c @@ -46,6 +46,7 @@ #include "DNA_image_types.h" #include "DNA_lamp_types.h" #include "DNA_material_types.h" +#include "DNA_meshdata_types.h" #include "DNA_object_types.h" #include "DNA_node_types.h" #include "DNA_packedFile_types.h" @@ -3025,7 +3026,10 @@ static void material_panel_map_input(Object *ob, Material *ma) uiBlockBeginAlign(block); uiDefButS(block, ROW, B_MATPRV, "Glob", 630,180,45,18, &(mtex->texco), 4.0, (float)TEXCO_GLOB, 0, 0, "Uses global coordinates for the texture coordinates"); uiDefButS(block, ROW, B_MATPRV, "Object", 675,180,75,18, &(mtex->texco), 4.0, (float)TEXCO_OBJECT, 0, 0, "Uses linked object's coordinates for texture coordinates"); - uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_MATPRV, "",750,180,158,18, &(mtex->object), ""); + if(mtex->texco == TEXCO_UV) + uiDefBut(block, TEX, B_MATPRV, "UV:", 750,180,158,18, mtex->uvname, 0, 31, 0, 0, "Set name of UV layer to use, default is active UV layer"); + else + uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_MATPRV, "Ob:",750,180,158,18, &(mtex->object), ""); uiDefButS(block, ROW, B_MATPRV, "UV", 630,160,40,18, &(mtex->texco), 4.0, (float)TEXCO_UV, 0, 0, "Uses UV coordinates for texture coordinates"); uiDefButS(block, ROW, B_MATPRV, "Orco", 670,160,55,18, &(mtex->texco), 4.0, (float)TEXCO_ORCO, 0, 0, "Uses the original undeformed coordinates of the object"); diff --git a/source/blender/src/drawmesh.c b/source/blender/src/drawmesh.c index 94255384108..c8c07748d6a 100644 --- a/source/blender/src/drawmesh.c +++ b/source/blender/src/drawmesh.c @@ -926,16 +926,19 @@ static int draw_tface__set_draw(MTFace *tface, MCol *mcol, int matnr) { if (tface && ((tface->flag&TF_HIDE) || (tface->mode&TF_INVISIBLE))) return 0; - if (set_draw_settings_cached(0, g_draw_tface_mesh_istex, tface, g_draw_tface_mesh_islight, g_draw_tface_mesh_ob, matnr, TF_TWOSIDE)) { + if (tface && set_draw_settings_cached(0, g_draw_tface_mesh_istex, tface, g_draw_tface_mesh_islight, g_draw_tface_mesh_ob, matnr, TF_TWOSIDE)) { glColor3ub(0xFF, 0x00, 0xFF); return 2; /* Don't set color */ } else if (tface && tface->mode&TF_OBCOL) { glColor3ubv(g_draw_tface_mesh_obcol); return 2; /* Don't set color */ } else if (!mcol) { - Material *ma= give_current_material(g_draw_tface_mesh_ob, matnr+1); - if(ma) glColor3f(ma->r, ma->g, ma->b); - else glColor3f(1.0, 1.0, 1.0); + if (tface) glColor3f(1.0, 1.0, 1.0); + else { + Material *ma= give_current_material(g_draw_tface_mesh_ob, matnr+1); + if(ma) glColor3f(ma->r, ma->g, ma->b); + else glColor3f(1.0, 1.0, 1.0); + } return 2; /* Don't set color */ } else { return 1; /* Set color from mcol */ diff --git a/source/blender/src/drawnode.c b/source/blender/src/drawnode.c index 831387de931..b6af394b9f4 100644 --- a/source/blender/src/drawnode.c +++ b/source/blender/src/drawnode.c @@ -599,6 +599,18 @@ static int node_shader_buts_vect_math(uiBlock *block, bNodeTree *ntree, bNode *n return 20; } +static int node_shader_buts_geometry(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +{ + if(block) { + NodeGeometry *ngeo= (NodeGeometry*)node->storage; + + uiDefBut(block, TEX, B_NODE_EXEC+node->nr, "UV:", butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, ngeo->uvname, 0, 31, 0, 0, "Set name of UV layer to use, default is active UV layer"); + } + + return 20; +} + + /* only once called */ static void node_shader_set_butfunc(bNodeType *ntype) { @@ -642,6 +654,9 @@ static void node_shader_set_butfunc(bNodeType *ntype) case SH_NODE_VECT_MATH: ntype->butfunc= node_shader_buts_vect_math; break; + case SH_NODE_GEOMETRY: + ntype->butfunc= node_shader_buts_geometry; + break; default: ntype->butfunc= NULL; } diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c index 538e7e6fef2..567e4a7bab2 100644 --- a/source/blender/src/drawobject.c +++ b/source/blender/src/drawobject.c @@ -2002,7 +2002,7 @@ static void draw_mesh_fancy(Base *base, DerivedMesh *baseDM, DerivedMesh *dm, in else if(dt==OB_WIRE || totface==0) { draw_wire = 1; } - else if( (ob==OBACT && (G.f & G_FACESELECT)) || (G.vd->drawtype==OB_TEXTURE && dt>OB_SOLID)) { + else if( (ob==OBACT && (G.f & (G_FACESELECT|G_TEXTUREPAINT))) || (G.vd->drawtype==OB_TEXTURE && dt>OB_SOLID)) { if ((G.vd->flag&V3D_SELECT_OUTLINE) && (base->flag&SELECT) && !(G.f&(G_FACESELECT|G_PICKSEL)) && !draw_wire) { draw_mesh_object_outline(ob, dm); @@ -2059,7 +2059,8 @@ static void draw_mesh_fancy(Base *base, DerivedMesh *baseDM, DerivedMesh *dm, in dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, NULL, 1); } else if((G.f & (G_VERTEXPAINT+G_TEXTUREPAINT)) && me->mtface) { - dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, NULL, 1); + glColor3f(1.0f, 1.0f, 1.0f); + dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, NULL, 0); } else do_draw= 1; } @@ -2177,7 +2178,7 @@ static int draw_mesh_object(Base *base, int dt, int flag) if(baseDM && realDM) draw_mesh_fancy(base, baseDM, realDM, dt, flag); if(me->totvert==0) retval= 1; - + baseDM->release(baseDM); realDM->release(realDM); } diff --git a/source/blender/src/editface.c b/source/blender/src/editface.c index 81c77adfdde..68fcc200622 100644 --- a/source/blender/src/editface.c +++ b/source/blender/src/editface.c @@ -1434,11 +1434,15 @@ void set_faceselect() /* toggle */ setcursor_space(SPACE_VIEW3D, CURSOR_STD); BIF_undo_push("End UV Faceselect"); } + + if(me) + select_mface_from_tface(me); } else if (me && (ob->lay & G.vd->lay)) { G.f |= G_FACESELECT; if(me->mtface==NULL) make_tfaces(me); + select_tface_from_mface(me); setcursor_space(SPACE_VIEW3D, CURSOR_FACESEL); BIF_undo_push("Set UV Faceselect"); @@ -1451,6 +1455,44 @@ void set_faceselect() /* toggle */ allqueue(REDRAWIMAGE, 0); } +void select_tface_from_mface(Mesh *me) +{ + MFace *mf; + MTFace *tf; + int a; + + if(!me->mtface) return; + + mf= me->mface; + tf= me->mtface; + for(a=0; a<me->totface; a++, mf++, tf++) { + if(mf->flag & ME_FACE_SEL) tf->flag |= TF_SELECT; + else tf->flag &= ~TF_SELECT; + + if(mf->flag & ME_HIDE) tf->flag |= TF_HIDE; + else tf->flag &= ~TF_HIDE; + } +} + +void select_mface_from_tface(Mesh *me) +{ + MFace *mf; + MTFace *tf; + int a; + + if(!me->mtface) return; + + mf= me->mface; + tf= me->mtface; + for(a=0; a<me->totface; a++, mf++, tf++) { + if(tf->flag & TF_SELECT) mf->flag |= ME_FACE_SEL; + else mf->flag &= ~ME_FACE_SEL; + + if(tf->flag & TF_HIDE) mf->flag |= ME_HIDE; + else mf->flag &= ~ME_HIDE; + } +} + /* Texture Paint */ void set_texturepaint() /* toggle */ @@ -1480,6 +1522,10 @@ void set_texturepaint() /* toggle */ } else if (me) { G.f |= G_TEXTUREPAINT; + + if(me->mtface==NULL) + make_tfaces(me); + brush_check_exists(&G.scene->toolsettings->imapaint.brush); texpaint_disable_mipmap(); } diff --git a/source/blender/src/editmesh.c b/source/blender/src/editmesh.c index b4f1bddc716..f5b0c432b3a 100644 --- a/source/blender/src/editmesh.c +++ b/source/blender/src/editmesh.c @@ -784,7 +784,6 @@ void make_editMesh() Mesh *me= G.obedit->data; EditMesh *em= G.editMesh; MFace *mface; - MTFace *tface; MVert *mvert; MSelect *mselect; KeyBlock *actkey; @@ -872,10 +871,11 @@ void make_editMesh() } CustomData_copy(&me->fdata, &em->fdata, CD_MASK_EDITMESH, CD_CALLOC, 0); + if (G.f & G_FACESELECT) + select_mface_from_tface(me); /* make faces */ mface= me->mface; - tface= me->mtface; for(a=0; a<me->totface; a++, mface++) { eve1= evlist[mface->v1]; @@ -892,22 +892,15 @@ void make_editMesh() efa->mat_nr= mface->mat_nr; efa->flag= mface->flag & ~ME_HIDE; - if((G.f & G_FACESELECT)==0) { - /* select face flag, if no edges we flush down */ - if(mface->flag & ME_FACE_SEL) { - efa->f |= SELECT; - } - if(mface->flag & ME_HIDE) efa->h= 1; - } - else if((tface = CustomData_get(&me->fdata, a, CD_MTFACE))) { - if(tface->flag & TF_HIDE) - efa->h= 1; - else if(tface->flag & TF_SELECT) - EM_select_face(efa, 1); + /* select and hide face flag */ + if(mface->flag & ME_FACE_SEL) { + efa->f |= SELECT; } - } + if(mface->flag & ME_HIDE) efa->h= 1; - if(me->mtface) tface++; + if((G.f & G_FACESELECT) && (efa->f & SELECT)) + EM_select_face(efa, 1); /* flush down */ + } } } @@ -956,7 +949,6 @@ void load_editMesh(void) MEdge *medge; MFace *mface; MSelect *mselect; - MTFace *tf; EditVert *eve; EditFace *efa; EditEdge *eed; @@ -1148,20 +1140,8 @@ void load_editMesh(void) } /* sync hide and select flags with faceselect mode */ - if(G.f & G_FACESELECT) { - if(me->mtface && (me->totface > 0)) { - efa= em->faces.first; - for(a=0, efa=em->faces.first; efa; a++, efa=efa->next) { - tf = &me->mtface[a]; - - if(efa->h) tf->flag |= TF_HIDE; - else tf->flag &= ~TF_HIDE; - if(efa->f & SELECT) tf->flag |= TF_SELECT; - else tf->flag &= ~TF_SELECT; - } - } - } - + if (G.f & G_FACESELECT) + select_tface_from_mface(me); /* patch hook indices and vertex parents */ { diff --git a/source/blender/src/imagepaint.c b/source/blender/src/imagepaint.c index 3724aaf43a0..e2bcc122df1 100644 --- a/source/blender/src/imagepaint.c +++ b/source/blender/src/imagepaint.c @@ -250,7 +250,7 @@ static void imapaint_redraw(int final, int texpaint, Image *image) imagepaint_composite_tags(G.scene->nodetree, image, &G.sima->iuser); } /* signal composite (hurmf, need an allqueue?) */ - if(G.sima->lock) { + if(!texpaint && G.sima->lock) { ScrArea *sa; for(sa=G.curscreen->areabase.first; sa; sa= sa->next) { if(sa->spacetype==SPACE_NODE) { diff --git a/source/blender/src/vpaint.c b/source/blender/src/vpaint.c index 95d4ae4dd55..8ba30f778c3 100644 --- a/source/blender/src/vpaint.c +++ b/source/blender/src/vpaint.c @@ -247,7 +247,7 @@ void make_vertexcol(int shade) /* single ob */ if(shade) shadeMeshMCol(ob, me); else - memset(me->mcol, 0, 4*sizeof(MCol)*me->totface); + memset(me->mcol, 255, 4*sizeof(MCol)*me->totface); DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); diff --git a/source/blender/yafray/intern/export_File.cpp b/source/blender/yafray/intern/export_File.cpp index 7d9f23a4e4c..c8c0b3c6bb1 100755 --- a/source/blender/yafray/intern/export_File.cpp +++ b/source/blender/yafray/intern/export_File.cpp @@ -1230,7 +1230,7 @@ void yafrayFileRender_t::writeObject(Object* obj, const vector<VlakRen*> &VLR_li string matname(face0mat->id.name); // use name in imgtex_shader list if 'TexFace' enabled for this material if (face0mat->mode & MA_FACETEXTURE) { - MTFace* tface = face0->tface; + MTFace* tface = RE_vlakren_get_tface(re, face0, 0, NULL, 0); if (tface) { Image* fimg = (Image*)tface->tpage; if (fimg) matname = imgtex_shader[string(face0mat->id.name) + string(fimg->id.name)]; @@ -1412,7 +1412,7 @@ void yafrayFileRender_t::writeObject(Object* obj, const vector<VlakRen*> &VLR_li string fmatname(fmat->id.name); // use name in imgtex_shader list if 'TexFace' enabled for this face material if (fmat->mode & MA_FACETEXTURE) { - MTFace* tface = vlr->tface; + MTFace* tface = RE_vlakren_get_tface(re, vlr, 0, NULL, 0); if (tface) { Image* fimg = (Image*)tface->tpage; if (fimg) fmatname = imgtex_shader[fmatname + string(fimg->id.name)]; @@ -1437,23 +1437,25 @@ void yafrayFileRender_t::writeObject(Object* obj, const vector<VlakRen*> &VLR_li } else if (vlr->flag & R_FACE_SPLIT) { ui2++; ui3++; } - MTFace* uvc = vlr->tface; // possible uvcoords (v upside down) + MTFace* uvc = RE_vlakren_get_tface(re, vlr, 0, NULL, 0); // possible uvcoords (v upside down) if (uvc) { ostr << " u_a=\"" << uvc->uv[ui1][0] << "\" v_a=\"" << 1-uvc->uv[ui1][1] << "\"" << " u_b=\"" << uvc->uv[ui2][0] << "\" v_b=\"" << 1-uvc->uv[ui2][1] << "\"" << " u_c=\"" << uvc->uv[ui3][0] << "\" v_c=\"" << 1-uvc->uv[ui3][1] << "\""; } + MCol *mcol= RE_vlakren_get_mcol(re, vlr, 0, NULL, 0); + // since Blender seems to need vcols when uvs are used, for yafray only export when the material actually uses vcols - if ((EXPORT_VCOL) && (vlr->vcol)) { + if ((EXPORT_VCOL) && mcol) { // vertex colors - unsigned char* pt = reinterpret_cast<unsigned char*>(&vlr->vcol[ui1]); + unsigned char* pt = reinterpret_cast<unsigned char*>(&mcol[ui1]); ostr << " vcol_a_r=\"" << (float)pt[3]/255.f << "\" vcol_a_g=\"" << (float)pt[2]/255.f << "\" vcol_a_b=\"" << (float)pt[1]/255.f << "\""; - pt = reinterpret_cast<unsigned char*>(&vlr->vcol[ui2]); + pt = reinterpret_cast<unsigned char*>(&mcol[ui2]); ostr << " vcol_b_r=\"" << (float)pt[3]/255.f << "\" vcol_b_g=\"" << (float)pt[2]/255.f << "\" vcol_b_b=\"" << (float)pt[1]/255.f << "\""; - pt = reinterpret_cast<unsigned char*>(&vlr->vcol[ui3]); + pt = reinterpret_cast<unsigned char*>(&mcol[ui3]); ostr << " vcol_c_r=\"" << (float)pt[3]/255.f << "\" vcol_c_g=\"" << (float)pt[2]/255.f << "\" vcol_c_b=\"" << (float)pt[1]/255.f << "\""; } @@ -1480,15 +1482,15 @@ void yafrayFileRender_t::writeObject(Object* obj, const vector<VlakRen*> &VLR_li << " u_b=\"" << uvc->uv[ui2][0] << "\" v_b=\"" << 1-uvc->uv[ui2][1] << "\"" << " u_c=\"" << uvc->uv[ui3][0] << "\" v_c=\"" << 1-uvc->uv[ui3][1] << "\""; } - if ((EXPORT_VCOL) && (vlr->vcol)) { + if ((EXPORT_VCOL) && mcol) { // vertex colors - unsigned char* pt = reinterpret_cast<unsigned char*>(&vlr->vcol[ui1]); + unsigned char* pt = reinterpret_cast<unsigned char*>(&mcol[ui1]); ostr << " vcol_a_r=\"" << (float)pt[3]/255.f << "\" vcol_a_g=\"" << (float)pt[2]/255.f << "\" vcol_a_b=\"" << (float)pt[1]/255.f << "\""; - pt = reinterpret_cast<unsigned char*>(&vlr->vcol[ui2]); + pt = reinterpret_cast<unsigned char*>(&mcol[ui2]); ostr << " vcol_b_r=\"" << (float)pt[3]/255.f << "\" vcol_b_g=\"" << (float)pt[2]/255.f << "\" vcol_b_b=\"" << (float)pt[1]/255.f << "\""; - pt = reinterpret_cast<unsigned char*>(&vlr->vcol[ui3]); + pt = reinterpret_cast<unsigned char*>(&mcol[ui3]); ostr << " vcol_c_r=\"" << (float)pt[3]/255.f << "\" vcol_c_g=\"" << (float)pt[2]/255.f << "\" vcol_c_b=\"" << (float)pt[1]/255.f << "\""; } diff --git a/source/blender/yafray/intern/export_Plugin.cpp b/source/blender/yafray/intern/export_Plugin.cpp index d2ed7f66f32..6a6137fefe9 100644 --- a/source/blender/yafray/intern/export_Plugin.cpp +++ b/source/blender/yafray/intern/export_Plugin.cpp @@ -1109,7 +1109,9 @@ void yafrayPluginRender_t::genUVcoords(vector<yafray::GFLOAT> &uvcoords, VlakRen void yafrayPluginRender_t::genVcol(vector<yafray::CFLOAT> &vcol, VlakRen *vlr, bool comple) { - if (vlr->vcol) + MCol *mcol= RE_vlakren_get_mcol(re, vlr, 0, NULL, 0); + + if (mcol) { // tri vcol split indices int ui1=0, ui2=1, ui3=2; @@ -1123,11 +1125,11 @@ void yafrayPluginRender_t::genVcol(vector<yafray::CFLOAT> &vcol, VlakRen *vlr, b ui2 = (ui2+2) & 3; ui3 = (ui3+2) & 3; } - unsigned char* pt = reinterpret_cast<unsigned char*>(&vlr->vcol[ui1]); + unsigned char* pt = reinterpret_cast<unsigned char*>(&mcol[ui1]); vcol.push_back((float)pt[3]/255.f); vcol.push_back((float)pt[2]/255.f); vcol.push_back((float)pt[1]/255.f); - pt = reinterpret_cast<unsigned char*>(&vlr->vcol[ui2]); + pt = reinterpret_cast<unsigned char*>(&mcol[ui2]); vcol.push_back((float)pt[3]/255.f); vcol.push_back((float)pt[2]/255.f); vcol.push_back((float)pt[1]/255.f); - pt = reinterpret_cast<unsigned char*>(&vlr->vcol[ui3]); + pt = reinterpret_cast<unsigned char*>(&mcol[ui3]); vcol.push_back((float)pt[3]/255.f); vcol.push_back((float)pt[2]/255.f); vcol.push_back((float)pt[1]/255.f); } else @@ -1148,7 +1150,7 @@ void yafrayPluginRender_t::genFace(vector<int> &faces,vector<string> &shaders,ve string fmatname(fmat->id.name); // use name in imgtex_shader list if 'TexFace' enabled for this face material if (fmat->mode & MA_FACETEXTURE) { - MTFace* tface = vlr->tface; + MTFace* tface = RE_vlakren_get_tface(re, vlr, 0, NULL, 0); if (tface) { Image* fimg = (Image*)tface->tpage; if (fimg) fmatname = imgtex_shader[fmatname + string(fimg->id.name)]; @@ -1168,7 +1170,8 @@ void yafrayPluginRender_t::genFace(vector<int> &faces,vector<string> &shaders,ve shaders.push_back(fmatname); faceshader.push_back(shaders.size()-1); } - MTFace* uvc = vlr->tface; // possible uvcoords (v upside down) + + MTFace* uvc = RE_vlakren_get_tface(re, vlr, 0, NULL, 0); // possible uvcoords (v upside down) int idx1, idx2, idx3; idx1 = vert_idx.find(vlr->v1)->second; @@ -1193,7 +1196,7 @@ void yafrayPluginRender_t::genCompleFace(vector<int> &faces,/*vector<string> &sh bool EXPORT_VCOL = ((fmat->mode & (MA_VERTEXCOL|MA_VERTEXCOLP))!=0); faceshader.push_back(faceshader.back()); - MTFace* uvc = vlr->tface; // possible uvcoords (v upside down) + MTFace* uvc = RE_vlakren_get_tface(re, vlr, 0, NULL, 0); // possible uvcoords (v upside down) int idx1, idx2, idx3; idx1 = vert_idx.find(vlr->v3)->second; idx2 = vert_idx.find(vlr->v4)->second; @@ -1336,7 +1339,7 @@ void yafrayPluginRender_t::writeObject(Object* obj, const vector<VlakRen*> &VLR_ { VlakRen* vlr = *fci; genVertices(verts, vidx, vert_idx, vlr, has_orco, obj); - if(vlr->tface) has_uv=true; + if(RE_vlakren_get_tface(re, vlr, 0, NULL, 0)) has_uv=true; } // all faces using the index list created above vector<int> faces; diff --git a/source/blender/yafray/intern/yafray_Render.cpp b/source/blender/yafray/intern/yafray_Render.cpp index 0d9757b19ad..01ab49c001b 100644 --- a/source/blender/yafray/intern/yafray_Render.cpp +++ b/source/blender/yafray/intern/yafray_Render.cpp @@ -86,7 +86,7 @@ bool yafrayRender_t::getAllMatTexObs() for (int i=0; i < re->totvlak; i++) { - if ((i & 255)==0) vlr = re->blovl[i>>8]; else vlr++; + if ((i & 255)==0) vlr=re->vlaknodes[i>>8].vlak; else vlr++; // ---- The materials & textures // in this case, probably every face has a material assigned, which can be the default material, @@ -129,17 +129,20 @@ bool yafrayRender_t::getAllMatTexObs() // Also make list of facetexture images (material 'TexFace'). if (vlr->ob) { int nv = 0; // number of vertices + MTFace *tface; + if (vlr->v4) nv=4; else if (vlr->v3) nv=3; if (nv) { renderobs[vlr->ob->id.name] = vlr->ob; all_objects[vlr->ob].push_back(vlr); - if (vlr->tface) { - Image* fc_img = vlr->tface->tpage; - if (fc_img) { - Material* fmat = vlr->mat; - // only save if TexFace enabled - if (fmat && (fmat->mode & MA_FACETEXTURE)) imagetex[fc_img].insert(fmat); - } + + tface= RE_vlakren_get_tface(re, vlr, 0, NULL, 0); + if (tface && tface->tpage) { + Material* fmat = vlr->mat; + + // only save if TexFace enabled + if(fmat && (fmat->mode & MA_FACETEXTURE)) + imagetex[tface->tpage].insert(fmat); } } } diff --git a/source/blender/yafray/intern/yafray_Render.h b/source/blender/yafray/intern/yafray_Render.h index 0d794b6755d..4002f514a6e 100644 --- a/source/blender/yafray/intern/yafray_Render.h +++ b/source/blender/yafray/intern/yafray_Render.h @@ -24,6 +24,7 @@ extern "C" { #include "BKE_global.h" #include "render_types.h" +#include "renderdatabase.h" /* display_draw() needs render layer info */ #include "renderpipeline.h" |