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 | |
parent | d594594cbe9c9eb3bc3c8a7708601e68693d324d (diff) | |
parent | 185c6bb49ce994d66fc67673b01a014161fa307d (diff) |
Tuesday merger of bf-blender into orange branch.
Diffstat (limited to 'source/blender')
42 files changed, 1115 insertions, 369 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"); diff --git a/source/blender/makesdna/DNA_ipo_types.h b/source/blender/makesdna/DNA_ipo_types.h index b3cb0c81148..c05c27ede6b 100644 --- a/source/blender/makesdna/DNA_ipo_types.h +++ b/source/blender/makesdna/DNA_ipo_types.h @@ -171,8 +171,8 @@ typedef short IPO_Channel; /* ******************** */ -#define TE_TOTIPO 21 -#define TE_TOTNAM 21 +#define TE_TOTIPO 26 +#define TE_TOTNAM 26 #define TE_NSIZE 1 #define TE_NDEPTH 2 @@ -200,6 +200,12 @@ typedef short IPO_Channel; #define TE_N_BAS1 20 #define TE_N_BAS2 21 +#define TE_COL_R 22 +#define TE_COL_G 23 +#define TE_COL_B 24 +#define TE_BRIGHT 25 +#define TE_CONTRA 26 + /* ******************** */ #define SEQ_TOTIPO 1 diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h index eaacdb3a398..9fe5a3acacf 100644 --- a/source/blender/makesdna/DNA_meshdata_types.h +++ b/source/blender/makesdna/DNA_meshdata_types.h @@ -75,6 +75,7 @@ typedef struct MSticky { #define ME_SPHERETEST 2 #define ME_SPHERETEMP 4 #define ME_HIDE 16 +#define ME_VERT_MERGED (1<<6) #define ME_VERT_STEPINDEX (1<<7) /* medge->flag (1=SELECT)*/ diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index b1b8239ac7d..19128bd0286 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -47,7 +47,8 @@ typedef struct ModifierData { typedef enum { eSubsurfModifierFlag_Incremental = (1<<0), eSubsurfModifierFlag_DebugIncr = (1<<1), - eSubsurfModifierFlag_ControlEdges = (1<<2) + eSubsurfModifierFlag_ControlEdges = (1<<2), + eSubsurfModifierFlag_SubsurfUv = (1<<3) } SubsurfModifierFlag; typedef struct SubsurfModifierData { diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index cc9d090a5e3..12de019dd16 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -318,7 +318,7 @@ typedef struct Scene { /* none of the dependancy graph vars is mean to be saved */ struct DagForest *theDag; short dagisvalid, dagflags; - int pad1; + int dirty; } Scene; @@ -424,6 +424,10 @@ typedef struct Scene { #define SCE_SELECT_EDGE 2 #define SCE_SELECT_FACE 4 +/* sce->dirty */ +#define SCE_CLEAN 0 +#define SCE_DIRTY 1 + /* sce->prop_mode (proportional falloff) */ #define PROP_SMOOTH 0 #define PROP_SPHERE 1 diff --git a/source/blender/python/api2_2x/Bone.c b/source/blender/python/api2_2x/Bone.c index d4f59e67ee5..b4f8af4fe12 100644 --- a/source/blender/python/api2_2x/Bone.c +++ b/source/blender/python/api2_2x/Bone.c @@ -460,11 +460,12 @@ static int EditBone_setOptions(BPy_EditBone *self, PyObject *value, void *closur //set the options if(self->editbone){ //make sure the 'connected' property is set up correctly - if (new_flag & BONE_CONNECTED) + if (new_flag & BONE_CONNECTED) { if(!self->editbone->parent) goto AttributeError3; else VECCOPY(self->editbone->head, self->editbone->parent->tail); + } self->editbone->flag = new_flag; }else{ self->flag = new_flag; @@ -479,11 +480,12 @@ static int EditBone_setOptions(BPy_EditBone *self, PyObject *value, void *closur if(self->editbone){ //make sure the 'connected' property is set up correctly - if (numeric_value & BONE_CONNECTED) + if (numeric_value & BONE_CONNECTED) { if(!self->editbone->parent) goto AttributeError3; else VECCOPY(self->editbone->head, self->editbone->parent->tail); + } self->editbone->flag = numeric_value; }else{ self->flag = numeric_value; diff --git a/source/blender/python/api2_2x/Draw.c b/source/blender/python/api2_2x/Draw.c index 57802c47746..198f4dfbd65 100644 --- a/source/blender/python/api2_2x/Draw.c +++ b/source/blender/python/api2_2x/Draw.c @@ -107,6 +107,8 @@ static PyObject *Method_PupFloatInput( PyObject * self, PyObject * args ); static PyObject *Method_PupStrInput( PyObject * self, PyObject * args ); /* next by Jonathan Merritt (lancelet): */ static PyObject *Method_Image( PyObject * self, PyObject * args); +/* CLEVER NUMBUT */ +static PyObject *Method_PupBlock( PyObject * self, PyObject * args ); static uiBlock *Get_uiBlock( void ); static void py_slider_update( void *butv, void *data2_unused ); @@ -277,6 +279,22 @@ static char Method_PupStrInput_doc[] = (max = 20) - The maximum number of chars the user can input;\n\ Return the user input value or None on user exit"; +static char Method_PupBlock_doc[] = + "(title, sequence) - Display a pop-up block.\n\ +(title) - The title of the block.\n\ +(sequence) - A sequence defining what the block contains. \ +The order of the list is the order of appearance, from top down.\n\ +Possible format for sequence items:\n\ +[value is an object created with Create]\n\ +\ttext: Defines a label in the block\n\ +\t(text, value, tooltip = ''): Defines a toggle button \n\ +\t(text, value, min, max, tooltip = ''): Defines a num or string button \n\ +\t\t\tdepending on the value.\n\ +\t\tFor string, max is the maximum length of the text and min is unused.\n\ +Return 1 if the pop-up is confirmed, 0 otherwise. \n\ +Warning: On cancel, the value objects are brought back to there previous values, \ +\texcept for string values which will still contain the modified values.\n"; + static char Method_Exit_doc[] = "() - Exit the windowing interface"; /* @@ -307,6 +325,7 @@ static struct PyMethodDef Draw_methods[] = { MethodDef( PupIntInput ), MethodDef( PupFloatInput ), MethodDef( PupStrInput ), + MethodDef( PupBlock ), MethodDef( Image ), MethodDef( Exit ), MethodDef( Redraw ), @@ -335,7 +354,7 @@ static void Button_dealloc( PyObject * self ) { Button *but = ( Button * ) self; - if( but->type == 3 ) { + if( but->type == BSTRING_TYPE ) { if( but->val.asstr ) MEM_freeN( but->val.asstr ); } @@ -348,11 +367,11 @@ static PyObject *Button_getattr( PyObject * self, char *name ) Button *but = ( Button * ) self; if( strcmp( name, "val" ) == 0 ) { - if( but->type == 1 ) + if( but->type == BINT_TYPE ) return Py_BuildValue( "i", but->val.asint ); - else if( but->type == 2 ) + else if( but->type == BFLOAT_TYPE ) return Py_BuildValue( "f", but->val.asfloat ); - else if( but->type == 3 ) + else if( but->type == BSTRING_TYPE ) return Py_BuildValue( "s", but->val.asstr ); } @@ -365,11 +384,11 @@ static int Button_setattr( PyObject * self, char *name, PyObject * v ) Button *but = ( Button * ) self; if( strcmp( name, "val" ) == 0 ) { - if( but->type == 1 ) + if( but->type == BINT_TYPE ) PyArg_Parse( v, "i", &but->val.asint ); - else if( but->type == 2 ) + else if( but->type == BFLOAT_TYPE ) PyArg_Parse( v, "f", &but->val.asfloat ); - else if( but->type == 3 ) { + else if( but->type == BSTRING_TYPE ) { char *newstr; PyArg_Parse( v, "s", &newstr ); @@ -705,15 +724,15 @@ static PyObject *Method_Create( PyObject * self, PyObject * args ) but = newbutton( ); if( PyFloat_Check( in ) ) { - but->type = 2; + but->type = BFLOAT_TYPE; but->val.asfloat = (float)PyFloat_AsDouble( in ); } else if( PyInt_Check( in ) ) { - but->type = 1; + but->type = BINT_TYPE; but->val.asint = PyInt_AsLong( in ); } else if( PyString_Check( in ) ) { char *newstr = PyString_AsString( in ); - but->type = 3; + but->type = BSTRING_TYPE; but->slen = strlen( newstr ); but->val.asstr = MEM_mallocN( but->slen + 1, "button string" ); @@ -790,7 +809,7 @@ static PyObject *Method_Menu( PyObject * self, PyObject * args ) "button event argument must be in the range [0, 16382]"); but = newbutton( ); - but->type = 1; + but->type = BINT_TYPE; but->val.asint = def; block = Get_uiBlock( ); @@ -819,7 +838,7 @@ static PyObject *Method_Toggle( PyObject * self, PyObject * args ) "button event argument must be in the range [0, 16382]"); but = newbutton( ); - but->type = 1; + but->type = BINT_TYPE; but->val.asint = def; block = Get_uiBlock( ); @@ -895,7 +914,7 @@ static PyObject *Method_Slider( PyObject * self, PyObject * args ) min = (float)PyFloat_AsDouble( mino ); max = (float)PyFloat_AsDouble( maxo ); - but->type = 2; + but->type = BFLOAT_TYPE; but->val.asfloat = ini; block = Get_uiBlock( ); @@ -915,7 +934,7 @@ static PyObject *Method_Slider( PyObject * self, PyObject * args ) min = PyInt_AsLong( mino ); max = PyInt_AsLong( maxo ); - but->type = 1; + but->type = BINT_TYPE; but->val.asint = ini; block = Get_uiBlock( ); @@ -960,15 +979,15 @@ another int and string as arguments" ); but = newbutton( ); if( PyFloat_Check( inio ) ) - but->type = 2; + but->type = BFLOAT_TYPE; else - but->type = 1; + but->type = BINT_TYPE; ini = (float)PyFloat_AsDouble( inio ); min = (float)PyFloat_AsDouble( mino ); max = (float)PyFloat_AsDouble( maxo ); - if( but->type == 2 ) { + if( but->type == BFLOAT_TYPE ) { but->val.asfloat = ini; block = Get_uiBlock( ); if( block ) { @@ -1025,7 +1044,7 @@ static PyObject *Method_Number( PyObject * self, PyObject * args ) min = (float)PyFloat_AsDouble( mino ); max = (float)PyFloat_AsDouble( maxo ); - but->type = 2; + but->type = BFLOAT_TYPE; but->val.asfloat = ini; block = Get_uiBlock( ); @@ -1039,7 +1058,7 @@ static PyObject *Method_Number( PyObject * self, PyObject * args ) min = PyInt_AsLong( mino ); max = PyInt_AsLong( maxo ); - but->type = 1; + but->type = BINT_TYPE; but->val.asint = ini; block = Get_uiBlock( ); @@ -1079,7 +1098,7 @@ static PyObject *Method_String( PyObject * self, PyObject * args ) if (real_len > len) real_len = len; but = newbutton( ); - but->type = 3; + but->type = BSTRING_TYPE; but->slen = len; but->val.asstr = MEM_mallocN( len + 1, "pybutton str" ); @@ -1260,6 +1279,125 @@ static PyObject *Method_PupStrInput( PyObject * self, PyObject * args ) "couldn't create a PyString" ); } +static PyObject *Method_PupBlock( PyObject * self, PyObject * args ) +{ + PyObject *pyList, *pyItem; + float min, max; + int len, i; + char *title; + + if (!PyArg_ParseTuple( args, "sO", &title, &pyList ) || !PySequence_Check( pyList )) + return EXPP_ReturnPyObjError( PyExc_TypeError, "expected a string and a sequence" ); + + + len = PySequence_Length(pyList); + + if (len == 0) + return EXPP_ReturnPyObjError( PyExc_ValueError, "expected a string and a non-empty sequence." ); + + if (len > 24) /* LIMIT DEFINED IN toolbox.c */ + return EXPP_ReturnPyObjError( PyExc_ValueError, "sequence cannot have more than 24 elements" ); + + for ( i=0 ; i<len ; i++ ) { + PyObject *pyMin = NULL, *pyMax = NULL; + PyObject *f1, *f2; + Button *but = NULL; + int tlen; + char *text, *tip = NULL; + + pyItem = PySequence_GetItem( pyList, i ); + if (!pyItem) + return NULL; + + if (PyString_Check( pyItem )) { + tlen = -2; /* single string for label, giving it a special len for later */ + } + else if (PyTuple_Check( pyItem )) { + /* tuple for other button, get the length for later */ + tlen = PyTuple_Size( pyItem ); + } + else { + /* Neither a string or a tuple, error */ + Py_DECREF( pyItem ); + return EXPP_ReturnPyObjError( PyExc_ValueError, "expected a string or a tuple containing 2 to 5 values." ); + } + + switch (tlen) { + case -2: /* LABEL */ + text = PyString_AsString( pyItem ); + add_numbut(i, LABEL, text, 0, 0, NULL, NULL); + break; + case 2: /* TOGGLE (no tooltip) */ + case 3: /* TOGGLE */ + if (!PyArg_ParseTuple( pyItem, "sO!|s", &text, &Button_Type, &but, &tip )) { + Py_DECREF( pyItem ); + return EXPP_ReturnPyObjError( PyExc_ValueError, "expected a tuple containing a string, a Button object and optionally a string for toggles" ); + } + + if (but->type != BINT_TYPE) { + Py_DECREF( pyItem ); + return EXPP_ReturnPyObjError( PyExc_ValueError, "Button object for toggles should hold an integer" ); + } + + add_numbut(i, TOG|INT, text, 0, 0, &but->val.asint, tip); + break; + case 4: /* TEX and NUM (no tooltip) */ + case 5: /* TEX and NUM */ + if (!PyArg_ParseTuple( pyItem, "sO!OO|s", &text, &Button_Type, &but, &pyMin, &pyMax, &tip )) { + Py_DECREF( pyItem ); + return EXPP_ReturnPyObjError( PyExc_ValueError, "expected a tuple containing a string, a Button object, two numerical values and optionally a string for Text and Num buttons" ); + } + + f1 = PyNumber_Float(pyMin); + f2 = PyNumber_Float(pyMax); + + if (!f1 || !f2) { + Py_DECREF( pyItem ); + return EXPP_ReturnPyObjError( PyExc_ValueError, "expected a tuple containing a string, a Button object, two numerical values and optionally a string for Text and Num buttons" ); + } + + min = (float)PyFloat_AS_DOUBLE(f1); + max = (float)PyFloat_AS_DOUBLE(f2); + Py_DECREF( f1 ); + Py_DECREF( f2 ); + + switch ( but->type ) { + case BINT_TYPE: + add_numbut(i, NUM|INT, text, min, max, &but->val.asint, tip); + break; + case BFLOAT_TYPE: + add_numbut(i, NUM|FLO, text, min, max, &but->val.asfloat, tip); + break; + case BSTRING_TYPE: + max = (float)floor(max); + + if (max > but->slen) { + int old_len = but->slen; + char *old_str = but->val.asstr; + but->slen = (int)max; + but->val.asstr = MEM_callocN( but->slen + 1, "button pupblock"); + BLI_strncpy( but->val.asstr, old_str, old_len + 1 ); + MEM_freeN(old_str); + } + + add_numbut(i, TEX, text, 0.0f, max, but->val.asstr, tip); + } + + break; + default: + Py_DECREF( pyItem ); + return EXPP_ReturnPyObjError( PyExc_ValueError, "expected a string or a tuple containing 2 to 5 values." ); + } + Py_DECREF( pyItem ); + } + + if (do_clever_numbuts(title, len, REDRAW)) + return EXPP_incr_ret_True(); + else + return EXPP_incr_ret_False(); +} + + /***************************************************************************** * Function: Method_Image * * Python equivalent: Blender.Draw.Image * diff --git a/source/blender/python/api2_2x/Draw.h b/source/blender/python/api2_2x/Draw.h index c644fd8ea35..ac3b7b53f3a 100644 --- a/source/blender/python/api2_2x/Draw.h +++ b/source/blender/python/api2_2x/Draw.h @@ -59,6 +59,10 @@ typedef struct _Button { char *tooltip; } Button; +#define BINT_TYPE 1 +#define BFLOAT_TYPE 2 +#define BSTRING_TYPE 3 + /* * these are declared in ../BPY_extern.h diff --git a/source/blender/python/api2_2x/Ipo.c b/source/blender/python/api2_2x/Ipo.c index 51a70706ae4..74107bd396a 100644 --- a/source/blender/python/api2_2x/Ipo.c +++ b/source/blender/python/api2_2x/Ipo.c @@ -914,9 +914,9 @@ static PyObject *Ipo_addCurve( BPy_Ipo * self, PyObject * args ) /* create the new ipo curve */ icu = MEM_callocN(sizeof(IpoCurve), "Python added ipocurve"); icu->blocktype= ipo->blocktype; - icu->flag |= IPO_VISIBLE|IPO_AUTO_HORIZ; - icu->blocktype= ipo->blocktype; icu->adrcode= (short)param; + icu->flag |= IPO_VISIBLE|IPO_AUTO_HORIZ; + set_icu_vars( icu ); BLI_addtail( &(ipo->curve), icu); allspace( REMAKEIPO, 0 ); diff --git a/source/blender/python/api2_2x/Object.c b/source/blender/python/api2_2x/Object.c index af945ea09c0..77179aad819 100644 --- a/source/blender/python/api2_2x/Object.c +++ b/source/blender/python/api2_2x/Object.c @@ -1856,16 +1856,11 @@ static PyObject *Object_join( BPy_Object * self, PyObject * args ) Base *temp_base; short type; int i, ok=0, ret_value=0, list_length=0; - - /* cant join in editmode */ - if( G.obedit ) - return EXPP_ReturnPyObjError(PyExc_RuntimeError, - "can't join objects while in edit mode" ); /* Check if the arguments passed to makeParent are valid. */ if( !PyArg_ParseTuple( args, "O", &list ) ) - return ( EXPP_ReturnPyObjError( PyExc_AttributeError, - "expected a list of objects and one or two integers as arguments" ) ); + return ( EXPP_ReturnPyObjError( PyExc_TypeError, + "expected a list of objects" ) ); if( !PySequence_Check( list ) ) return ( EXPP_ReturnPyObjError( PyExc_TypeError, @@ -1880,11 +1875,16 @@ static PyObject *Object_join( BPy_Object * self, PyObject * args ) parent = ( Object * ) self->object; type = parent->type; + /* Only these object types are sypported */ if (type==OB_MESH || type==OB_MESH || type==OB_CURVE || type==OB_SURF || type==OB_ARMATURE); else return ( EXPP_ReturnPyObjError( PyExc_TypeError, "Base object is not a type blender can join" ) ); + /* exit editmode so join can be done */ + if( G.obedit ) + exit_editmode( 1 ); + temp_scene = add_scene( "Scene" ); /* make the new scene */ temp_scene->lay= 2097151; /* all layers on */ @@ -1940,8 +1940,9 @@ static PyObject *Object_join( BPy_Object * self, PyObject * args ) else if(type == OB_SURF) ret_value = join_curve(OB_SURF); else if(type == OB_ARMATURE) - ret_value = join_armature (); - /* May use for correcting object user counts */ + ret_value = join_armature(); + + /* May use this for correcting object user counts later on */ /* if (!ret_value) { temp_base = temp_scene->base.first; @@ -1952,15 +1953,23 @@ static PyObject *Object_join( BPy_Object * self, PyObject * args ) } }*/ - /* remove old scene */ set_scene( orig_scene ); free_libblock( &G.main->scene, temp_scene ); - if (!ok) /* no objects were of the correct type, return 0 */ - return ( PyInt_FromLong(0) ); - return ( PyInt_FromLong(ret_value) ); + /* no objects were of the correct type, return None */ + if (!ok) + return EXPP_incr_ret( Py_None ); + + /* If the join failed then raise an error */ + if (!ret_value) + return ( EXPP_ReturnPyObjError( PyExc_RuntimeError, +"Blender failed to join the objects, this is not a script error\n\ +Please add exception handeling to your script with a RuntimeError exception\n\ +letting the user know that their data could not be joined." ) ); + + return EXPP_incr_ret( Py_None ); } static PyObject *internal_makeParent(Object *parent, PyObject *py_child, diff --git a/source/blender/python/api2_2x/Scene.c b/source/blender/python/api2_2x/Scene.c index 90aa548d7ce..4f1ce26778d 100644 --- a/source/blender/python/api2_2x/Scene.c +++ b/source/blender/python/api2_2x/Scene.c @@ -934,7 +934,7 @@ static PyObject *Scene_setCurrentCamera( BPy_Scene * self, PyObject * args ) scene->camera = object; /* set the current Camera */ /* if this is the current scene, update its window now */ - if( scene == G.scene ) + if( !G.background && scene == G.scene ) /* Traced a crash to redrawing while in background mode -Campbell */ copy_view3d_lock( REDRAW ); /* XXX copy_view3d_lock(REDRAW) prints "bad call to addqueue: 0 (18, 1)". diff --git a/source/blender/python/api2_2x/doc/Draw.py b/source/blender/python/api2_2x/doc/Draw.py index b88eade5d00..3f972beae84 100644 --- a/source/blender/python/api2_2x/doc/Draw.py +++ b/source/blender/python/api2_2x/doc/Draw.py @@ -9,6 +9,7 @@ Draw B{New}: - access to ASCII values in L{events<Register>} callbacks; - 'large' fonts for L{Text} and L{GetStringWidth}. + - Pop-up blocks with L{PupBlock} This module provides access to a B{windowing interface} in Blender. Its widgets include many kinds of buttons: push, toggle, menu, number, string, slider, @@ -406,6 +407,50 @@ def PupStrInput(text, default, max = 20): @return: The text entered by the user or None if none was chosen. """ +def PupBlock(title, sequence): + """ + Display a pop-up block. + + Possible formats for the items in the sequence parameter. + (Value are objects created with L{Create}) + - string: Defines a label + - (string, Value, string): Defines a toggle button. The first string is the text on the button, the optional second string is the tooltip. + - (string, Value, min, max, string): Defines a numeric or string button, depending on the content of Value. The first string is the text on the button, the optional second string is the tooltip. I{For string, max is the maximum length of the string and min is unused.} + + Example:: + import Blender + + text = Blender.Draw.Create("short text") + f = Blender.Draw.Create(1.0) + i = Blender.Draw.Create(2) + tog = Blender.Draw.Create(0) + + block = [] + + block.append(("Name: ", text, 0, 30, "this is some tool tip")) + block.append("Some Label") + block.append(("Value: ", f, 0.0, 100.0)) + block.append(("Value: ", i, 0, 100)) + block.append(("Option", tog, "another tooltip")) + + retval = Blender.Draw.PupBlock("PupBlock test", block) + + print "PupBlock returned", retval + + print "text\\t", text + print "float\\t", f + print "int\\t", i + print "toggle\\t", tog + + @warning: On cancel, the Value objects are brought back to there initial values except for string values which will still contain the modified values. + @type title: string + @param title: The title of the block. + @param sequence: A sequence defining what the block contains. + The order of the list is the order of appearance, from top down. + @rtype: int + @return: 1 if the pop-up is confirmed, 0 otherwise + """ + def Menu(name, event, x, y, width, height, default, tooltip = None): """ Create a new Menu Button object. diff --git a/source/blender/python/api2_2x/doc/Lamp.py b/source/blender/python/api2_2x/doc/Lamp.py index b1e0754c05c..20a25db41ac 100644 --- a/source/blender/python/api2_2x/doc/Lamp.py +++ b/source/blender/python/api2_2x/doc/Lamp.py @@ -39,15 +39,15 @@ Example:: - 'NoDiffuse' - 'RayShadow' -Example:: - from Blender import Lamp, Object - # Change the mode of selected lamp objects. - for ob in Object.GetSelected(): # Loop through the current selection - if ob.getType() == "Lamp": # if this is a lamp. - lamp = ob.getData() # get the lamp data. - if lamp.type == Lamp.Types["Spot"]: # Lamp type is not a flag - lamp.mode &= ~Lamp.Modes["RayShadow"] # Disable RayShadow. - lamp.mode |= Lamp.Modes["Shadows"] # Enable Shadowbuffer shadows + Example:: + from Blender import Lamp, Object + # Change the mode of selected lamp objects. + for ob in Object.GetSelected(): # Loop through the current selection + if ob.getType() == "Lamp": # if this is a lamp. + lamp = ob.getData() # get the lamp data. + if lamp.type == Lamp.Types["Spot"]: # Lamp type is not a flag + lamp.mode &= ~Lamp.Modes["RayShadow"] # Disable RayShadow. + lamp.mode |= Lamp.Modes["Shadows"] # Enable Shadowbuffer shadows """ def New (type = 'Lamp', name = 'LampData'): diff --git a/source/blender/python/api2_2x/doc/Object.py b/source/blender/python/api2_2x/doc/Object.py index bddf09c92cd..45d3fb9c90d 100644 --- a/source/blender/python/api2_2x/doc/Object.py +++ b/source/blender/python/api2_2x/doc/Object.py @@ -556,12 +556,17 @@ class Object: @type objects: Sequence of Blender Object @param objects: A list of objects matching the objects type. - @note: Objects in the list will not be removed, to avoid duplicate data you may want to remove them manualy after joining. - @note: Join modifies the object in place so that other objects are joined into it. no new object or data is created. - @note: Join will only work for object types Mesh, Armature, Curve and Surface, an error will be raised if the object is not of this type. + @note: Objects in the list will not be removed from the scene, + to avoid overlapping data you may want to remove them manualy after joining. + @note: Join modifies the base objects data in place so that + other objects are joined into it. no new object or data is created. + @note: Join will only work for object types Mesh, Armature, Curve and Surface, + an error will be raised if the object is not of this type. @note: objects in the list will be ignored if they to not match the base object. - @rtype: int - @return: 0 is returned if the join is not successfull, otherwise 1 will be returned. + @note: An error in the join function input will raise a TypeError, + otherwise an error in the data input will raise a RuntimeError, + for situations where you don't have tight control on the data that is being joined, + you should handel the RuntimeError error, litting the user know the data cant be joined. """ def makeParentDeform(objects, noninverse = 0, fast = 0): diff --git a/source/blender/python/api2_2x/matrix.c b/source/blender/python/api2_2x/matrix.c index d1e6a53bae5..c66482eab1c 100644 --- a/source/blender/python/api2_2x/matrix.c +++ b/source/blender/python/api2_2x/matrix.c @@ -100,7 +100,7 @@ PyObject *Matrix_toEuler(MatrixObject * self) //---------------------------Matrix.resize4x4() ------------------ PyObject *Matrix_Resize4x4(MatrixObject * self) { - int x, first_row_elem, curr_pos, new_pos, blank_columns, blank_rows; + int x, first_row_elem, curr_pos, new_pos, blank_columns, blank_rows, index; if(self->data.blend_data){ return EXPP_ReturnPyObjError(PyExc_TypeError, @@ -125,7 +125,12 @@ PyObject *Matrix_Resize4x4(MatrixObject * self) //move data to new spot in array + clean for(blank_rows = (4 - self->rowSize); blank_rows > 0; blank_rows--){ for(x = 0; x < 4; x++){ - self->contigPtr[(4 * (self->rowSize + (blank_rows - 1))) + x] = 0.0f; + index = (4 * (self->rowSize + (blank_rows - 1))) + x; + if (index == 10 || index == 15){ + self->contigPtr[index] = 1.0f; + }else{ + self->contigPtr[index] = 0.0f; + } } } for(x = 1; x <= self->rowSize; x++){ diff --git a/source/blender/renderconverter/intern/convertBlenderScene.c b/source/blender/renderconverter/intern/convertBlenderScene.c index 790daa1d818..b11fa7439d8 100644 --- a/source/blender/renderconverter/intern/convertBlenderScene.c +++ b/source/blender/renderconverter/intern/convertBlenderScene.c @@ -2840,8 +2840,8 @@ extern ListBase duplilist; void RE_rotateBlenderScene(void) { Base *base; - Object *ob; - Scene *sce; + Object *ob, *obd; + Scene *sce, *setscene; unsigned int lay; float mat[4][4]; @@ -2908,7 +2908,7 @@ void RE_rotateBlenderScene(void) } sce= G.scene; - + setscene= G.scene->set; base= G.scene->base.first; while(base) { @@ -3014,11 +3014,17 @@ void RE_rotateBlenderScene(void) } if(blender_test_break()) break; - if(base->next==0 && G.scene->set && base==G.scene->base.last) { + base= base->next; + if(base==0 && setscene) { + sce= setscene; + base= setscene->base.first; + setscene= setscene->set; + } + /*if(base->next==0 && G.scene->set && base==G.scene->base.last) { base= G.scene->set->base.first; sce= G.scene->set; } - else base= base->next; + else base= base->next;*/ } diff --git a/source/blender/src/booleanops_mesh.c b/source/blender/src/booleanops_mesh.c index e2bdc51ecea..1323bbcb17f 100644 --- a/source/blender/src/booleanops_mesh.c +++ b/source/blender/src/booleanops_mesh.c @@ -52,10 +52,6 @@ #include "BLI_arithb.h" -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - /** * Implementation of boolean ops mesh interface. */ @@ -304,5 +300,5 @@ NewBooleanMeshTest( return 1; } +#endif -#endif
\ No newline at end of file diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index c6ca4ffed3b..5c2e3cc6723 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -1212,7 +1212,7 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco int lx = x + width - 60 - 15; if (md->type==eModifierType_Subsurf) { - height = 86; + height = 106; } else if (md->type==eModifierType_Lattice) { height = 46; } else if (md->type==eModifierType_Curve) { @@ -1274,6 +1274,7 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco */ uiDefButBitS(block, TOG, eSubsurfModifierFlag_ControlEdges, B_MODIFIER_RECALC, "Optimal Draw", lx, (cy-=19), buttonWidth,19,&smd->flags, 0, 0, 0, 0, "Skip drawing/rendering of interior subdivided edges"); + uiDefButBitS(block, TOG, eSubsurfModifierFlag_SubsurfUv, B_MODIFIER_RECALC, "Subsurf UV", lx, (cy-=19),buttonWidth,19,&smd->flags, 0, 0, 0, 0, "Use subsurf to subdivide UVs"); } else if (md->type==eModifierType_Lattice) { LatticeModifierData *lmd = (LatticeModifierData*) md; uiDefIDPoinBut(block, modifier_testLatticeObj, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &lmd->object, "Lattice object to deform with"); diff --git a/source/blender/src/buttons_scene.c b/source/blender/src/buttons_scene.c index 72a7c3f1e2c..0e76593aeaf 100644 --- a/source/blender/src/buttons_scene.c +++ b/source/blender/src/buttons_scene.c @@ -457,10 +457,46 @@ static void ftype_pic(char *name) allqueue(REDRAWBUTSSCENE, 0); } +static void scene_chain_cleanup(Scene *sc) { + while(sc) { + sc->dirty = SCE_CLEAN; + sc = sc->set; + } +} static void scene_change_set(Scene *sc, Scene *set) { + Scene *scene = G.main->scene.first; + int clean = SCE_CLEAN; + int breakout = 0; if (sc->set!=set) { sc->set= set; + while(breakout==0 && scene) { + Scene *setchain = scene; + while(breakout==0 && setchain) { + clean = setchain->dirty; + if(clean == SCE_DIRTY) { + /* we have not reached yet end of chain, and we + * encountered dirty node - we have a cycle. + * sc->set = 0, clean the chain and break out. + */ + error("Can't change set. It would create a loop!"); + sc->set = 0; + breakout = 1; + scene_chain_cleanup(scene); + + } + + if(breakout == 0) { + setchain->dirty = SCE_DIRTY; + setchain = setchain->set; + } + } + + if(breakout == 0) { + scene_chain_cleanup(scene); + scene = scene->id.next; + } + } allqueue(REDRAWBUTSSCENE, 0); allqueue(REDRAWVIEW3D, 0); diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c index 603e7023f23..58b6e759aee 100644 --- a/source/blender/src/drawview.c +++ b/source/blender/src/drawview.c @@ -2167,6 +2167,7 @@ void drawview3dspace(ScrArea *sa, void *spacedata) View3D *v3d= spacedata; Base *base; Object *ob; + Scene *setscene; setwinmatrixview3d(0); /* 0= no pick rect */ setviewmatrixview3d(); /* note: calls where_is_object for camera... */ @@ -2249,9 +2250,10 @@ void drawview3dspace(ScrArea *sa, void *spacedata) view3d_set_clipping(v3d); /* draw set first */ - if(G.scene->set) { + setscene= G.scene->set; + if(setscene) { /* if(G.scene->set) { */ - base= G.scene->set->base.first; + base= setscene->base.first; /* base= G.scene->set->base.first; */ while(base) { if(v3d->lay & base->lay) { @@ -2265,7 +2267,12 @@ void drawview3dspace(ScrArea *sa, void *spacedata) draw_dupli_objects(v3d, base); } } + base= base->next; + if(base==0 && setscene && setscene->set) { + setscene= setscene->set; + base= setscene->base.first; + } } /* Transp and X-ray afterdraw stuff */ @@ -2372,6 +2379,7 @@ void drawview3d_render(struct View3D *v3d) { extern short v3d_windowmode; Base *base; + Scene *setscene; update_for_newframe_muted(); /* first, since camera can be animated */ @@ -2415,9 +2423,10 @@ void drawview3d_render(struct View3D *v3d) G.f |= G_SIMULATION; /* first draw set */ - if(G.scene->set) { + setscene= G.scene->set; + if(setscene) { /* if(G.scene->set) { */ - base= G.scene->set->base.first; + base= setscene->base.first; /* base= G.scene->set->base.first; */ while(base) { if(v3d->lay & base->lay) { if ELEM3(base->object->type, OB_LAMP, OB_CAMERA, OB_LATTICE); @@ -2433,6 +2442,10 @@ void drawview3d_render(struct View3D *v3d) } } base= base->next; + if(base==0 && setscene && setscene->set) { + setscene= setscene->set; + base= setscene->base.first; + } } /* Transp and X-ray afterdraw stuff */ diff --git a/source/blender/src/editaction.c b/source/blender/src/editaction.c index 9790dd506f0..4d38175e69d 100644 --- a/source/blender/src/editaction.c +++ b/source/blender/src/editaction.c @@ -33,10 +33,6 @@ #include <string.h> #include <math.h> -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - #include "MEM_guardedalloc.h" #include "PIL_time.h" @@ -97,6 +93,10 @@ #include "nla.h" extern int count_action_levels (bAction *act); +void top_sel_action(); +void up_sel_action(); +void bottom_sel_action(); +void down_sel_action(); #define BEZSELECTED(bezt) (((bezt)->f1 & 1) || ((bezt)->f2 & 1) || ((bezt)->f3 & 1)) diff --git a/source/blender/src/editconstraint.c b/source/blender/src/editconstraint.c index dad204fee6c..a85f0dd835d 100644 --- a/source/blender/src/editconstraint.c +++ b/source/blender/src/editconstraint.c @@ -783,4 +783,5 @@ void ob_clear_constraints(void) BIF_undo_push("Clear Constraint(s)"); -}
\ No newline at end of file +} + diff --git a/source/blender/src/editipo.c b/source/blender/src/editipo.c index 3fb48fb417f..e6a98b4b004 100644 --- a/source/blender/src/editipo.c +++ b/source/blender/src/editipo.c @@ -587,7 +587,7 @@ static void make_mat_editipo(SpaceIpo *si) static void make_texture_editipo(SpaceIpo *si) { EditIpo *ei; - int a; + int a, len; char *name; if(si->from==0) return; @@ -602,7 +602,13 @@ static void make_texture_editipo(SpaceIpo *si) ei->adrcode= te_ar[a]; ei->col= ipo_rainbow(a, TE_TOTIPO); - + + len= strlen(ei->name); + if(len) { + if( ei->name[ len-1 ]=='R') ei->col= 0x5050FF; + else if( ei->name[ len-1 ]=='G') ei->col= 0x50FF50; + else if( ei->name[ len-1 ]=='B') ei->col= 0xFF7050; + } ei->icu= find_ipocurve(si->ipo, ei->adrcode); if(ei->icu) { ei->flag= ei->icu->flag; @@ -2133,25 +2139,26 @@ void common_insertkey(void) IpoCurve *icu; World *wo; Lamp *la; + Tex *te; int tlay, map, event; char menustr[256]; - + if(curarea->spacetype==SPACE_IPO) { insertkey_editipo(); } else if(curarea->spacetype==SPACE_BUTS) { if(G.buts->mainb==CONTEXT_SHADING) { int tab= G.buts->tab[CONTEXT_SHADING]; - + if(tab==TAB_SHADING_MAT) { id= G.buts->lockpoin; ma= G.buts->lockpoin; if(id) { event= pupmenu("Insert Key %t|RGB%x0|Alpha%x1|Halo Size%x2|Mode %x3|All Color%x10|All Mirror%x14|Ofs%x12|Size%x13|All Mapping%x11"); if(event== -1) return; - + map= texchannel_to_adrcode(ma->texact); - + if(event==0 || event==10) { insertkey(id, ID_MA, NULL, NULL, MA_COL_R); insertkey(id, ID_MA, NULL, NULL, MA_COL_G); @@ -2214,9 +2221,9 @@ void common_insertkey(void) if(id) { event= pupmenu("Insert Key %t|Zenith RGB%x0|Horizon RGB%x1|Mist%x2|Stars %x3|Offset%x12|Size%x13"); if(event== -1) return; - + map= texchannel_to_adrcode(wo->texact); - + if(event==0) { insertkey(id, ID_WO, NULL, NULL, WO_ZEN_R); insertkey(id, ID_WO, NULL, NULL, WO_ZEN_G); @@ -2258,9 +2265,9 @@ void common_insertkey(void) if(id) { event= pupmenu("Insert Key %t|RGB%x0|Energy%x1|Spot Size%x2|Offset%x12|Size%x13"); if(event== -1) return; - + map= texchannel_to_adrcode(la->texact); - + if(event==0) { insertkey(id, ID_LA, NULL, NULL, LA_COL_R); insertkey(id, ID_LA, NULL, NULL, LA_COL_G); @@ -2285,6 +2292,85 @@ void common_insertkey(void) } } + else if(tab==TAB_SHADING_TEX) { + id= G.buts->lockpoin; + te= G.buts->lockpoin; + if(id) { + event= pupmenu("Insert Key %t|Cloud%x0|Mable%x1|Stucci%x2|Wood%x3|Magic%x4|Blend%x5|Musgrave%x6|Voronoi%x7|Distnoise%x8|ColourFilter%x9"); + if(event== -1) return; + + if(event==0) { + insertkey(id, ID_TE, NULL, NULL, TE_NSIZE); + insertkey(id, ID_TE, NULL, NULL, TE_NDEPTH); + insertkey(id, ID_TE, NULL, NULL, TE_NTYPE); + insertkey(id, ID_TE, NULL, NULL, TE_MG_TYP); + insertkey(id, ID_TE, NULL, NULL, TE_N_BAS1); + } + if(event==1) { + insertkey(id, ID_TE, NULL, NULL, TE_NSIZE); + insertkey(id, ID_TE, NULL, NULL, TE_NDEPTH); + insertkey(id, ID_TE, NULL, NULL, TE_NTYPE); + insertkey(id, ID_TE, NULL, NULL, TE_TURB); + insertkey(id, ID_TE, NULL, NULL, TE_MG_TYP); + insertkey(id, ID_TE, NULL, NULL, TE_N_BAS1); + insertkey(id, ID_TE, NULL, NULL, TE_N_BAS2); + } + if(event==2) { + insertkey(id, ID_TE, NULL, NULL, TE_NSIZE); + insertkey(id, ID_TE, NULL, NULL, TE_NTYPE); + insertkey(id, ID_TE, NULL, NULL, TE_TURB); + insertkey(id, ID_TE, NULL, NULL, TE_MG_TYP); + insertkey(id, ID_TE, NULL, NULL, TE_N_BAS1); + } + if(event==3) { + insertkey(id, ID_TE, NULL, NULL, TE_NSIZE); + insertkey(id, ID_TE, NULL, NULL, TE_NTYPE); + insertkey(id, ID_TE, NULL, NULL, TE_TURB); + insertkey(id, ID_TE, NULL, NULL, TE_MG_TYP); + insertkey(id, ID_TE, NULL, NULL, TE_N_BAS1); + insertkey(id, ID_TE, NULL, NULL, TE_N_BAS2); + } + if(event==4) { + insertkey(id, ID_TE, NULL, NULL, TE_NDEPTH); + insertkey(id, ID_TE, NULL, NULL, TE_TURB); + } + if(event==5) { + insertkey(id, ID_TE, NULL, NULL, TE_MG_TYP); + } + if(event==6) { + insertkey(id, ID_TE, NULL, NULL, TE_MG_TYP); + insertkey(id, ID_TE, NULL, NULL, TE_MGH); + insertkey(id, ID_TE, NULL, NULL, TE_MG_LAC); + insertkey(id, ID_TE, NULL, NULL, TE_MG_OCT); + insertkey(id, ID_TE, NULL, NULL, TE_MG_OFF); + insertkey(id, ID_TE, NULL, NULL, TE_MG_GAIN); + } + if(event==7) { + insertkey(id, ID_TE, NULL, NULL, TE_VNW1); + insertkey(id, ID_TE, NULL, NULL, TE_VNW2); + insertkey(id, ID_TE, NULL, NULL, TE_VNW3); + insertkey(id, ID_TE, NULL, NULL, TE_VNW4); + insertkey(id, ID_TE, NULL, NULL, TE_VNMEXP); + insertkey(id, ID_TE, NULL, NULL, TE_VN_DISTM); + insertkey(id, ID_TE, NULL, NULL, TE_VN_COLT); + insertkey(id, ID_TE, NULL, NULL, TE_ISCA); + insertkey(id, ID_TE, NULL, NULL, TE_NSIZE); + } + if(event==8) { + insertkey(id, ID_TE, NULL, NULL, TE_MG_OCT); + insertkey(id, ID_TE, NULL, NULL, TE_MG_OFF); + insertkey(id, ID_TE, NULL, NULL, TE_MG_GAIN); + insertkey(id, ID_TE, NULL, NULL, TE_DISTA); + } + if(event==9) { + insertkey(id, ID_TE, NULL, NULL, TE_COL_R); + insertkey(id, ID_TE, NULL, NULL, TE_COL_G); + insertkey(id, ID_TE, NULL, NULL, TE_COL_B); + insertkey(id, ID_TE, NULL, NULL, TE_BRIGHT); + insertkey(id, ID_TE, NULL, NULL, TE_CONTRA); + } + } + } } else if(G.buts->mainb==CONTEXT_OBJECT) { ob= OBACT; @@ -2363,7 +2449,7 @@ void common_insertkey(void) } } } - + BIF_undo_push("Insert Key Buttons"); allqueue(REDRAWACTION, 0); @@ -2385,25 +2471,24 @@ void common_insertkey(void) base= base->next; } if(base==NULL) return; - strcpy(menustr, "Insert Key%t|Loc%x0|Rot%x1|Size%x2|LocRot%x3|LocRotSize%x4|Layer%x5|Avail%x9|VisualLoc%x11|VisualRot%x12|VisualLocRot%x13"); } - + if(ob) { if(ob->type==OB_MESH) strcat(menustr, "| %x6|Mesh%x7"); else if(ob->type==OB_LATTICE) strcat(menustr, "| %x6|Lattice%x7"); else if(ob->type==OB_CURVE) strcat(menustr, "| %x6|Curve%x7"); else if(ob->type==OB_SURF) strcat(menustr, "| %x6|Surface%x7"); } - + event= pupmenu(menustr); if(event== -1) return; - + if(event==7) { // ob != NULL insert_shapekey(ob); return; } - + if (ob && (ob->flag & OB_POSEMODE)){ bPoseChannel *pchan; @@ -2411,7 +2496,7 @@ void common_insertkey(void) error ("Can't key libactions"); return; } - + set_pose_keys(ob); // sets pchan->flag to POSE_KEY if bone selected id= &ob->id; for (pchan=ob->pose->chanbase.first; pchan; pchan=pchan->next) { @@ -2434,7 +2519,7 @@ void common_insertkey(void) } if (event==9 && ob->action) { bActionChannel *achan; - + for (achan = ob->action->chanbase.first; achan; achan=achan->next){ if (achan->ipo && !strcmp (achan->name, pchan->name)){ for (icu = achan->ipo->curve.first; icu; icu=icu->next){ @@ -2477,12 +2562,12 @@ void common_insertkey(void) while(base) { if TESTBASELIB(base) { char *actname= NULL; - + id= (ID *)(base->object); - + if(ob->ipoflag & OB_ACTION_OB) actname= "Object"; - + /* all curves in ipo deselect */ if(base->object->ipo) { icu= base->object->ipo->curve.first; @@ -2492,7 +2577,7 @@ void common_insertkey(void) icu= icu->next; } } - + if(event==0 || event==3 ||event==4) { insertkey(id, ID_OB, actname, NULL, OB_LOC_X); insertkey(id, ID_OB, actname, NULL, OB_LOC_Y); @@ -2550,7 +2635,7 @@ void common_insertkey(void) allqueue(REDRAWACTION, 0); allqueue(REDRAWNLA, 0); } - + } /* ****************************************************************************** */ @@ -4531,3 +4616,4 @@ void bone2objectspace(float obSpaceBoneMat[][4], float obSpace[][4], float restP Mat4Invert(imat, restPos); Mat4MulMat4(obSpaceBoneMat, obSpace, imat); } + diff --git a/source/blender/src/editipo_lib.c b/source/blender/src/editipo_lib.c index c3c80c4e238..22587c2da3c 100644 --- a/source/blender/src/editipo_lib.c +++ b/source/blender/src/editipo_lib.c @@ -61,7 +61,7 @@ char *mtex_ic_names[TEX_TOTNAM] = { "OfsX", "OfsY", "OfsZ", "SizeX", "SizeY", "S char *tex_ic_names[TE_TOTNAM] = { "NSize", "NDepth", "NType", "Turb", "Vnw1", "Vnw2", "Vnw3", "Vnw4", "MinkMExp", "DistM", "ColT", "iScale", "DistA", "MgType", "MgH", "Lacu", "Oct", "MgOff", - "MgGain", "NBase1", "NBase2" }; + "MgGain", "NBase1", "NBase2", "ColR", "ColG", "ColB", "Bright", "Contras"}; char *ma_ic_names[MA_TOTNAM] = { "R", "G", "B", "SpecR", "SpecG", "SpecB", "MirR", "MirG", "MirB", "Ref", "Alpha", "Emit", "Amb", "Spec", "Hard", "SpTra", "Ior", "Mode", "HaSize", "Translu", @@ -133,7 +133,7 @@ char *getname_ob_ei(int nr, int colipo) char *getname_tex_ei(int nr) { - if(nr>=TE_NSIZE && nr<=TE_N_BAS2) return tex_ic_names[nr-1]; + if(nr>=TE_NSIZE && nr<=TE_CONTRA) return tex_ic_names[nr-1]; return ic_name_empty[0]; } diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c index abc4f826e24..243ae777923 100644 --- a/source/blender/src/editobject.c +++ b/source/blender/src/editobject.c @@ -2221,7 +2221,7 @@ void special_editmenu(void) void convertmenu(void) { Base *base, *basen, *basact, *basedel=NULL; - Object *ob, *ob1; + Object *obact, *ob, *ob1; Curve *cu; MetaBall *mb; Mesh *me; @@ -2230,31 +2230,31 @@ void convertmenu(void) if(G.scene->id.lib) return; - ob= OBACT; - if(ob==0) return; + obact= OBACT; + if(obact==0) return; + if(!obact->flag & SELECT) return; if(G.obedit) return; basact= BASACT; /* will be restored */ - if(ob->type==OB_FONT) { + if(obact->type==OB_FONT) { nr= pupmenu("Convert Font to%t|Curve"); if(nr>0) ok= 1; } - else if(ob->type==OB_MBALL) { + else if(obact->type==OB_MBALL) { nr= pupmenu("Convert Metaball to%t|Mesh (keep original)%x1|Mesh (Delete Original)%x2"); if(nr>0) ok= 1; } - else if(ob->type==OB_CURVE) { + else if(obact->type==OB_CURVE) { nr= pupmenu("Convert Curve to%t|Mesh"); if(nr>0) ok= 1; } - else if(ob->type==OB_SURF) { + else if(obact->type==OB_SURF) { nr= pupmenu("Convert Nurbs Surface to%t|Mesh"); if(nr>0) ok= 1; } - else if(ob->type==OB_MESH) { - if(ob->modifiers.first) - nr= pupmenu("Convert Modifiers to%t|Mesh (Keep Original)%x1|Mesh (Delete Original)%x2"); + else if(obact->type==OB_MESH) { + nr= pupmenu("Convert Modifiers to%t|Mesh (Keep Original)%x1|Mesh (Delete Original)%x2"); if(nr>0) ok= 1; } if(ok==0) return; @@ -2277,7 +2277,7 @@ void convertmenu(void) ob= base->object; if(ob->flag & OB_DONE); - else if(ob->type==OB_MESH) { + else if(ob->type==OB_MESH && ob->modifiers.first) { /* converting a mesh with no modifiers causes a segfault */ DispListMesh *dlm; DerivedMesh *dm; @@ -2293,7 +2293,9 @@ void convertmenu(void) *basen= *base; BLI_addhead(&G.scene->base, basen); /* addhead: otherwise eternal loop */ basen->object= ob1; - basen->flag &= ~SELECT; + basen->flag |= SELECT; + base->flag &= ~SELECT; + ob->flag &= ~SELECT; /* decrement original mesh's usage count */ me= ob1->data; @@ -2308,6 +2310,12 @@ void convertmenu(void) dlm= dm->convertToDispListMesh(dm, 0); displistmesh_to_mesh(dlm, ob1->data); dm->release(dm); + + /* If the original object is active then make this object active */ + if (ob == obact) { + set_active_base( basen ); + basact = basen; + } } else if(ob->type==OB_FONT) { if(nr==1) { @@ -2381,7 +2389,9 @@ void convertmenu(void) *basen= *base; BLI_addhead(&G.scene->base, basen); /* addhead: othwise eternal loop */ basen->object= ob1; - basen->flag &= ~SELECT; + basen->flag |= SELECT; + basedel->flag &= ~SELECT; + ob->flag &= ~SELECT; mb= ob1->data; mb->id.us--; @@ -2398,6 +2408,19 @@ void convertmenu(void) } mball_to_mesh(&ob->disp, ob1->data); + + /* So we can see the wireframe */ + BASACT= basen; + enter_editmode(); + exit_editmode(1); // freedata, but no undo + BASACT= basact; + + /* If the original object is active then make this object active */ + if (ob == obact) { + set_active_base( basen ); + basact = basen; + } + } } } diff --git a/source/blender/src/editsima.c b/source/blender/src/editsima.c index 3075cb6b637..2cef5428316 100644 --- a/source/blender/src/editsima.c +++ b/source/blender/src/editsima.c @@ -90,25 +90,11 @@ #include "blendef.h" #include "mydevice.h" -struct uvvertsort { - unsigned int v, f; - unsigned char tf_sel; - char flag; -}; - /* local prototypes */ void clever_numbuts_sima(void); void sel_uvco_inside_radius(short , TFace *, int , float *, float *, short); void uvedit_selectionCB(short , Object *, short *, float ); /* used in edit.c*/ -static int compuvvert(const void *u1, const void *u2) -{ - const struct uvvertsort *v1=u1, *v2=u2; - if (v1->v > v2->v) return 1; - else if (v1->v < v2->v) return -1; - return 0; -} - void object_uvs_changed(Object *ob) { DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); @@ -597,7 +583,7 @@ void mouse_select_sima(void) { Mesh *me; TFace *tf, *nearesttf; - MFace *mf, *nearestmf; + MFace *mf, *nearestmf=NULL; int a, selectsticky, sticky, actface, nearestuv, i; unsigned int hitv[4], nearestv; float *hituv[4], limit[2]; @@ -1027,14 +1013,15 @@ void reveal_tface_uv(void) void stitch_uv_tface(int mode) { - MFace *mf; - TFace *tf, *tface; Mesh *me; - int a, b, c, tot, vtot, vtot2; - float newuv[2], limit[2], *uv, *uv1; - struct uvvertsort *sortblock, *sb, *sb1, *sb2; + TFace *tf; + int a, vtot; + float newuv[2], limit[2]; + UvMapVert *vlist, *iterv, *v; + UvVertMap *vmap; - if( is_uv_tface_editing_allowed()==0 ) return; + if(is_uv_tface_editing_allowed()==0) + return; limit[0]= limit[1]= 20.0; if(mode==1) { @@ -1050,115 +1037,80 @@ void stitch_uv_tface(int mode) } else limit[0]= limit[1]= limit[0]/256.0; - - me= get_mesh(OBACT); - tface= (TFace*)me->tface; - - tot= 0; - mf= (MFace*)me->mface; - tf= (TFace*)me->tface; - for(a=me->totface; a>0; a--, tf++, mf++) { - if((tf->flag & TF_SELECT)) { - if(tf->flag & TF_SEL1) tot++; - if(tf->flag & TF_SEL2) tot++; - if(tf->flag & TF_SEL3) tot++; - if(mf->v4 && tf->flag & TF_SEL4) tot++; - } - } - if(tot==0) return; - sb= sortblock= MEM_callocN(sizeof(struct uvvertsort)*tot,"sortstitchuv"); + me= get_mesh(OBACT); + tf= me->tface; - mf= (MFace*)me->mface; - tf= (TFace*)me->tface; - for(a=0; a<me->totface; a++, tf++, mf++) { - if((tf->flag & TF_SELECT)) { - if(tf->flag & TF_SEL1) { - sb->v= mf->v1; - sb->f= a; - sb->tf_sel= 0; - sb++; - } - if(tf->flag & TF_SEL2) { - sb->v= mf->v2; - sb->f= a; - sb->tf_sel= 1; - sb++; - } - if(tf->flag & TF_SEL3) { - sb->v= mf->v3; - sb->f= a; - sb->tf_sel= 2; - sb++; - } - if(mf->v4 && tf->flag & TF_SEL4) { - sb->v= mf->v4; - sb->f= a; - sb->tf_sel= 3; - sb++; - } - } - } - - /* sort by vertex */ - qsort(sortblock, tot, sizeof(struct uvvertsort), compuvvert); + vmap= make_uv_vert_map(me->mface, tf, me->totface, me->totvert, 1, limit); + if(vmap == NULL) + return; if(mode==0) { - for (a=0, sb=sortblock; a<tot; a+=vtot, sb+=vtot) { + for(a=0; a<me->totvert; a++) { + v = get_uv_map_vert(vmap, a); + + if(v == NULL) + continue; + newuv[0]= 0; newuv[1]= 0; vtot= 0; - for (b=a, sb1=sb; b<tot && sb1->v==sb->v; b++, sb1++) { - newuv[0] += tface[sb1->f].uv[sb1->tf_sel][0]; - newuv[1] += tface[sb1->f].uv[sb1->tf_sel][1]; - vtot++; + for(iterv=v; iterv; iterv=iterv->next) { + if (tf[iterv->f].flag & TF_SEL_MASK(iterv->tfindex)) { + newuv[0] += tf[iterv->f].uv[iterv->tfindex][0]; + newuv[1] += tf[iterv->f].uv[iterv->tfindex][1]; + vtot++; + } } - newuv[0] /= vtot; newuv[1] /= vtot; + if (vtot > 1) { + newuv[0] /= vtot; newuv[1] /= vtot; - for (b=a, sb1=sb; b<a+vtot; b++, sb1++) { - tface[sb1->f].uv[sb1->tf_sel][0]= newuv[0]; - tface[sb1->f].uv[sb1->tf_sel][1]= newuv[1]; + for(iterv=v; iterv; iterv=iterv->next) { + if (tf[iterv->f].flag & TF_SEL_MASK(iterv->tfindex)) { + tf[iterv->f].uv[iterv->tfindex][0]= newuv[0]; + tf[iterv->f].uv[iterv->tfindex][1]= newuv[1]; + } + } } } } else if(mode==1) { - for (a=0, sb=sortblock; a<tot; a+=vtot, sb+=vtot) { - vtot= 0; - for (b=a, sb1=sb; b<tot && sb1->v==sb->v; b++, sb1++) - vtot++; - - for (b=a, sb1=sb; b<a+vtot; b++, sb1++) { - if(sb1->flag & 2) continue; + for(a=0; a<me->totvert; a++) { + vlist= get_uv_map_vert(vmap, a); + while(vlist) { newuv[0]= 0; newuv[1]= 0; - vtot2 = 0; - - for (c=b, sb2=sb1; c<a+vtot; c++, sb2++) { - uv = tface[sb2->f].uv[sb2->tf_sel]; - uv1 = tface[sb1->f].uv[sb1->tf_sel]; - if (fabs(uv[0]-uv1[0]) < limit[0] && - fabs(uv[1]-uv1[1]) < limit[1]) { - newuv[0] += uv[0]; - newuv[1] += uv[1]; - sb2->flag |= 2; - sb2->flag |= 4; - vtot2++; + vtot= 0; + + for(iterv=vlist; iterv; iterv=iterv->next) { + if((iterv != vlist) && iterv->separate) + break; + if (tf[iterv->f].flag & TF_SEL_MASK(iterv->tfindex)) { + newuv[0] += tf[iterv->f].uv[iterv->tfindex][0]; + newuv[1] += tf[iterv->f].uv[iterv->tfindex][1]; + vtot++; } } - newuv[0] /= vtot2; newuv[1] /= vtot2; + if (vtot > 1) { + newuv[0] /= vtot; newuv[1] /= vtot; - for (c=b, sb2=sb1; c<a+vtot; c++, sb2++) { - if(sb2->flag & 4) { - tface[sb2->f].uv[sb2->tf_sel][0]= newuv[0]; - tface[sb2->f].uv[sb2->tf_sel][1]= newuv[1]; - sb2->flag &= ~4; + for(iterv=vlist; iterv; iterv=iterv->next) { + if((iterv != vlist) && iterv->separate) + break; + if (tf[iterv->f].flag & TF_SEL_MASK(iterv->tfindex)) { + tf[iterv->f].uv[iterv->tfindex][0]= newuv[0]; + tf[iterv->f].uv[iterv->tfindex][1]= newuv[1]; + } } } + + vlist= iterv; } } } - MEM_freeN(sortblock); + + free_uv_vert_map(vmap); if(G.sima->flag & SI_BE_SQUARE) be_square_tface_uv(me); @@ -1169,109 +1121,102 @@ void stitch_uv_tface(int mode) void select_linked_tface_uv(int mode) { - MFace *mf; - TFace *tface, *tf, *nearesttf=NULL; Mesh *me; - char sel, *linkflag; - int a, b, c, tot, vtot, nearestv, nearestuv, i, nverts; - float limit[2], *uv, *uv1; - struct uvvertsort *sortblock, *sb, *sb1, *sb2; + MFace *mf; + TFace *tf, *nearesttf=NULL; + UvVertMap *vmap; + UvMapVert *vlist, *iterv, *startv; + unsigned int *stack, stacksize= 0, nearestv; + char *flag; + int a, nearestuv, i, nverts; + float limit[2]; - if( is_uv_tface_editing_allowed()==0 ) return; + if(is_uv_tface_editing_allowed()==0) + return; me= get_mesh(OBACT); - get_connected_limit_tface_uv(limit); - - tot= 0; - mf= (MFace*)me->mface; - tf= (TFace*)me->tface; - for(a=me->totface; a>0; a--, tf++, mf++) - if(tf->flag & TF_SELECT) - tot += mf->v4? 4: 3; - - if(tot==0) return; + if (mode == 2) { + nearesttf= NULL; + nearestuv= 0; + } if (mode!=2) { find_nearest_uv(&nearesttf, &nearestv, &nearestuv); - if(nearesttf==NULL) return; } - else { - nearesttf= NULL; - nearestuv= 0; - } - sb= sortblock= MEM_callocN(sizeof(struct uvvertsort)*tot, "sortsellinkuv"); - linkflag= MEM_callocN(sizeof(char)*me->totface, "linkflaguv"); + get_connected_limit_tface_uv(limit); + vmap= make_uv_vert_map(me->mface, me->tface, me->totface, me->totvert, 1, limit); + if(vmap == NULL) + return; - mf= (MFace*)me->mface; - tf= (TFace*)me->tface; - for(a=0; a<me->totface; a++, tf++, mf++) { - if(!(tf->flag & TF_HIDE) && (tf->flag & TF_SELECT)) { - sel= 0; - sb1= sb; - nverts= mf->v4? 4: 3; - for(i=0; i<nverts; i++) { - if(tf->flag & TF_SEL_MASK(i)) - sel= 1; - sb->f= a; - sb->tf_sel= i; - sb++; + stack= MEM_mallocN(sizeof(*stack)*me->totface, "UvLinkStack"); + flag= MEM_callocN(sizeof(*flag)*me->totface, "UvLinkFlag"); + + if (mode == 2) { + tf= me->tface; + for(a=0; a<me->totface; a++, tf++) + if(!(tf->flag & TF_HIDE) && (tf->flag & TF_SELECT)) + if(tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4)) { + stack[stacksize]= a; + stacksize++; + flag[a]= 1; + } + } + else { + tf= me->tface; + for(a=0; a<me->totface; a++, tf++) + if(tf == nearesttf) { + stack[stacksize]= a; + stacksize++; + flag[a]= 1; + break; } + } - if(nearesttf==tf || ((sel && mode==2))) - linkflag[a] = 1; + while(stacksize > 0) { + stacksize--; + a= stack[stacksize]; + mf= me->mface+a; + tf= me->tface+a; - (sb1)->v= mf->v1; - (sb1+1)->v= mf->v2; - (sb1+2)->v= mf->v3; - if(mf->v4) (sb1+3)->v= mf->v4; - } - } - - /* sort by vertex */ - qsort(sortblock, tot, sizeof(struct uvvertsort), compuvvert); + nverts= mf->v4? 4: 3; - tface= (TFace*)me->tface; - sel= 1; - while(sel) { - sel= 0; + for(i=0; i<nverts; i++) { + vlist= get_uv_map_vert(vmap, *(&mf->v1 + i)); + startv= vlist; - /* select all tex vertices that are near a selected tex vertex */ - for (a=0, sb=sortblock; a<tot; a+=vtot, sb+=vtot) { - vtot= 0; - for (b=a, sb1=sb; b<tot && sb1->v==sb->v; b++, sb1++) - vtot++; - for (b=a, sb1=sb; b<a+vtot; b++, sb1++) { - if(linkflag[sb1->f]) continue; + for(iterv=vlist; iterv; iterv=iterv->next) { + if(iterv->separate) + startv= iterv; + if(iterv->f == a) + break; + } - for (c=a, sb2=sb; c<a+vtot; c++, sb2++) { - if(!(linkflag[sb2->f])) continue; - - uv = tface[sb2->f].uv[sb2->tf_sel]; - uv1 = tface[sb1->f].uv[sb1->tf_sel]; - if (fabs(uv[0]-uv1[0]) < limit[0] && - fabs(uv[1]-uv1[1]) < limit[1]) { - linkflag[sb1->f] = 1; - sel= 1; - break; - } + for(iterv=startv; iterv; iterv=iterv->next) { + if((startv != iterv) && (iterv->separate)) + break; + else if(!flag[iterv->f]) { + flag[iterv->f]= 1; + stack[stacksize]= iterv->f;; + stacksize++; } } } } if(mode==0 || mode==2) { - for(a=0, tf=tface; a<me->totface; a++, tf++) - if(linkflag[a]) + for(a=0, tf=me->tface; a<me->totface; a++, tf++) + if(flag[a]) tf->flag |= (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4); else tf->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4); } else if(mode==1) { - for(a=0, tf=tface; a<me->totface; a++, tf++) { - if(linkflag[a]) { + mf= me->mface; + for(a=0, tf=me->tface; a<me->totface; a++, tf++, mf++) { + if(flag[a]) { if (mf->v4) { if((tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4))) break; @@ -1282,19 +1227,20 @@ void select_linked_tface_uv(int mode) } if (a<me->totface) { - for(a=0, tf=tface; a<me->totface; a++, tf++) - if(linkflag[a]) + for(a=0, tf=me->tface; a<me->totface; a++, tf++) + if(flag[a]) tf->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4); } else { - for(a=0, tf=tface; a<me->totface; a++, tf++) - if(linkflag[a]) + for(a=0, tf=me->tface; a<me->totface; a++, tf++) + if(flag[a]) tf->flag |= (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4); } } - MEM_freeN(sortblock); - MEM_freeN(linkflag); + MEM_freeN(stack); + MEM_freeN(flag); + free_uv_vert_map(vmap); BIF_undo_push("Select linked UV"); scrarea_queue_winredraw(curarea); diff --git a/source/blender/src/fluidsim.c b/source/blender/src/fluidsim.c index cc9f240ef94..3044584cb31 100644 --- a/source/blender/src/fluidsim.c +++ b/source/blender/src/fluidsim.c @@ -276,7 +276,7 @@ void fluidsimBake(struct Object *ob) char targetFile[FILE_MAXDIR+FILE_MAXFILE]; // temp. store filename from targetDir for access int outStringsChanged = 0; // modified? copy back before baking int haveSomeFluid = 0; // check if any fluid objects are set - int noFrames = G.scene->r.efra - G.scene->r.sfra; + int noFrames = G.scene->r.efra - 1 /*G.scene->r.sfra*/; const char *strEnvName = "BLENDER_ELBEEMDEBUG"; // from blendercall.cpp @@ -400,7 +400,7 @@ void fluidsimBake(struct Object *ob) } // dump data for frame 0 - G.scene->r.cfra = G.scene->r.sfra; + G.scene->r.cfra = 1 /*G.scene->r.sfra*/; scene_update_for_newframe(G.scene, G.scene->lay); // start writing @@ -468,15 +468,15 @@ void fluidsimBake(struct Object *ob) int i; float tsum=0.0, shouldbe=0.0; fprintf(fileCfg, " CHANNEL p_aniframetime = "); - for(i=G.scene->r.sfra; i<G.scene->r.efra; i++) { + for(i=1 /*G.scene->r.sfra*/; i<G.scene->r.efra; i++) { float anit = (calc_ipo_time(fsDomain->ipo, i+1) - calc_ipo_time(fsDomain->ipo, i)) * aniFrameTime; if(anit<0.0) anit = 0.0; tsum += anit; } // make sure inaccurate integration doesnt modify end time - shouldbe = ((float)(G.scene->r.efra - G.scene->r.sfra)) *aniFrameTime; - for(i=G.scene->r.sfra; i<G.scene->r.efra; i++) { + shouldbe = ((float)(G.scene->r.efra - 1 /*G.scene->r.sfra*/)) *aniFrameTime; + for(i=1 /*G.scene->r.sfra*/; i<G.scene->r.efra; i++) { float anit = (calc_ipo_time(fsDomain->ipo, i+1) - calc_ipo_time(fsDomain->ipo, i)) * aniFrameTime; if(anit<0.0) anit = 0.0; @@ -771,7 +771,7 @@ void fluidsimBake(struct Object *ob) } for(i=0; i<numCreatedFiles; i++) { if(doDeleteCreatedFiles>0) { - fprintf(stderr," CREATED '%s' deleting... \n", createdFiles[i]); + //fprintf(stderr," CREATED '%s' deleting... \n", createdFiles[i]); // debug BLI_delete(createdFiles[i], 0,0); } free(createdFiles[i]); diff --git a/source/blender/src/header_image.c b/source/blender/src/header_image.c index 38e8938b052..0a4a8391b20 100644 --- a/source/blender/src/header_image.c +++ b/source/blender/src/header_image.c @@ -177,7 +177,6 @@ static void save_paint(char *name) { char str[FILE_MAXDIR+FILE_MAXFILE]; Image *ima = G.sima->image; - ImBuf *ibuf; if (ima && ima->ibuf) { BLI_strncpy(str, name, sizeof(str)); @@ -185,7 +184,7 @@ static void save_paint(char *name) BLI_convertstringcode(str, G.sce, G.scene->r.cfra); if (saveover(str)) { - if (BIF_write_ibuf(ibuf, str)) { + if (BIF_write_ibuf(ima->ibuf, str)) { BLI_strncpy(ima->name, name, sizeof(ima->name)); ima->ibuf->userflags &= ~IB_BITMAPDIRTY; allqueue(REDRAWHEADERS, 0); diff --git a/source/blender/src/header_info.c b/source/blender/src/header_info.c index 78bdc169bfa..5aebdac7c65 100644 --- a/source/blender/src/header_info.c +++ b/source/blender/src/header_info.c @@ -1264,6 +1264,7 @@ static void do_info_gamemenu(void *arg, int event) case G_FILE_SHOW_DEBUG_PROPS: case G_FILE_AUTOPLAY: case G_FILE_GAME_TO_IPO: + case G_FILE_GAME_MAT: G.fileflags ^= event; break; default: @@ -1298,7 +1299,12 @@ static uiBlock *info_gamemenu(void *arg_unused) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Record Game Physics to IPO", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, G_FILE_GAME_TO_IPO, ""); } - + if(G.fileflags & G_FILE_GAME_MAT) { + uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Use Blender Materials", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, G_FILE_GAME_MAT, ""); + } else { + uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Use Blender Materials", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, G_FILE_GAME_MAT, ""); + } + if(G.fileflags & G_FILE_SHOW_FRAMERATE) { @@ -1322,7 +1328,7 @@ static uiBlock *info_gamemenu(void *arg_unused) } uiBlockSetDirection(block, UI_DOWN); - uiTextBoundsBlock(block, 50); + uiTextBoundsBlock(block, 70); return block; } diff --git a/source/blender/src/interface.c b/source/blender/src/interface.c index 106286648b9..7333f1aabfa 100644 --- a/source/blender/src/interface.c +++ b/source/blender/src/interface.c @@ -1671,7 +1671,8 @@ static int ui_do_but_TEX(uiBut *but) else if(dev==MOUSEY) val= 0; if(ascii) { - if(len <= but->max) { + + if(len-SELWIDTH+1 <= but->max) { /* type over the current selection */ if (SELWIDTH > 0) { diff --git a/source/blender/src/space.c b/source/blender/src/space.c index 5c2e308a4fa..f2ef4cbd566 100644 --- a/source/blender/src/space.c +++ b/source/blender/src/space.c @@ -365,6 +365,9 @@ void space_set_commmandline_options(void) { a= (G.fileflags & G_FILE_GAME_TO_IPO); SYS_WriteCommandLineInt(syshandle, "game2ipo", a); + a=(G.fileflags & G_FILE_GAME_MAT); + SYS_WriteCommandLineInt(syshandle, "blender_material", a); + } } diff --git a/source/blender/src/toolbox.c b/source/blender/src/toolbox.c index 61a9eb6418d..bc111938538 100644 --- a/source/blender/src/toolbox.c +++ b/source/blender/src/toolbox.c @@ -1383,16 +1383,16 @@ int do_clever_numbuts(char *name, int tot, int winevent) uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_RET_1|UI_BLOCK_ENTER_OK); /* WATCH IT: TEX BUTTON EXCEPTION */ - /* WARNING: ONLY A SINGLE BIT-BUTTON POSSIBLE: WE WORK AT COPIED DATA! -*/ - + /* WARNING: ONLY A SINGLE BIT-BUTTON POSSIBLE: WE WORK AT COPIED DATA! */ uiDefBut(block, LABEL, 0, name, (short)(x1+15), (short)(y2-35), (short)(sizex-60), 19, 0, 1.0, 0.0, 0, 0, ""); - + + /* if(name[0]=='A' && name[7]=='O') { y2 -= 20; uiDefBut(block, LABEL, 0, "Rotations in degrees!", (short)(x1+15), (short)(y2-35), (short)(sizex-60), 19, 0, 0.0, 0.0, 0, 0, ""); - } + }*/ + uiBlockBeginAlign(block); varstr= &numbuts[0]; for(a=0; a<tot; a++, varstr++) { if(varstr->type==TEX) { @@ -1402,9 +1402,10 @@ int do_clever_numbuts(char *name, int tot, int winevent) uiDefBut(block, varstr->type, 0, varstr->name,(short)(x1+15),(short)(y2-55-20*a), (short)(sizex-60), 19, &(numbdata[a]), varstr->min, varstr->max, 100, 0, varstr->tip); } } + uiBlockEndAlign(block); uiDefBut(block, BUT, 4000, "OK", (short)(x1+sizex-40),(short)(y2-35-20*a), 25, (short)(sizey-50), 0, 0, 0, 0, 0, "OK: Assign Values"); - + uiBoundsBlock(block, 5); event= uiDoBlocks(&listb, 0); @@ -1419,12 +1420,13 @@ int do_clever_numbuts(char *name, int tot, int winevent) else if ELEM( (varstr->type & BUTPOIN), FLO, INT ) memcpy(numbpoin[a], numbdata+a, 4); else if((varstr->type & BUTPOIN)==SHO ) *((short *)(numbpoin[a]))= *( (short *)(numbdata+a)); + /* if( strncmp(varstr->name, "Rot", 3)==0 ) { float *fp; fp= numbpoin[a]; fp[0]= M_PI*fp[0]/180.0; - } + }*/ } if(winevent) { @@ -1463,12 +1465,12 @@ void add_numbut(int nr, int type, char *str, float min, float max, void *poin, c if ELEM( (type & BUTPOIN), FLO, INT ) memcpy(numbdata+nr, poin, 4); if((type & BUTPOIN)==SHO ) *((short *)(numbdata+nr))= *( (short *)poin); - if( strncmp(numbuts[nr].name, "Rot", 3)==0 ) { + /* if( strncmp(numbuts[nr].name, "Rot", 3)==0 ) { float *fp; fp= (float *)(numbdata+nr); fp[0]= 180.0*fp[0]/M_PI; - } + } */ } |