diff options
author | Ton Roosendaal <ton@blender.org> | 2006-01-11 01:10:14 +0300 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2006-01-11 01:10:14 +0300 |
commit | e7285229b824f959f84efe6774c506034cf0f98e (patch) | |
tree | f4c96dae29629cc5e5b1c335d93abc82647a11c5 /source/blender/blenkernel | |
parent | d594594cbe9c9eb3bc3c8a7708601e68693d324d (diff) | |
parent | 185c6bb49ce994d66fc67673b01a014161fa307d (diff) |
Tuesday merger of bf-blender into orange branch.
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_global.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_mesh.h | 16 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/CCGSubSurf.c | 65 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/CCGSubSurf.h | 3 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/DerivedMesh.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/displist.c | 11 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/ipo.c | 28 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mesh.c | 121 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/modifier.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/subsurf_ccg.c | 249 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/text.c | 3 |
11 files changed, 454 insertions, 47 deletions
diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h index bef63bfa261..490c8dfc01e 100644 --- a/source/blender/blenkernel/BKE_global.h +++ b/source/blender/blenkernel/BKE_global.h @@ -192,6 +192,7 @@ typedef struct Global { #define G_FIle_PUBLISH (1 << 9) #define G_FILE_NO_UI (1 << 10) #define G_FILE_GAME_TO_IPO (1 << 11) +#define G_FILE_GAME_MAT (1 << 12) /* G.windowstate */ #define G_WINDOWSTATE_USERDEF 0 diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index 9f8ee3c6127..5cf6dd41e6f 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -92,6 +92,22 @@ void mesh_calc_normals(struct MVert *mverts, int numVerts, struct MFace *mfaces, * (_numVerts_r_ may be NULL) */ float (*mesh_getVertexCos(struct Mesh *me, int *numVerts_r))[3]; +/* map from uv vertex to face (for select linked, stitch, uv suburf) */ + +struct UvVertMap; +typedef struct UvVertMap UvVertMap; + +typedef struct UvMapVert { + struct UvMapVert *next; + unsigned int f; + unsigned char tfindex, separate; +} UvMapVert; + +UvVertMap *make_uv_vert_map(struct MFace *mface, struct TFace *tface, unsigned int totface, unsigned int totvert, int selected, float *limit); +UvMapVert *get_uv_map_vert(UvVertMap *vmap, unsigned int v); +UvMapVert *get_first_uv_map_vert(UvVertMap *vmap); +void free_uv_vert_map(UvVertMap *vmap); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/intern/CCGSubSurf.c b/source/blender/blenkernel/intern/CCGSubSurf.c index dc6543858c1..5bbd397e9c4 100644 --- a/source/blender/blenkernel/intern/CCGSubSurf.c +++ b/source/blender/blenkernel/intern/CCGSubSurf.c @@ -223,6 +223,7 @@ static int _edge_isBoundary(CCGEdge *e); enum { Vert_eEffected= (1<<0), Vert_eChanged= (1<<1), + Vert_eSeam= (1<<2), } VertFlags; enum { Edge_eEffected= (1<<0), @@ -400,6 +401,10 @@ static void _vert_free(CCGVert *v, CCGSubSurf *ss) { CCGSUBSURF_free(ss, v); } +static int VERT_seam(CCGVert *v, CCGSubSurf *ss) { + return ((v->flags & Vert_eSeam) != 0); +} + /***/ static CCGEdge *_edge_new(CCGEdgeHDL eHDL, CCGVert *v0, CCGVert *v1, float crease, int levels, int dataSize, CCGSubSurf *ss) { @@ -871,9 +876,10 @@ CCGError ccgSubSurf_syncFaceDel(CCGSubSurf *ss, CCGFaceHDL fHDL) { return eCCGError_None; } -CCGError ccgSubSurf_syncVert(CCGSubSurf *ss, CCGVertHDL vHDL, void *vertData, CCGVert **v_r) { +CCGError ccgSubSurf_syncVert(CCGSubSurf *ss, CCGVertHDL vHDL, void *vertData, int seam, CCGVert **v_r) { void **prevp; CCGVert *v = NULL; + short seamflag = (seam)? Vert_eSeam: 0; if (ss->syncState==eSyncState_Partial) { v = _ehash_lookupWithPrev(ss->vMap, vHDL, &prevp); @@ -881,12 +887,12 @@ CCGError ccgSubSurf_syncVert(CCGSubSurf *ss, CCGVertHDL vHDL, void *vertData, CC v = _vert_new(vHDL, ss->subdivLevels, ss->meshIFC.vertDataSize, ss); VertDataCopy(_vert_getCo(v,0,ss->meshIFC.vertDataSize), vertData); _ehash_insert(ss->vMap, (EHEntry*) v); - v->flags = Vert_eEffected; - } else if (!VertDataEqual(vertData, _vert_getCo(v, 0, ss->meshIFC.vertDataSize))) { + v->flags = Vert_eEffected|seamflag; + } else if (!VertDataEqual(vertData, _vert_getCo(v, 0, ss->meshIFC.vertDataSize)) || ((v->flags & Vert_eSeam) != seamflag)) { int i, j; VertDataCopy(_vert_getCo(v,0,ss->meshIFC.vertDataSize), vertData); - v->flags = Vert_eEffected; + v->flags = Vert_eEffected|seamflag; for (i=0; i<v->numEdges; i++) { CCGEdge *e = v->edges[i]; @@ -910,12 +916,12 @@ CCGError ccgSubSurf_syncVert(CCGSubSurf *ss, CCGVertHDL vHDL, void *vertData, CC v = _vert_new(vHDL, ss->subdivLevels, ss->meshIFC.vertDataSize, ss); VertDataCopy(_vert_getCo(v,0,ss->meshIFC.vertDataSize), vertData); _ehash_insert(ss->vMap, (EHEntry*) v); - v->flags = Vert_eEffected; - } else if (!VertDataEqual(vertData, _vert_getCo(v, 0, ss->meshIFC.vertDataSize))) { + v->flags = Vert_eEffected|seamflag; + } else if (!VertDataEqual(vertData, _vert_getCo(v, 0, ss->meshIFC.vertDataSize)) || ((v->flags & Vert_eSeam) != seamflag)) { *prevp = v->next; _ehash_insert(ss->vMap, (EHEntry*) v); VertDataCopy(_vert_getCo(v,0,ss->meshIFC.vertDataSize), vertData); - v->flags = Vert_eEffected|Vert_eChanged; + v->flags = Vert_eEffected|Vert_eChanged|seamflag; } else { *prevp = v->next; _ehash_insert(ss->vMap, (EHEntry*) v); @@ -1222,11 +1228,15 @@ static void ccgSubSurf__sync(CCGSubSurf *ss) { void *nCo = VERT_getCo(v, nextLvl); int sharpCount = 0, allSharp = 1; float avgSharpness = 0.0; + int seam = VERT_seam(v, ss), seamEdges = 0; for (i=0; i<v->numEdges; i++) { CCGEdge *e = v->edges[i]; float sharpness = EDGE_getSharpness(e, curLvl, ss); + if (seam && _edge_isBoundary(e)) + seamEdges++; + if (sharpness!=0.0f) { sharpCount++; avgSharpness += sharpness; @@ -1240,6 +1250,9 @@ static void ccgSubSurf__sync(CCGSubSurf *ss) { avgSharpness = 1.0; } + if (seam && seamEdges < 2) + seam = 0; + if (!v->numEdges) { VertDataCopy(nCo, co); } else if (_vert_isBoundary(v)) { @@ -1282,14 +1295,25 @@ static void ccgSubSurf__sync(CCGSubSurf *ss) { VertDataMulN(nCo, 1.0f/numEdges); } - if (sharpCount>1 && v->numFaces) { + if ((sharpCount>1 && v->numFaces) || seam) { VertDataZero(q); + if (seam) { + avgSharpness = 1.0f; + sharpCount = seamEdges; + allSharp = 1; + } + for (i=0; i<v->numEdges; i++) { CCGEdge *e = v->edges[i]; float sharpness = EDGE_getSharpness(e, curLvl, ss); - if (sharpness != 0.0) { + if (seam) { + if (_edge_isBoundary(e)) { + CCGVert *oV = _edge_getOtherVert(e, v); + VertDataAdd(q, VERT_getCo(oV, curLvl)); + } + } else if (sharpness != 0.0) { CCGVert *oV = _edge_getOtherVert(e, v); VertDataAdd(q, VERT_getCo(oV, curLvl)); } @@ -1502,11 +1526,15 @@ static void ccgSubSurf__sync(CCGSubSurf *ss) { void *nCo = VERT_getCo(v, nextLvl); int sharpCount = 0, allSharp = 1; float avgSharpness = 0.0; + int seam = VERT_seam(v, ss), seamEdges = 0; for (i=0; i<v->numEdges; i++) { CCGEdge *e = v->edges[i]; float sharpness = EDGE_getSharpness(e, curLvl, ss); + if (seam && _edge_isBoundary(e)) + seamEdges++; + if (sharpness!=0.0f) { sharpCount++; avgSharpness += sharpness; @@ -1520,6 +1548,9 @@ static void ccgSubSurf__sync(CCGSubSurf *ss) { avgSharpness = 1.0; } + if (seam && seamEdges < 2) + seam = 0; + if (!v->numEdges) { VertDataCopy(nCo, co); } else if (_vert_isBoundary(v)) { @@ -1564,14 +1595,23 @@ static void ccgSubSurf__sync(CCGSubSurf *ss) { VertDataMulN(nCo, 1.0f/numEdges); } - if (sharpCount>1 && v->numFaces) { + if ((sharpCount>1 && v->numFaces) || seam) { VertDataZero(q); + if (seam) { + avgSharpness = 1.0f; + sharpCount = seamEdges; + allSharp = 1; + } + for (i=0; i<v->numEdges; i++) { CCGEdge *e = v->edges[i]; float sharpness = EDGE_getSharpness(e, curLvl, ss); - if (sharpness != 0.0) { + if (seam) { + if (_edge_isBoundary(e)) + VertDataAdd(q, _edge_getCoVert(e, v, curLvl, 1, vertDataSize)); + } else if (sharpness != 0.0) { VertDataAdd(q, _edge_getCoVert(e, v, curLvl, 1, vertDataSize)); } } @@ -2121,6 +2161,9 @@ void *ccgSubSurf_getEdgeLevelData(CCGSubSurf *ss, CCGEdge *e, int x, int level) return _edge_getCo(e, level, x, ss->meshIFC.vertDataSize); } } +float ccgSubSurf_getEdgeCrease(CCGSubSurf *ss, CCGEdge *e) { + return e->crease; +} /* Face accessors */ diff --git a/source/blender/blenkernel/intern/CCGSubSurf.h b/source/blender/blenkernel/intern/CCGSubSurf.h index 9f276989bc5..91f3ffab43b 100644 --- a/source/blender/blenkernel/intern/CCGSubSurf.h +++ b/source/blender/blenkernel/intern/CCGSubSurf.h @@ -49,7 +49,7 @@ CCGError ccgSubSurf_sync (CCGSubSurf *ss); CCGError ccgSubSurf_initFullSync (CCGSubSurf *ss); CCGError ccgSubSurf_initPartialSync (CCGSubSurf *ss); -CCGError ccgSubSurf_syncVert (CCGSubSurf *ss, CCGVertHDL vHDL, void *vertData, CCGVert **v_r); +CCGError ccgSubSurf_syncVert (CCGSubSurf *ss, CCGVertHDL vHDL, void *vertData, int seam, CCGVert **v_r); CCGError ccgSubSurf_syncEdge (CCGSubSurf *ss, CCGEdgeHDL eHDL, CCGVertHDL e_vHDL0, CCGVertHDL e_vHDL1, float crease, CCGEdge **e_r); CCGError ccgSubSurf_syncFace (CCGSubSurf *ss, CCGFaceHDL fHDL, int numVerts, CCGVertHDL *vHDLs, CCGFace **f_r); @@ -99,6 +99,7 @@ int ccgSubSurf_getEdgeNumFaces (CCGSubSurf *ss, CCGEdge *e); CCGFace* ccgSubSurf_getEdgeFace (CCGSubSurf *ss, CCGEdge *e, int index); CCGVert* ccgSubSurf_getEdgeVert0 (CCGSubSurf *ss, CCGEdge *e); CCGVert* ccgSubSurf_getEdgeVert1 (CCGSubSurf *ss, CCGEdge *e); +float ccgSubSurf_getEdgeCrease (CCGSubSurf *ss, CCGEdge *e); int ccgSubSurf_getEdgeAge (CCGSubSurf *ss, CCGEdge *e); void* ccgSubSurf_getEdgeUserData (CCGSubSurf *ss, CCGEdge *e); diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 0156d77c161..1a26b52a0aa 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -2266,7 +2266,7 @@ void loadFluidsimMesh(Object *srcob, int useRenderParams) float *bbStart = NULL, *bbSize = NULL; float lastBB[3]; int displaymode = 0; - int curFrame = G.scene->r.cfra - G.scene->r.sfra; /* start with 0 at start frame */ + int curFrame = G.scene->r.cfra - 1 /*G.scene->r.sfra*/; /* start with 0 at start frame */ char targetDir[FILE_MAXFILE+FILE_MAXDIR], targetFile[FILE_MAXFILE+FILE_MAXDIR]; char debugStrBuffer[256]; //snprintf(debugStrBuffer,256,"loadFluidsimMesh call (obid '%s', rp %d)\n", srcob->id.name, useRenderParams); // debug diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index 95d328dcd5e..668e8d6e71c 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -291,6 +291,7 @@ void copy_displist(ListBase *lbn, ListBase *lb) static void initfastshade(void) { Base *base; + Scene *setscene; Object *ob; Lamp *la; FastLamp *fl; @@ -309,7 +310,7 @@ static void initfastshade(void) Mat4Invert(fviewmat, R.viewinv); /* initrendertexture(); */ - + setscene = G.scene->set; base= G.scene->base.first; while(base) { ob= base->object; @@ -349,8 +350,12 @@ static void initfastshade(void) fl->b= la->energy*la->b; } - if(base->next==0 && G.scene->set && base==G.scene->base.last) base= G.scene->set->base.first; - else base= base->next; + if(base->next==0 && setscene && setscene->set) {/*if(base->next==0 && G.scene->set && base==G.scene->base.last) {*/ + setscene = setscene->set; + base= setscene->base.first; /* base= G.scene->set->base.first;*/ + } else { + base= base->next; + } } } diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c index 8aee2c9e785..60ba7f3cfeb 100644 --- a/source/blender/blenkernel/intern/ipo.c +++ b/source/blender/blenkernel/intern/ipo.c @@ -126,7 +126,9 @@ int te_ar[TE_TOTIPO] ={ TE_MG_TYP, TE_MGH, TE_MG_LAC, TE_MG_OCT, TE_MG_OFF, TE_MG_GAIN, - TE_N_BAS1, TE_N_BAS2 + TE_N_BAS1, TE_N_BAS2, + + TE_COL_R, TE_COL_G, TE_COL_B, TE_BRIGHT, TE_CONTRA }; int seq_ar[SEQ_TOTIPO]= { @@ -1068,6 +1070,17 @@ static void *give_tex_poin(Tex *tex, int adrcode, int *type ) poin= &(tex->noisebasis); *type= IPO_SHORT; break; case TE_N_BAS2: poin= &(tex->noisebasis2); *type= IPO_SHORT; break; + case TE_COL_R: + poin= &(tex->rfac); break; + case TE_COL_G: + poin= &(tex->gfac); break; + case TE_COL_B: + poin= &(tex->bfac); break; + case TE_BRIGHT: + poin= &(tex->bright); break; + case TE_CONTRA: + poin= &(tex->contrast); break; + } return poin; @@ -1576,7 +1589,7 @@ void set_icu_vars(IpoCurve *icu) case TE_MG_TYP: icu->vartype= IPO_SHORT; icu->ipo= IPO_CONST; - icu->ymax= 4.0; break; + icu->ymax= 6.0; break; case TE_MGH: icu->ymin= 0.0001; icu->ymax= 2.0; break; @@ -1591,6 +1604,17 @@ void set_icu_vars(IpoCurve *icu) icu->vartype= IPO_SHORT; icu->ipo= IPO_CONST; icu->ymax= 8.0; break; + case TE_COL_R: + icu->ymax= 0.0; break; + case TE_COL_G: + icu->ymax= 2.0; break; + case TE_COL_B: + icu->ymax= 2.0; break; + case TE_BRIGHT: + icu->ymax= 2.0; break; + case TE_CONTRA: + icu->ymax= 5.0; break; + } } else if(icu->blocktype==ID_SEQ) { diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index ab213f78200..bbe2a35bcd4 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -1082,3 +1082,124 @@ float (*mesh_getVertexCos(Mesh *me, int *numVerts_r))[3] return cos; } + +/* UvVertMap */ + +struct UvVertMap { + struct UvMapVert **vert; + struct UvMapVert *buf; +}; + +UvVertMap *make_uv_vert_map(struct MFace *mface, struct TFace *tface, unsigned int totface, unsigned int totvert, int selected, float *limit) +{ + UvVertMap *vmap; + UvMapVert *buf; + MFace *mf; + TFace *tf; + int a, i, totuv, nverts; + + totuv = 0; + + /* generate UvMapVert array */ + mf= mface; + tf= tface; + for(a=0; a<totface; a++, mf++, tf++) + if(!selected || (!(tf->flag & TF_HIDE) && (tf->flag & TF_SELECT))) + totuv += (mf->v4)? 4: 3; + + if(totuv==0) + return NULL; + + vmap= (UvVertMap*)MEM_mallocN(sizeof(*vmap), "UvVertMap"); + if (!vmap) + return NULL; + + vmap->vert= (UvMapVert**)MEM_callocN(sizeof(*vmap->vert)*totvert, "UvMapVert*"); + buf= vmap->buf= (UvMapVert*)MEM_mallocN(sizeof(*vmap->buf)*totuv, "UvMapVert"); + + if (!vmap->vert || !vmap->buf) { + free_uv_vert_map(vmap); + return NULL; + } + + mf= mface; + tf= tface; + for(a=0; a<totface; a++, mf++, tf++) { + if(!selected || (!(tf->flag & TF_HIDE) && (tf->flag & TF_SELECT))) { + nverts= (mf->v4)? 4: 3; + + for(i=0; i<nverts; i++) { + buf->tfindex= i; + buf->f= a; + buf->separate = 0; + buf->next= vmap->vert[*(&mf->v1 + i)]; + vmap->vert[*(&mf->v1 + i)]= buf; + buf++; + } + } + } + + /* sort individual uvs for each vert */ + tf= tface; + for(a=0; a<totvert; a++) { + UvMapVert *newvlist= NULL, *vlist=vmap->vert[a]; + UvMapVert *iterv, *v, *lastv, *next; + float *uv, *uv2, uvdiff[2]; + + while(vlist) { + v= vlist; + vlist= vlist->next; + v->next= newvlist; + newvlist= v; + + uv= (tf+v->f)->uv[v->tfindex]; + lastv= NULL; + iterv= vlist; + + while(iterv) { + next= iterv->next; + + uv2= (tf+iterv->f)->uv[iterv->tfindex]; + Vec2Subf(uvdiff, uv2, uv); + + + if(fabs(uv[0]-uv2[0]) < limit[0] && fabs(uv[1]-uv2[1]) < limit[1]) { + if(lastv) lastv->next= next; + else vlist= next; + iterv->next= newvlist; + newvlist= iterv; + } + else + lastv=iterv; + + iterv= next; + } + + newvlist->separate = 1; + } + + vmap->vert[a]= newvlist; + } + + return vmap; +} + +UvMapVert *get_uv_map_vert(UvVertMap *vmap, unsigned int v) +{ + return vmap->vert[v]; +} + +UvMapVert *get_first_uv_map_vert(UvVertMap *vmap) +{ + return ((vmap->buf != NULL)? vmap->buf: NULL); +} + +void free_uv_vert_map(UvVertMap *vmap) +{ + if (vmap) { + if (vmap->vert) MEM_freeN(vmap->vert); + if (vmap->buf) MEM_freeN(vmap->buf); + MEM_freeN(vmap); + } +} + diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 34777930b4b..5f3a57ce4db 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -147,6 +147,7 @@ static void subsurfModifier_initData(ModifierData *md) smd->levels = 1; smd->renderLevels = 2; + smd->flags |= eSubsurfModifierFlag_SubsurfUv; } static void subsurfModifier_copyData(ModifierData *md, ModifierData *target) @@ -505,6 +506,7 @@ static DispListMesh *mirrorModifier__doMirror(MirrorModifierData *mmd, DispListM if (isShared) { mv->co[axis] = 0; + mv->flag |= ME_VERT_MERGED; } else { MVert *mv2 = &dlm->mvert[dlm->totvert++]; diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 3fb6a486dc3..6c64a954b49 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -56,6 +56,7 @@ #include "BLI_arithb.h" #include "BLI_linklist.h" #include "BLI_memarena.h" +#include "BLI_edgehash.h" #include "BIF_gl.h" @@ -66,6 +67,16 @@ typedef struct _VertData { float no[3]; } VertData; +struct CCGDerivedMesh { + DerivedMesh dm; + + CCGSubSurf *ss; + int fromEditmesh, drawInteriorEdges, useSubsurfUv; + + Mesh *me; + DispListMesh *dlm; +}; + typedef struct CCGDerivedMesh CCGDerivedMesh; static int ccgDM_getVertMapIndex(CCGDerivedMesh *ccgdm, CCGSubSurf *ss, CCGVert *v); @@ -194,6 +205,154 @@ static int getFaceIndex(CCGSubSurf *ss, CCGFace *f, int S, int x, int y, int edg } } +static float *getFaceUV(CCGSubSurf *ss, CCGFace *f, int S, int x, int y, int edgeSize, int gridSize) +{ + int numVerts = ccgSubSurf_getFaceNumVerts(ss, f); + + if (x==gridSize-1 && y==gridSize-1) { + CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S); + return ccgSubSurf_getVertData(ss, v); + } + else if (x==gridSize-1) { + CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S); + CCGEdge *e = ccgSubSurf_getFaceEdge(ss, f, S); + + if (v==ccgSubSurf_getEdgeVert0(ss, e)) + return ccgSubSurf_getEdgeData(ss, e, gridSize-1-y); + else + return ccgSubSurf_getEdgeData(ss, e, (edgeSize-2-1)-(gridSize-1-y-2)); + } + else if (y==gridSize-1) { + CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S); + CCGEdge *e = ccgSubSurf_getFaceEdge(ss, f, (S+numVerts-1)%numVerts); + + if (v==ccgSubSurf_getEdgeVert0(ss, e)) + return ccgSubSurf_getEdgeData(ss, e, gridSize-1-x); + else + return ccgSubSurf_getEdgeData(ss, e, (edgeSize-2-1)-(gridSize-1-x-2)); + } + else if (x==0 && y==0) + return ccgSubSurf_getFaceCenterData(ss, f); + else if (x==0) + return ccgSubSurf_getFaceGridEdgeData(ss, f, (S+numVerts-1)%numVerts, y); + else if (y==0) + return ccgSubSurf_getFaceGridEdgeData(ss, f, S, x); + else + return ccgSubSurf_getFaceGridData(ss, f, S, x, y); +} + +static void get_face_uv_map_vert(UvVertMap *vmap, struct MFace *mf, int fi, CCGVertHDL *fverts) { + unsigned int *fv = &mf->v1; + UvMapVert *v, *nv, *firstv = get_first_uv_map_vert(vmap); + int j, nverts= mf->v4? 4: 3; + + for (j=0; j<nverts; j++, fv++) { + for (nv=v=get_uv_map_vert(vmap, *fv); v; v=v->next) { + if (v->separate) + nv= v; + if (v->f == fi) + break; + } + + fverts[j]= (CCGVertHDL)(nv - firstv); + } +} + +static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, Mesh *me, DispListMesh *dlm) { + MFace *mface = dlm?dlm->mface:me->mface; + TFace *tface = dlm?dlm->tface:me->tface; + MVert *mvert = dlm?dlm->mvert:me->mvert; + int totvert = dlm?dlm->totvert:me->totvert; + int totface = dlm?dlm->totface:me->totface; + int i, j, seam; + UvMapVert *v, *firstv; + UvVertMap *vmap; + float limit[2]; + CCGVertHDL fverts[4]; + EdgeHash *ehash; + + limit[0]= limit[1]= 0.0001f; + vmap= make_uv_vert_map(mface, tface, totface, totvert, 0, limit); + if (!vmap) + return 0; + + ccgSubSurf_initFullSync(ss); + + /* use this to get consistent vert handles with different heap addresses */ + firstv= (totvert > 0)? get_first_uv_map_vert(vmap): NULL; + + /* create vertices */ + for (i=0; i<totvert; i++) { + for (v=get_uv_map_vert(vmap, i)->next; v; v=v->next) + if (v->separate) + break; + + seam = (v != NULL) || ((mvert+i)->flag & ME_VERT_MERGED); + + for (v=get_uv_map_vert(vmap, i); v; v=v->next) { + if (v->separate) { + CCGVert *ssv; + CCGVertHDL vhdl = (CCGVertHDL)(v - firstv); + float uv[3]; + + uv[0]= (tface+v->f)->uv[v->tfindex][0]; + uv[1]= (tface+v->f)->uv[v->tfindex][1]; + uv[2]= 0.0f; + + ccgSubSurf_syncVert(ss, vhdl, uv, seam, &ssv); + } + } + } + + /* create edges */ + ehash = BLI_edgehash_new(); + + for (i=0; i<totface; i++) { + MFace *mf = &((MFace*) mface)[i]; + int nverts= mf->v4? 4: 3; + CCGFace *origf= ccgSubSurf_getFace(origss, (CCGFaceHDL)i); + unsigned int *fv = &mf->v1; + + get_face_uv_map_vert(vmap, mf, i, fverts); + + for (j=0; j<nverts; j++) { + int v0 = (int)fverts[j]; + int v1 = (int)fverts[(j+1)%nverts]; + MVert *mv0 = mvert + *(fv+j); + MVert *mv1 = mvert + *(fv+((j+1)%nverts)); + + if (!BLI_edgehash_haskey(ehash, v0, v1)) { + CCGEdge *e, *orige= ccgSubSurf_getFaceEdge(origss, origf, j); + CCGEdgeHDL ehdl= (CCGEdgeHDL)((int)fverts[j], (int)fverts[(j+1)%nverts]); + float crease = ccgSubSurf_getEdgeCrease(origss, orige); + + if ((mv0->flag&mv1->flag) & ME_VERT_MERGED) + crease = 2.0f; + + ccgSubSurf_syncEdge(ss, ehdl, fverts[j], fverts[(j+1)%nverts], crease, &e); + BLI_edgehash_insert(ehash, v0, v1, NULL); + } + } + } + + BLI_edgehash_free(ehash, NULL); + + /* create faces */ + for (i=0; i<totface; i++) { + MFace *mf = &((MFace*) mface)[i]; + int nverts= mf->v4? 4: 3; + CCGFace *f; + + get_face_uv_map_vert(vmap, mf, i, fverts); + ccgSubSurf_syncFace(ss, (CCGFaceHDL)i, nverts, fverts, &f); + } + + free_uv_vert_map(vmap); + ccgSubSurf_processSync(ss); + + return 1; +} + #if 0 static unsigned int ss_getEdgeFlags(CCGSubSurf *ss, CCGEdge *e, int ssFromEditmesh, DispListMesh *dlm, MEdge *medge, TFace *tface) { @@ -225,7 +384,7 @@ static unsigned int ss_getEdgeFlags(CCGSubSurf *ss, CCGEdge *e, int ssFromEditme } #endif -static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, CCGDerivedMesh *ccgdm, int ssFromEditmesh, int drawInteriorEdges, Mesh *inMe, DispListMesh *inDLM) { +static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, CCGDerivedMesh *ccgdm, int ssFromEditmesh, int drawInteriorEdges, int useSubsurfUv, Mesh *inMe, DispListMesh *inDLM) { DispListMesh *dlm = MEM_callocN(sizeof(*dlm), "dlm"); int edgeSize = ccgSubSurf_getEdgeSize(ss); int gridSize = ccgSubSurf_getGridSize(ss); @@ -239,11 +398,12 @@ static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, CCGDerivedMesh *ccgdm, i CCGVertIterator *vi; CCGEdgeIterator *ei; CCGFaceIterator *fi; - CCGFace **faceMap2; + CCGFace **faceMap2, **faceMap2Uv = NULL; CCGEdge **edgeMap2; CCGVert **vertMap2; int totvert, totedge, totface; - + CCGSubSurf *uvss= NULL; + totvert = ccgSubSurf_getNumVerts(ss); vertMap2 = MEM_mallocN(totvert*sizeof(*vertMap2), "vertmap"); vi = ccgSubSurf_getVertIterator(ss); @@ -317,6 +477,23 @@ static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, CCGDerivedMesh *ccgdm, i dlm->mcol = NULL; } + + if (useSubsurfUv && tface) { + /* not for editmesh currently */ + uvss= _getSubSurf(NULL, ccgSubSurf_getSubdivisionLevels(ss), 0, 1, 0); + + if (ss_sync_from_uv(uvss, ss, inMe, inDLM)) { + faceMap2Uv = MEM_mallocN(totface*sizeof(*faceMap2Uv), "facemapuv"); + + fi = ccgSubSurf_getFaceIterator(uvss); + for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { + CCGFace *f = ccgFaceIterator_getCurrent(fi); + faceMap2Uv[(int) ccgSubSurf_getFaceFaceHandle(uvss, f)] = f; + } + ccgFaceIterator_free(fi); + } + } + /* Load vertices... we do in this funny order because * all "added" vertices" are required to appear first * in the displist (before STEPINDEX flags start). Also @@ -460,6 +637,7 @@ static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, CCGDerivedMesh *ccgdm, i lastIndex = -1; for (index=0; index<totface; index++) { CCGFace *f = faceMap2[index]; + CCGFace *uvf = faceMap2Uv? faceMap2Uv[index]: NULL; int numVerts = ccgSubSurf_getFaceNumVerts(ss, f); float edge_data[4][6]; float corner_data[4][6]; @@ -483,10 +661,12 @@ static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, CCGDerivedMesh *ccgdm, i corner_data[S][1] = col[1]/255.0f; corner_data[S][2] = col[2]/255.0f; corner_data[S][3] = col[3]/255.0f; - corner_data[S][4] = origTFace->uv[S][0]; - corner_data[S][5] = origTFace->uv[S][1]; + if (!uvf) { + corner_data[S][4] = origTFace->uv[S][0]; + corner_data[S][5] = origTFace->uv[S][1]; + } } - numDataComponents = 6; + numDataComponents = uvf? 4: 6; } else if (mcol) { MCol *origMCol = &mcol[origIdx*4]; @@ -523,6 +703,8 @@ static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, CCGDerivedMesh *ccgdm, i for (y=0; y<gridSize-1; y++) { for (x=0; x<gridSize-1; x++) { + float smoothuv[4][3]; + MFace *mf = &dlm->mface[i]; mf->v1 = getFaceIndex(ss, f, S, x+0, y+0, edgeSize, gridSize); mf->v2 = getFaceIndex(ss, f, S, x+0, y+1, edgeSize, gridSize); @@ -531,6 +713,13 @@ static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, CCGDerivedMesh *ccgdm, i mf->mat_nr = mat_nr; mf->flag = flag&~ME_FACE_STEPINDEX; + if(uvf) { + VECCOPY(smoothuv[0], getFaceUV(uvss, uvf, S, x+0, y+0, edgeSize, gridSize)); + VECCOPY(smoothuv[1], getFaceUV(uvss, uvf, S, x+0, y+1, edgeSize, gridSize)); + VECCOPY(smoothuv[2], getFaceUV(uvss, uvf, S, x+1, y+1, edgeSize, gridSize)); + VECCOPY(smoothuv[3], getFaceUV(uvss, uvf, S, x+1, y+0, edgeSize, gridSize)); + } + if (S==0 && x==0 && y==0) { if (mapIndex!=lastIndex) mf->flag |= ME_FACE_STEPINDEX; @@ -557,8 +746,14 @@ static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, CCGDerivedMesh *ccgdm, i col[2] = (int) (data[2]*255); col[3] = (int) (data[3]*255); tf->col[j] = *((unsigned int*) col); - tf->uv[j][0] = data[4]; - tf->uv[j][1] = data[5]; + if (uvf) { + tf->uv[j][0] = smoothuv[j][0]; + tf->uv[j][1] = smoothuv[j][1]; + } + else { + tf->uv[j][0] = (float)(data[4]); + tf->uv[j][1] = (float)(data[5]); + } } else if (dlm->mcol) { unsigned char *col = (unsigned char*) &dlm->mcol[i*4+j]; col[0] = (int) (data[0]*255); @@ -587,6 +782,11 @@ static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, CCGDerivedMesh *ccgdm, i MEM_freeN(edgeMap2); MEM_freeN(vertMap2); + if(uvss) { + ccgSubSurf_free(uvss); + MEM_freeN(faceMap2Uv); + } + mesh_calc_normals(dlm->mvert, dlm->totvert, dlm->mface, dlm->totface, &dlm->nors); return dlm; @@ -607,7 +807,7 @@ static void ss_sync_from_mesh(CCGSubSurf *ss, Mesh *me, DispListMesh *dlm, float for (i=0,index=-1; i<totvert; i++) { CCGVert *v; - ccgSubSurf_syncVert(ss, (CCGVertHDL) i, vertexCos?vertexCos[i]:mvert[i].co, &v); + ccgSubSurf_syncVert(ss, (CCGVertHDL) i, vertexCos?vertexCos[i]:mvert[i].co, 0, &v); if (!dlm || (mvert[i].flag&ME_VERT_STEPINDEX)) index++; ((int*) ccgSubSurf_getVertUserData(ss, v))[1] = index; @@ -676,13 +876,13 @@ void ss_sync_from_editmesh(CCGSubSurf *ss, EditMesh *em, float (*vertCos)[3], in if (vertCos) { for (i=0,ev=em->verts.first; ev; i++,ev=ev->next) { CCGVert *v; - ccgSubSurf_syncVert(ss, ev, vertCos[i], &v); + ccgSubSurf_syncVert(ss, ev, vertCos[i], 0, &v); ((int*) ccgSubSurf_getVertUserData(ss, v))[1] = i; } } else { for (i=0,ev=em->verts.first; ev; i++,ev=ev->next) { CCGVert *v; - ccgSubSurf_syncVert(ss, ev, ev->co, &v); + ccgSubSurf_syncVert(ss, ev, ev->co, 0, &v); ((int*) ccgSubSurf_getVertUserData(ss, v))[1] = i; } } @@ -710,16 +910,6 @@ void ss_sync_from_editmesh(CCGSubSurf *ss, EditMesh *em, float (*vertCos)[3], in /***/ -struct CCGDerivedMesh { - DerivedMesh dm; - - CCGSubSurf *ss; - int fromEditmesh, drawInteriorEdges; - - Mesh *me; - DispListMesh *dlm; -}; - static int ccgDM_getVertMapIndex(CCGDerivedMesh *ccgdm, CCGSubSurf *ss, CCGVert *v) { return ((int*) ccgSubSurf_getVertUserData(ss, v))[1]; } @@ -918,7 +1108,7 @@ static void ccgDM_foreachMappedEdge(DerivedMesh *dm, void (*func)(void *userData static DispListMesh *ccgDM_convertToDispListMesh(DerivedMesh *dm, int allowShared) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; - return ss_to_displistmesh(ccgdm->ss, ccgdm, ccgdm->fromEditmesh, ccgdm->drawInteriorEdges, ccgdm->me, ccgdm->dlm); + return ss_to_displistmesh(ccgdm->ss, ccgdm, ccgdm->fromEditmesh, ccgdm->drawInteriorEdges, ccgdm->useSubsurfUv, ccgdm->me, ccgdm->dlm); } static void ccgDM_drawVerts(DerivedMesh *dm) { @@ -1452,7 +1642,7 @@ static void ccgDM_release(DerivedMesh *dm) { MEM_freeN(ccgdm); } -static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, int fromEditmesh, int drawInteriorEdges, Mesh *me, DispListMesh *dlm) { +static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, int fromEditmesh, int drawInteriorEdges, int useSubsurfUv, Mesh *me, DispListMesh *dlm) { CCGDerivedMesh *ccgdm = MEM_callocN(sizeof(*ccgdm), "ccgdm"); ccgdm->dm.getMinMax = ccgDM_getMinMax; @@ -1480,6 +1670,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, int fromEditmesh, int d ccgdm->ss = ss; ccgdm->fromEditmesh = fromEditmesh; ccgdm->drawInteriorEdges = drawInteriorEdges; + ccgdm->useSubsurfUv = useSubsurfUv; ccgdm->me = me; ccgdm->dlm = dlm; @@ -1496,23 +1687,25 @@ DerivedMesh *subsurf_make_derived_from_editmesh(EditMesh *em, SubsurfModifierDat smd->emCache = _getSubSurf(smd->emCache, smd->levels, useAging, 0, useSimple); ss_sync_from_editmesh(smd->emCache, em, vertCos, useSimple); - return (DerivedMesh*) getCCGDerivedMesh(smd->emCache, 1, drawInteriorEdges, NULL, NULL); + return (DerivedMesh*) getCCGDerivedMesh(smd->emCache, 1, drawInteriorEdges, 0, NULL, NULL); } DerivedMesh *subsurf_make_derived_from_dlm_em(DispListMesh *dlm, SubsurfModifierData *smd, float (*vertCos)[3]) { int useSimple = smd->subdivType==ME_SIMPLE_SUBSURF; int useAging = smd->flags&eSubsurfModifierFlag_DebugIncr; + int useSubsurfUv = smd->flags&eSubsurfModifierFlag_SubsurfUv; int drawInteriorEdges = !(smd->flags&eSubsurfModifierFlag_ControlEdges); smd->emCache = _getSubSurf(smd->emCache, smd->levels, useAging, 0, useSimple); ss_sync_from_mesh(smd->emCache, NULL, dlm, vertCos, useSimple); - return (DerivedMesh*) getCCGDerivedMesh(smd->emCache, 0, drawInteriorEdges, NULL, dlm); + return (DerivedMesh*) getCCGDerivedMesh(smd->emCache, 0, drawInteriorEdges, useSubsurfUv, NULL, dlm); } DerivedMesh *subsurf_make_derived_from_mesh(Mesh *me, DispListMesh *dlm, SubsurfModifierData *smd, int useRenderParams, float (*vertCos)[3], int isFinalCalc) { int useSimple = smd->subdivType==ME_SIMPLE_SUBSURF; + int useSubsurfUv = smd->flags&eSubsurfModifierFlag_SubsurfUv; int drawInteriorEdges = !(smd->flags&eSubsurfModifierFlag_ControlEdges); DispListMesh *ndlm; @@ -1522,7 +1715,7 @@ DerivedMesh *subsurf_make_derived_from_mesh(Mesh *me, DispListMesh *dlm, Subsurf ss_sync_from_mesh(ss, me, dlm, vertCos, useSimple); - ndlm = ss_to_displistmesh(ss, NULL, 0, drawInteriorEdges, me, dlm); + ndlm = ss_to_displistmesh(ss, NULL, 0, drawInteriorEdges, useSubsurfUv, me, dlm); if (dlm) displistmesh_free(dlm); ccgSubSurf_free(ss); @@ -1551,7 +1744,7 @@ DerivedMesh *subsurf_make_derived_from_mesh(Mesh *me, DispListMesh *dlm, Subsurf ss_sync_from_mesh(ss, me, dlm, vertCos, useSimple); - return (DerivedMesh*) getCCGDerivedMesh(ss, 0, drawInteriorEdges, me, dlm); + return (DerivedMesh*) getCCGDerivedMesh(ss, 0, drawInteriorEdges, useSubsurfUv, me, dlm); } else { if (smd->mCache && isFinalCalc) { ccgSubSurf_free(smd->mCache); @@ -1561,7 +1754,7 @@ DerivedMesh *subsurf_make_derived_from_mesh(Mesh *me, DispListMesh *dlm, Subsurf ss = _getSubSurf(NULL, smd->levels, 0, 1, useSimple); ss_sync_from_mesh(ss, me, dlm, vertCos, useSimple); - ndlm = ss_to_displistmesh(ss, NULL, 0, drawInteriorEdges, me, dlm); + ndlm = ss_to_displistmesh(ss, NULL, 0, drawInteriorEdges, useSubsurfUv, me, dlm); if (dlm) displistmesh_free(dlm); ccgSubSurf_free(ss); diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c index 330d46c959f..ea0134470f1 100644 --- a/source/blender/blenkernel/intern/text.c +++ b/source/blender/blenkernel/intern/text.c @@ -320,7 +320,8 @@ Text *add_text(char *file) char str[FILE_MAXDIR+FILE_MAXFILE]; BLI_strncpy(str, file, FILE_MAXDIR+FILE_MAXFILE); - BLI_convertstringcode(str, G.sce, G.scene->r.cfra); + if (G.scene) /* can be NULL (bg mode) */ + BLI_convertstringcode(str, G.sce, G.scene->r.cfra); BLI_split_dirfile(str, sdir, sfile); fp= fopen(str, "r"); |