diff options
author | Andre Susano Pinto <andresusanopinto@gmail.com> | 2008-07-13 17:21:01 +0400 |
---|---|---|
committer | Andre Susano Pinto <andresusanopinto@gmail.com> | 2008-07-13 17:21:01 +0400 |
commit | 70730c722679653d6accbb0ce36840ed84baf739 (patch) | |
tree | e857975f39f0c7365da1993407d954f49f3aaf80 /source/blender | |
parent | 7d6e004153e356101bb37be4fb6867791eb7b251 (diff) |
svn merge -r 15392:15551 https://svn.blender.org/svnroot/bf-blender/trunk/blender
Diffstat (limited to 'source/blender')
86 files changed, 2530 insertions, 918 deletions
diff --git a/source/blender/blenkernel/BKE_bmesh.h b/source/blender/blenkernel/BKE_bmesh.h index 51a5d29dbb7..8ec7144faf6 100644 --- a/source/blender/blenkernel/BKE_bmesh.h +++ b/source/blender/blenkernel/BKE_bmesh.h @@ -39,12 +39,12 @@ #include "DNA_listBase.h" #include "BLI_ghash.h" +#include "BLI_mempool.h" #include "BLI_memarena.h" #include "DNA_image_types.h" #include "BLI_editVert.h" #include "BKE_DerivedMesh.h" #include "transform.h" -#include "BKE_bmeshCustomData.h" /*forward declerations*/ struct BME_Vert; @@ -53,13 +53,6 @@ struct BME_Poly; struct BME_Loop; -/*structure for fast memory allocation/frees*/ -typedef struct BME_mempool{ - struct ListBase chunks; - int esize, csize, pchunk; /*size of elements and chunks in bytes and number of elements per chunk*/ - struct BME_freenode *free; /*free element list. Interleaved into chunk datas.*/ -}BME_mempool; - /*Notes on further structure Cleanup: -Remove the tflags, they belong in custom data layers -Remove the eflags completely, they are mostly not used @@ -78,10 +71,10 @@ typedef struct BME_Mesh { ListBase verts, edges, polys; /*memory pools used for storing mesh elements*/ - struct BME_mempool *vpool; - struct BME_mempool *epool; - struct BME_mempool *ppool; - struct BME_mempool *lpool; + struct BLI_mempool *vpool; + struct BLI_mempool *epool; + struct BLI_mempool *ppool; + struct BLI_mempool *lpool; /*some scratch arrays used by eulers*/ struct BME_Vert **vtar; struct BME_Edge **edar; @@ -90,7 +83,7 @@ typedef struct BME_Mesh int vtarlen, edarlen, lparlen, plarlen; int totvert, totedge, totpoly, totloop; /*record keeping*/ int nextv, nexte, nextp, nextl; /*Next element ID for verts/edges/faces/loops. Never reused*/ - struct BME_CustomData vdata, edata, pdata, ldata; /*Custom Data Layer information*/ + struct CustomData vdata, edata, pdata, ldata; /*Custom Data Layer information*/ } BME_Mesh; typedef struct BME_Vert @@ -169,7 +162,7 @@ int BME_radial_find_face(struct BME_Edge *e,struct BME_Poly *f); struct BME_Loop *BME_loop_find_loop(struct BME_Poly *f, struct BME_Vert *v); /*MESH CREATION/DESTRUCTION*/ -struct BME_Mesh *BME_make_mesh(int allocsize[4], struct BME_CustomDataInit init[4]); +struct BME_Mesh *BME_make_mesh(int allocsize[4]); void BME_free_mesh(struct BME_Mesh *bm); /*FULL MESH VALIDATION*/ int BME_validate_mesh(struct BME_Mesh *bm, int halt); diff --git a/source/blender/blenkernel/BKE_bmeshCustomData.h b/source/blender/blenkernel/BKE_bmeshCustomData.h index 423f75e532d..4f5f2641f54 100644 --- a/source/blender/blenkernel/BKE_bmeshCustomData.h +++ b/source/blender/blenkernel/BKE_bmeshCustomData.h @@ -38,7 +38,7 @@ #ifndef BKE_BMESHCUSTOMDATA_H #define BKE_BMESHCUSTOMDATA_H -struct BME_mempool; +struct BLI_mempool; /*Custom Data Types and defines Eventual plan is to move almost everything to custom data and let caller @@ -62,7 +62,7 @@ typedef struct BME_CustomDataLayer { typedef struct BME_CustomData { struct BME_CustomDataLayer *layers; /*Custom Data Layers*/ - struct BME_mempool *pool; /*pool for alloc of blocks*/ + struct BLI_mempool *pool; /*pool for alloc of blocks*/ int totlayer, totsize; /*total layers and total size in bytes of each block*/ } BME_CustomData; diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index 2e5da236a89..f3c13d3d820 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -208,7 +208,7 @@ typedef enum //////////////////////////////////////////////// // needed for implicit.c -int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt ); +int cloth_bvh_objcollision ( Object *ob, ClothModifierData * clmd, float step, float dt ); //////////////////////////////////////////////// diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h index d0535f1752e..e84c7d30956 100644 --- a/source/blender/blenkernel/BKE_customdata.h +++ b/source/blender/blenkernel/BKE_customdata.h @@ -40,6 +40,8 @@ extern const CustomDataMask CD_MASK_BAREMESH; extern const CustomDataMask CD_MASK_MESH; extern const CustomDataMask CD_MASK_EDITMESH; extern const CustomDataMask CD_MASK_DERIVEDMESH; +extern const CustomDataMask CD_MASK_BMESH; +extern const CustomDataMask CD_MASK_FACECORNERS; /* for ORIGINDEX layer type, indicates no original index for this element */ #define ORIGINDEX_NONE -1 @@ -134,6 +136,9 @@ void CustomData_copy_data(const struct CustomData *source, void CustomData_em_copy_data(const struct CustomData *source, struct CustomData *dest, void *src_block, void **dest_block); +void CustomData_bmesh_copy_data(const struct CustomData *source, + struct CustomData *dest,void *src_block, + void **dest_block); /* frees data in a CustomData object * return 1 on success, 0 on failure @@ -160,6 +165,10 @@ void CustomData_interp(const struct CustomData *source, struct CustomData *dest, void CustomData_em_interp(struct CustomData *data, void **src_blocks, float *weights, float *sub_weights, int count, void *dest_block); +void CustomData_bmesh_interp(struct CustomData *data, void **src_blocks, + float *weights, float *sub_weights, int count, + void *dest_block); + /* swaps the data in the element corners, to new corners with indices as specified in corner_indices. for edges this is an array of length 2, for @@ -172,6 +181,8 @@ void CustomData_swap(struct CustomData *data, int index, int *corner_indices); void *CustomData_get(const struct CustomData *data, int index, int type); void *CustomData_em_get(const struct CustomData *data, void *block, int type); void *CustomData_em_get_n(const struct CustomData *data, void *block, int type, int n); +void *CustomData_bmesh_get(const struct CustomData *data, void *block, int type); +void *CustomData_bmesh_get_n(const struct CustomData *data, void *block, int type, int n); /* gets a pointer to the active or first layer of type * returns NULL if there is no layer of type @@ -199,6 +210,12 @@ void CustomData_em_set(struct CustomData *data, void *block, int type, void CustomData_em_set_n(struct CustomData *data, void *block, int type, int n, void *source); +void CustomData_bmesh_set(const struct CustomData *data, void *block, int type, + void *source); + +void CustomData_bmesh_set_n(struct CustomData *data, void *block, int type, int n, + void *source); + /* set the pointer of to the first layer of type. the old data is not freed. * returns the value of ptr if the layer is found, NULL otherwise */ @@ -220,12 +237,20 @@ void CustomData_set_layer_flag(struct CustomData *data, int type, int flag); void CustomData_em_set_default(struct CustomData *data, void **block); void CustomData_em_free_block(struct CustomData *data, void **block); +void CustomData_bmesh_set_default(struct CustomData *data, void **block); +void CustomData_bmesh_free_block(struct CustomData *data, void **block); + /* copy custom data to/from layers as in mesh/derivedmesh, to editmesh blocks of data. the CustomData's must not be compatible */ void CustomData_to_em_block(const struct CustomData *source, struct CustomData *dest, int index, void **block); void CustomData_from_em_block(const struct CustomData *source, struct CustomData *dest, void *block, int index); +void CustomData_to_bmesh_block(const struct CustomData *source, + struct CustomData *dest, int src_index, void **dest_block); +void CustomData_from_bmesh_block(const struct CustomData *source, + struct CustomData *dest, void *src_block, int dest_index); + /* query info over types */ void CustomData_file_write_info(int type, char **structname, int *structnum); @@ -241,4 +266,8 @@ void CustomData_set_layer_unique_name(struct CustomData *data, int index); only after this test passes, layer->data should be assigned */ int CustomData_verify_versions(struct CustomData *data, int index); +/*BMesh specific customdata stuff*/ +void CustomData_to_bmeshpoly(struct CustomData *fdata, struct CustomData *pdata, struct CustomData *ldata); +void CustomData_from_bmeshpoly(struct CustomData *fdata, struct CustomData *pdata, struct CustomData *ldata, int total); +void CustomData_bmesh_init_pool(struct CustomData *data, int allocsize); #endif diff --git a/source/blender/blenkernel/intern/BME_Customdata.c b/source/blender/blenkernel/intern/BME_Customdata.c index 8b48efbdbd2..1fc8a4071dc 100644 --- a/source/blender/blenkernel/intern/BME_Customdata.c +++ b/source/blender/blenkernel/intern/BME_Customdata.c @@ -40,6 +40,7 @@ #include "bmesh_private.h" #include <string.h> #include "MEM_guardedalloc.h" +#include "BLI_mempool.h" /********************* Layer type information **********************/ typedef struct BME_LayerTypeInfo { @@ -83,7 +84,7 @@ void BME_CD_Create(BME_CustomData *data, BME_CustomDataInit *init, int initalloc if(data->totlayer){ /*alloc memory*/ data->layers = MEM_callocN(sizeof(BME_CustomDataLayer)*data->totlayer, "BMesh Custom Data Layers"); - data->pool = BME_mempool_create(data->totsize, initalloc, initalloc); + data->pool = BLI_mempool_create(data->totsize, initalloc, initalloc); /*initialize layer data*/ for(i=0; i < BME_CD_NUMTYPES; i++){ if(init->layout[i]){ @@ -102,7 +103,7 @@ void BME_CD_Create(BME_CustomData *data, BME_CustomDataInit *init, int initalloc void BME_CD_Free(BME_CustomData *data) { - if(data->pool) BME_mempool_destroy(data->pool); + if(data->pool) BLI_mempool_destroy(data->pool); } /*Block level ops*/ @@ -119,7 +120,7 @@ void BME_CD_free_block(BME_CustomData *data, void **block) typeInfo->free((char*)*block + offset, 1, typeInfo->size); } } - BME_mempool_free(data->pool, *block); + BLI_mempool_free(data->pool, *block); *block = NULL; } @@ -130,7 +131,7 @@ static void BME_CD_alloc_block(BME_CustomData *data, void **block) if (*block) BME_CD_free_block(data, block); //if we copy layers that have their own free functions like deformverts if (data->totsize > 0) - *block = BME_mempool_alloc(data->pool); + *block = BLI_mempool_alloc(data->pool); else *block = NULL; } diff --git a/source/blender/blenkernel/intern/BME_conversions.c b/source/blender/blenkernel/intern/BME_conversions.c index 08483711c45..daf0de5b748 100644 --- a/source/blender/blenkernel/intern/BME_conversions.c +++ b/source/blender/blenkernel/intern/BME_conversions.c @@ -33,6 +33,7 @@ */ #include "MEM_guardedalloc.h" +#include "BKE_customdata.h" #include "DNA_listBase.h" #include "DNA_meshdata_types.h" @@ -55,10 +56,199 @@ #include "BSE_edit.h" +/*merge these functions*/ +static void BME_DMcorners_to_loops(BME_Mesh *bm, CustomData *facedata, int index, BME_Poly *f, int numCol, int numTex){ + int i, j; + BME_Loop *l; + MTFace *texface; + MTexPoly *texpoly; + MCol *mcol; + MLoopCol *mloopcol; + MLoopUV *mloopuv; + + for(i=0; i< numTex; i++){ + texface = CustomData_get_layer_n(facedata, CD_MTFACE, i); + texpoly = CustomData_bmesh_get_n(&bm->pdata, f->data, CD_MTEXPOLY, i); + + texpoly->tpage = texface[index].tpage; + texpoly->flag = texface[index].flag; + texpoly->transp = texface[index].transp; + texpoly->mode = texface[index].mode; + texpoly->tile = texface[index].tile; + texpoly->unwrap = texface[index].unwrap; + + j = 0; + l = f->loopbase; + do{ + mloopuv = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPUV, i); + mloopuv->uv[0] = texface[index].uv[j][0]; + mloopuv->uv[1] = texface[index].uv[j][1]; + j++; + l = l->next; + }while(l!=f->loopbase); + } + + for(i=0; i < numCol; i++){ + mcol = CustomData_get_layer_n(facedata, CD_MCOL, i); + j = 0; + l = f->loopbase; + do{ + mloopcol = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPCOL, i); + mloopcol->r = mcol[(index*4)+j].r; + mloopcol->g = mcol[(index*4)+j].g; + mloopcol->b = mcol[(index*4)+j].b; + mloopcol->a = mcol[(index*4)+j].a; + j++; + l = l->next; + }while(l!=f->loopbase); + } +} + +static void BME_DMloops_to_corners(BME_Mesh *bm, CustomData *facedata, int index, BME_Poly *f,int numCol, int numTex){ + int i, j; + BME_Loop *l; + MTFace *texface; + MTexPoly *texpoly; + MCol *mcol; + MLoopCol *mloopcol; + MLoopUV *mloopuv; + + for(i=0; i < numTex; i++){ + texface = CustomData_get_layer_n(facedata, CD_MTFACE, i); + texpoly = CustomData_bmesh_get_n(&bm->pdata, f->data, CD_MTEXPOLY, i); + + texface[index].tpage = texpoly->tpage; + texface[index].flag = texpoly->flag; + texface[index].transp = texpoly->transp; + texface[index].mode = texpoly->mode; + texface[index].tile = texpoly->tile; + texface[index].unwrap = texpoly->unwrap; + + j = 0; + l = f->loopbase; + do{ + mloopuv = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPUV, i); + texface[index].uv[j][0] = mloopuv->uv[0]; + texface[index].uv[j][1] = mloopuv->uv[1]; + j++; + l = l->next; + }while(l!=f->loopbase); + + } + for(i=0; i < numCol; i++){ + mcol = CustomData_get_layer_n(facedata,CD_MCOL, i); + j = 0; + l = f->loopbase; + do{ + mloopcol = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPCOL, i); + mcol[(index*4) + j].r = mloopcol->r; + mcol[(index*4) + j].g = mloopcol->g; + mcol[(index*4) + j].b = mloopcol->b; + mcol[(index*4) + j].a = mloopcol->a; + j++; + l = l->next; + }while(l!=f->loopbase); + } +} + + +static void BME_corners_to_loops(BME_Mesh *bm, CustomData *facedata, void *face_block, BME_Poly *f,int numCol, int numTex){ + int i, j; + BME_Loop *l; + MTFace *texface; + MTexPoly *texpoly; + MCol *mcol; + MLoopCol *mloopcol; + MLoopUV *mloopuv; + + for(i=0; i < numTex; i++){ + texface = CustomData_em_get_n(facedata, face_block, CD_MTFACE, i); + texpoly = CustomData_bmesh_get_n(&bm->pdata, f->data, CD_MTEXPOLY, i); + + texpoly->tpage = texface->tpage; + texpoly->flag = texface->flag; + texpoly->transp = texface->transp; + texpoly->mode = texface->mode; + texpoly->tile = texface->tile; + texpoly->unwrap = texface->unwrap; + + j = 0; + l = f->loopbase; + do{ + mloopuv = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPUV, i); + mloopuv->uv[0] = texface->uv[j][0]; + mloopuv->uv[1] = texface->uv[j][1]; + j++; + l = l->next; + }while(l!=f->loopbase); + + } + for(i=0; i < numCol; i++){ + mcol = CustomData_em_get_n(facedata, face_block, CD_MCOL, i); + j = 0; + l = f->loopbase; + do{ + mloopcol = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPCOL, i); + mloopcol->r = mcol[j].r; + mloopcol->g = mcol[j].g; + mloopcol->b = mcol[j].b; + mloopcol->a = mcol[j].a; + j++; + l = l->next; + }while(l!=f->loopbase); + } +} + +static void BME_loops_to_corners(BME_Mesh *bm, CustomData *facedata, void *face_block, BME_Poly *f,int numCol, int numTex){ + int i, j; + BME_Loop *l; + MTFace *texface; + MTexPoly *texpoly; + MCol *mcol; + MLoopCol *mloopcol; + MLoopUV *mloopuv; + + for(i=0; i < numTex; i++){ + texface = CustomData_em_get_n(facedata, face_block, CD_MTFACE, i); + texpoly = CustomData_bmesh_get_n(&bm->pdata, f->data, CD_MTEXPOLY, i); + + texface->tpage = texpoly->tpage; + texface->flag = texpoly->flag; + texface->transp = texpoly->transp; + texface->mode = texpoly->mode; + texface->tile = texpoly->tile; + texface->unwrap = texpoly->unwrap; + + j = 0; + l = f->loopbase; + do{ + mloopuv = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPUV, i); + texface->uv[j][0] = mloopuv->uv[0]; + texface->uv[j][1] = mloopuv->uv[1]; + j++; + l = l->next; + }while(l!=f->loopbase); + + } + for(i=0; i < numCol; i++){ + mcol = CustomData_em_get_n(facedata, face_block, CD_MCOL, i); + j = 0; + l = f->loopbase; + do{ + mloopcol = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPCOL, i); + mcol[j].r = mloopcol->r; + mcol[j].g = mloopcol->g; + mcol[j].b = mloopcol->b; + mcol[j].a = mloopcol->a; + j++; + l = l->next; + }while(l!=f->loopbase); + } +} +/*move the EditMesh conversion functions to editmesh_tools.c*/ BME_Mesh *BME_editmesh_to_bmesh(EditMesh *em) { BME_Mesh *bm; - int allocsize[4] = {512,512,2048,512}; - BME_CustomDataInit *init = MEM_callocN(sizeof(BME_CustomDataInit) * 4, "Bmesh custom data init"); + int allocsize[4] = {512,512,2048,512}, numTex, numCol; BME_Vert *v1, *v2; BME_Edge *e, *edar[4]; BME_Poly *f; @@ -68,9 +258,25 @@ BME_Mesh *BME_editmesh_to_bmesh(EditMesh *em) { EditFace *efa; int len; - bm = BME_make_mesh(allocsize,init); + bm = BME_make_mesh(allocsize); + + /*copy custom data layout*/ + CustomData_copy(&em->vdata, &bm->vdata, CD_MASK_BMESH, CD_CALLOC, 0); + CustomData_copy(&em->edata, &bm->edata, CD_MASK_BMESH, CD_CALLOC, 0); + CustomData_copy(&em->fdata, &bm->pdata, CD_MASK_BMESH, CD_CALLOC, 0); + + /*copy face corner data*/ + CustomData_to_bmeshpoly(&em->fdata, &bm->pdata, &bm->ldata); + /*initialize memory pools*/ + CustomData_bmesh_init_pool(&bm->vdata, allocsize[0]); + CustomData_bmesh_init_pool(&bm->edata, allocsize[1]); + CustomData_bmesh_init_pool(&bm->ldata, allocsize[2]); + CustomData_bmesh_init_pool(&bm->pdata, allocsize[3]); + /*needed later*/ + numTex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY); + numCol = CustomData_number_of_layers(&bm->ldata, CD_MLOOPCOL); + BME_model_begin(bm); - /*add verts*/ eve= em->verts.first; while(eve) { @@ -79,9 +285,8 @@ BME_Mesh *BME_editmesh_to_bmesh(EditMesh *em) { v1->flag = eve->f; v1->h = eve->h; v1->bweight = eve->bweight; - - /* link the verts for edge and face construction; - * kind of a dangerous thing - remember to cast back to BME_Vert before using! */ + /*Copy Custom Data*/ + CustomData_bmesh_copy_data(&em->vdata, &bm->vdata, eve->data, &v1->data); eve->tmp.v = (EditVert*)v1; eve = eve->next; } @@ -99,13 +304,10 @@ BME_Mesh *BME_editmesh_to_bmesh(EditMesh *em) { if(eed->seam) e->flag |= ME_SEAM; if(eed->h & EM_FGON) e->flag |= ME_FGON; if(eed->h & 1) e->flag |= ME_HIDE; - - /* link the edges for face construction; - * kind of a dangerous thing - remember to cast back to BME_Edge before using! */ eed->tmp.e = (EditEdge*)e; + CustomData_bmesh_copy_data(&em->edata, &bm->edata, eed->data, &e->data); eed = eed->next; } - /*add faces.*/ efa= em->faces.first; while(efa) { @@ -134,13 +336,13 @@ BME_Mesh *BME_editmesh_to_bmesh(EditMesh *em) { if(efa->f & 1) f->flag |= ME_FACE_SEL; else f->flag &= ~ME_FACE_SEL; } + CustomData_bmesh_copy_data(&em->fdata, &bm->pdata, efa->data, &f->data); + BME_corners_to_loops(bm, &em->fdata, efa->data, f,numCol,numTex); efa = efa->next; } BME_model_end(bm); - MEM_freeN(init); return bm; } - /* adds the geometry in the bmesh to G.editMesh (does not free G.editMesh) * if td != NULL, the transdata will be mapped to the EditVert's co */ EditMesh *BME_bmesh_to_editmesh(BME_Mesh *bm, BME_TransData_Head *td) { @@ -155,12 +357,21 @@ EditMesh *BME_bmesh_to_editmesh(BME_Mesh *bm, BME_TransData_Head *td) { EditEdge *eed; EditFace *efa; - int totvert, len, i; + int totvert, len, i, numTex, numCol; em = G.editMesh; if (em == NULL) return NULL; + + CustomData_copy(&bm->vdata, &em->vdata, CD_MASK_BMESH, CD_CALLOC, 0); + CustomData_copy(&bm->edata, &em->edata, CD_MASK_BMESH, CD_CALLOC, 0); + CustomData_copy(&bm->pdata, &em->fdata, CD_MASK_BMESH, CD_CALLOC, 0); + CustomData_from_bmeshpoly(&em->fdata, &bm->pdata, &bm->ldata,0); + numTex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY); + numCol = CustomData_number_of_layers(&bm->ldata, CD_MLOOPCOL); + + /* convert to EditMesh */ /* make editverts */ totvert = BLI_countlist(&(bm->verts)); @@ -176,6 +387,7 @@ EditMesh *BME_bmesh_to_editmesh(BME_Mesh *bm, BME_TransData_Head *td) { eve1->f = (unsigned char)v1->flag; eve1->h = (unsigned char)v1->h; eve1->bweight = v1->bweight; + CustomData_em_copy_data(&bm->vdata, &em->vdata, v1->data, &eve1->data); } /* make edges */ @@ -191,6 +403,8 @@ EditMesh *BME_bmesh_to_editmesh(BME_Mesh *bm, BME_TransData_Head *td) { if(e->flag & ME_HIDE) eed->h |= 1; if(G.scene->selectmode==SCE_SELECT_EDGE) EM_select_edge(eed, eed->f & SELECT); + + CustomData_em_copy_data(&bm->edata, &em->edata, e->data, &eed->data); } } @@ -217,6 +431,8 @@ EditMesh *BME_bmesh_to_editmesh(BME_Mesh *bm, BME_TransData_Head *td) { if(f->flag & ME_HIDE) efa->h= 1; if((G.f & G_FACESELECT) && (efa->f & SELECT)) EM_select_face(efa, 1); /* flush down */ + CustomData_em_copy_data(&bm->pdata, &em->fdata, f->data, &efa->data); + BME_loops_to_corners(bm, &em->fdata, efa->data, f,numCol,numTex); } } @@ -234,18 +450,33 @@ BME_Mesh *BME_derivedmesh_to_bmesh(DerivedMesh *dm) BME_Mesh *bm; int allocsize[4] = {512,512,2048,512}; - BME_CustomDataInit *init = MEM_callocN(sizeof(BME_CustomDataInit) * 4, "Bmesh custom data init"); MVert *mvert, *mv; MEdge *medge, *me; MFace *mface, *mf; - int totface,totedge,totvert,i,len; + int totface,totedge,totvert,i,len, numTex, numCol; BME_Vert *v1=NULL,*v2=NULL, **vert_array; BME_Edge *e=NULL; BME_Poly *f=NULL; EdgeHash *edge_hash = BLI_edgehash_new(); - bm = BME_make_mesh(allocsize,init); + bm = BME_make_mesh(allocsize); + /*copy custom data layout*/ + CustomData_copy(&dm->vertData, &bm->vdata, CD_MASK_BMESH, CD_CALLOC, 0); + CustomData_copy(&dm->edgeData, &bm->edata, CD_MASK_BMESH, CD_CALLOC, 0); + CustomData_copy(&dm->faceData, &bm->pdata, CD_MASK_BMESH, CD_CALLOC, 0); + + /*copy face corner data*/ + CustomData_to_bmeshpoly(&dm->faceData, &bm->pdata, &bm->ldata); + /*initialize memory pools*/ + CustomData_bmesh_init_pool(&bm->vdata, allocsize[0]); + CustomData_bmesh_init_pool(&bm->edata, allocsize[1]); + CustomData_bmesh_init_pool(&bm->ldata, allocsize[2]); + CustomData_bmesh_init_pool(&bm->pdata, allocsize[3]); + /*needed later*/ + numTex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY); + numCol = CustomData_number_of_layers(&bm->ldata, CD_MLOOPCOL); + totvert = dm->getNumVerts(dm); totedge = dm->getNumEdges(dm); totface = dm->getNumFaces(dm); @@ -262,6 +493,7 @@ BME_Mesh *BME_derivedmesh_to_bmesh(DerivedMesh *dm) vert_array[i] = v1; v1->flag = mv->flag; v1->bweight = mv->bweight/255.0f; + CustomData_to_bmesh_block(&dm->vertData, &bm->vdata, i, &v1->data); } /*add edges*/ for(i=0,me = medge; i < totedge;i++,me++){ @@ -272,6 +504,7 @@ BME_Mesh *BME_derivedmesh_to_bmesh(DerivedMesh *dm) e->bweight = me->bweight/255.0f; e->flag = (unsigned char)me->flag; BLI_edgehash_insert(edge_hash,me->v1,me->v2,e); + CustomData_to_bmesh_block(&dm->edgeData, &bm->edata, i, &e->data); } /*add faces.*/ for(i=0,mf = mface; i < totface;i++,mf++){ @@ -295,12 +528,13 @@ BME_Mesh *BME_derivedmesh_to_bmesh(DerivedMesh *dm) f = BME_MF(bm,v1,v2,edar,len); f->mat_nr = mf->mat_nr; f->flag = mf->flag; + CustomData_to_bmesh_block(&dm->faceData,&bm->pdata,i,&f->data); + BME_DMcorners_to_loops(bm, &dm->faceData,i,f, numCol,numTex); } BME_model_end(bm); BLI_edgehash_free(edge_hash, NULL); MEM_freeN(vert_array); - MEM_freeN(init); return bm; } @@ -309,7 +543,7 @@ DerivedMesh *BME_bmesh_to_derivedmesh(BME_Mesh *bm, DerivedMesh *dm) MFace *mface, *mf; MEdge *medge, *me; MVert *mvert, *mv; - int totface,totedge,totvert,i,bmeshok,len; + int totface,totedge,totvert,i,bmeshok,len, numTex, numCol; BME_Vert *v1=NULL; BME_Edge *e=NULL, *oe=NULL; @@ -345,12 +579,21 @@ DerivedMesh *BME_bmesh_to_derivedmesh(BME_Mesh *bm, DerivedMesh *dm) /*convert back to mesh*/ result = CDDM_from_template(dm,totvert,totedge,totface); + CustomData_merge(&bm->vdata, &result->vertData, CD_MASK_BMESH, CD_CALLOC, totvert); + CustomData_merge(&bm->edata, &result->edgeData, CD_MASK_BMESH, CD_CALLOC, totedge); + CustomData_merge(&bm->pdata, &result->faceData, CD_MASK_BMESH, CD_CALLOC, totface); + CustomData_from_bmeshpoly(&result->faceData, &bm->pdata, &bm->ldata,totface); + numTex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY); + numCol = CustomData_number_of_layers(&bm->ldata, CD_MLOOPCOL); + + /*Make Verts*/ mvert = CDDM_get_verts(result); for(i=0,v1=bm->verts.first,mv=mvert;v1;v1=v1->next,i++,mv++){ VECCOPY(mv->co,v1->co); mv->flag = (unsigned char)v1->flag; mv->bweight = (char)(255.0*v1->bweight); + CustomData_from_bmesh_block(&bm->vdata, &result->vertData, &v1->data, i); } medge = CDDM_get_edges(result); i=0; @@ -368,6 +611,7 @@ DerivedMesh *BME_bmesh_to_derivedmesh(BME_Mesh *bm, DerivedMesh *dm) me->crease = (char)(255.0*e->crease); me->bweight = (char)(255.0*e->bweight); me->flag = e->flag; + CustomData_from_bmesh_block(&bm->edata, &result->edgeData, &e->data, i); me++; i++; } @@ -389,9 +633,11 @@ DerivedMesh *BME_bmesh_to_derivedmesh(BME_Mesh *bm, DerivedMesh *dm) if(mf->v3 == 0 || (len == 4 && mf->v4 == 0)){ test_index_face(mf, NULL, i, len); } - i++; mf->mat_nr = (unsigned char)f->mat_nr; mf->flag = (unsigned char)f->flag; + CustomData_from_bmesh_block(&bm->pdata, &result->faceData, &f->data, i); + BME_DMloops_to_corners(bm, &result->faceData, i, f,numCol,numTex); + i++; } } } diff --git a/source/blender/blenkernel/intern/BME_eulers.c b/source/blender/blenkernel/intern/BME_eulers.c index 3403f5829fe..801e0b8bdec 100644 --- a/source/blender/blenkernel/intern/BME_eulers.c +++ b/source/blender/blenkernel/intern/BME_eulers.c @@ -39,6 +39,7 @@ #include "DNA_mesh_types.h" #include "BKE_utildefines.h" +#include "BKE_customdata.h" #include "BKE_bmesh.h" #include "BLI_blenlib.h" @@ -618,8 +619,8 @@ BME_Poly *BME_SFME(BME_Mesh *bm, BME_Poly *f, BME_Vert *v1, BME_Vert *v2, BME_Lo BME_disk_append_edge(e, v2); f2 = BME_addpolylist(bm,f); - f1loop = BME_create_loop(bm,v2,e,f,NULL); - f2loop = BME_create_loop(bm,v1,e,f2,NULL); + f1loop = BME_create_loop(bm,v2,e,f,v2loop); + f2loop = BME_create_loop(bm,v1,e,f2,v1loop); f1loop->prev = v2loop->prev; f2loop->prev = v1loop->prev; @@ -663,16 +664,16 @@ BME_Poly *BME_SFME(BME_Mesh *bm, BME_Poly *f, BME_Vert *v1, BME_Vert *v2, BME_Lo * Takes a an edge and pointer to one of its vertices and collapses * the edge on that vertex. * - * Before: OE KE + * Before: OE KE * ------- ------- * | || | - * OV KV TV + * OV KV TV * * * After: OE * --------------- * | | - * OV TV + * OV TV * * * Restrictions: @@ -723,6 +724,8 @@ int BME_JEKV(BME_Mesh *bm, BME_Edge *ke, BME_Vert *kv) /*remove ke from tv's disk cycle*/ BME_disk_remove_edge(ke, tv); + + /*deal with radial cycle of ke*/ if(ke->loop){ /*first step, fix the neighboring loops of all loops in ke's radial cycle*/ @@ -763,6 +766,7 @@ int BME_JEKV(BME_Mesh *bm, BME_Edge *ke, BME_Vert *kv) } + /*Validate disk cycles*/ diskbase = BME_disk_getpointer(ov->edge,ov); edok = BME_cycle_validate(valance1, diskbase); diff --git a/source/blender/blenkernel/intern/BME_mesh.c b/source/blender/blenkernel/intern/BME_mesh.c index 184ef2b8a0e..ad46a7c1eb7 100644 --- a/source/blender/blenkernel/intern/BME_mesh.c +++ b/source/blender/blenkernel/intern/BME_mesh.c @@ -32,64 +32,33 @@ * ***** END GPL LICENSE BLOCK ***** */ -#include "MEM_guardedalloc.h" +#include "MEM_guardedalloc.h" #include "DNA_listBase.h" -#include "DNA_meshdata_types.h" -#include "DNA_mesh_types.h" -#include "DNA_object_types.h" -#include "DNA_scene_types.h" - - +#include "BLI_blenlib.h" #include "BKE_utildefines.h" #include "BKE_bmesh.h" -#include "BKE_global.h" -#include "BKE_depsgraph.h" -#include "BLI_blenlib.h" -#include "BLI_editVert.h" -#include "BIF_editmesh.h" -#include "BIF_space.h" -#include "editmesh.h" #include "bmesh_private.h" -#include "mydevice.h" - -#include "BSE_edit.h" /* * BME MAKE MESH * * Allocates a new BME_Mesh structure. - * The arguments are two arrays, one of type int - * and another of type BME_CustomDataInit. The first array - * contains the allocation size for each element pool in - * the mesh. For instance allocsize[0] contains the number - * of vertices to allocate at a time for the vertex pool. - * - * The second array contains structures describing the layout - * of custom data for each element type in the mesh. So init[0] - * contains the custom data layout information for vertices, init[1] - * the layout information for edges and so on. - * * Returns - * Pointer to a Bmesh * */ -BME_Mesh *BME_make_mesh(int allocsize[4], BME_CustomDataInit init[4]) +BME_Mesh *BME_make_mesh(int allocsize[4]) { /*allocate the structure*/ BME_Mesh *bm = MEM_callocN(sizeof(BME_Mesh),"BMesh"); /*allocate the memory pools for the mesh elements*/ - bm->vpool = BME_mempool_create(sizeof(BME_Vert), allocsize[0], allocsize[0]); - bm->epool = BME_mempool_create(sizeof(BME_Edge), allocsize[1], allocsize[1]); - bm->lpool = BME_mempool_create(sizeof(BME_Loop), allocsize[2], allocsize[2]); - bm->ppool = BME_mempool_create(sizeof(BME_Poly), allocsize[3], allocsize[3]); - /*Setup custom data layers*/ - BME_CD_Create(&bm->vdata, &init[0], allocsize[0]); - BME_CD_Create(&bm->edata, &init[1], allocsize[1]); - BME_CD_Create(&bm->ldata, &init[2], allocsize[2]); - BME_CD_Create(&bm->pdata, &init[3], allocsize[3]); + bm->vpool = BLI_mempool_create(sizeof(BME_Vert), allocsize[0], allocsize[0]); + bm->epool = BLI_mempool_create(sizeof(BME_Edge), allocsize[1], allocsize[1]); + bm->lpool = BLI_mempool_create(sizeof(BME_Loop), allocsize[2], allocsize[2]); + bm->ppool = BLI_mempool_create(sizeof(BME_Poly), allocsize[3], allocsize[3]); return bm; } /* @@ -105,26 +74,35 @@ void BME_free_mesh(BME_Mesh *bm) BME_Loop *l; BME_Poly *f; - for(v=bm->verts.first; v; v=v->next) BME_CD_free_block(&bm->vdata, &v->data); - for(e=bm->edges.first; e; e=e->next) BME_CD_free_block(&bm->edata, &e->data); + for(v=bm->verts.first; v; v=v->next) CustomData_bmesh_free_block(&bm->vdata, &v->data); + for(e=bm->edges.first; e; e=e->next) CustomData_bmesh_free_block(&bm->edata, &e->data); for(f=bm->polys.first; f; f=f->next){ - BME_CD_free_block(&bm->pdata, &f->data); + CustomData_bmesh_free_block(&bm->pdata, &f->data); l = f->loopbase; do{ - BME_CD_free_block(&bm->ldata, &l->data); + CustomData_bmesh_free_block(&bm->ldata, &l->data); l = l->next; }while(l!=f->loopbase); } + + /*Free custom data pools, This should probably go in CustomData_free?*/ + if(bm->vdata.totlayer) BLI_mempool_destroy(bm->vdata.pool); + if(bm->edata.totlayer) BLI_mempool_destroy(bm->edata.pool); + if(bm->ldata.totlayer) BLI_mempool_destroy(bm->ldata.pool); + if(bm->pdata.totlayer) BLI_mempool_destroy(bm->pdata.pool); + + /*free custom data*/ + CustomData_free(&bm->vdata,0); + CustomData_free(&bm->edata,0); + CustomData_free(&bm->ldata,0); + CustomData_free(&bm->pdata,0); + /*destroy element pools*/ - BME_mempool_destroy(bm->vpool); - BME_mempool_destroy(bm->epool); - BME_mempool_destroy(bm->ppool); - BME_mempool_destroy(bm->lpool); - /*free custom data pools*/ - BME_CD_Free(&bm->vdata); - BME_CD_Free(&bm->edata); - BME_CD_Free(&bm->ldata); - BME_CD_Free(&bm->pdata); + BLI_mempool_destroy(bm->vpool); + BLI_mempool_destroy(bm->epool); + BLI_mempool_destroy(bm->ppool); + BLI_mempool_destroy(bm->lpool); + MEM_freeN(bm); } diff --git a/source/blender/blenkernel/intern/BME_structure.c b/source/blender/blenkernel/intern/BME_structure.c index cbf780c6467..ca27f5efd10 100644 --- a/source/blender/blenkernel/intern/BME_structure.c +++ b/source/blender/blenkernel/intern/BME_structure.c @@ -41,101 +41,6 @@ #include "BLI_blenlib.h" #include "BLI_linklist.h" #include "BLI_ghash.h" - -#include "BKE_customdata.h" - -/* - Simple, fast memory allocator for allocating many elements of the same size. -*/ -typedef struct BME_mempool_chunk{ - struct BME_mempool_chunk *next, *prev; - void *data; -}BME_mempool_chunk; - -/*this is just to make things prettier*/ -typedef struct BME_freenode{ - struct BME_freenode *next; -}BME_freenode; - -BME_mempool *BME_mempool_create(int esize, int tote, int pchunk) -{ BME_mempool *pool = NULL; - BME_freenode *lasttail = NULL, *curnode = NULL; - int i,j, maxchunks; - char *addr; - - /*allocate the pool structure*/ - pool = MEM_mallocN(sizeof(BME_mempool),"memory pool"); - pool->esize = esize; - pool->pchunk = pchunk; - pool->csize = esize * pchunk; - pool->chunks.first = pool->chunks.last = NULL; - - maxchunks = tote / pchunk; - - /*allocate the actual chunks*/ - for(i=0; i < maxchunks; i++){ - BME_mempool_chunk *mpchunk = MEM_mallocN(sizeof(BME_mempool_chunk), "BME_Mempool Chunk"); - mpchunk->next = mpchunk->prev = NULL; - mpchunk->data = MEM_mallocN(pool->csize, "BME Mempool Chunk Data"); - BLI_addtail(&(pool->chunks), mpchunk); - - if(i==0) pool->free = mpchunk->data; /*start of the list*/ - /*loop through the allocated data, building the pointer structures*/ - for(addr = mpchunk->data, j=0; j < pool->pchunk; j++){ - curnode = ((BME_freenode*)addr); - addr += pool->esize; - curnode->next = (BME_freenode*)addr; - } - /*final pointer in the previously allocated chunk is wrong.*/ - if(lasttail) lasttail->next = mpchunk->data; - /*set the end of this chunks memory to the new tail for next iteration*/ - lasttail = curnode; - } - /*terminate the list*/ - curnode->next = NULL; - return pool; -} - -void *BME_mempool_alloc(BME_mempool *pool){ - void *retval=NULL; - BME_freenode *curnode=NULL; - char *addr=NULL; - int j; - - if(!(pool->free)){ - /*need to allocate a new chunk*/ - BME_mempool_chunk *mpchunk = MEM_mallocN(sizeof(BME_mempool_chunk), "BME_Mempool Chunk"); - mpchunk->next = mpchunk->prev = NULL; - mpchunk->data = MEM_mallocN(pool->csize, "BME_Mempool Chunk Data"); - BLI_addtail(&(pool->chunks), mpchunk); - - pool->free = mpchunk->data; /*start of the list*/ - for(addr = mpchunk->data, j=0; j < pool->pchunk; j++){ - curnode = ((BME_freenode*)addr); - addr += pool->esize; - curnode->next = (BME_freenode*)addr; - } - curnode->next = NULL; /*terminate the list*/ - } - - retval = pool->free; - pool->free = pool->free->next; - //memset(retval, 0, pool->esize); - return retval; -} - -void BME_mempool_free(BME_mempool *pool, void *addr){ //doesnt protect against double frees, dont be stupid! - BME_freenode *newhead = addr; - newhead->next = pool->free; - pool->free = newhead; -} -void BME_mempool_destroy(BME_mempool *pool) -{ - BME_mempool_chunk *mpchunk=NULL; - for(mpchunk = pool->chunks.first; mpchunk; mpchunk = mpchunk->next) MEM_freeN(mpchunk->data); - BLI_freelistN(&(pool->chunks)); - MEM_freeN(pool); -} /** * MISC utility functions. * @@ -179,7 +84,7 @@ int BME_edge_swapverts(BME_Edge *e, BME_Vert *orig, BME_Vert *new){ BME_Vert *BME_addvertlist(BME_Mesh *bm, BME_Vert *example){ BME_Vert *v=NULL; - v = BME_mempool_alloc(bm->vpool); + v = BLI_mempool_alloc(bm->vpool); v->next = v->prev = NULL; v->EID = bm->nextv; v->co[0] = v->co[1] = v->co[2] = 0.0f; @@ -195,16 +100,16 @@ BME_Vert *BME_addvertlist(BME_Mesh *bm, BME_Vert *example){ if(example){ VECCOPY(v->co,example->co); - BME_CD_copy_data(&bm->vdata, &bm->vdata, example->data, &v->data); + CustomData_bmesh_copy_data(&bm->vdata, &bm->vdata, example->data, &v->data); } else - BME_CD_set_default(&bm->vdata, &v->data); + CustomData_bmesh_set_default(&bm->vdata, &v->data); return v; } BME_Edge *BME_addedgelist(BME_Mesh *bm, BME_Vert *v1, BME_Vert *v2, BME_Edge *example){ BME_Edge *e=NULL; - e = BME_mempool_alloc(bm->epool); + e = BLI_mempool_alloc(bm->epool); e->next = e->prev = NULL; e->EID = bm->nexte; e->v1 = v1; @@ -222,16 +127,16 @@ BME_Edge *BME_addedgelist(BME_Mesh *bm, BME_Vert *v1, BME_Vert *v2, BME_Edge *ex BLI_addtail(&(bm->edges), e); if(example) - BME_CD_copy_data(&bm->edata, &bm->edata, example->data, &e->data); + CustomData_bmesh_copy_data(&bm->edata, &bm->edata, example->data, &e->data); else - BME_CD_set_default(&bm->edata, &e->data); + CustomData_bmesh_set_default(&bm->edata, &e->data); return e; } BME_Loop *BME_create_loop(BME_Mesh *bm, BME_Vert *v, BME_Edge *e, BME_Poly *f, BME_Loop *example){ BME_Loop *l=NULL; - l = BME_mempool_alloc(bm->lpool); + l = BLI_mempool_alloc(bm->lpool); l->next = l->prev = NULL; l->EID = bm->nextl; l->radial.next = l->radial.prev = NULL; @@ -246,16 +151,16 @@ BME_Loop *BME_create_loop(BME_Mesh *bm, BME_Vert *v, BME_Edge *e, BME_Poly *f, B bm->totloop++; if(example) - BME_CD_copy_data(&bm->ldata, &bm->ldata, example->data, &l->data); + CustomData_bmesh_copy_data(&bm->ldata, &bm->ldata, example->data, &l->data); else - BME_CD_set_default(&bm->ldata, &l->data); + CustomData_bmesh_set_default(&bm->ldata, &l->data); return l; } BME_Poly *BME_addpolylist(BME_Mesh *bm, BME_Poly *example){ BME_Poly *f = NULL; - f = BME_mempool_alloc(bm->ppool); + f = BLI_mempool_alloc(bm->ppool); f->next = f->prev = NULL; f->EID = bm->nextp; f->loopbase = NULL; @@ -268,9 +173,9 @@ BME_Poly *BME_addpolylist(BME_Mesh *bm, BME_Poly *example){ bm->totpoly++; if(example) - BME_CD_copy_data(&bm->pdata, &bm->pdata, example->data, &f->data); + CustomData_bmesh_copy_data(&bm->pdata, &bm->pdata, example->data, &f->data); else - BME_CD_set_default(&bm->pdata, &f->data); + CustomData_bmesh_set_default(&bm->pdata, &f->data); return f; @@ -281,23 +186,23 @@ BME_Poly *BME_addpolylist(BME_Mesh *bm, BME_Poly *example){ */ void BME_free_vert(BME_Mesh *bm, BME_Vert *v){ bm->totvert--; - BME_CD_free_block(&bm->vdata, &v->data); - BME_mempool_free(bm->vpool, v); + CustomData_bmesh_free_block(&bm->vdata, &v->data); + BLI_mempool_free(bm->vpool, v); } void BME_free_edge(BME_Mesh *bm, BME_Edge *e){ bm->totedge--; - BME_CD_free_block(&bm->edata, &e->data); - BME_mempool_free(bm->epool, e); + CustomData_bmesh_free_block(&bm->edata, &e->data); + BLI_mempool_free(bm->epool, e); } void BME_free_poly(BME_Mesh *bm, BME_Poly *f){ bm->totpoly--; - BME_CD_free_block(&bm->pdata, &f->data); - BME_mempool_free(bm->ppool, f); + CustomData_bmesh_free_block(&bm->pdata, &f->data); + BLI_mempool_free(bm->ppool, f); } void BME_free_loop(BME_Mesh *bm, BME_Loop *l){ bm->totloop--; - BME_CD_free_block(&bm->ldata, &l->data); - BME_mempool_free(bm->lpool, l); + CustomData_bmesh_free_block(&bm->ldata, &l->data); + BLI_mempool_free(bm->lpool, l); } /** * BMESH CYCLES diff --git a/source/blender/blenkernel/intern/BME_tools.c b/source/blender/blenkernel/intern/BME_tools.c index 7ce967d1d22..90259031e5c 100644 --- a/source/blender/blenkernel/intern/BME_tools.c +++ b/source/blender/blenkernel/intern/BME_tools.c @@ -205,7 +205,53 @@ static BME_Poly *BME_split_face(BME_Mesh *bm, BME_Poly *f, BME_Vert *v1, BME_Ver return nf; } -/* a wrapper for BME_SEMV that transfers element flags */ + +static void BME_data_interp_from_verts(BME_Mesh *bm, BME_Vert *v1, BME_Vert *v2, BME_Vert *v, float fac) +{ + void *src[2]; + float w[2]; + if (v1->data && v2->data) { + src[0]= v1->data; + src[1]= v2->data; + w[0] = 1.0f-fac; + w[1] = fac; + CustomData_bmesh_interp(&bm->vdata, src, w, NULL, 2, v->data); + } +} + + +static void BME_data_facevert_edgesplit(BME_Mesh *bm, BME_Vert *v1, BME_Vert *v2, BME_Vert *v, BME_Edge *e1, float fac){ + void *src[2]; + float w[2]; + BME_Loop *l=NULL, *v1loop = NULL, *vloop = NULL, *v2loop = NULL; + + w[0] = 1.0f - fac; + w[1] = fac; + + if(!e1->loop) return; + l = e1->loop; + do{ + if(l->v == v1){ + v1loop = l; + vloop = v1loop->next; + v2loop = vloop->next; + }else if(l->v == v){ + v1loop = l->next; + vloop = l; + v2loop = l->prev; + + } + + src[0] = v1loop->data; + src[1] = v2loop->data; + + CustomData_bmesh_interp(&bm->ldata, src,w, NULL, 2, vloop->data); + l = l->radial.next->data; + }while(l!=e1->loop); +} + + +/* a wrapper for BME_SEMV that transfers element flags */ /*add custom data interpolation in here!*/ static BME_Vert *BME_split_edge(BME_Mesh *bm, BME_Vert *v, BME_Edge *e, BME_Edge **ne, float percent) { BME_Vert *nv, *v2; float len; @@ -224,10 +270,39 @@ static BME_Vert *BME_split_edge(BME_Mesh *bm, BME_Vert *v, BME_Edge *e, BME_Edge (*ne)->crease = e->crease; (*ne)->bweight = e->bweight; } - + /*v->nv->v2*/ + BME_data_facevert_edgesplit(bm,v2, v, nv, e, 0.75); return nv; } +static void BME_collapse_vert(BME_Mesh *bm, BME_Edge *ke, BME_Vert *kv, float fac){ + void *src[2]; + float w[2]; + BME_Loop *l=NULL, *kvloop=NULL, *tvloop=NULL; + BME_Vert *tv = BME_edge_getothervert(ke,kv); + + w[0] = 1.0f - fac; + w[1] = fac; + + if(ke->loop){ + l = ke->loop; + do{ + if(l->v == tv && l->next->v == kv){ + tvloop = l; + kvloop = l->next; + + src[0] = kvloop->data; + src[1] = tvloop->data; + CustomData_bmesh_interp(&bm->ldata, src,w, NULL, 2, kvloop->data); + } + l=l->radial.next->data; + }while(l!=ke->loop); + } + BME_JEKV(bm,ke,kv); +} + + + static int BME_bevel_is_split_vert(BME_Loop *l) { /* look for verts that have already been added to the edge when * beveling other polys; this can be determined by testing the @@ -315,7 +390,7 @@ static float BME_bevel_project_vec(float *vec1, float *vec2, float *up_vec, int * Finally, return the split vert. */ static BME_Vert *BME_bevel_split_edge(BME_Mesh *bm, BME_Vert *v, BME_Vert *v1, BME_Loop *l, float *up_vec, float value, BME_TransData_Head *td) { BME_TransData *vtd, *vtd1, *vtd2; - BME_Vert *sv, *v2, *v3; + BME_Vert *sv, *v2, *v3, *ov; BME_Loop *lv1, *lv2; BME_Edge *ne, *e1, *e2; float maxfactor, scale, len, dis, vec1[3], vec2[3], t_up_vec[3]; @@ -349,7 +424,11 @@ static BME_Vert *BME_bevel_split_edge(BME_Mesh *bm, BME_Vert *v, BME_Vert *v1, B else { e1 = e2; } + ov = BME_edge_getothervert(e1,v); sv = BME_split_edge(bm,v,e1,&ne,0); + //BME_data_interp_from_verts(bm, v, ov, sv, 0.25); /*this is technically wrong...*/ + //BME_data_interp_from_faceverts(bm, v, ov, sv, 0.25); + //BME_data_interp_from_faceverts(bm, ov, v, sv, 0.25); BME_assign_transdata(td, bm, sv, sv->co, sv->co, NULL, sv->co, 0, -1, -1, NULL); /* quick default */ sv->tflag1 |= BME_BEVEL_BEVEL; ne->tflag1 = BME_BEVEL_ORIG; /* mark edge as original, even though it isn't */ @@ -388,7 +467,11 @@ static BME_Vert *BME_bevel_split_edge(BME_Mesh *bm, BME_Vert *v, BME_Vert *v1, B } else { is_split_vert = 0; + ov = BME_edge_getothervert(l->e,v); sv = BME_split_edge(bm,v,l->e,&ne,0); + //BME_data_interp_from_verts(bm, v, ov, sv, 0.25); /*this is technically wrong...*/ + //BME_data_interp_from_faceverts(bm, v, ov, sv, 0.25); + //BME_data_interp_from_faceverts(bm, ov, v, sv, 0.25); BME_assign_transdata(td, bm, sv, sv->co, sv->co, NULL, sv->co, 0, -1, -1, NULL); /* quick default */ sv->tflag1 |= BME_BEVEL_BEVEL; ne->tflag1 = BME_BEVEL_ORIG; /* mark edge as original, even though it isn't */ @@ -567,12 +650,15 @@ static BME_Loop *BME_bevel_edge(BME_Mesh *bm, BME_Loop *l, float value, int opti if (kl->v == kv) { BME_split_face(bm,kl->f,kl->prev->v,kl->next->v,&nl,kl->prev->e); BME_JFKE(bm,((BME_Loop*)kl->prev->radial.next->data)->f,kl->f,kl->prev->e); - BME_JEKV(bm,kl->e,kv); + BME_collapse_vert(bm, kl->e, kv, 1.0); + //BME_JEKV(bm,kl->e,kv); + } else { BME_split_face(bm,kl->f,kl->next->next->v,kl->v,&nl,kl->next->e); BME_JFKE(bm,((BME_Loop*)kl->next->radial.next->data)->f,kl->f,kl->next->e); - BME_JEKV(bm,kl->e,kv); + BME_collapse_vert(bm, kl->e, kv, 1.0); + //BME_JEKV(bm,kl->e,kv); } l = l->prev; } @@ -601,12 +687,14 @@ static BME_Loop *BME_bevel_edge(BME_Mesh *bm, BME_Loop *l, float value, int opti if (kl->v == kv) { BME_split_face(bm,kl->f,kl->prev->v,kl->next->v,&nl,kl->prev->e); BME_JFKE(bm,((BME_Loop*)kl->prev->radial.next->data)->f,kl->f,kl->prev->e); - BME_JEKV(bm,kl->e,kv); + BME_collapse_vert(bm, kl->e, kv, 1.0); + //BME_JEKV(bm,kl->e,kv); } else { BME_split_face(bm,kl->f,kl->next->next->v,kl->v,&nl,kl->next->e); BME_JFKE(bm,((BME_Loop*)kl->next->radial.next->data)->f,kl->f,kl->next->e); - BME_JEKV(bm,kl->e,kv); + BME_collapse_vert(bm, kl->e, kv, 1.0); + //BME_JEKV(bm,kl->e,kv); } } @@ -1073,7 +1161,8 @@ static void bmesh_dissolve_disk(BME_Mesh *bm, BME_Vert *v){ e = BME_disk_nextedge(e,v); }while(e != v->edge); } - BME_JEKV(bm,v->edge,v); + BME_collapse_vert(bm, v->edge, v, 1.0); + //BME_JEKV(bm,v->edge,v); } } static BME_Mesh *BME_bevel_mesh(BME_Mesh *bm, float value, int res, int options, int defgrp_index, BME_TransData_Head *td) { diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 30405660658..4d3f9143b85 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -1052,7 +1052,7 @@ void emDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r) /* store vertex indices in tmp union */ for(ev = em->verts.first, i = 0; ev; ev = ev->next, ++i) - ev->tmp.l = (long) i++; + ev->tmp.l = (long) i; for( ; ee; ee = ee->next, ++edge_r) { edge_r->crease = (unsigned char) (ee->crease*255.0f); diff --git a/source/blender/blenkernel/intern/bmesh_private.h b/source/blender/blenkernel/intern/bmesh_private.h index 4aa2a85b8b1..f34ef0090f3 100644 --- a/source/blender/blenkernel/intern/bmesh_private.h +++ b/source/blender/blenkernel/intern/bmesh_private.h @@ -39,11 +39,6 @@ #include "BKE_bmesh.h" -struct BME_mempool *BME_mempool_create(int esize, int tote, int pchunk); -void BME_mempool_destroy(struct BME_mempool *pool); -void *BME_mempool_alloc(struct BME_mempool *pool); -void BME_mempool_free(struct BME_mempool *pool, void *address); - /*ALLOCATION/DEALLOCATION*/ struct BME_Vert *BME_addvertlist(struct BME_Mesh *bm, struct BME_Vert *example); struct BME_Edge *BME_addedgelist(struct BME_Mesh *bm, struct BME_Vert *v1, struct BME_Vert *v2, struct BME_Edge *example); @@ -54,7 +49,6 @@ void BME_free_vert(struct BME_Mesh *bm, struct BME_Vert *v); void BME_free_edge(struct BME_Mesh *bm, struct BME_Edge *e); void BME_free_poly(struct BME_Mesh *bm, struct BME_Poly *f); void BME_free_loop(struct BME_Mesh *bm, struct BME_Loop *l); -//void BME_delete_loop(struct BME_Mesh *bm, struct BME_Loop *l); /*DOUBLE CIRCULAR LINKED LIST FUNCTIONS*/ void BME_cycle_append(void *h, void *nt); diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 6034b85e20f..c7817b017ef 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -132,7 +132,7 @@ void cloth_init ( ClothModifierData *clmd ) clmd->coll_parms->self_friction = 5.0; clmd->coll_parms->friction = 5.0; - clmd->coll_parms->loop_count = 3; + clmd->coll_parms->loop_count = 2; clmd->coll_parms->epsilon = 0.015f; clmd->coll_parms->flags = CLOTH_COLLSETTINGS_FLAG_ENABLED; clmd->coll_parms->collision_list = NULL; @@ -471,7 +471,7 @@ static int do_step_cloth(Object *ob, ClothModifierData *clmd, DerivedMesh *resul tend(); - /* printf ( "Cloth simulation time: %f\n", ( float ) tval() ); */ + // printf ( "%f\n", ( float ) tval() ); return ret; } diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index 7f41ca033d3..26c5d186d87 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -541,7 +541,7 @@ int cloth_collision_response_static ( ClothModifierData *clmd, CollisionModifier { Normalize ( vrel_t_pre ); - impulse = 2.0 * magtangent / ( 1.0 + w1*w1 + w2*w2 + w3*w3 ); + impulse = magtangent / ( 1.0 + w1*w1 + w2*w2 + w3*w3 ); // 2.0 * VECADDMUL ( cloth1->verts[collpair->ap1].impulse, vrel_t_pre, w1 * impulse ); VECADDMUL ( cloth1->verts[collpair->ap2].impulse, vrel_t_pre, w2 * impulse ); VECADDMUL ( cloth1->verts[collpair->ap3].impulse, vrel_t_pre, w3 * impulse ); @@ -1291,52 +1291,223 @@ int cloth_collision_moving ( ClothModifierData *clmd, CollisionModifierData *col return 1; } -int cloth_bvh_objcollisions_do ( ClothModifierData * clmd, CollisionModifierData *collmd, float step, float dt ) -{ +int cloth_do_selfcollisions(ClothModifierData * clmd) +{ + int ret2 = 0, l; Cloth *cloth = clmd->clothObject; - BVHTree *cloth_bvh= ( BVHTree * ) cloth->bvhtree; - long i=0, j = 0, numfaces = 0, numverts = 0; - ClothVertex *verts = NULL; - CollPair *collisions = NULL, *collisions_index = NULL; - int ret = 0; - int result = 0; - float tnull[3] = {0,0,0}; - BVHTreeOverlap *overlap = NULL; - - - numfaces = clmd->clothObject->numfaces; - numverts = clmd->clothObject->numverts; - - verts = cloth->verts; + + if ( clmd->clothObject->bvhselftree ) + { + for(l = 0; l < clmd->coll_parms->self_loop_count; l++) + { + BVHTreeOverlap *overlap = NULL; + ClothVertex *verts = clmd->clothObject->verts; // needed for openMP + int k; + int ret = 0, result = 0; + + // search for overlapping collision pairs + overlap = BLI_bvhtree_overlap ( cloth->bvhselftree, cloth->bvhselftree, &result ); + +// #pragma omp parallel for private(k, i, j) schedule(static) + for ( k = 0; k < result; k++ ) + { + float temp[3]; + float length = 0; + float mindistance; + int i, j; + + i = overlap[k].indexA; + j = overlap[k].indexB; + + mindistance = clmd->coll_parms->selfepsilon* ( cloth->verts[i].avg_spring_len + cloth->verts[j].avg_spring_len ); + + if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) + { + if ( ( cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED ) + && ( cloth->verts [j].flags & CLOTH_VERT_FLAG_PINNED ) ) + { + continue; + } + } + + VECSUB ( temp, verts[i].tx, verts[j].tx ); + + if ( ( ABS ( temp[0] ) > mindistance ) || ( ABS ( temp[1] ) > mindistance ) || ( ABS ( temp[2] ) > mindistance ) ) continue; + + // check for adjacent points (i must be smaller j) + if ( BLI_edgehash_haskey ( cloth->edgehash, MIN2(i, j), MAX2(i, j) ) ) + { + continue; + } + + length = Normalize ( temp ); + + if ( length < mindistance ) + { + float correction = mindistance - length; + + if ( cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED ) + { + VecMulf ( temp, -correction ); + VECADD ( verts[j].tx, verts[j].tx, temp ); + } + else if ( cloth->verts [j].flags & CLOTH_VERT_FLAG_PINNED ) + { + VecMulf ( temp, correction ); + VECADD ( verts[i].tx, verts[i].tx, temp ); + } + else + { + VecMulf ( temp, -correction*0.5 ); + VECADD ( verts[j].tx, verts[j].tx, temp ); + + VECSUB ( verts[i].tx, verts[i].tx, temp ); + } + ret = 1; + ret2 += ret; + } + else + { + // check for approximated time collisions + } + } + + if ( overlap ) + MEM_freeN ( overlap ); + + if(!ret) + break; + + } + //////////////////////////////////////////////////////////// + + //////////////////////////////////////////////////////////// + // SELFCOLLISIONS: update velocities + //////////////////////////////////////////////////////////// + if ( ret2 ) + { + int i; + ClothVertex *verts = clmd->clothObject->verts; // needed for openMP + + for ( i = 0; i < cloth->numverts; i++ ) + { + if ( ! ( verts [i].flags & CLOTH_VERT_FLAG_PINNED ) ) + { + VECSUB ( verts[i].tv, verts[i].tx, verts[i].txold ); + } + } + } + //////////////////////////////////////////////////////////// + } + return ret2; +} - if ( collmd->bvhtree ) +// return all collision objects in scene +// collision object will exclude self +CollisionModifierData **get_collisionobjects(Object *self, int *numcollobj) +{ + Base *base=NULL; + CollisionModifierData **objs = NULL; + Object *coll_ob = NULL; + CollisionModifierData *collmd = NULL; + int numobj = 0, maxobj = 100; + + objs = MEM_callocN(sizeof(CollisionModifierData *)*maxobj, "CollisionObjectsArray"); + // check all collision objects + for ( base = G.scene->base.first; base; base = base->next ) { - /* get pointer to bounding volume hierarchy */ - BVHTree *coll_bvh = collmd->bvhtree; + coll_ob = base->object; + collmd = ( CollisionModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Collision ); + + if ( !collmd ) + { + if ( coll_ob->dup_group ) + { + GroupObject *go; + Group *group = coll_ob->dup_group; - /* move object to position (step) in time */ - collision_move_object ( collmd, step + dt, step ); + for ( go= group->gobject.first; go; go= go->next ) + { + coll_ob = go->ob; - /* search for overlapping collision pairs */ - overlap = BLI_bvhtree_overlap ( cloth_bvh, coll_bvh, &result ); + collmd = ( CollisionModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Collision ); - collisions = ( CollPair* ) MEM_mallocN ( sizeof ( CollPair ) * result*4, "collision array" ); //*4 since cloth_collision_static can return more than 1 collision - collisions_index = collisions; + if ( !collmd ) + continue; - for ( i = 0; i < result; i++ ) - { - collisions_index = cloth_collision ( ( ModifierData * ) clmd, ( ModifierData * ) collmd, overlap+i, collisions_index ); - } + if(coll_ob == self) + continue; - if ( overlap ) - MEM_freeN ( overlap ); + if(numobj >= maxobj) + { + // realloc + int oldmax = maxobj; + CollisionModifierData **tmp; + maxobj *= 2; + tmp = MEM_callocN(sizeof(CollisionModifierData *)*maxobj, "CollisionObjectsArray"); + memcpy(tmp, objs, sizeof(CollisionModifierData *)*oldmax); + MEM_freeN(objs); + objs = tmp; + } + + objs[numobj] = collmd; + numobj++; + } + } + } + else + { + if(coll_ob == self) + continue; + + if(numobj >= maxobj) + { + // realloc + int oldmax = maxobj; + CollisionModifierData **tmp; + maxobj *= 2; + tmp = MEM_callocN(sizeof(CollisionModifierData *)*maxobj, "CollisionObjectsArray"); + memcpy(tmp, objs, sizeof(CollisionModifierData *)*oldmax); + MEM_freeN(objs); + objs = tmp; + + } + + objs[numobj] = collmd; + numobj++; + } } - else + *numcollobj = numobj; + return objs; +} + +void cloth_bvh_objcollisions_nearcheck ( ClothModifierData * clmd, CollisionModifierData *collmd, CollPair **collisions, CollPair **collisions_index, int numresult, BVHTreeOverlap *overlap) +{ + int i; + + *collisions = ( CollPair* ) MEM_mallocN ( sizeof ( CollPair ) * numresult * 4, "collision array" ); //*4 since cloth_collision_static can return more than 1 collision + *collisions_index = *collisions; + + for ( i = 0; i < numresult; i++ ) { - if ( G.rt > 0 ) - printf ( "cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n" ); + *collisions_index = cloth_collision ( ( ModifierData * ) clmd, ( ModifierData * ) collmd, overlap+i, *collisions_index ); } +} +int cloth_bvh_objcollisions_resolve ( ClothModifierData * clmd, CollisionModifierData *collmd, CollPair *collisions, CollPair *collisions_index) +{ + Cloth *cloth = clmd->clothObject; + int i=0, j = 0, numfaces = 0, numverts = 0; + ClothVertex *verts = NULL; + int ret = 0; + int result = 0; + float tnull[3] = {0,0,0}; + + numfaces = clmd->clothObject->numfaces; + numverts = clmd->clothObject->numverts; + + verts = cloth->verts; + // process all collisions (calculate impulses, TODO: also repulses if distance too short) result = 1; for ( j = 0; j < 5; j++ ) // 5 is just a value that ensures convergence @@ -1363,48 +1534,22 @@ int cloth_bvh_objcollisions_do ( ClothModifierData * clmd, CollisionModifierData } } } -/* - result += cloth_collision_moving ( clmd, collmd, collisions, collisions_index ); - - // apply impulses in parallel - if ( result ) - { - for ( i = 0; i < numverts; i++ ) - { - // calculate "velocities" (just xnew = xold + v; no dt in v) - if ( verts[i].impulse_count ) - { - VECADDMUL ( verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count ); - VECCOPY ( verts[i].impulse, tnull ); - verts[i].impulse_count = 0; - - ret++; - } - } - } -*/ } } - - if ( collisions ) MEM_freeN ( collisions ); - return ret; } // cloth - object collisions -int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt ) +int cloth_bvh_objcollision ( Object *ob, ClothModifierData * clmd, float step, float dt ) { - Base *base=NULL; - CollisionModifierData *collmd=NULL; Cloth *cloth=NULL; - Object *coll_ob=NULL; BVHTree *cloth_bvh=NULL; - long i=0, j = 0, k = 0, l = 0, numfaces = 0, numverts = 0; - int result = 0, rounds = 0; // result counts applied collisions; ic is for debug output; + long i=0, numfaces = 0, numverts = 0; + int rounds = 0; // result counts applied collisions; ic is for debug output; ClothVertex *verts = NULL; int ret = 0, ret2 = 0; - ClothModifierData *tclmd; - int collisions = 0; + CollisionModifierData **collobjs = NULL; + int numcollobj = 0; if ( ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ ) || ! ( ( ( Cloth * ) clmd->clothObject )->bvhtree ) ) { @@ -1424,54 +1569,61 @@ int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt ) // update cloth bvh bvhtree_update_from_cloth ( clmd, 1 ); // 0 means STATIC, 1 means MOVING (see later in this function) bvhselftree_update_from_cloth ( clmd, 0 ); // 0 means STATIC, 1 means MOVING (see later in this function) + + collobjs = get_collisionobjects(ob, &numcollobj); + + if(!collobjs) + return 0; do { - result = 0; + CollPair **collisions, **collisions_index; + ret2 = 0; + collisions = MEM_callocN(sizeof(CollPair *) *numcollobj , "CollPair"); + collisions_index = MEM_callocN(sizeof(CollPair *) *numcollobj , "CollPair"); + // check all collision objects - for ( base = G.scene->base.first; base; base = base->next ) + for(i = 0; i < numcollobj; i++) { - coll_ob = base->object; - collmd = ( CollisionModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Collision ); - - if ( !collmd ) - { - if ( coll_ob->dup_group ) - { - GroupObject *go; - Group *group = coll_ob->dup_group; - - for ( go= group->gobject.first; go; go= go->next ) - { - coll_ob = go->ob; - - collmd = ( CollisionModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Collision ); - - if ( !collmd ) - continue; - - tclmd = ( ClothModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Cloth ); - if ( tclmd == clmd ) - continue; - - ret += cloth_bvh_objcollisions_do ( clmd, collmd, step, dt ); - ret2 += ret; - } - } - } - else + CollisionModifierData *collmd = collobjs[i]; + BVHTreeOverlap *overlap = NULL; + int result = 0; + + /* move object to position (step) in time */ + collision_move_object ( collmd, step + dt, step ); + + /* search for overlapping collision pairs */ + overlap = BLI_bvhtree_overlap ( cloth_bvh, collmd->bvhtree, &result ); + + // go to next object if no overlap is there + if(!result || !overlap) { - tclmd = ( ClothModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Cloth ); - if ( tclmd == clmd ) - continue; - - ret += cloth_bvh_objcollisions_do ( clmd, collmd, step, dt ); - ret2 += ret; + if ( overlap ) + MEM_freeN ( overlap ); + continue; } + + /* check if collisions really happen (costly near check) */ + cloth_bvh_objcollisions_nearcheck ( clmd, collmd, &collisions[i], &collisions_index[i], result, overlap); + + // resolve nearby collisions + ret += cloth_bvh_objcollisions_resolve ( clmd, collmd, collisions[i], collisions_index[i]); + ret2 += ret; + + if ( overlap ) + MEM_freeN ( overlap ); } rounds++; + + for(i = 0; i < numcollobj; i++) + { + if ( collisions[i] ) MEM_freeN ( collisions[i] ); + } + + MEM_freeN(collisions); + MEM_freeN(collisions_index); //////////////////////////////////////////////////////////// // update positions @@ -1493,117 +1645,20 @@ int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt ) } //////////////////////////////////////////////////////////// - + //////////////////////////////////////////////////////////// // Test on *simple* selfcollisions //////////////////////////////////////////////////////////// if ( clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_SELF ) { - for(l = 0; l < clmd->coll_parms->self_loop_count; l++) - { - // TODO: add coll quality rounds again - BVHTreeOverlap *overlap = NULL; - - collisions = 1; - verts = cloth->verts; // needed for openMP - - numfaces = clmd->clothObject->numfaces; - numverts = clmd->clothObject->numverts; - - verts = cloth->verts; - - if ( cloth->bvhselftree ) - { - // search for overlapping collision pairs - overlap = BLI_bvhtree_overlap ( cloth->bvhselftree, cloth->bvhselftree, &result ); - - // #pragma omp parallel for private(k, i, j) schedule(static) - for ( k = 0; k < result; k++ ) - { - float temp[3]; - float length = 0; - float mindistance; - - i = overlap[k].indexA; - j = overlap[k].indexB; - - mindistance = clmd->coll_parms->selfepsilon* ( cloth->verts[i].avg_spring_len + cloth->verts[j].avg_spring_len ); - - if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) - { - if ( ( cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED ) - && ( cloth->verts [j].flags & CLOTH_VERT_FLAG_PINNED ) ) - { - continue; - } - } - - VECSUB ( temp, verts[i].tx, verts[j].tx ); - - if ( ( ABS ( temp[0] ) > mindistance ) || ( ABS ( temp[1] ) > mindistance ) || ( ABS ( temp[2] ) > mindistance ) ) continue; - - // check for adjacent points (i must be smaller j) - if ( BLI_edgehash_haskey ( cloth->edgehash, MIN2(i, j), MAX2(i, j) ) ) - { - continue; - } - - length = Normalize ( temp ); - - if ( length < mindistance ) - { - float correction = mindistance - length; - - if ( cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED ) - { - VecMulf ( temp, -correction ); - VECADD ( verts[j].tx, verts[j].tx, temp ); - } - else if ( cloth->verts [j].flags & CLOTH_VERT_FLAG_PINNED ) - { - VecMulf ( temp, correction ); - VECADD ( verts[i].tx, verts[i].tx, temp ); - } - else - { - VecMulf ( temp, -correction*0.5 ); - VECADD ( verts[j].tx, verts[j].tx, temp ); - - VECSUB ( verts[i].tx, verts[i].tx, temp ); - } - ret = 1; - ret2 += ret; - } - else - { - // check for approximated time collisions - } - } - - if ( overlap ) - MEM_freeN ( overlap ); - - } - } - //////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////// - // SELFCOLLISIONS: update velocities - //////////////////////////////////////////////////////////// - if ( ret2 ) - { - for ( i = 0; i < cloth->numverts; i++ ) - { - if ( ! ( verts [i].flags & CLOTH_VERT_FLAG_PINNED ) ) - { - VECSUB ( verts[i].tv, verts[i].tx, verts[i].txold ); - } - } - } - //////////////////////////////////////////////////////////// + ret2 += cloth_do_selfcollisions(clmd); } + //////////////////////////////////////////////////////////// } while ( ret2 && ( clmd->coll_parms->loop_count>rounds ) ); + + if(collobjs) + + MEM_freeN(collobjs); return MIN2 ( ret, 1 ); } diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index 77068d8ed66..501293ecd81 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -36,6 +36,7 @@ #include "BLI_blenlib.h" #include "BLI_linklist.h" +#include "BLI_mempool.h" #include "DNA_customdata_types.h" #include "DNA_listBase.h" @@ -359,8 +360,80 @@ static void layerDefault_origspace_face(void *data, int count) } /* --------- */ +static void layerDefault_mloopcol(void *data, int count) +{ + static MLoopCol default_mloopcol = {255,255,255,255}; + MLoopCol *mlcol = (MLoopCol*)data; + int i; + for(i = 0; i < count; i++) + mlcol[i] = default_mloopcol; + +} + +static void layerInterp_mloopcol(void **sources, float *weights, + float *sub_weights, int count, void *dest) +{ + MLoopCol *mc = dest; + int i; + float *sub_weight; + struct { + float a; + float r; + float g; + float b; + } col; + col.a = col.r = col.g = col.b = 0; + sub_weight = sub_weights; + for(i = 0; i < count; ++i){ + float weight = weights ? weights[i] : 1; + MLoopCol *src = sources[i]; + if(sub_weights){ + col.a += src->a * (*sub_weight) * weight; + col.r += src->r * (*sub_weight) * weight; + col.g += src->g * (*sub_weight) * weight; + col.b += src->b * (*sub_weight) * weight; + sub_weight++; + } else { + col.a += src->a * weight; + col.r += src->r * weight; + col.g += src->g * weight; + col.b += src->b * weight; + } + } + mc->a = (int)col.a; + mc->r = (int)col.r; + mc->g = (int)col.g; + mc->b = (int)col.b; +} +static void layerInterp_mloopuv(void **sources, float *weights, + float *sub_weights, int count, void *dest) +{ + MLoopUV *mluv = dest; + int i; + float *sub_weight; + struct { + float u; + float v; + }uv; + uv.u = uv.v = 0.0; + sub_weight = sub_weights; + for(i = 0; i < count; ++i){ + float weight = weights ? weights[i] : 1; + MLoopUV *src = sources[i]; + if(sub_weights){ + uv.u += src->uv[0] * (*sub_weight) * weight; + uv.v += src->uv[1] * (*sub_weight) * weight; + sub_weight++; + } else { + uv.u += src->uv[0] * weight; + uv.v += src->uv[1] * weight; + } + } + mluv->uv[0] = uv.u; + mluv->uv[1] = uv.v; +} static void layerInterp_mcol(void **sources, float *weights, float *sub_weights, int count, void *dest) @@ -432,6 +505,8 @@ static void layerDefault_mcol(void *data, int count) mcol[i] = default_mcol; } + + const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = { {sizeof(MVert), "MVert", 1, NULL, NULL, NULL, NULL, NULL, NULL}, {sizeof(MSticky), "MSticky", 1, NULL, NULL, NULL, layerInterp_msticky, NULL, @@ -454,13 +529,16 @@ const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = { {sizeof(MStringProperty), "MStringProperty",1,"String",NULL,NULL,NULL,NULL}, {sizeof(OrigSpaceFace), "OrigSpaceFace", 1, "UVTex", layerCopy_origspace_face, NULL, layerInterp_origspace_face, layerSwap_origspace_face, layerDefault_origspace_face}, - {sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL} + {sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL}, + {sizeof(MTexPoly), "MTexPoly", 1, "Face Texture", NULL, NULL, NULL, NULL, NULL}, + {sizeof(MLoopUV), "MLoopUV", 1, "UV coord", NULL, NULL, layerInterp_mloopuv, NULL, NULL}, + {sizeof(MLoopCol), "MLoopCol", 1, "Col", NULL, NULL, layerInterp_mloopcol, NULL, layerDefault_mloopcol} }; const char *LAYERTYPENAMES[CD_NUMTYPES] = { "CDMVert", "CDMSticky", "CDMDeformVert", "CDMEdge", "CDMFace", "CDMTFace", "CDMCol", "CDOrigIndex", "CDNormal", "CDFlags","CDMFloatProperty", - "CDMIntProperty","CDMStringProperty", "CDOrigSpace", "CDOrco"}; + "CDMIntProperty","CDMStringProperty", "CDOrigSpace", "CDOrco", "CDMTexPoly", "CDMLoopUV", "CDMloopCol"}; const CustomDataMask CD_MASK_BAREMESH = CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE; @@ -475,6 +553,12 @@ const CustomDataMask CD_MASK_DERIVEDMESH = CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_ORIGINDEX | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORCO; +const CustomDataMask CD_MASK_BMESH = + CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR; +const CustomDataMask CD_MASK_FACECORNERS = + CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_MTEXPOLY | CD_MASK_MLOOPUV | + CD_MASK_MLOOPCOL; + static const LayerTypeInfo *layerType_getInfo(int type) { @@ -1449,6 +1533,302 @@ void CustomData_from_em_block(const CustomData *source, CustomData *dest, } +/*Bmesh functions*/ +/*needed to convert to/from different face reps*/ +void CustomData_to_bmeshpoly(CustomData *fdata, CustomData *pdata, CustomData *ldata) +{ + int i; + for(i=0; i < fdata->totlayer; i++){ + if(fdata->layers[i].type == CD_MTFACE){ + CustomData_add_layer(pdata, CD_MTEXPOLY, CD_CALLOC, &(fdata->layers[i].name), 0); + CustomData_add_layer(ldata, CD_MLOOPUV, CD_CALLOC, &(fdata->layers[i].name), 0); + } + else if(fdata->layers[i].type == CD_MCOL) + CustomData_add_layer(ldata, CD_MLOOPCOL, CD_CALLOC, &(fdata->layers[i].name), 0); + } +} +void CustomData_from_bmeshpoly(CustomData *fdata, CustomData *pdata, CustomData *ldata, int total){ + int i; + for(i=0; i < pdata->totlayer; i++){ + if(pdata->layers[i].type == CD_MTEXPOLY) + CustomData_add_layer(fdata, CD_MTFACE, CD_CALLOC, &(pdata->layers[i].name), total); + } + for(i=0; i < ldata->totlayer; i++){ + if(ldata->layers[i].type == CD_MLOOPCOL) + CustomData_add_layer(fdata, CD_MCOL, CD_CALLOC, &(ldata->layers[i].name), total); + } +} + + +void CustomData_bmesh_init_pool(CustomData *data, int allocsize){ + if(data->totlayer)data->pool = BLI_mempool_create(data->totsize, allocsize, allocsize); +} + +void CustomData_bmesh_free_block(CustomData *data, void **block) +{ + const LayerTypeInfo *typeInfo; + int i; + + if(!*block) return; + for(i = 0; i < data->totlayer; ++i) { + if(!(data->layers[i].flag & CD_FLAG_NOFREE)) { + typeInfo = layerType_getInfo(data->layers[i].type); + + if(typeInfo->free) { + int offset = data->layers[i].offset; + typeInfo->free((char*)*block + offset, 1, typeInfo->size); + } + } + } + + BLI_mempool_free(data->pool, *block); + *block = NULL; +} + +static void CustomData_bmesh_alloc_block(CustomData *data, void **block) +{ + + if (*block) + CustomData_bmesh_free_block(data, block); + + if (data->totsize > 0) + *block = BLI_mempool_calloc(data->pool); + else + *block = NULL; +} + +void CustomData_bmesh_copy_data(const CustomData *source, CustomData *dest, + void *src_block, void **dest_block) +{ + const LayerTypeInfo *typeInfo; + int dest_i, src_i; + + if (!*dest_block) + CustomData_bmesh_alloc_block(dest, dest_block); + + /* copies a layer at a time */ + dest_i = 0; + for(src_i = 0; src_i < source->totlayer; ++src_i) { + + /* find the first dest layer with type >= the source type + * (this should work because layers are ordered by type) + */ + while(dest_i < dest->totlayer + && dest->layers[dest_i].type < source->layers[src_i].type) + ++dest_i; + + /* if there are no more dest layers, we're done */ + if(dest_i >= dest->totlayer) return; + + /* if we found a matching layer, copy the data */ + if(dest->layers[dest_i].type == source->layers[src_i].type && + strcmp(dest->layers[dest_i].name, source->layers[src_i].name) == 0) { + char *src_data = (char*)src_block + source->layers[src_i].offset; + char *dest_data = (char*)*dest_block + dest->layers[dest_i].offset; + + typeInfo = layerType_getInfo(source->layers[src_i].type); + + if(typeInfo->copy) + typeInfo->copy(src_data, dest_data, 1); + else + memcpy(dest_data, src_data, typeInfo->size); + + /* if there are multiple source & dest layers of the same type, + * we don't want to copy all source layers to the same dest, so + * increment dest_i + */ + ++dest_i; + } + } +} + +/*Bmesh Custom Data Functions. Should replace editmesh ones with these as well, due to more effecient memory alloc*/ +void *CustomData_bmesh_get(const CustomData *data, void *block, int type) +{ + int layer_index; + + /* get the layer index of the first layer of type */ + layer_index = CustomData_get_active_layer_index(data, type); + if(layer_index < 0) return NULL; + + return (char *)block + data->layers[layer_index].offset; +} + +void *CustomData_bmesh_get_n(const CustomData *data, void *block, int type, int n) +{ + int layer_index; + + /* get the layer index of the first layer of type */ + layer_index = CustomData_get_layer_index(data, type); + if(layer_index < 0) return NULL; + + return (char *)block + data->layers[layer_index+n].offset; +} + +void CustomData_bmesh_set(const CustomData *data, void *block, int type, void *source) +{ + void *dest = CustomData_bmesh_get(data, block, type); + const LayerTypeInfo *typeInfo = layerType_getInfo(type); + + if(!dest) return; + + if(typeInfo->copy) + typeInfo->copy(source, dest, 1); + else + memcpy(dest, source, typeInfo->size); +} + +void CustomData_bmesh_set_n(CustomData *data, void *block, int type, int n, void *source) +{ + void *dest = CustomData_bmesh_get_n(data, block, type, n); + const LayerTypeInfo *typeInfo = layerType_getInfo(type); + + if(!dest) return; + + if(typeInfo->copy) + typeInfo->copy(source, dest, 1); + else + memcpy(dest, source, typeInfo->size); +} + +void CustomData_bmesh_interp(CustomData *data, void **src_blocks, float *weights, + float *sub_weights, int count, void *dest_block) +{ + int i, j; + void *source_buf[SOURCE_BUF_SIZE]; + void **sources = source_buf; + + /* slow fallback in case we're interpolating a ridiculous number of + * elements + */ + if(count > SOURCE_BUF_SIZE) + sources = MEM_callocN(sizeof(*sources) * count, + "CustomData_interp sources"); + + /* interpolates a layer at a time */ + for(i = 0; i < data->totlayer; ++i) { + CustomDataLayer *layer = &data->layers[i]; + const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type); + if(typeInfo->interp) { + for(j = 0; j < count; ++j) + sources[j] = (char *)src_blocks[j] + layer->offset; + + typeInfo->interp(sources, weights, sub_weights, count, + (char *)dest_block + layer->offset); + } + } + + if(count > SOURCE_BUF_SIZE) MEM_freeN(sources); +} + +void CustomData_bmesh_set_default(CustomData *data, void **block) +{ + const LayerTypeInfo *typeInfo; + int i; + + if (!*block) + CustomData_bmesh_alloc_block(data, block); + + for(i = 0; i < data->totlayer; ++i) { + int offset = data->layers[i].offset; + + typeInfo = layerType_getInfo(data->layers[i].type); + + if(typeInfo->set_default) + typeInfo->set_default((char*)*block + offset, 1); + } +} + +void CustomData_to_bmesh_block(const CustomData *source, CustomData *dest, + int src_index, void **dest_block) +{ + const LayerTypeInfo *typeInfo; + int dest_i, src_i, src_offset; + + if (!*dest_block) + CustomData_bmesh_alloc_block(dest, dest_block); + + /* copies a layer at a time */ + dest_i = 0; + for(src_i = 0; src_i < source->totlayer; ++src_i) { + + /* find the first dest layer with type >= the source type + * (this should work because layers are ordered by type) + */ + while(dest_i < dest->totlayer + && dest->layers[dest_i].type < source->layers[src_i].type) + ++dest_i; + + /* if there are no more dest layers, we're done */ + if(dest_i >= dest->totlayer) return; + + /* if we found a matching layer, copy the data */ + if(dest->layers[dest_i].type == source->layers[src_i].type) { + int offset = dest->layers[dest_i].offset; + char *src_data = source->layers[src_i].data; + char *dest_data = (char*)*dest_block + offset; + + typeInfo = layerType_getInfo(dest->layers[dest_i].type); + src_offset = src_index * typeInfo->size; + + if(typeInfo->copy) + typeInfo->copy(src_data + src_offset, dest_data, 1); + else + memcpy(dest_data, src_data + src_offset, typeInfo->size); + + /* if there are multiple source & dest layers of the same type, + * we don't want to copy all source layers to the same dest, so + * increment dest_i + */ + ++dest_i; + } + } +} + +void CustomData_from_bmesh_block(const CustomData *source, CustomData *dest, + void *src_block, int dest_index) +{ + const LayerTypeInfo *typeInfo; + int dest_i, src_i, dest_offset; + + /* copies a layer at a time */ + dest_i = 0; + for(src_i = 0; src_i < source->totlayer; ++src_i) { + + /* find the first dest layer with type >= the source type + * (this should work because layers are ordered by type) + */ + while(dest_i < dest->totlayer + && dest->layers[dest_i].type < source->layers[src_i].type) + ++dest_i; + + /* if there are no more dest layers, we're done */ + if(dest_i >= dest->totlayer) return; + + /* if we found a matching layer, copy the data */ + if(dest->layers[dest_i].type == source->layers[src_i].type) { + int offset = source->layers[src_i].offset; + char *src_data = (char*)src_block + offset; + char *dest_data = dest->layers[dest_i].data; + + typeInfo = layerType_getInfo(dest->layers[dest_i].type); + dest_offset = dest_index * typeInfo->size; + + if(typeInfo->copy) + typeInfo->copy(src_data, dest_data + dest_offset, 1); + else + memcpy(dest_data + dest_offset, src_data, typeInfo->size); + + /* if there are multiple source & dest layers of the same type, + * we don't want to copy all source layers to the same dest, so + * increment dest_i + */ + ++dest_i; + } + } + +} + void CustomData_file_write_info(int type, char **structname, int *structnum) { const LayerTypeInfo *typeInfo = layerType_getInfo(type); diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index c73279746fb..b6c8ad59e08 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -848,10 +848,6 @@ void BKE_add_image_extension(char *string, int imtype) if(!BLI_testextensie(string, ".tga")) extension= ".tga"; } - else if(ELEM5(imtype, R_MOVIE, R_AVICODEC, R_AVIRAW, R_AVIJPEG, R_JPEG90)) { - if(!( BLI_testextensie(string, ".jpg") || BLI_testextensie(string, ".jpeg"))) - extension= ".jpg"; - } else if(imtype==R_BMP) { if(!BLI_testextensie(string, ".bmp")) extension= ".bmp"; @@ -874,10 +870,14 @@ void BKE_add_image_extension(char *string, int imtype) if (!BLI_testextensie(string, ".dpx")) extension= ".dpx"; } - else { /* targa default */ + else if(imtype==R_TARGA) { if(!BLI_testextensie(string, ".tga")) extension= ".tga"; } + else { // R_MOVIE, R_AVICODEC, R_AVIRAW, R_AVIJPEG, R_JPEG90, R_QUICKTIME etc + if(!( BLI_testextensie(string, ".jpg") || BLI_testextensie(string, ".jpeg"))) + extension= ".jpg"; + } strcat(string, extension); } @@ -1512,6 +1512,10 @@ static ImBuf *image_load_sequence_file(Image *ima, ImageUser *iuser, int frame) image_initialize_after_load(ima, ibuf); image_assign_ibuf(ima, ibuf, 0, frame); #endif + + if(ima->flag & IMA_DO_PREMUL) + converttopremul(ibuf); + } else ima->ok= 0; diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index 808984aaa3c..297ac0b1530 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -1588,10 +1588,17 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase VECSUB(verts[i].tv, verts[i].tx, verts[i].txold); VECCOPY(verts[i].v, verts[i].tv); } - + // call collision function - result = cloth_bvh_objcollision(clmd, step + dt, dt); - + // TODO: check if "step" or "step+dt" is correct - dg + result = cloth_bvh_objcollision(ob, clmd, step, dt); + + // correct velocity again, just to be sure we had to change it due to adaptive collisions + for(i = 0; i < numverts; i++) + { + VECSUB(verts[i].tv, verts[i].tx, id->X[i]); + } + // copy corrected positions back to simulation for(i = 0; i < numverts; i++) { diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 7c50b409693..c3dddf06e7c 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -224,48 +224,50 @@ void flag_all_listbases_ids(short flag, short value) /* note: MAX_LIBARRAY define should match this code */ int set_listbasepointers(Main *main, ListBase **lb) { + int a = 0; + /* BACKWARDS! also watch order of free-ing! (mesh<->mat) */ - lb[0]= &(main->ipo); - lb[1]= &(main->key); - lb[2]= &(main->image); - lb[3]= &(main->tex); - lb[4]= &(main->mat); - lb[5]= &(main->vfont); + lb[a++]= &(main->ipo); + lb[a++]= &(main->key); + lb[a++]= &(main->nodetree); + lb[a++]= &(main->image); + lb[a++]= &(main->tex); + lb[a++]= &(main->mat); + lb[a++]= &(main->vfont); /* Important!: When adding a new object type, * the specific data should be inserted here */ - lb[6]= &(main->armature); - lb[7]= &(main->action); + lb[a++]= &(main->armature); + lb[a++]= &(main->action); - lb[8]= &(main->mesh); - lb[9]= &(main->curve); - lb[10]= &(main->mball); + lb[a++]= &(main->mesh); + lb[a++]= &(main->curve); + lb[a++]= &(main->mball); - lb[11]= &(main->wave); - lb[12]= &(main->latt); - lb[13]= &(main->lamp); - lb[14]= &(main->camera); + lb[a++]= &(main->wave); + lb[a++]= &(main->latt); + lb[a++]= &(main->lamp); + lb[a++]= &(main->camera); - lb[15]= &(main->text); - lb[16]= &(main->sound); - lb[17]= &(main->group); - lb[18]= &(main->nodetree); - lb[19]= &(main->brush); - lb[20]= &(main->script); - lb[21]= &(main->particle); + lb[a++]= &(main->text); + lb[a++]= &(main->sound); + lb[a++]= &(main->group); + lb[a++]= &(main->brush); + lb[a++]= &(main->script); + lb[a++]= &(main->particle); - lb[22]= &(main->world); - lb[23]= &(main->screen); - lb[24]= &(main->object); - lb[25]= &(main->scene); - lb[26]= &(main->library); + lb[a++]= &(main->world); + lb[a++]= &(main->screen); + lb[a++]= &(main->object); + lb[a++]= &(main->scene); + lb[a++]= &(main->library); - lb[27]= NULL; + lb[a]= NULL; - return 27; + return a; } /* *********** ALLOC AND FREE ***************** diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 6779b18154f..124474ca09c 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -4923,7 +4923,7 @@ static void waveModifier_deformVertsEM( if(!wmd->texture && !wmd->defgrp_name[0] && !(wmd->flag & MOD_WAVE_NORM)) dm = derivedData; - else if(derivedData) dm = derivedData; + else if(derivedData) dm = CDDM_copy(derivedData); else dm = CDDM_from_editmesh(editData, ob->data); if(wmd->flag & MOD_WAVE_NORM) { diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index b72d9a0b044..7b36e46d45e 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -732,6 +732,17 @@ void *add_lamp(char *name) la->preview=NULL; la->falloff_type = LA_FALLOFF_INVLINEAR; la->curfalloff = curvemapping_add(1, 0.0f, 1.0f, 1.0f, 0.0f); + la->sun_effect_type = 0; + la->horizon_brightness = 1.0; + la->spread = 1.0; + la->sun_brightness = 1.0; + la->sun_size = 1.0; + la->backscattered_light = 1.0; + la->atm_turbidity = 2.0; + la->atm_inscattering_factor = 1.0; + la->atm_extinction_factor = 1.0; + la->atm_distance_factor = 1.0; + la->sun_intensity = 1.0; curvemapping_initialize(la->curfalloff); return la; } diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 18fca5439ef..24a3d348ae7 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -1371,7 +1371,7 @@ void psys_particle_on_shape(int distr, int index, float *fuv, float *vec, float /************************************************/ void psys_particle_on_emitter(Object *ob, ParticleSystemModifierData *psmd, int from, int index, int index_dmcache, float *fuv, float foffset, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor){ if(psmd){ - if(psmd->psys->part->distr==PART_DISTR_GRID){ + if(psmd->psys->part->distr==PART_DISTR_GRID && psmd->psys->part->from != PART_FROM_VERT){ if(vec){ VECCOPY(vec,fuv); } diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 458171cc232..f70648965f4 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -168,7 +168,7 @@ static void realloc_particles(Object *ob, ParticleSystem *psys, int new_totpart) int i, totpart, totsaved = 0; if(new_totpart<0) { - if(psys->part->distr==PART_DISTR_GRID) { + if(psys->part->distr==PART_DISTR_GRID && psys->part->from != PART_FROM_VERT) { totpart= psys->part->grid_res; totpart*=totpart*totpart; } @@ -1056,7 +1056,7 @@ int psys_threads_init_distribution(ParticleThread *threads, DerivedMesh *finaldm dm= CDDM_from_mesh((Mesh*)ob->data, ob); /* special handling of grid distribution */ - if(part->distr==PART_DISTR_GRID){ + if(part->distr==PART_DISTR_GRID && from != PART_FROM_VERT){ distribute_particles_in_grid(dm,psys); dm->release(dm); return 0; @@ -1600,7 +1600,7 @@ void initialize_particle(ParticleData *pa, int p, Object *ob, ParticleSystem *ps NormalQuat(pa->r_rot); - if(part->distr!=PART_DISTR_GRID){ + if(part->distr!=PART_DISTR_GRID && part->from != PART_FROM_VERT){ /* any unique random number will do (r_ave[0]) */ if(ptex.exist < 0.5*(1.0+pa->r_ave[0])) pa->flag |= PARS_UNEXIST; @@ -4515,7 +4515,7 @@ void psys_changed_type(ParticleSystem *psys) if(part->from == PART_FROM_PARTICLE) { if(part->type != PART_REACTOR) part->from = PART_FROM_FACE; - if(part->distr == PART_DISTR_GRID) + if(part->distr == PART_DISTR_GRID && part->from != PART_FROM_VERT) part->distr = PART_DISTR_JIT; } @@ -4710,7 +4710,7 @@ static void system_step(Object *ob, ParticleSystem *psys, ParticleSystemModifier oldtotpart = psys->totpart; oldtotchild = psys->totchild; - if(part->distr == PART_DISTR_GRID) + if(part->distr == PART_DISTR_GRID && part->from != PART_FROM_VERT) totpart = part->grid_res*part->grid_res*part->grid_res; else totpart = psys->part->totpart; diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 57ecffbb796..43805959e62 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -459,9 +459,10 @@ int BKE_ptcache_object_reset(Object *ob, int mode) PTCacheID pid; ParticleSystem *psys; ModifierData *md; - int reset; + int reset, skip; reset= 0; + skip= 0; if(ob->soft) { BKE_ptcache_id_from_softbody(&pid, ob, ob->soft); @@ -469,11 +470,18 @@ int BKE_ptcache_object_reset(Object *ob, int mode) } for(psys=ob->particlesystem.first; psys; psys=psys->next) { - BKE_ptcache_id_from_particles(&pid, ob, psys); - reset |= BKE_ptcache_id_reset(&pid, mode); - + /* Baked softbody hair has to be checked first, because we don't want to reset */ + /* particles or softbody in that case -jahka */ if(psys->soft) { BKE_ptcache_id_from_softbody(&pid, ob, psys->soft); + if(mode == PSYS_RESET_ALL || !(psys->part->type == PART_HAIR && (pid.cache->flag & PTCACHE_BAKED))) + reset |= BKE_ptcache_id_reset(&pid, mode); + else + skip = 1; + } + + if(skip == 0) { + BKE_ptcache_id_from_particles(&pid, ob, psys); reset |= BKE_ptcache_id_reset(&pid, mode); } } diff --git a/source/blender/blenkernel/intern/sca.c b/source/blender/blenkernel/intern/sca.c index 16ca5d7542d..fcf1c7ce311 100644 --- a/source/blender/blenkernel/intern/sca.c +++ b/source/blender/blenkernel/intern/sca.c @@ -150,6 +150,9 @@ void init_sensor(bSensor *sens) case SENS_PROPERTY: sens->data= MEM_callocN(sizeof(bPropertySensor), "propsens"); break; + case SENS_ACTUATOR: + sens->data= MEM_callocN(sizeof(bActuatorSensor), "actsens"); + break; case SENS_MOUSE: ms=sens->data= MEM_callocN(sizeof(bMouseSensor), "mousesens"); ms->type= LEFTMOUSE; diff --git a/source/blender/blenlib/BLI_arithb.h b/source/blender/blenlib/BLI_arithb.h index 4fa880c36d1..c22b6f79e08 100644 --- a/source/blender/blenlib/BLI_arithb.h +++ b/source/blender/blenlib/BLI_arithb.h @@ -50,6 +50,9 @@ extern "C" { #ifndef M_SQRT1_2 #define M_SQRT1_2 0.70710678118654752440 #endif +#ifndef M_1_PI +#define M_1_PI 0.318309886183790671538 +#endif #ifdef WIN32 #ifndef FREE_WINDOWS @@ -323,6 +326,9 @@ void yuv_to_rgb(float y, float u, float v, float *lr, float *lg, float *lb); void ycc_to_rgb(float y, float cb, float cr, float *lr, float *lg, float *lb); void rgb_to_ycc(float r, float g, float b, float *ly, float *lcb, float *lcr); void rgb_to_hsv(float r, float g, float b, float *lh, float *ls, float *lv); +void xyz_to_rgb(float x, float y, float z, float *r, float *g, float *b); +int constrain_rgb(float *r, float *g, float *b); +void gamma_correct_rgb(float *r, float *g, float *b); unsigned int hsv_to_cpack(float h, float s, float v); unsigned int rgb_to_cpack(float r, float g, float b); void cpack_to_rgb(unsigned int col, float *r, float *g, float *b); diff --git a/source/blender/blenlib/BLI_winstuff.h b/source/blender/blenlib/BLI_winstuff.h index 9c192ba8b09..11150075bac 100644 --- a/source/blender/blenlib/BLI_winstuff.h +++ b/source/blender/blenlib/BLI_winstuff.h @@ -73,6 +73,9 @@ #ifndef M_SQRT1_2 #define M_SQRT1_2 0.70710678118654752440 #endif +#ifndef M_1_PI +#define M_1_PI 0.318309886183790671538 +#endif #define MAXPATHLEN MAX_PATH diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c index e7b5ccd4d54..d84a9d09d4b 100644 --- a/source/blender/blenlib/intern/BLI_kdopbvh.c +++ b/source/blender/blenlib/intern/BLI_kdopbvh.c @@ -551,6 +551,7 @@ static void bvh_div_nodes(BVHTree *tree, BVHNode *node, int start, int end, char return; } +#if 0 static void verify_tree(BVHTree *tree) { int i, j, check = 0; @@ -597,6 +598,7 @@ static void verify_tree(BVHTree *tree) printf("branches: %d, leafs: %d, total: %d\n", tree->totbranch, tree->totleaf, tree->totbranch + tree->totleaf); } +#endif void BLI_bvhtree_balance(BVHTree *tree) { diff --git a/source/blender/blenlib/intern/arithb.c b/source/blender/blenlib/intern/arithb.c index a366862d064..dd9c76d9172 100644 --- a/source/blender/blenlib/intern/arithb.c +++ b/source/blender/blenlib/intern/arithb.c @@ -3413,6 +3413,66 @@ void rgb_to_hsv(float r, float g, float b, float *lh, float *ls, float *lv) *lv = v; } +/*http://brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html + * SMPTE-C XYZ to RGB matrix*/ +void xyz_to_rgb(float xc, float yc, float zc, float *r, float *g, float *b) +{ + *r = (3.50570 * xc) + (-1.73964 * yc) + (-0.544011 * zc); + *g = (-1.06906 * xc) + (1.97781 * yc) + (0.0351720 * zc); + *b = (0.0563117 * xc) + (-0.196994 * yc) + (1.05005 * zc); +} + +/*If the requested RGB shade contains a negative weight for + one of the primaries, it lies outside the colour gamut + accessible from the given triple of primaries. Desaturate + it by adding white, equal quantities of R, G, and B, enough + to make RGB all positive. The function returns 1 if the + components were modified, zero otherwise.*/ +int constrain_rgb(float *r, float *g, float *b) +{ + float w; + + /* Amount of white needed is w = - min(0, *r, *g, *b) */ + + w = (0 < *r) ? 0 : *r; + w = (w < *g) ? w : *g; + w = (w < *b) ? w : *b; + w = -w; + + /* Add just enough white to make r, g, b all positive. */ + + if (w > 0) { + *r += w; *g += w; *b += w; + return 1; /* Colour modified to fit RGB gamut */ + } + + return 0; /* Colour within RGB gamut */ +} + +/*Transform linear RGB values to nonlinear RGB values. Rec. + 709 is ITU-R Recommendation BT. 709 (1990) ``Basic + Parameter Values for the HDTV Standard for the Studio and + for International Programme Exchange'', formerly CCIR Rec. + 709.*/ +void gamma_correct(float *c) +{ + /* Rec. 709 gamma correction. */ + float cc = 0.018; + + if (*c < cc) { + *c *= ((1.099 * pow(cc, 0.45)) - 0.099) / cc; + } else { + *c = (1.099 * pow(*c, 0.45)) - 0.099; + } +} + +void gamma_correct_rgb(float *r, float *g, float *b) +{ + gamma_correct(r); + gamma_correct(g); + gamma_correct(b); +} + /* we define a 'cpack' here as a (3 byte color code) number that can be expressed like 0xFFAA66 or so. for that reason it is sensitive for endianness... with this function it works correctly diff --git a/source/blender/blenlib/intern/util.c b/source/blender/blenlib/intern/util.c index 5a85fbfc375..48ebf770e1b 100644 --- a/source/blender/blenlib/intern/util.c +++ b/source/blender/blenlib/intern/util.c @@ -1722,6 +1722,7 @@ void BLI_where_am_i(char *fullname, const char *name) path = br_find_exe( NULL ); if (path) { strcpy(fullname, path); + free(path); return; } #endif diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 9cfce5e34fa..3c629818b2d 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -7646,6 +7646,23 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } + /* sun/sky */ + if ((main->versionfile < 246) ){ + Lamp *la; + for(la=main->lamp.first; la; la= la->id.next) { + la->sun_effect_type = 0; + la->horizon_brightness = 1.0; + la->spread = 1.0; + la->sun_brightness = 1.0; + la->sun_size = 1.0; + la->backscattered_light = 1.0; + la->atm_turbidity = 2.0; + la->atm_inscattering_factor = 1.0; + la->atm_extinction_factor = 1.0; + la->atm_distance_factor = 1.0; + la->sun_intensity = 1.0; + } + } /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ /* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */ diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 9f28e13ff7b..ca91f1dc346 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -603,6 +603,9 @@ static void write_sensors(WriteData *wd, ListBase *lb) case SENS_PROPERTY: writestruct(wd, DATA, "bPropertySensor", 1, sens->data); break; + case SENS_ACTUATOR: + writestruct(wd, DATA, "bActuatorSensor", 1, sens->data); + break; case SENS_COLLISION: writestruct(wd, DATA, "bCollisionSensor", 1, sens->data); break; diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp index b59908fef39..fe352610a40 100644 --- a/source/blender/imbuf/intern/openexr/openexr_api.cpp +++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp @@ -842,7 +842,7 @@ typedef struct RGBA } RGBA; -#if 0 +/* debug only */ static void exr_print_filecontents(InputFile *file) { const ChannelList &channels = file->header().channels(); @@ -853,7 +853,27 @@ static void exr_print_filecontents(InputFile *file) printf("OpenEXR-load: Found channel %s of type %d\n", i.name(), channel.type); } } -#endif + +/* for non-multilayer, map R G B A channel names to something that's in this file */ +static const char *exr_rgba_channelname(InputFile *file, const char *chan) +{ + const ChannelList &channels = file->header().channels(); + + for (ChannelList::ConstIterator i = channels.begin(); i != channels.end(); ++i) + { + const Channel &channel = i.channel(); + const char *str= i.name(); + int len= strlen(str); + if(len) { + if(BLI_strcasecmp(chan, str+len-1)==0) { + return str; + } + } + } + return chan; +} + + static int exr_has_zbuffer(InputFile *file) { @@ -896,7 +916,8 @@ struct ImBuf *imb_load_openexr(unsigned char *mem, int size, int flags) //printf("OpenEXR-load: image data window %d %d %d %d\n", // dw.min.x, dw.min.y, dw.max.x, dw.max.y); - // exr_print_filecontents(file); + if(0) // debug + exr_print_filecontents(file); is_multi= exr_is_renderresult(file); @@ -935,11 +956,15 @@ struct ImBuf *imb_load_openexr(unsigned char *mem, int size, int flags) /* but, since we read y-flipped (negative y stride) we move to last scanline */ first+= 4*(height-1)*width; - frameBuffer.insert ("R", Slice (FLOAT, (char *) first, xstride, ystride)); - frameBuffer.insert ("G", Slice (FLOAT, (char *) (first+1), xstride, ystride)); - frameBuffer.insert ("B", Slice (FLOAT, (char *) (first+2), xstride, ystride)); - /* 1.0 is fill value */ - frameBuffer.insert ("A", Slice (FLOAT, (char *) (first+3), xstride, ystride, 1, 1, 1.0f)); + frameBuffer.insert ( exr_rgba_channelname(file, "R"), + Slice (FLOAT, (char *) first, xstride, ystride)); + frameBuffer.insert ( exr_rgba_channelname(file, "G"), + Slice (FLOAT, (char *) (first+1), xstride, ystride)); + frameBuffer.insert ( exr_rgba_channelname(file, "B"), + Slice (FLOAT, (char *) (first+2), xstride, ystride)); + + frameBuffer.insert ( exr_rgba_channelname(file, "A"), + Slice (FLOAT, (char *) (first+3), xstride, ystride, 1, 1, 1.0f)); /* 1.0 is fill value */ if(exr_has_zbuffer(file)) { diff --git a/source/blender/include/BDR_drawobject.h b/source/blender/include/BDR_drawobject.h index 3f9a6e438cc..de28db64c3b 100644 --- a/source/blender/include/BDR_drawobject.h +++ b/source/blender/include/BDR_drawobject.h @@ -63,6 +63,7 @@ void get_local_bounds(struct Object *ob, float *center, float *size); /* drawing flags: */ #define DRAW_PICKING 1 #define DRAW_CONSTCOLOR 2 +#define DRAW_SCENESET 4 void draw_object(struct Base *base, int flag); void drawaxes(float size, int flag, char drawtype); diff --git a/source/blender/include/BIF_editaction.h b/source/blender/include/BIF_editaction.h index 2d751f56fc5..7e0f703681b 100644 --- a/source/blender/include/BIF_editaction.h +++ b/source/blender/include/BIF_editaction.h @@ -141,6 +141,7 @@ void paste_actdata(void); /* Group/Channel Operations */ struct bActionGroup *get_active_actiongroup(struct bAction *act); void set_active_actiongroup(struct bAction *act, struct bActionGroup *agrp, short select); +void actionbone_group_copycolors(struct bActionGroup *grp, short init_new); void verify_pchan2achan_grouping(struct bAction *act, struct bPose *pose, char name[]); void sync_pchan2achan_grouping(void); void action_groups_group(short add_group); @@ -166,6 +167,7 @@ void deselect_action_channels(short mode); void deselect_actionchannels(struct bAction *act, short mode); int select_channel(struct bAction *act, struct bActionChannel *achan, int selectmode); void select_actionchannel_by_name(struct bAction *act, char *name, int select); +void select_action_group_channels(struct bAction *act, struct bActionGroup *agrp); void selectkeys_leftright (short leftright, short select_mode); /* Action Markers */ diff --git a/source/blender/include/BIF_editarmature.h b/source/blender/include/BIF_editarmature.h index 0e1557ac378..24112c7f11a 100644 --- a/source/blender/include/BIF_editarmature.h +++ b/source/blender/include/BIF_editarmature.h @@ -80,7 +80,7 @@ void clear_armature(struct Object *ob, char mode); void delete_armature(void); void deselectall_armature(int toggle, int doundo); void deselectall_posearmature (struct Object *ob, int test, int doundo); -int draw_armature(struct Base *base, int dt); +int draw_armature(struct Base *base, int dt, int flag); void extrude_armature(int forked); void subdivide_armature(int numcuts); diff --git a/source/blender/include/BIF_resources.h b/source/blender/include/BIF_resources.h index e6cbe7bb69a..df514190270 100644 --- a/source/blender/include/BIF_resources.h +++ b/source/blender/include/BIF_resources.h @@ -591,6 +591,9 @@ void BIF_load_ui_colors (void); char *BIF_ThemeGetColorPtr(struct bTheme *btheme, int spacetype, int colorid); char *BIF_ThemeColorsPup(int spacetype); +/* only for Bone Color sets */ +char *BIF_ThemeColorSetsPup(short inc_custom); + void BIF_def_color (BIFColorID colorid, unsigned char r, unsigned char g, unsigned char b); diff --git a/source/blender/include/BSE_sequence.h b/source/blender/include/BSE_sequence.h index 15a9218b735..0d96de7be60 100644 --- a/source/blender/include/BSE_sequence.h +++ b/source/blender/include/BSE_sequence.h @@ -92,6 +92,8 @@ void update_changed_seq_and_deps(struct Sequence *seq, int len_change, int ibuf_ struct RenderResult; void do_render_seq(struct RenderResult *rr, int cfra); +int seq_can_blend(struct Sequence *seq); + #define SEQ_HAS_PATH(seq) (seq->type==SEQ_MOVIE || seq->type==SEQ_HD_SOUND || seq->type==SEQ_RAM_SOUND || seq->type==SEQ_IMAGE) #endif diff --git a/source/blender/include/blendef.h b/source/blender/include/blendef.h index a798224b35b..6f8b94d7cd1 100644 --- a/source/blender/include/blendef.h +++ b/source/blender/include/blendef.h @@ -409,6 +409,12 @@ #define B_ACTCOPYKEYS 710 #define B_ACTPASTEKEYS 711 +#define B_ACTCUSTCOLORS 712 +#define B_ACTCOLSSELECTOR 713 +#define B_ACTGRP_SELALL 714 +#define B_ACTGRP_ADDTOSELF 715 +#define B_ACTGRP_UNGROUP 716 + /* TIME: 751 - 800 */ #define B_TL_REW 751 #define B_TL_PLAY 752 diff --git a/source/blender/makesdna/DNA_actuator_types.h b/source/blender/makesdna/DNA_actuator_types.h index 51f03a676e4..ac9761f165d 100644 --- a/source/blender/makesdna/DNA_actuator_types.h +++ b/source/blender/makesdna/DNA_actuator_types.h @@ -51,8 +51,9 @@ typedef struct bActionActuator { int sta, end; /* Start & End frames */ char name[32]; /* For property-driven playback */ char frameProp[32]; /* Set this property to the actions current frame */ - int blendin; /* Number of frames of blending */ - short priority; /* Execution priority */ + short blendin; /* Number of frames of blending */ + short priority; /* Execution priority */ + short end_reset; /* Ending the actuator (negative pulse) wont reset the the action to its starting frame */ short strideaxis; /* Displacement axis */ float stridelength; /* Displacement incurred by cycle */ } bActionActuator; @@ -98,8 +99,8 @@ typedef struct bPropertyActuator { } bPropertyActuator; typedef struct bObjectActuator { - short flag, type; - int damping; + short flag, type, otype; + short damping; float forceloc[3], forcerot[3]; float loc[3], rot[3]; float dloc[3], drot[3]; @@ -124,10 +125,13 @@ typedef struct bCameraActuator { } bCameraActuator ; typedef struct bConstraintActuator { + short type, mode; short flag, damp; - float slow; + short time, rotdamp; + int pad; float minloc[3], maxloc[3]; float minrot[3], maxrot[3]; + char matprop[32]; } bConstraintActuator; typedef struct bGroupActuator { @@ -192,9 +196,7 @@ typedef struct bVisibilityActuator { } bVisibilityActuator; typedef struct bTwoDFilterActuator{ - char pad[2]; - /* bitwise flag for enabling or disabling depth(bit 0) and luminance(bit 1) */ - short texture_flag; + char pad[4]; /* Tells what type of 2D Filter */ short type; /* (flag == 0) means 2D filter is activate and @@ -249,20 +251,19 @@ typedef struct FreeCamera { /* objectactuator->flag */ #define ACT_FORCE_LOCAL 1 #define ACT_TORQUE_LOCAL 2 +#define ACT_SERVO_LIMIT_X 2 #define ACT_DLOC_LOCAL 4 +#define ACT_SERVO_LIMIT_Y 4 #define ACT_DROT_LOCAL 8 +#define ACT_SERVO_LIMIT_Z 8 #define ACT_LIN_VEL_LOCAL 16 #define ACT_ANG_VEL_LOCAL 32 //#define ACT_ADD_LIN_VEL_LOCAL 64 #define ACT_ADD_LIN_VEL 64 -#define ACT_CLAMP_VEL 128 -#define ACT_OBJECT_FORCE 0 -#define ACT_OBJECT_TORQUE 1 -#define ACT_OBJECT_DLOC 2 -#define ACT_OBJECT_DROT 3 -#define ACT_OBJECT_LINV 4 -#define ACT_OBJECT_ANGV 5 +/* objectactuator->type */ +#define ACT_OBJECT_NORMAL 0 +#define ACT_OBJECT_SERVO 1 /* actuator->type */ #define ACT_OBJECT 0 @@ -337,8 +338,9 @@ typedef struct FreeCamera { /* ipoactuator->flag */ #define ACT_IPOFORCE (1 << 0) #define ACT_IPOEND (1 << 1) -#define ACT_IPOFORCE_LOCAL (1 << 2) -#define ACT_IPOCHILD (1 << 4) +#define ACT_IPOLOCAL (1 << 2) +#define ACT_IPOCHILD (1 << 4) +#define ACT_IPOADD (1 << 5) /* ipoactuator->flag for k2k */ #define ACT_K2K_PREV 1 @@ -358,6 +360,22 @@ typedef struct FreeCamera { #define ACT_CONST_ROTX 8 #define ACT_CONST_ROTY 16 #define ACT_CONST_ROTZ 32 +#define ACT_CONST_NORMAL 64 +#define ACT_CONST_MATERIAL 128 +#define ACT_CONST_PERMANENT 256 +#define ACT_CONST_DISTANCE 512 +/* constraint mode */ +#define ACT_CONST_DIRPX 1 +#define ACT_CONST_DIRPY 2 +#define ACT_CONST_DIRPZ 4 +#define ACT_CONST_DIRMX 8 +#define ACT_CONST_DIRMY 16 +#define ACT_CONST_DIRMZ 32 + +/* constraint type */ +#define ACT_CONST_TYPE_LOC 0 +#define ACT_CONST_TYPE_DIST 1 +#define ACT_CONST_TYPE_ORI 2 /* editObjectActuator->type */ #define ACT_EDOB_ADD_OBJECT 0 diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h index 73a39abac55..72557145270 100644 --- a/source/blender/makesdna/DNA_customdata_types.h +++ b/source/blender/makesdna/DNA_customdata_types.h @@ -26,6 +26,7 @@ * * ***** END GPL LICENSE BLOCK ***** */ + #ifndef DNA_CUSTOMDATA_TYPES_H #define DNA_CUSTOMDATA_TYPES_H @@ -48,6 +49,7 @@ typedef struct CustomData { CustomDataLayer *layers; /* CustomDataLayers, ordered by type */ int totlayer, maxlayer; /* number of layers, size of layers array */ int totsize, pad; /* in editmode, total size of all data layers */ + void *pool; /* for Bmesh: Memory pool for allocation of blocks*/ } CustomData; /* CustomData.type */ @@ -66,7 +68,10 @@ typedef struct CustomData { #define CD_PROP_STR 12 #define CD_ORIGSPACE 13 /* for modifier stack face location mapping */ #define CD_ORCO 14 -#define CD_NUMTYPES 15 +#define CD_MTEXPOLY 15 +#define CD_MLOOPUV 16 +#define CD_MLOOPCOL 17 +#define CD_NUMTYPES 18 /* Bits for CustomDataMask */ #define CD_MASK_MVERT (1 << CD_MVERT) @@ -84,6 +89,9 @@ typedef struct CustomData { #define CD_MASK_PROP_STR (1 << CD_PROP_STR) #define CD_MASK_ORIGSPACE (1 << CD_ORIGSPACE) #define CD_MASK_ORCO (1 << CD_ORCO) +#define CD_MASK_MTEXPOLY (1 << CD_MTEXPOLY) +#define CD_MASK_MLOOPUV (1 << CD_MLOOPUV) +#define CD_MASK_MLOOPCOL (1 << CD_MLOOPCOL) /* CustomData.flag */ diff --git a/source/blender/makesdna/DNA_lamp_types.h b/source/blender/makesdna/DNA_lamp_types.h index 2afe78289c1..c00dae08eb4 100644 --- a/source/blender/makesdna/DNA_lamp_types.h +++ b/source/blender/makesdna/DNA_lamp_types.h @@ -76,6 +76,21 @@ typedef struct Lamp { /* texact is for buttons */ short texact, shadhalostep; + /* sun/sky */ + short sun_effect_type; + short atm_pad[3]; + float horizon_brightness; + float spread; + float sun_brightness; + float sun_size; + float backscattered_light; + float sun_intensity; + float atm_turbidity; + float atm_inscattering_factor; + float atm_extinction_factor; + float atm_distance_factor; + + /* yafray: photonlight params */ int YF_numphotons, YF_numsearch; short YF_phdepth, YF_useqmc, YF_bufsize, YF_pad; @@ -123,6 +138,10 @@ typedef struct Lamp { /* Since it is used with LOCAL lamp, can't use LA_SHAD */ #define LA_YF_SOFT 16384 +/* sun effect type*/ +#define LA_SUN_EFFECT_SKY 1 +#define LA_SUN_EFFECT_AP 2 + /* falloff_type */ #define LA_FALLOFF_CONSTANT 0 #define LA_FALLOFF_INVLINEAR 1 diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h index a717df640f1..6d025839ac8 100644 --- a/source/blender/makesdna/DNA_meshdata_types.h +++ b/source/blender/makesdna/DNA_meshdata_types.h @@ -69,6 +69,21 @@ typedef struct MCol { char a, r, g, b; } MCol; +/*bmesh custom data stuff*/ +typedef struct MTexPoly{ + struct Image *tpage; + char flag, transp; + short mode,tile,unwrap; +}MTexPoly; + +typedef struct MLoopUV{ + float uv[2]; +}MLoopUV; + +typedef struct MLoopCol{ + char a, r, g, b; +}MLoopCol; + typedef struct MSticky { float co[2]; } MSticky; diff --git a/source/blender/makesdna/DNA_sensor_types.h b/source/blender/makesdna/DNA_sensor_types.h index ae7b92bb06c..c0306f43730 100644 --- a/source/blender/makesdna/DNA_sensor_types.h +++ b/source/blender/makesdna/DNA_sensor_types.h @@ -82,6 +82,12 @@ typedef struct bPropertySensor { char maxvalue[32]; } bPropertySensor; +typedef struct bActuatorSensor { + int type; + int pad; + char name[32]; +} bActuatorSensor; + typedef struct bCollisionSensor { char name[32]; /* property name */ char materialName[32]; /* material */ @@ -197,6 +203,7 @@ typedef struct bJoystickSensor { #define SENS_RAY 9 #define SENS_MESSAGE 10 #define SENS_JOYSTICK 11 +#define SENS_ACTUATOR 12 /* sensor->flag */ #define SENS_SHOW 1 #define SENS_DEL 2 diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index af60f9ca713..bc30a12ff27 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -232,8 +232,9 @@ typedef struct SpaceImage { short imanr; short curtile; /* the currently active tile of the image when tile is enabled, is kept in sync with the active faces tile */ int flag; + short selectmode; short imtypenr, lock; - short pin, pad2; + short pin; float zoom; char dt_uv; /* UV draw type */ char sticky; /* sticky selection type */ @@ -496,6 +497,12 @@ typedef struct SpaceImaSel { #define SI_STICKY_DISABLE 1 #define SI_STICKY_VERTEX 2 +/* SpaceImage->selectmode */ +#define SI_SELECT_VERTEX 0 +#define SI_SELECT_EDGE 1 /* not implemented */ +#define SI_SELECT_FACE 2 +#define SI_SELECT_ISLAND 3 + /* SpaceImage->flag */ #define SI_BE_SQUARE 1<<0 #define SI_EDITTILE 1<<1 @@ -503,7 +510,7 @@ typedef struct SpaceImaSel { #define SI_DRAWTOOL 1<<3 #define SI_DEPRECATED1 1<<4 /* stick UVs to others in the same location */ #define SI_DRAWSHADOW 1<<5 -#define SI_SELACTFACE 1<<6 +#define SI_SELACTFACE 1<<6 /* deprecated */ #define SI_DEPRECATED2 1<<7 #define SI_DEPRECATED3 1<<8 /* stick UV selection to mesh vertex (UVs wont always be touching) */ #define SI_COORDFLOATS 1<<9 diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 3de5b0ff5ba..cd1c047dac9 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -116,6 +116,7 @@ typedef struct ThemeWireColor { /* flags for ThemeWireColor */ #define TH_WIRECOLOR_CONSTCOLS (1<<0) +#define TH_WIRECOLOR_TEXTCOLS (1<<1) /* A theme */ typedef struct bTheme { diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_gamma.c b/source/blender/nodes/intern/CMP_nodes/CMP_gamma.c index ff9e2b716ce..e77de3726cb 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_gamma.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_gamma.c @@ -47,7 +47,7 @@ static void do_gamma(bNode *node, float *out, float *in, float *fac) int i=0; for(i=0; i<3; i++) { /* check for negative to avoid nan's */ - out[i] = (in[0] > 0.0f)? pow(in[i],fac[0]): in[0]; + out[i] = (in[i] > 0.0f)? pow(in[i],fac[0]): in[i]; } out[3] = in[3]; } diff --git a/source/blender/python/BPY_interface.c b/source/blender/python/BPY_interface.c index 2f94e0eeebc..226657655fa 100644 --- a/source/blender/python/BPY_interface.c +++ b/source/blender/python/BPY_interface.c @@ -229,13 +229,6 @@ void BPY_start_python( int argc, char **argv ) /* Initialize thread support (also acquires lock) */ PyEval_InitThreads(); - /* Don't allow the Python Interpreter to release the GIL on - * its own, to guarantee PyNodes work properly. For Blender this - * is currently the best default behavior. - * The following code in C is equivalent in Python to: - * "import sys; sys.setcheckinterval(sys.maxint)" */ - _Py_CheckInterval = PyInt_GetMax(); - //Overrides __import__ init_ourImport( ); init_ourReload( ); @@ -2188,6 +2181,18 @@ void BPY_do_all_scripts( short event ) BPY_do_pyscript( &( G.scene->id ), event ); + /* Don't allow the Python Interpreter to release the GIL on + * its own, to guarantee PyNodes work properly. For Blender this + * is currently the best default behavior. + * The following code in C is equivalent in Python to: + * "import sys; sys.setcheckinterval(sys.maxint)" */ + if (event == SCRIPT_RENDER) { + _Py_CheckInterval = PyInt_GetMax(); + } + else if (event == SCRIPT_POSTRENDER) { + _Py_CheckInterval = 100; /* Python default */ + } + return; } @@ -2270,9 +2275,9 @@ void BPY_do_pyscript( ID * id, short event ) return; } - /* tell we're running a scriptlink. The sum also tells if this script - * is running nested inside another. Blender.Load needs this info to - * avoid trouble with invalid slink pointers. */ + /* tell we're running a scriptlink. The sum also tells if this + * script is running nested inside another. Blender.Load needs + * this info to avoid trouble with invalid slink pointers. */ during_slink++; disable_where_scriptlink( (short)during_slink ); diff --git a/source/blender/python/api2_2x/matrix.c b/source/blender/python/api2_2x/matrix.c index d81e56ec3dc..9f5e49e8d88 100644 --- a/source/blender/python/api2_2x/matrix.c +++ b/source/blender/python/api2_2x/matrix.c @@ -483,7 +483,7 @@ static char MatrixObject_doc[] = "This is a wrapper for matrix objects."; sequence length*/ static int Matrix_len(MatrixObject * self) { - return (self->colSize * self->rowSize); + return (self->rowSize); } /*----------------------------object[]--------------------------- sequence accessor (get) diff --git a/source/blender/python/api2_2x/sceneSequence.c b/source/blender/python/api2_2x/sceneSequence.c index 56821980cd2..0d3ad3fcb44 100644 --- a/source/blender/python/api2_2x/sceneSequence.c +++ b/source/blender/python/api2_2x/sceneSequence.c @@ -81,6 +81,7 @@ returns None if notfound.\nIf 'name' is not specified, it returns a list of all static PyObject *Sequence_copy( BPy_Sequence * self ); static PyObject *Sequence_new( BPy_Sequence * self, PyObject * args ); static PyObject *Sequence_remove( BPy_Sequence * self, PyObject * args ); +static PyObject *Sequence_rebuildProxy( BPy_Sequence * self ); static PyObject *SceneSeq_new( BPy_SceneSeq * self, PyObject * args ); static PyObject *SceneSeq_remove( BPy_SceneSeq * self, PyObject * args ); @@ -96,6 +97,8 @@ static PyMethodDef BPy_Sequence_methods[] = { "() - Return a copy of the sequence containing the same objects."}, {"copy", ( PyCFunction ) Sequence_copy, METH_NOARGS, "() - Return a copy of the sequence containing the same objects."}, + {"rebuildProxy", ( PyCFunction ) Sequence_rebuildProxy, METH_VARARGS, + "() - Rebuild the active strip's Proxy."}, {NULL, NULL, 0, NULL} }; @@ -309,6 +312,7 @@ static PyObject *Sequence_copy( BPy_Sequence * self ) Py_RETURN_NONE; } + /*****************************************************************************/ /* PythonTypeObject callback function prototypes */ /*****************************************************************************/ @@ -383,8 +387,6 @@ static PyObject *SceneSeq_nextIter( BPy_Sequence * self ) } - - static PyObject *Sequence_getName( BPy_Sequence * self ) { return PyString_FromString( self->seq->name+2 ); @@ -403,11 +405,13 @@ static int Sequence_setName( BPy_Sequence * self, PyObject * value ) return 0; } + static PyObject *Sequence_getProxyDir( BPy_Sequence * self ) { return PyString_FromString( self->seq->strip->proxy ? self->seq->strip->proxy->dir : "" ); } + static int Sequence_setProxyDir( BPy_Sequence * self, PyObject * value ) { char *name = NULL; @@ -430,6 +434,14 @@ static int Sequence_setProxyDir( BPy_Sequence * self, PyObject * value ) } +static PyObject *Sequence_rebuildProxy( BPy_Sequence * self ) +{ + if (self->seq->strip->proxy) + seq_proxy_rebuild(self->seq); + Py_RETURN_NONE; +} + + static PyObject *Sequence_getSound( BPy_Sequence * self ) { if (self->seq->type == SEQ_RAM_SOUND && self->seq->sound) @@ -622,6 +634,54 @@ static int Sequence_setImages( BPy_Sequence * self, PyObject *value ) return 0; } +static PyObject *M_Sequence_BlendModesDict( void ) +{ + PyObject *M = PyConstant_New( ); + + if( M ) { + BPy_constant *d = ( BPy_constant * ) M; + PyConstant_Insert( d, "CROSS", PyInt_FromLong( SEQ_CROSS ) ); + PyConstant_Insert( d, "ADD", PyInt_FromLong( SEQ_ADD ) ); + PyConstant_Insert( d, "SUBTRACT", PyInt_FromLong( SEQ_SUB ) ); + PyConstant_Insert( d, "ALPHAOVER", PyInt_FromLong( SEQ_ALPHAOVER ) ); + PyConstant_Insert( d, "ALPHAUNDER", PyInt_FromLong( SEQ_ALPHAUNDER ) ); + PyConstant_Insert( d, "GAMMACROSS", PyInt_FromLong( SEQ_GAMCROSS ) ); + PyConstant_Insert( d, "MULTIPLY", PyInt_FromLong( SEQ_MUL ) ); + PyConstant_Insert( d, "OVERDROP", PyInt_FromLong( SEQ_OVERDROP ) ); + PyConstant_Insert( d, "PLUGIN", PyInt_FromLong( SEQ_PLUGIN ) ); + PyConstant_Insert( d, "WIPE", PyInt_FromLong( SEQ_WIPE ) ); + PyConstant_Insert( d, "GLOW", PyInt_FromLong( SEQ_GLOW ) ); + PyConstant_Insert( d, "TRANSFORM", PyInt_FromLong( SEQ_TRANSFORM ) ); + PyConstant_Insert( d, "COLOR", PyInt_FromLong( SEQ_COLOR ) ); + PyConstant_Insert( d, "SPEED", PyInt_FromLong( SEQ_SPEED ) ); + } + return M; +} + +static PyObject *Sequence_getBlendMode( BPy_Sequence * self ) +{ + return PyInt_FromLong( self->seq->blend_mode ); +} + +static int Sequence_setBlendMode( BPy_Sequence * self, PyObject * value ) +{ + struct Sequence *seq= self->seq; + int number = PyInt_AsLong( value ); + + if( number==-1 && PyErr_Occurred() ) + return EXPP_ReturnIntError( PyExc_TypeError, "expected an int value" ); + + if ( !seq_can_blend(seq) ) + return EXPP_ReturnIntError( PyExc_AttributeError, "this sequence type dosnt support blending" ); + + if (number<SEQ_EFFECT || number>SEQ_EFFECT_MAX) + return EXPP_ReturnIntError( PyExc_TypeError, "expected an int value" ); + + seq->blend_mode=number; + + return 0; +} + /* * get floating point attributes */ @@ -836,7 +896,11 @@ static PyGetSetDef BPy_Sequence_getseters[] = { (getter)Sequence_getImages, (setter)Sequence_setImages, "Sequence scene", NULL}, - + {"blendMode", + (getter)Sequence_getBlendMode, (setter)Sequence_setBlendMode, + "Sequence Blend Mode", + NULL}, + {"type", (getter)getIntAttr, (setter)NULL, "", @@ -1131,6 +1195,7 @@ PyObject *M_Sequence_Get( PyObject * self, PyObject * args ) /*****************************************************************************/ PyObject *Sequence_Init( void ) { + PyObject *BlendModesDict = M_Sequence_BlendModesDict( ); PyObject *submodule; if( PyType_Ready( &Sequence_Type ) < 0 ) return NULL; @@ -1142,6 +1207,9 @@ PyObject *Sequence_Init( void ) "The Blender Sequence module\n\n\ This module provides access to **Sequence Data** in Blender.\n" ); + if( BlendModesDict ) + PyModule_AddObject( submodule, "BlendModes", BlendModesDict ); + /*Add SUBMODULES to the module*/ /*PyDict_SetItemString(dict, "Constraint", Constraint_Init()); //creates a *new* module*/ return submodule; diff --git a/source/blender/radiosity/intern/source/radrender.c b/source/blender/radiosity/intern/source/radrender.c index e5ef1e9a4a2..68b5fa81f43 100644 --- a/source/blender/radiosity/intern/source/radrender.c +++ b/source/blender/radiosity/intern/source/radrender.c @@ -369,9 +369,18 @@ printf(" Rad elems: %d emittors %d\n", RG.totelem, RG.totpatch); if(vlr->mat->mode & MA_RADIO) { /* during render, vlr->n gets flipped/corrected, we cannot have that */ - if(vlr->v4) CalcNormFloat4(vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4->co, rf->norm); - else CalcNormFloat(vlr->v1->co, vlr->v2->co, vlr->v3->co, rf->norm); - + if (obr->ob->transflag & OB_NEG_SCALE){ + /* The object has negative scale that will cause the normals to flip. + To counter this unwanted normal flip, swap vertex 2 and 4 for a quad + or vertex 2 and 3 (see flip_face) for a triangle in the call to CalcNormFloat4 + in order to flip the normals back to the way they were in the original mesh. */ + if(vlr->v4) CalcNormFloat4(vlr->v1->co, vlr->v4->co, vlr->v3->co, vlr->v2->co, rf->norm); + else CalcNormFloat(vlr->v1->co, vlr->v3->co, vlr->v2->co, rf->norm); + }else{ + if(vlr->v4) CalcNormFloat4(vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4->co, rf->norm); + else CalcNormFloat(vlr->v1->co, vlr->v2->co, vlr->v3->co, rf->norm); + } + rf->totrad[0]= vlr->mat->emit*vlr->mat->r; rf->totrad[1]= vlr->mat->emit*vlr->mat->g; rf->totrad[2]= vlr->mat->emit*vlr->mat->b; diff --git a/source/blender/render/intern/include/pixelshading.h b/source/blender/render/intern/include/pixelshading.h index ee7199a4295..15d696df89d 100644 --- a/source/blender/render/intern/include/pixelshading.h +++ b/source/blender/render/intern/include/pixelshading.h @@ -55,6 +55,7 @@ int shadeHaloFloat(HaloRen *har, */ void shadeSkyPixel(float *collector, float fx, float fy); void shadeSkyView(float *colf, float *rco, float *view, float *dxyview); +void shadeAtmPixel(struct SunSky *sunsky, float *collector, float fx, float fy, float distance); /* ------------------------------------------------------------------------- */ diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h index 8414b6aefe3..2f97b19f75c 100644 --- a/source/blender/render/intern/include/render_types.h +++ b/source/blender/render/intern/include/render_types.h @@ -42,6 +42,7 @@ #include "RE_pipeline.h" #include "RE_shader_ext.h" /* TexResult, ShadeResult, ShadeInput */ +#include "sunsky.h" struct Object; struct MemArena; @@ -455,6 +456,9 @@ typedef struct LampRen { float area_size, area_sizey, area_sizez; float adapt_thresh; + /* sun/sky */ + struct SunSky *sunsky; + struct ShadBuf *shb; float *jitter; diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 796a99ca796..faa7a68f754 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -114,6 +114,7 @@ #include "sss.h" #include "strand.h" #include "zbuf.h" +#include "sunsky.h" #ifndef DISABLE_YAFRAY /* disable yafray */ @@ -203,6 +204,7 @@ void RE_make_stars(Render *re, void (*initfunc)(void), else stargrid *= 1.0; /* then it draws fewer */ if(re) MTC_Mat4Invert(mat, re->viewmat); + else MTC_Mat4One(mat); /* BOUNDING BOX CALCULATION * bbox goes from z = loc_near_var | loc_far_var, @@ -3494,6 +3496,7 @@ static GroupObject *add_render_lamp(Render *re, Object *ob) LampRen *lar; GroupObject *go; float mat[4][4], angle, xn, yn; + float vec[3]; int c; /* previewrender sets this to zero... prevent accidents */ @@ -3576,8 +3579,9 @@ static GroupObject *add_render_lamp(Render *re, Object *ob) lar->ray_samp_type= la->ray_samp_type; lar->adapt_thresh= la->adapt_thresh; + lar->sunsky = NULL; - if( ELEM3(lar->type, LA_SPOT, LA_SUN, LA_LOCAL)) { + if( ELEM(lar->type, LA_SPOT, LA_LOCAL)) { lar->ray_totsamp= lar->ray_samp*lar->ray_samp; lar->area_shape = LA_AREA_SQUARE; lar->area_sizey= lar->area_size; @@ -3607,6 +3611,26 @@ static GroupObject *add_render_lamp(Render *re, Object *ob) area_lamp_vectors(lar); init_jitter_plane(lar); // subsamples } + else if(lar->type==LA_SUN){ + lar->ray_totsamp= lar->ray_samp*lar->ray_samp; + lar->area_shape = LA_AREA_SQUARE; + lar->area_sizey= lar->area_size; + + if((la->sun_effect_type & LA_SUN_EFFECT_SKY) || + (la->sun_effect_type & LA_SUN_EFFECT_AP)){ + lar->sunsky = (struct SunSky*)MEM_callocN(sizeof(struct SunSky), "sunskyren"); + lar->sunsky->effect_type = la->sun_effect_type; + + VECCOPY(vec,ob->obmat[2]); + Normalize(vec); + + InitSunSky(lar->sunsky, la->atm_turbidity, vec, la->horizon_brightness, + la->spread, la->sun_brightness, la->sun_size, la->backscattered_light); + + InitAtmosphere(lar->sunsky, la->sun_intensity, 1.0, 1.0, la->atm_inscattering_factor, la->atm_extinction_factor, + la->atm_distance_factor); + } + } else lar->ray_totsamp= 0; #ifndef DISABLE_YAFRAY @@ -4447,6 +4471,7 @@ void RE_Database_Free(Render *re) freeshadowbuf(lar); if(lar->jitter) MEM_freeN(lar->jitter); if(lar->shadsamp) MEM_freeN(lar->shadsamp); + if(lar->sunsky) MEM_freeN(lar->sunsky); curvemapping_free(lar->curfalloff); } diff --git a/source/blender/render/intern/source/pixelshading.c b/source/blender/render/intern/source/pixelshading.c index fc5ac68e8c9..2e3509f0471 100644 --- a/source/blender/render/intern/source/pixelshading.c +++ b/source/blender/render/intern/source/pixelshading.c @@ -57,6 +57,7 @@ #include "rendercore.h" #include "shadbuf.h" #include "pixelshading.h" +#include "sunsky.h" /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /* defined in pipeline.c, is hardcopy of active dynamic allocated Render */ @@ -567,13 +568,49 @@ void shadeSkyView(float *colf, float *rco, float *view, float *dxyview) } } +/* shade sky according to sun lamps, all parameters are like shadeSkyView except sunsky*/ +void shadeSunView(struct SunSky *sunsky, float *colf, float *rco, float *view, float *dxyview) +{ + float colorxyz[3]; + float scale; + + /** + sunAngle = sqrt(sunsky->sunSolidAngle / M_PI); + + sunDir[0] = sunsky->toSun[0]; + sunDir[1] = sunsky->toSun[1]; + sunDir[2] = sunsky->toSun[2]; + */ + + Normalize(view); + MTC_Mat3MulVecfl(R.imat, view); + if (view[2] < 0.0) + view[2] = 0.0; + Normalize(view); + GetSkyXYZRadiancef(sunsky, view, colorxyz); + scale = MAX3(colorxyz[0], colorxyz[1], colorxyz[2]); + colorxyz[0] /= scale; + colorxyz[1] /= scale; + colorxyz[2] /= scale; + + xyz_to_rgb(colorxyz[0], colorxyz[1], colorxyz[2], &colf[0], &colf[1], &colf[2]); + + ClipColor(colf); +} + + /* Stuff the sky color into the collector. */ void shadeSkyPixel(float *collector, float fx, float fy) { float view[3], dxyview[2]; - + float sun_collector[3]; + float suns_color[3]; + short num_sun_lamp; + GroupObject *go; + LampRen *lar; + /* The rules for sky: 1. Draw an image, if a background image was provided. Stop @@ -585,7 +622,6 @@ void shadeSkyPixel(float *collector, float fx, float fy) /* 1. Do a backbuffer image: */ if(R.r.bufflag & 1) { fillBackgroundImage(collector, fx, fy); - return; } else if((R.wrld.skytype & (WO_SKYBLEND+WO_SKYTEX))==0) { /* 2. solid color */ @@ -620,7 +656,45 @@ void shadeSkyPixel(float *collector, float fx, float fy) shadeSkyView(collector, NULL, view, dxyview); collector[3] = 0.0f; } + + suns_color[0] = suns_color[1] = suns_color[2] = 0; + num_sun_lamp = 0; + for(go=R.lights.first; go; go= go->next) { + lar= go->lampren; + if(lar->type==LA_SUN && lar->sunsky && (lar->sunsky->effect_type & LA_SUN_EFFECT_SKY)){ + + num_sun_lamp ++; + calc_view_vector(view, fx, fy); + Normalize(view); + + shadeSunView(lar->sunsky, sun_collector, NULL, view, NULL); + suns_color[0] += sun_collector[0]; + suns_color[1] += sun_collector[1]; + suns_color[2] += sun_collector[2]; + + } + } + if( num_sun_lamp > 0 ){ + suns_color[0] /= num_sun_lamp; + suns_color[1] /= num_sun_lamp; + suns_color[2] /= num_sun_lamp; + + collector[0] += suns_color[0]; + collector[1] += suns_color[1]; + collector[2] += suns_color[2]; + ClipColor(collector); + } } +/* aerial perspective */ +void shadeAtmPixel(struct SunSky *sunsky, float *collector, float fx, float fy, float distance) +{ + float view[3]; + + calc_view_vector(view, fx, fy); + Normalize(view); + /*MTC_Mat3MulVecfl(R.imat, view);*/ + AtmospherePixleShader(sunsky, view, distance, collector); +} /* eof */ diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index dae7b0dcd88..67be0ce4c00 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -47,6 +47,7 @@ #include "DNA_lamp_types.h" #include "DNA_material_types.h" #include "DNA_meshdata_types.h" +#include "DNA_group_types.h" #include "BKE_global.h" #include "BKE_image.h" @@ -665,6 +666,88 @@ static void sky_tile(RenderPart *pa, RenderLayer *rl) } } +static void atm_tile(RenderPart *pa, RenderLayer *rl) +{ + RenderPass *zpass; + GroupObject *go; + LampRen *lar; + + int x, y; + short first_lamp; + float *zrect; + float *rgbrect; + float rgb[3]={0}; + float tmp_rgb[3]; + float fac; + float facm; + + fac = 0.5; + facm = 1.0 - fac; + + /* check that z pass is enabled */ + if(pa->rectz==NULL) return; + for(zpass= rl->passes.first; zpass; zpass= zpass->next) + if(zpass->passtype==SCE_PASS_Z) + break; + + if(zpass==NULL) return; + + /* check for at least one sun lamp that its atmosphere flag is is enabled */ + first_lamp = 1; + for(go=R.lights.first; go; go= go->next) { + lar= go->lampren; + if(lar->type==LA_SUN && lar->sunsky && + (lar->sunsky->effect_type & LA_SUN_EFFECT_AP)){ + first_lamp = 0; + break; + } + } + /* do nothign and return if there is no sun lamp */ + if(first_lamp) + return; + + zrect = zpass->rect; + rgbrect = rl->rectf; + /* for each x,y and sun lamp*/ + for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++) { + for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, zrect++, rgbrect+=4) { + + first_lamp = 1; + for(go=R.lights.first; go; go= go->next) { + lar= go->lampren; + if(lar->type==LA_SUN && lar->sunsky) + + { + /* if it's sky continue and don't apply atmosphere effect on it */ + if(*zrect >= 9.9e10){ + continue; + } + + if(lar->sunsky->effect_type & LA_SUN_EFFECT_AP){ + VECCOPY(tmp_rgb, rgbrect); + + shadeAtmPixel(lar->sunsky, tmp_rgb, x, y, *zrect); + + if(first_lamp){ + VECCOPY(rgb, tmp_rgb); + first_lamp = 0; + } + else{ + rgb[0] = facm*rgb[0] + fac*tmp_rgb[0]; + rgb[1] = facm*rgb[1] + fac*tmp_rgb[1]; + rgb[2] = facm*rgb[2] + fac*tmp_rgb[2]; + } + } + } + } + + /* if at least for one sun lamp aerial perspective was applied*/ + if(first_lamp==0) + VECCOPY(rgbrect, rgb); + } + } +} + static void shadeDA_tile(RenderPart *pa, RenderLayer *rl) { RenderResult *rr= pa->result; @@ -1122,6 +1205,10 @@ void zbufshadeDA_tile(RenderPart *pa) if(R.r.mode & R_EDGE) edge_enhance_add(pa, rl->rectf, edgerect); + /* sun/sky */ + if(rl->layflag & SCE_LAY_SKY) + atm_tile(pa, rl); + if(rl->passflag & SCE_PASS_VECTOR) reset_sky_speed(pa, rl); @@ -1282,6 +1369,10 @@ void zbufshade_tile(RenderPart *pa) edge_enhance_add(pa, rl->rectf, edgerect); } + /* sun/sky */ + if(rl->layflag & SCE_LAY_SKY) + atm_tile(pa, rl); + if(rl->passflag & SCE_PASS_VECTOR) reset_sky_speed(pa, rl); diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 36ab0961150..a21dc8b0f5d 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -5291,32 +5291,6 @@ static void verify_posegroup_groupname(void *arg1, void *arg2) BLI_uniquename(&pose->agroups, grp, "Group", offsetof(bActionGroup, name), 32); } -static char *build_colorsets_menustr () -{ - DynStr *pupds= BLI_dynstr_new(); - char *str; - char buf[48]; - int i; - - /* add title first (and the "default" entry) */ - BLI_dynstr_append(pupds, "Bone Color Set%t|Default Colors%x0|"); - - /* loop through set indices, adding them */ - for (i=1; i<21; i++) { - sprintf(buf, "%d - Theme Color Set%%x%d|", i, i); - BLI_dynstr_append(pupds, buf); - } - - /* add the 'custom' entry */ - BLI_dynstr_append(pupds, "Custom Set %x-1"); - - /* convert to normal MEM_malloc'd string */ - str= BLI_dynstr_get_cstring(pupds); - BLI_dynstr_free(pupds); - - return str; -} - static void editing_panel_links(Object *ob) { uiBlock *block; @@ -5476,32 +5450,14 @@ static void editing_panel_links(Object *ob) /* color set for 'active' group */ if (pose->active_group && grp) { uiBlockBeginAlign(block); - menustr= build_colorsets_menustr(); + menustr= BIF_ThemeColorSetsPup(1); uiDefButI(block, MENU,B_POSEGRP_RECALC, menustr, xco,85,140,19, &grp->customCol, -1, 20, 0.0, 0.0, "Index of set of Custom Colors to shade Group's bones with. 0 = Use Default Color Scheme, -1 = Use Custom Color Scheme"); MEM_freeN(menustr); /* show color-selection/preview */ if (grp->customCol) { - if (grp->customCol > 0) { - /* copy theme colors on-to group's custom color in case user tries to edit color */ - bTheme *btheme= U.themes.first; - ThemeWireColor *col_set= &btheme->tarm[(grp->customCol - 1)]; - - memcpy(&grp->cs, col_set, sizeof(ThemeWireColor)); - } - else { - /* init custom colors with a generic multi-color rgb set, if not initialised already */ - if (grp->cs.solid[0] == 0) { - /* define for setting colors in theme below */ - #define SETCOL(col, r, g, b, a) col[0]=r; col[1]=g; col[2]= b; col[3]= a; - - SETCOL(grp->cs.solid, 0xff, 0x00, 0x00, 255); - SETCOL(grp->cs.select, 0x81, 0xe6, 0x14, 255); - SETCOL(grp->cs.active, 0x18, 0xb6, 0xe0, 255); - - #undef SETCOL - } - } + /* do color copying/init (to stay up to date) */ + actionbone_group_copycolors(grp, 1); /* color changing */ uiDefButC(block, COL, B_POSEGRP_MCUSTOM, "", xco, 65, 30, 19, grp->cs.solid, 0, 0, 0, 0, "Color to use for surface of bones"); diff --git a/source/blender/src/buttons_logic.c b/source/blender/src/buttons_logic.c index 4e5e8a605ee..441d00ffc30 100644 --- a/source/blender/src/buttons_logic.c +++ b/source/blender/src/buttons_logic.c @@ -387,7 +387,6 @@ void do_logic_buts(unsigned short event) bSensor *sens; bController *cont; bActuator *act; - Base *base; Object *ob; int didit, bit; @@ -443,16 +442,14 @@ void do_logic_buts(unsigned short event) break; case B_ADD_SENS: - base= FIRSTBASE; - while(base) { - if(base->object->scaflag & OB_ADDSENS) { - base->object->scaflag &= ~OB_ADDSENS; + for(ob=G.main->object.first; ob; ob=ob->id.next) { + if(ob->scaflag & OB_ADDSENS) { + ob->scaflag &= ~OB_ADDSENS; sens= new_sensor(SENS_ALWAYS); - BLI_addtail(&(base->object->sensors), sens); + BLI_addtail(&(ob->sensors), sens); make_unique_prop_names(sens->name); - base->object->scaflag |= OB_SHOWSENS; + ob->scaflag |= OB_SHOWSENS; } - base= base->next; } BIF_undo_push("Add sensor"); @@ -460,9 +457,8 @@ void do_logic_buts(unsigned short event) break; case B_CHANGE_SENS: - base= FIRSTBASE; - while(base) { - sens= base->object->sensors.first; + for(ob=G.main->object.first; ob; ob=ob->id.next) { + sens= ob->sensors.first; while(sens) { if(sens->type != sens->otype) { init_sensor(sens); @@ -471,43 +467,39 @@ void do_logic_buts(unsigned short event) } sens= sens->next; } - base= base->next; } allqueue(REDRAWBUTSLOGIC, 0); break; case B_DEL_SENS: - base= FIRSTBASE; - while(base) { - sens= base->object->sensors.first; + for(ob=G.main->object.first; ob; ob=ob->id.next) { + sens= ob->sensors.first; while(sens) { if(sens->flag & SENS_DEL) { - BLI_remlink(&(base->object->sensors), sens); + BLI_remlink(&(ob->sensors), sens); free_sensor(sens); break; } sens= sens->next; } - base= base->next; } BIF_undo_push("Delete sensor"); allqueue(REDRAWBUTSLOGIC, 0); break; case B_ADD_CONT: - base= FIRSTBASE; - while(base) { - if(base->object->scaflag & OB_ADDCONT) { - base->object->scaflag &= ~OB_ADDCONT; + for(ob=G.main->object.first; ob; ob=ob->id.next) { + if(ob->scaflag & OB_ADDCONT) { + ob->scaflag &= ~OB_ADDCONT; cont= new_controller(CONT_LOGIC_AND); make_unique_prop_names(cont->name); - base->object->scaflag |= OB_SHOWCONT; - BLI_addtail(&(base->object->controllers), cont); + ob->scaflag |= OB_SHOWCONT; + BLI_addtail(&(ob->controllers), cont); /* set the controller state mask from the current object state. A controller is always in a single state, so select the lowest bit set from the object state */ for (bit=0; bit<32; bit++) { - if (base->object->state & (1<<bit)) + if (ob->state & (1<<bit)) break; } cont->state_mask = (1<<bit); @@ -516,42 +508,36 @@ void do_logic_buts(unsigned short event) cont->state_mask = 1; } } - base= base->next; } BIF_undo_push("Add controller"); allqueue(REDRAWBUTSLOGIC, 0); break; case B_SET_STATE_BIT: - base= FIRSTBASE; - while(base) { - if(base->object->scaflag & OB_SETSTBIT) { - base->object->scaflag &= ~OB_SETSTBIT; - base->object->state = 0x3FFFFFFF; + for(ob=G.main->object.first; ob; ob=ob->id.next) { + if(ob->scaflag & OB_SETSTBIT) { + ob->scaflag &= ~OB_SETSTBIT; + ob->state = 0x3FFFFFFF; } - base= base->next; } allqueue(REDRAWBUTSLOGIC, 0); break; case B_INIT_STATE_BIT: - base= FIRSTBASE; - while(base) { - if(base->object->scaflag & OB_INITSTBIT) { - base->object->scaflag &= ~OB_INITSTBIT; - base->object->state = base->object->init_state; - if (!base->object->state) - base->object->state = 1; + for(ob=G.main->object.first; ob; ob=ob->id.next) { + if(ob->scaflag & OB_INITSTBIT) { + ob->scaflag &= ~OB_INITSTBIT; + ob->state = ob->init_state; + if (!ob->state) + ob->state = 1; } - base= base->next; } allqueue(REDRAWBUTSLOGIC, 0); break; case B_CHANGE_CONT: - base= FIRSTBASE; - while(base) { - cont= base->object->controllers.first; + for(ob=G.main->object.first; ob; ob=ob->id.next) { + cont= ob->controllers.first; while(cont) { if(cont->type != cont->otype) { init_controller(cont); @@ -560,51 +546,45 @@ void do_logic_buts(unsigned short event) } cont= cont->next; } - base= base->next; } allqueue(REDRAWBUTSLOGIC, 0); break; case B_DEL_CONT: - base= FIRSTBASE; - while(base) { - cont= base->object->controllers.first; + for(ob=G.main->object.first; ob; ob=ob->id.next) { + cont= ob->controllers.first; while(cont) { if(cont->flag & CONT_DEL) { - BLI_remlink(&(base->object->controllers), cont); + BLI_remlink(&(ob->controllers), cont); unlink_controller(cont); free_controller(cont); break; } cont= cont->next; } - base= base->next; } BIF_undo_push("Delete controller"); allqueue(REDRAWBUTSLOGIC, 0); break; case B_ADD_ACT: - base= FIRSTBASE; - while(base) { - if(base->object->scaflag & OB_ADDACT) { - base->object->scaflag &= ~OB_ADDACT; + for(ob=G.main->object.first; ob; ob=ob->id.next) { + if(ob->scaflag & OB_ADDACT) { + ob->scaflag &= ~OB_ADDACT; act= new_actuator(ACT_OBJECT); make_unique_prop_names(act->name); - BLI_addtail(&(base->object->actuators), act); - base->object->scaflag |= OB_SHOWACT; + BLI_addtail(&(ob->actuators), act); + ob->scaflag |= OB_SHOWACT; } - base= base->next; } BIF_undo_push("Add actuator"); allqueue(REDRAWBUTSLOGIC, 0); break; case B_CHANGE_ACT: - base= FIRSTBASE; - while(base) { - act= base->object->actuators.first; + for(ob=G.main->object.first; ob; ob=ob->id.next) { + act= ob->actuators.first; while(act) { if(act->type != act->otype) { init_actuator(act); @@ -613,25 +593,22 @@ void do_logic_buts(unsigned short event) } act= act->next; } - base= base->next; } allqueue(REDRAWBUTSLOGIC, 0); break; case B_DEL_ACT: - base= FIRSTBASE; - while(base) { - act= base->object->actuators.first; + for(ob=G.main->object.first; ob; ob=ob->id.next) { + act= ob->actuators.first; while(act) { if(act->flag & ACT_DEL) { - BLI_remlink(&(base->object->actuators), act); + BLI_remlink(&(ob->actuators), act); unlink_actuator(act); free_actuator(act); break; } act= act->next; } - base= base->next; } BIF_undo_push("Delete actuator"); allqueue(REDRAWBUTSLOGIC, 0); @@ -640,10 +617,8 @@ void do_logic_buts(unsigned short event) case B_SOUNDACT_BROWSE: /* since we don't know which... */ didit= 0; - base= FIRSTBASE; - while(base) - { - act= base->object->actuators.first; + for(ob=G.main->object.first; ob; ob=ob->id.next) { + act= ob->actuators.first; while(act) { if(act->type==ACT_SOUND) @@ -684,7 +659,6 @@ void do_logic_buts(unsigned short event) } if(didit) break; - base= base->next; } allqueue(REDRAWBUTSLOGIC, 0); allqueue(REDRAWSOUND, 0); @@ -707,6 +681,8 @@ static char *sensor_name(int type) return "Keyboard"; case SENS_PROPERTY: return "Property"; + case SENS_ACTUATOR: + return "Actuator"; case SENS_MOUSE: return "Mouse"; case SENS_COLLISION: @@ -730,7 +706,7 @@ static char *sensor_pup(void) /* the number needs to match defines in game.h */ return "Sensors %t|Always %x0|Keyboard %x3|Mouse %x5|" "Touch %x1|Collision %x6|Near %x2|Radar %x7|" - "Property %x4|Random %x8|Ray %x9|Message %x10|Joystick %x11"; + "Property %x4|Random %x8|Ray %x9|Message %x10|Joystick %x11|Actuator %x12"; } static char *controller_name(int type) @@ -1029,6 +1005,7 @@ static int get_col_sensor(int type) case SENS_NEAR: return TH_BUT_SETTING1; case SENS_KEYBOARD: return TH_BUT_SETTING2; case SENS_PROPERTY: return TH_BUT_NUM; + case SENS_ACTUATOR: return TH_BUT_NUM; case SENS_MOUSE: return TH_BUT_TEXTFIELD; case SENS_RADAR: return TH_BUT_POPUP; case SENS_RANDOM: return TH_BUT_NEUTRAL; @@ -1093,6 +1070,7 @@ static short draw_sensorbuttons(bSensor *sens, uiBlock *block, short xco, short bRaySensor *raySens = NULL; bMessageSensor *mes = NULL; bJoystickSensor *joy = NULL; + bActuatorSensor *as = NULL; short ysize; char *str; @@ -1303,6 +1281,22 @@ static short draw_sensorbuttons(bSensor *sens, uiBlock *block, short xco, short yco-= ysize; break; } + case SENS_ACTUATOR: + { + ysize= 48; + + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, + (float)xco+width, (float)yco, 1); + + draw_default_sensor_header(sens, block, xco, yco, width); + as= sens->data; + + uiDefBut(block, TEX, 1, "Act: ", xco+30,yco-44,width-60, 19, + as->name, 0, 31, 0, 0, "Actuator name, actuator active state modifications will be detected"); + yco-= ysize; + break; + } case SENS_MOUSE: { ms= sens->data; @@ -1563,6 +1557,48 @@ static void set_col_actuator(int item, int medium) } +static void change_object_actuator(void *act, void *arg) +{ + bObjectActuator *oa = act; + + if (oa->type != oa->otype) { + switch (oa->type) { + case ACT_OBJECT_NORMAL: + memset(oa, 0, sizeof(bObjectActuator)); + oa->flag = ACT_FORCE_LOCAL|ACT_TORQUE_LOCAL|ACT_DLOC_LOCAL|ACT_DROT_LOCAL; + oa->type = ACT_OBJECT_NORMAL; + break; + + case ACT_OBJECT_SERVO: + memset(oa, 0, sizeof(bObjectActuator)); + oa->flag = ACT_LIN_VEL_LOCAL; + oa->type = ACT_OBJECT_SERVO; + oa->forcerot[0] = 30.0f; + oa->forcerot[1] = 0.5f; + oa->forcerot[2] = 0.0f; + break; + } + } +} + +static void change_ipo_actuator(void *arg1_but, void *arg2_ia) +{ + bIpoActuator *ia = arg2_ia; + uiBut *but = arg1_but; + + if (but->retval & ACT_IPOFORCE) + ia->flag &= ~ACT_IPOADD; + else if (but->retval & ACT_IPOADD) + ia->flag &= ~ACT_IPOFORCE; + but->retval = B_REDR; +} + +void update_object_actuator_PID(void *act, void *arg) +{ + bObjectActuator *oa = act; + oa->forcerot[0] = 60.0f*oa->forcerot[1]; +} + char *get_state_name(Object *ob, short bit) { bController *cont; @@ -1604,6 +1640,7 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh short ysize = 0, wval; char *str; int myline, stbit; + uiBut *but; /* yco is at the top of the rect, draw downwards */ uiBlockSetEmboss(block, UI_EMBOSSM); @@ -1613,57 +1650,100 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh { case ACT_OBJECT: { - ysize= 152; - - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - oa = act->data; wval = (width-100)/3; - - uiDefBut(block, LABEL, 0, "Force", xco, yco-22, 55, 19, NULL, 0, 0, 0, 0, "Sets the force"); - uiDefButF(block, NUM, 0, "", xco+45, yco-22, wval, 19, oa->forceloc, -10000.0, 10000.0, 10, 0, ""); - uiDefButF(block, NUM, 0, "", xco+45+wval, yco-22, wval, 19, oa->forceloc+1, -10000.0, 10000.0, 10, 0, ""); - uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-22, wval, 19, oa->forceloc+2, -10000.0, 10000.0, 10, 0, ""); - - uiDefBut(block, LABEL, 0, "Torque", xco, yco-41, 55, 19, NULL, 0, 0, 0, 0, "Sets the torque"); - uiDefButF(block, NUM, 0, "", xco+45, yco-41, wval, 19, oa->forcerot, -10000.0, 10000.0, 10, 0, ""); - uiDefButF(block, NUM, 0, "", xco+45+wval, yco-41, wval, 19, oa->forcerot+1, -10000.0, 10000.0, 10, 0, ""); - uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-41, wval, 19, oa->forcerot+2, -10000.0, 10000.0, 10, 0, ""); - - uiDefBut(block, LABEL, 0, "dLoc", xco, yco-64, 45, 19, NULL, 0, 0, 0, 0, "Sets the dLoc"); - uiDefButF(block, NUM, 0, "", xco+45, yco-64, wval, 19, oa->dloc, -10000.0, 10000.0, 10, 0, ""); - uiDefButF(block, NUM, 0, "", xco+45+wval, yco-64, wval, 19, oa->dloc+1, -10000.0, 10000.0, 10, 0, ""); - uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-64, wval, 19, oa->dloc+2, -10000.0, 10000.0, 10, 0, ""); - - uiDefBut(block, LABEL, 0, "dRot", xco, yco-83, 45, 19, NULL, 0, 0, 0, 0, "Sets the dRot"); - uiDefButF(block, NUM, 0, "", xco+45, yco-83, wval, 19, oa->drot, -10000.0, 10000.0, 10, 0, ""); - uiDefButF(block, NUM, 0, "", xco+45+wval, yco-83, wval, 19, oa->drot+1, -10000.0, 10000.0, 10, 0, ""); - uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-83, wval, 19, oa->drot+2, -10000.0, 10000.0, 10, 0, ""); - - uiDefBut(block, LABEL, 0, "linV", xco, yco-106, 45, 19, NULL, 0, 0, 0, 0, "Sets the linear velocity"); - uiDefButF(block, NUM, 0, "", xco+45, yco-106, wval, 19, oa->linearvelocity, -10000.0, 10000.0, 10, 0, ""); - uiDefButF(block, NUM, 0, "", xco+45+wval, yco-106, wval, 19, oa->linearvelocity+1, -10000.0, 10000.0, 10, 0, ""); - uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-106, wval, 19, oa->linearvelocity+2, -10000.0, 10000.0, 10, 0, ""); - - uiDefBut(block, LABEL, 0, "angV", xco, yco-125, 45, 19, NULL, 0, 0, 0, 0, "Sets the angular velocity"); - uiDefButF(block, NUM, 0, "", xco+45, yco-125, wval, 19, oa->angularvelocity, -10000.0, 10000.0, 10, 0, ""); - uiDefButF(block, NUM, 0, "", xco+45+wval, yco-125, wval, 19, oa->angularvelocity+1, -10000.0, 10000.0, 10, 0, ""); - uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-125, wval, 19, oa->angularvelocity+2, -10000.0, 10000.0, 10, 0, ""); - - uiDefBut(block, LABEL, 0, "damp", xco, yco-148, 45, 19, NULL, 0, 0, 0, 0, "Number of frames to reach the target velocity"); - uiDefButI(block, NUM, 0, "", xco+45, yco-148, wval, 19, &oa->damping, 0.0, 1000.0, 100, 0, ""); - uiDefButBitS(block, TOG, ACT_CLAMP_VEL, 0, "clamp",xco+45+wval, yco-148, wval, 19, &oa->flag, 0.0, 0.0, 0, 0, "Toggles between SET and CLAMP Velocity"); - - uiDefButBitS(block, TOG, ACT_FORCE_LOCAL, 0, "L", xco+45+3*wval, yco-22, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); - uiDefButBitS(block, TOG, ACT_TORQUE_LOCAL, 0, "L", xco+45+3*wval, yco-41, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); - uiDefButBitS(block, TOG, ACT_DLOC_LOCAL, 0, "L", xco+45+3*wval, yco-64, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); - uiDefButBitS(block, TOG, ACT_DROT_LOCAL, 0, "L", xco+45+3*wval, yco-83, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); - uiDefButBitS(block, TOG, ACT_LIN_VEL_LOCAL, 0, "L", xco+45+3*wval, yco-106, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); - uiDefButBitS(block, TOG, ACT_ANG_VEL_LOCAL, 0, "L", xco+45+3*wval, yco-125, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); - - uiDefButBitS(block, TOG, ACT_ADD_LIN_VEL, 0, "add",xco+45+3*wval+15, yco-106, 35, 19, &oa->flag, 0.0, 0.0, 0, 0, "Toggles between ADD and SET linV"); - + if (oa->type == ACT_OBJECT_NORMAL) + { + ysize= 175; + + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + uiDefBut(block, LABEL, 0, "Force", xco, yco-45, 55, 19, NULL, 0, 0, 0, 0, "Sets the force"); + uiDefButF(block, NUM, 0, "", xco+45, yco-45, wval, 19, oa->forceloc, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45+wval, yco-45, wval, 19, oa->forceloc+1, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-45, wval, 19, oa->forceloc+2, -10000.0, 10000.0, 10, 0, ""); + + uiDefBut(block, LABEL, 0, "Torque", xco, yco-64, 55, 19, NULL, 0, 0, 0, 0, "Sets the torque"); + uiDefButF(block, NUM, 0, "", xco+45, yco-64, wval, 19, oa->forcerot, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45+wval, yco-64, wval, 19, oa->forcerot+1, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-64, wval, 19, oa->forcerot+2, -10000.0, 10000.0, 10, 0, ""); + + uiDefBut(block, LABEL, 0, "dLoc", xco, yco-87, 45, 19, NULL, 0, 0, 0, 0, "Sets the dLoc"); + uiDefButF(block, NUM, 0, "", xco+45, yco-87, wval, 19, oa->dloc, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45+wval, yco-87, wval, 19, oa->dloc+1, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-87, wval, 19, oa->dloc+2, -10000.0, 10000.0, 10, 0, ""); + + uiDefBut(block, LABEL, 0, "dRot", xco, yco-106, 45, 19, NULL, 0, 0, 0, 0, "Sets the dRot"); + uiDefButF(block, NUM, 0, "", xco+45, yco-106, wval, 19, oa->drot, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45+wval, yco-106, wval, 19, oa->drot+1, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-106, wval, 19, oa->drot+2, -10000.0, 10000.0, 10, 0, ""); + + uiDefBut(block, LABEL, 0, "linV", xco, yco-129, 45, 19, NULL, 0, 0, 0, 0, "Sets the linear velocity"); + uiDefButF(block, NUM, 0, "", xco+45, yco-129, wval, 19, oa->linearvelocity, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45+wval, yco-129, wval, 19, oa->linearvelocity+1, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-129, wval, 19, oa->linearvelocity+2, -10000.0, 10000.0, 10, 0, ""); + + uiDefBut(block, LABEL, 0, "angV", xco, yco-148, 45, 19, NULL, 0, 0, 0, 0, "Sets the angular velocity"); + uiDefButF(block, NUM, 0, "", xco+45, yco-148, wval, 19, oa->angularvelocity, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45+wval, yco-148, wval, 19, oa->angularvelocity+1, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-148, wval, 19, oa->angularvelocity+2, -10000.0, 10000.0, 10, 0, ""); + + uiDefBut(block, LABEL, 0, "damp", xco, yco-171, 45, 19, NULL, 0, 0, 0, 0, "Number of frames to reach the target velocity"); + uiDefButS(block, NUM, 0, "", xco+45, yco-171, wval, 19, &oa->damping, 0.0, 1000.0, 100, 0, ""); + + uiDefButBitS(block, TOG, ACT_FORCE_LOCAL, 0, "L", xco+45+3*wval, yco-45, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); + uiDefButBitS(block, TOG, ACT_TORQUE_LOCAL, 0, "L", xco+45+3*wval, yco-64, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); + uiDefButBitS(block, TOG, ACT_DLOC_LOCAL, 0, "L", xco+45+3*wval, yco-87, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); + uiDefButBitS(block, TOG, ACT_DROT_LOCAL, 0, "L", xco+45+3*wval, yco-106, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); + uiDefButBitS(block, TOG, ACT_LIN_VEL_LOCAL, 0, "L", xco+45+3*wval, yco-129, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); + uiDefButBitS(block, TOG, ACT_ANG_VEL_LOCAL, 0, "L", xco+45+3*wval, yco-148, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); + + uiDefButBitS(block, TOG, ACT_ADD_LIN_VEL, 0, "add",xco+45+3*wval+15, yco-129, 35, 19, &oa->flag, 0.0, 0.0, 0, 0, "Toggles between ADD and SET linV"); + + } else if (oa->type == ACT_OBJECT_SERVO) + { + ysize= 172; + + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + uiDefBut(block, LABEL, 0, "linV", xco, yco-45, 45, 19, NULL, 0, 0, 0, 0, "Sets the target linear velocity, it will be achieve by automatic application of force. Null velocity is a valid target"); + uiDefButF(block, NUM, 0, "", xco+45, yco-45, wval, 19, oa->linearvelocity, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45+wval, yco-45, wval, 19, oa->linearvelocity+1, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-45, wval, 19, oa->linearvelocity+2, -10000.0, 10000.0, 10, 0, ""); + uiDefButBitS(block, TOG, ACT_LIN_VEL_LOCAL, 0, "L", xco+45+3*wval, yco-45, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Velocity is defined in local coordinates"); + + uiDefBut(block, LABEL, 0, "Limit", xco, yco-68, 45, 19, NULL, 0, 0, 0, 0, "Select if the force need to be limited along certain axis (local or global depending on LinV Local flag)"); + uiDefButBitS(block, TOG, ACT_SERVO_LIMIT_X, B_REDR, "X", xco+45, yco-68, wval, 19, &oa->flag, 0.0, 0.0, 0, 0, "Set limit to force along the X axis"); + uiDefButBitS(block, TOG, ACT_SERVO_LIMIT_Y, B_REDR, "Y", xco+45+wval, yco-68, wval, 19, &oa->flag, 0.0, 0.0, 0, 0, "Set limit to force along the Y axis"); + uiDefButBitS(block, TOG, ACT_SERVO_LIMIT_Z, B_REDR, "Z", xco+45+2*wval, yco-68, wval, 19, &oa->flag, 0.0, 0.0, 0, 0, "Set limit to force along the Z axis"); + uiDefBut(block, LABEL, 0, "Max", xco, yco-87, 45, 19, NULL, 0, 0, 0, 0, "Set the upper limit for force"); + uiDefBut(block, LABEL, 0, "Min", xco, yco-106, 45, 19, NULL, 0, 0, 0, 0, "Set the lower limit for force"); + if (oa->flag & ACT_SERVO_LIMIT_X) { + uiDefButF(block, NUM, 0, "", xco+45, yco-87, wval, 19, oa->dloc, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45, yco-106, wval, 19, oa->drot, -10000.0, 10000.0, 10, 0, ""); + } + if (oa->flag & ACT_SERVO_LIMIT_Y) { + uiDefButF(block, NUM, 0, "", xco+45+wval, yco-87, wval, 19, oa->dloc+1, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45+wval, yco-106, wval, 19, oa->drot+1, -10000.0, 10000.0, 10, 0, ""); + } + if (oa->flag & ACT_SERVO_LIMIT_Z) { + uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-87, wval, 19, oa->dloc+2, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-106, wval, 19, oa->drot+2, -10000.0, 10000.0, 10, 0, ""); + } + uiDefBut(block, LABEL, 0, "Servo", xco, yco-129, 45, 19, NULL, 0, 0, 0, 0, "Coefficients of the PID servo controller"); + uiDefButF(block, NUMSLI, B_REDR, "P: ", xco+45, yco-129, wval*3, 19, oa->forcerot, 0.00, 200.0, 100, 0, "Proportional coefficient, typical value is 60x Integral coefficient"); + uiDefBut(block, LABEL, 0, "Slow", xco, yco-148, 45, 19, NULL, 0, 0, 0, 0, "Low value of I coefficient correspond to slow response"); + but = uiDefButF(block, NUMSLI, B_REDR, " I : ", xco+45, yco-148, wval*3, 19, oa->forcerot+1, 0.0, 3.0, 1, 0, "Integral coefficient, low value (0.01) for slow response, high value (0.5) for fast response"); + uiButSetFunc(but, update_object_actuator_PID, oa, NULL); + uiDefBut(block, LABEL, 0, "Fast", xco+45+3*wval, yco-148, 45, 19, NULL, 0, 0, 0, 0, "High value of I coefficient correspond to fast response"); + uiDefButF(block, NUMSLI, B_REDR, "D: ", xco+45, yco-167, wval*3, 19, oa->forcerot+2, -100.0, 100.0, 100, 0, "Derivate coefficient, not required, high values can cause instability"); + } + str= "Motion Type %t|Simple motion %x0|Servo Control %x1"; + but = uiDefButS(block, MENU, B_REDR, str, xco+40, yco-23, (width-80), 19, &oa->type, 0.0, 0.0, 0, 0, ""); + oa->otype = oa->type; + uiButSetFunc(but, change_object_actuator, oa, NULL); yco-= ysize; break; } @@ -1689,23 +1769,27 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh #else str= "Action types %t|Play %x0|Flipper %x2|Loop Stop %x3|Loop End %x4|Property %x6"; #endif - uiDefButS(block, MENU, B_REDR, str, xco+30, yco-24, (width-60)/2, 19, &aa->type, 0.0, 0.0, 0.0, 0.0, "Action playback type"); - uiDefIDPoinBut(block, test_actionpoin_but, ID_AC, 1, "AC: ", xco+30 + ((width-60)/2), yco-24, (width-60)/2, 19, &aa->act, "Action name"); + uiDefButS(block, MENU, B_REDR, str, xco+10, yco-24, width/3, 19, &aa->type, 0.0, 0.0, 0.0, 0.0, "Action playback type"); + uiDefIDPoinBut(block, test_actionpoin_but, ID_AC, 1, "AC: ", xco+10+ (width/3), yco-24, ((width/3)*2) - (20 + 60), 19, &aa->act, "Action name"); + + uiDefButBitS(block, TOGN, 1, 0, "Continue", xco+((width/3)*2)+20, yco-24, 60, 19, + &aa->end_reset, 0.0, 0.0, 0, 0, "Restore last frame when switching on/off, otherwise play from the start each time"); + if(aa->type == ACT_ACTION_FROM_PROP) { - uiDefBut(block, TEX, 0, "Prop: ",xco+30, yco-44, width-60, 19, aa->name, 0.0, 31.0, 0, 0, "Use this property to define the Action position"); + uiDefBut(block, TEX, 0, "Prop: ",xco+10, yco-44, width-20, 19, aa->name, 0.0, 31.0, 0, 0, "Use this property to define the Action position"); } else { - uiDefButI(block, NUM, 0, "Sta: ",xco+30, yco-44, (width-60)/2, 19, &aa->sta, 0.0, MAXFRAMEF, 0, 0, "Start frame"); - uiDefButI(block, NUM, 0, "End: ",xco+30+(width-60)/2, yco-44, (width-60)/2, 19, &aa->end, 0.0, MAXFRAMEF, 0, 0, "End frame"); + uiDefButI(block, NUM, 0, "Sta: ",xco+10, yco-44, (width-20)/2, 19, &aa->sta, 0.0, MAXFRAMEF, 0, 0, "Start frame"); + uiDefButI(block, NUM, 0, "End: ",xco+10+(width-20)/2, yco-44, (width-20)/2, 19, &aa->end, 0.0, MAXFRAMEF, 0, 0, "End frame"); } - uiDefButI(block, NUM, 0, "Blendin: ", xco+30, yco-64, (width-60)/2, 19, &aa->blendin, 0.0, MAXFRAMEF, 0.0, 0.0, "Number of frames of motion blending"); - uiDefButS(block, NUM, 0, "Priority: ", xco+30+(width-60)/2, yco-64, (width-60)/2, 19, &aa->priority, 0.0, 100.0, 0.0, 0.0, "Execution priority - lower numbers will override actions with higher numbers, With 2 or more actions at once, the overriding channels must be lower in the stack"); + uiDefButS(block, NUM, 0, "Blendin: ", xco+10, yco-64, (width-20)/2, 19, &aa->blendin, 0.0, 32767, 0.0, 0.0, "Number of frames of motion blending"); + uiDefButS(block, NUM, 0, "Priority: ", xco+10+(width-20)/2, yco-64, (width-20)/2, 19, &aa->priority, 0.0, 100.0, 0.0, 0.0, "Execution priority - lower numbers will override actions with higher numbers, With 2 or more actions at once, the overriding channels must be lower in the stack"); - uiDefBut(block, TEX, 0, "FrameProp: ",xco+30, yco-84, width-60, 19, aa->frameProp, 0.0, 31.0, 0, 0, "Assign this property this actions current frame number"); + uiDefBut(block, TEX, 0, "FrameProp: ",xco+10, yco-84, width-20, 19, aa->frameProp, 0.0, 31.0, 0, 0, "Assign this property this actions current frame number"); #ifdef __NLA_ACTION_BY_MOTION_ACTUATOR @@ -1731,42 +1815,49 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh str = "Ipo types %t|Play %x0|Ping Pong %x1|Flipper %x2|Loop Stop %x3|Loop End %x4|Property %x6"; - uiDefButS(block, MENU, B_REDR, str, xco+20, yco-24, width-40 - (width-40)/3, 19, &ia->type, 0, 0, 0, 0, ""); - uiDefButBitS(block, TOG, ACT_IPOCHILD, B_REDR, - "Child", xco+20+0.666*(width-40), yco-24, (width-40)/3, 19, + uiDefButS(block, MENU, B_REDR, str, xco+10, yco-24, (width-20)/2, 19, &ia->type, 0, 0, 0, 0, ""); + + but = uiDefButBitS(block, TOG, ACT_IPOFORCE, ACT_IPOFORCE, + "Force", xco+10+(width-20)/2, yco-24, (width-20)/4-10, 19, &ia->flag, 0, 0, 0, 0, - "Add all children Objects as well"); + "Convert Ipo to force. Force is applied in global or local coordinate according to Local flag"); + uiButSetFunc(but, change_ipo_actuator, but, ia); + + but = uiDefButBitS(block, TOG, ACT_IPOADD, ACT_IPOADD, + "Add", xco+3*(width-20)/4, yco-24, (width-20)/4-10, 19, + &ia->flag, 0, 0, 0, 0, + "Ipo is added to the current loc/rot/scale in global or local coordinate according to Local flag"); + uiButSetFunc(but, change_ipo_actuator, but, ia); + + /* Only show the do-force-local toggle if force is requested */ + if (ia->flag & (ACT_IPOFORCE|ACT_IPOADD)) { + uiDefButBitS(block, TOG, ACT_IPOLOCAL, 0, + "L", xco+width-30, yco-24, 20, 19, + &ia->flag, 0, 0, 0, 0, + "Let the ipo acts in local coordinates, used in Force and Add mode."); + } if(ia->type==ACT_IPO_FROM_PROP) { uiDefBut(block, TEX, 0, - "Prop: ", xco+20, yco-44, width-40, 19, + "Prop: ", xco+10, yco-44, width-80, 19, ia->name, 0.0, 31.0, 0, 0, "Use this property to define the Ipo position"); } else { uiDefButI(block, NUM, 0, - "Sta", xco+20, yco-44, (width-100)/2, 19, + "Sta", xco+10, yco-44, (width-80)/2, 19, &ia->sta, 0.0, MAXFRAMEF, 0, 0, - "Start frame"); + "Start frame, (subtract 1 to match blenders frame numbers)"); uiDefButI(block, NUM, 0, - "End", xco+18+(width-90)/2, yco-44, (width-100)/2, 19, + "End", xco+10+(width-80)/2, yco-44, (width-80)/2, 19, &ia->end, 0.0, MAXFRAMEF, 0, 0, - "End frame"); - - uiDefButBitS(block, TOG, ACT_IPOFORCE, B_REDR, - "Force", xco+width-78, yco-44, 43, 19, - &ia->flag, 0, 0, 0, 0, - "Convert Ipo to force"); - - /* Only show the do-force-local toggle if force is requested */ - if (ia->flag & ACT_IPOFORCE) { - uiDefButBitS(block, TOG, ACT_IPOFORCE_LOCAL, 0, - "L", xco+width-35, yco-44, 15, 19, - &ia->flag, 0, 0, 0, 0, - "Let the force-ipo act in local coordinates."); - } - + "End frame, (subtract 1 to match blenders frame numbers)"); } + uiDefButBitS(block, TOG, ACT_IPOCHILD, B_REDR, + "Child", xco+10+(width-80), yco-44, 60, 19, + &ia->flag, 0, 0, 0, 0, + "Update IPO on all children Objects as well"); + yco-= ysize; break; } @@ -1898,7 +1989,7 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh glRects(xco, yco-ysize, xco+width, yco); uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:", xco+10, yco-44, (width-20)/2, 19, &(eoa->ob), "Add this Object (cant be on an visible layer)"); + uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:", xco+10, yco-44, (width-20)/2, 19, &(eoa->ob), "Add this Object and all its children (cant be on an visible layer)"); uiDefButI(block, NUM, 0, "Time:", xco+10+(width-20)/2, yco-44, (width-20)/2, 19, &eoa->time, 0.0, 2000.0, 0, 0, "Duration the new Object lives"); wval= (width-60)/3; @@ -1956,34 +2047,97 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh break; case ACT_CONSTRAINT: + coa= act->data; - ysize= 44; + if (coa->type == ACT_CONST_TYPE_LOC) { + ysize= 69; - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + /* str= "Limit %t|None %x0|Loc X %x1|Loc Y %x2|Loc Z %x4|Rot X %x8|Rot Y %x16|Rot Z %x32"; */ + /* coa->flag &= ~(63); */ + str= "Limit %t|None %x0|Loc X %x1|Loc Y %x2|Loc Z %x4"; + coa->flag &= ~(7); + coa->time = 0; + uiDefButS(block, MENU, 1, str, xco+10, yco-65, 70, 19, &coa->flag, 0.0, 0.0, 0, 0, ""); - coa= act->data; + uiDefButS(block, NUM, 0, "Damp:", xco+10, yco-45, 70, 19, &coa->damp, 0.0, 100.0, 0, 0, ""); + uiDefBut(block, LABEL, 0, "Min", xco+80, yco-45, (width-90)/2, 19, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, LABEL, 0, "Max", xco+80+(width-90)/2, yco-45, (width-90)/2, 19, NULL, 0.0, 0.0, 0, 0, ""); + + if(coa->flag & ACT_CONST_LOCX) fp= coa->minloc; + else if(coa->flag & ACT_CONST_LOCY) fp= coa->minloc+1; + else if(coa->flag & ACT_CONST_LOCZ) fp= coa->minloc+2; + else if(coa->flag & ACT_CONST_ROTX) fp= coa->minrot; + else if(coa->flag & ACT_CONST_ROTY) fp= coa->minrot+1; + else fp= coa->minrot+2; + + uiDefButF(block, NUM, 0, "", xco+80, yco-65, (width-90)/2, 19, fp, -2000.0, 2000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+80+(width-90)/2, yco-65, (width-90)/2, 19, fp+3, -2000.0, 2000.0, 10, 0, ""); + } else if (coa->type == ACT_CONST_TYPE_DIST) { + ysize= 106; + + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + str= "Direction %t|None %x0|X axis %x1|Y axis %x2|Z axis %x4|-X axis %x8|-Y axis %x16|-Z axis %x32"; + uiDefButS(block, MENU, B_REDR, str, xco+10, yco-65, 70, 19, &coa->mode, 0.0, 0.0, 0, 0, "Set the direction of the ray"); -/* str= "Limit %t|None %x0|Loc X %x1|Loc Y %x2|Loc Z %x4|Rot X %x8|Rot Y %x16|Rot Z %x32"; */ - str= "Limit %t|None %x0|Loc X %x1|Loc Y %x2|Loc Z %x4"; - uiDefButS(block, MENU, 1, str, xco+10, yco-40, 70, 19, &coa->flag, 0.0, 0.0, 0, 0, ""); - - uiDefButS(block, NUM, 0, "Damp:", xco+10, yco-20, 70, 19, &coa->damp, 0.0, 100.0, 0, 0, ""); - uiDefBut(block, LABEL, 0, "Min", xco+80, yco-20, (width-90)/2, 19, NULL, 0.0, 0.0, 0, 0, ""); - uiDefBut(block, LABEL, 0, "Max", xco+80+(width-90)/2, yco-20, (width-90)/2, 19, NULL, 0.0, 0.0, 0, 0, ""); - - if(coa->flag & ACT_CONST_LOCX) fp= coa->minloc; - else if(coa->flag & ACT_CONST_LOCY) fp= coa->minloc+1; - else if(coa->flag & ACT_CONST_LOCZ) fp= coa->minloc+2; - else if(coa->flag & ACT_CONST_ROTX) fp= coa->minrot; - else if(coa->flag & ACT_CONST_ROTY) fp= coa->minrot+1; - else fp= coa->minrot+2; + uiDefButS(block, NUM, 0, "Damp:", xco+10, yco-45, 70, 19, &coa->damp, 0.0, 100.0, 0, 0, ""); + uiDefBut(block, LABEL, 0, "Range", xco+80, yco-45, (width-115)/2, 19, NULL, 0.0, 0.0, 0, 0, "Set the maximum length of ray"); + uiDefButBitS(block, TOG, ACT_CONST_DISTANCE, B_REDR, "Dist", xco+80+(width-115)/2, yco-45, (width-115)/2, 19, &coa->flag, 0.0, 0.0, 0, 0, "Force distance of object to point of impact of ray"); + + if(coa->mode & (ACT_CONST_DIRPX|ACT_CONST_DIRMX)) fp= coa->minloc; + else if(coa->mode & (ACT_CONST_DIRPY|ACT_CONST_DIRMY)) fp= coa->minloc+1; + else fp= coa->minloc+2; + + uiDefButF(block, NUM, 0, "", xco+80, yco-65, (width-115)/2, 19, fp+3, 0.0, 2000.0, 10, 0, "Maximum length of ray"); + if (coa->flag & ACT_CONST_DISTANCE) + uiDefButF(block, NUM, 0, "", xco+80+(width-115)/2, yco-65, (width-115)/2, 19, fp, -2000.0, 2000.0, 10, 0, "Keep this distance to target"); + uiDefButBitS(block, TOG, ACT_CONST_NORMAL, 0, "N", xco+80+(width-115), yco-65, 25, 19, + &coa->flag, 0.0, 0.0, 0, 0, "Set object axis along the normal at hit position"); + uiDefButBitS(block, TOG, ACT_CONST_MATERIAL, B_REDR, "M/P", xco+10, yco-84, 40, 19, + &coa->flag, 0.0, 0.0, 0, 0, "Detect material instead of property"); + if (coa->flag & ACT_CONST_MATERIAL) + { + uiDefBut(block, TEX, 1, "Material:", xco + 50, yco-84, (width-60), 19, + coa->matprop, 0, 31, 0, 0, + "Ray detects only Objects with this material"); + } + else + { + uiDefBut(block, TEX, 1, "Property:", xco + 50, yco-84, (width-60), 19, + coa->matprop, 0, 31, 0, 0, + "Ray detect only Objects with this property"); + } + uiDefButBitS(block, TOG, ACT_CONST_PERMANENT, 0, "PER", xco+10, yco-103, 40, 19, + &coa->flag, 0.0, 0.0, 0, 0, "Persistent actuator: stays active even if ray does not reach target"); + uiDefButS(block, NUM, 0, "time", xco+50, yco-103, (width-60)/2, 19, &(coa->time), 0.0, 1000.0, 0, 0, "Maximum activation time in frame, 0 for unlimited"); + uiDefButS(block, NUM, 0, "rotDamp", xco+50+(width-60)/2, yco-103, (width-60)/2, 19, &(coa->rotdamp), 0.0, 100.0, 0, 0, "Use a different damping for orientation"); + } else if (coa->type == ACT_CONST_TYPE_ORI) { + ysize= 87; + + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + str= "Direction %t|None %x0|X axis %x1|Y axis %x2|Z axis %x4"; + uiDefButS(block, MENU, B_REDR, str, xco+10, yco-65, 70, 19, &coa->mode, 0.0, 0.0, 0, 0, "Select the axis to be aligned along the reference direction"); - uiDefButF(block, NUM, 0, "", xco+80, yco-40, (width-90)/2, 19, fp, -2000.0, 2000.0, 10, 0, ""); - uiDefButF(block, NUM, 0, "", xco+80+(width-90)/2, yco-40, (width-90)/2, 19, fp+3, -2000.0, 2000.0, 10, 0, ""); + uiDefButS(block, NUM, 0, "Damp:", xco+10, yco-45, 70, 19, &coa->damp, 0.0, 100.0, 0, 0, ""); + uiDefBut(block, LABEL, 0, "X", xco+80, yco-45, (width-115)/3, 19, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, LABEL, 0, "Y", xco+80+(width-115)/3, yco-45, (width-115)/3, 19, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, LABEL, 0, "Z", xco+80+2*(width-115)/3, yco-45, (width-115)/3, 19, NULL, 0.0, 0.0, 0, 0, ""); + uiDefButF(block, NUM, 0, "", xco+80, yco-65, (width-115)/3, 19, &coa->maxrot[0], -2000.0, 2000.0, 10, 0, "X component of reference direction"); + uiDefButF(block, NUM, 0, "", xco+80+(width-115)/3, yco-65, (width-115)/3, 19, &coa->maxrot[1], -2000.0, 2000.0, 10, 0, "Y component of reference direction"); + uiDefButF(block, NUM, 0, "", xco+80+2*(width-115)/3, yco-65, (width-115)/3, 19, &coa->maxrot[2], -2000.0, 2000.0, 10, 0, "Z component of reference direction"); + + uiDefButS(block, NUM, 0, "time", xco+10, yco-84, 70+(width-115)/3, 19, &(coa->time), 0.0, 1000.0, 0, 0, "Maximum activation time in frame, 0 for unlimited"); + } + str= "Constraint Type %t|Location %x0|Distance %x1|Orientation %x2"; + but = uiDefButS(block, MENU, B_REDR, str, xco+40, yco-23, (width-80), 19, &coa->type, 0.0, 0.0, 0, 0, ""); yco-= ysize; - break; case ACT_SCENE: @@ -2116,7 +2270,7 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh uiDefBut(block, TEX, 0, "Prop: ", xco+20, yco-44, width-40, 19, ga->name, 0.0, 31.0, 0, 0, "Use this property to define the Group position"); } else { - uiDefButI(block, NUM, 0, "Sta", xco+20, yco-44, (width-40)/2, 19, &ga->sta, 0.0, 2500.0, 0, 0, "Start frame"); + uiDefButI(block, NUM, 0, "State", xco+20, yco-44, (width-40)/2, 19, &ga->sta, 0.0, 2500.0, 0, 0, "Start frame"); uiDefButI(block, NUM, 0, "End", xco+20+(width-40)/2, yco-44, (width-40)/2, 19, &ga->end, 0.0, 2500.0, 0, 0, "End frame"); } yco-= ysize; @@ -2382,11 +2536,7 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh break; case ACT_2DFILTER_CUSTOMFILTER: uiDefButI(block, NUM, B_REDR, "Pass Number:", xco+30,yco-44,width-60,19,&tdfa->int_arg,0.0,MAX_RENDER_PASS-1,0.0,0.0,"Set motion blur value"); - uiDefIDPoinBut(block, test_scriptpoin_but, ID_SCRIPT, 1, "Script: ", xco+30,yco-64,width/2-32, 19, &tdfa->text, ""); - uiDefButS(block, TOG|BIT|0, B_REDR, "Depth", xco+width/2+2 , yco - 64, width/4-16 , 19, - &tdfa->texture_flag, 0.0, 0.0, 0, 0, "Includes Depth Texture (bgl_DepthTexture)"); - uiDefButS(block, TOG|BIT|1, B_REDR, "Luminance", xco+3*width/4-14 , yco - 64, width/4-16 , 19, - &tdfa->texture_flag, 0.0, 0.0, 0, 0, "Includes Luminance Texture (bgl_LuminanceTexture)"); + uiDefIDPoinBut(block, test_scriptpoin_but, ID_SCRIPT, 1, "Script: ", xco+30,yco-64,width-60, 19, &tdfa->text, ""); break; } @@ -2994,6 +3144,8 @@ void logic_buts(void) ob= OBACT; for(a=0; a<count; a++) { + unsigned int controller_state_mask = 0; /* store a bitmask for states that are used */ + ob= (Object *)idar[a]; uiClearButLock(); uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE); @@ -3018,6 +3170,7 @@ void logic_buts(void) act = cont->links[iact]; act->flag |= ACT_LINKED; } + controller_state_mask |= cont->state_mask; cont = cont->next; } @@ -3032,11 +3185,11 @@ void logic_buts(void) for (offset=0; offset<15; offset+=5) { uiBlockBeginAlign(block); for (stbit=0; stbit<5; stbit++) { - but = uiDefButBitI(block, TOG, 1<<(stbit+offset), stbit+offset, "", (short)(xco+35+12*stbit+13*offset), yco, 12, 12, (int *)&(ob->state), 0, 0, 0, 0, get_state_name(ob, (short)(stbit+offset))); + but = uiDefButBitI(block, controller_state_mask&(1<<(stbit+offset)) ? BUT_TOGDUAL:TOG, 1<<(stbit+offset), stbit+offset, "", (short)(xco+35+12*stbit+13*offset), yco, 12, 12, (int *)&(ob->state), 0, 0, 0, 0, get_state_name(ob, (short)(stbit+offset))); uiButSetFunc(but, check_object_state, but, &(ob->state)); } for (stbit=0; stbit<5; stbit++) { - but = uiDefButBitI(block, TOG, 1<<(stbit+offset+15), stbit+offset+15, "", (short)(xco+35+12*stbit+13*offset), yco-12, 12, 12, (int *)&(ob->state), 0, 0, 0, 0, get_state_name(ob, (short)(stbit+offset+15))); + but = uiDefButBitI(block, controller_state_mask&(1<<(stbit+offset+15)) ? BUT_TOGDUAL:TOG, 1<<(stbit+offset+15), stbit+offset+15, "", (short)(xco+35+12*stbit+13*offset), yco-12, 12, 12, (int *)&(ob->state), 0, 0, 0, 0, get_state_name(ob, (short)(stbit+offset+15))); uiButSetFunc(but, check_object_state, but, &(ob->state)); } } @@ -3120,7 +3273,7 @@ void logic_buts(void) uiDefButBitS(block, TOG, BUTS_SENS_SEL, B_REDR, "Sel", xco+80, yco+35, (width-70)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show all selected Objects"); uiDefButBitS(block, TOG, BUTS_SENS_ACT, B_REDR, "Act", xco+80+(width-70)/4, yco+35, (width-70)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show active Object"); uiDefButBitS(block, TOG, BUTS_SENS_LINK, B_REDR, "Link", xco+80+2*(width-70)/4, yco+35, (width-70)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show linked Objects to Controller"); - uiDefButBitS(block, TOG, BUTS_SENS_STATE, B_REDR, "Sta", xco+80+3*(width-70)/4, yco+35, (width-70)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show only sensors connected to active states"); + uiDefButBitS(block, TOG, BUTS_SENS_STATE, B_REDR, "State", xco+80+3*(width-70)/4, yco+35, (width-70)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show only sensors connected to active states"); uiBlockEndAlign(block); for(a=0; a<count; a++) { @@ -3193,7 +3346,7 @@ void logic_buts(void) uiDefButBitS(block, TOG, BUTS_ACT_SEL, B_REDR, "Sel", xco+110, yco+35, (width-100)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show all selected Objects"); uiDefButBitS(block, TOG, BUTS_ACT_ACT, B_REDR, "Act", xco+110+(width-100)/4, yco+35, (width-100)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show active Object"); uiDefButBitS(block, TOG, BUTS_ACT_LINK, B_REDR, "Link", xco+110+2*(width-100)/4, yco+35, (width-100)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show linked Objects to Controller"); - uiDefButBitS(block, TOG, BUTS_ACT_STATE, B_REDR, "Sta", xco+110+3*(width-100)/4, yco+35, (width-100)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show only actuators connected to active states"); + uiDefButBitS(block, TOG, BUTS_ACT_STATE, B_REDR, "State", xco+110+3*(width-100)/4, yco+35, (width-100)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show only actuators connected to active states"); uiBlockEndAlign(block); for(a=0; a<count; a++) { ob= (Object *)idar[a]; diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index ba409723784..ebe770c89e7 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -4812,7 +4812,7 @@ static void object_panel_particle_system(Object *ob) uiDefBut(block, LABEL, 0, "Basic:", butx,(buty-=buth),butw,buth, NULL, 0.0, 0, 0, 0, ""); uiBlockBeginAlign(block); - if(part->distr==PART_DISTR_GRID) + if(part->distr==PART_DISTR_GRID && part->from != PART_FROM_VERT) uiDefButI(block, NUM, B_PART_ALLOC, "Resol:", butx,(buty-=buth),butw,buth, &part->grid_res, 1.0, 100.0, 0, 0, "The resolution of the particle grid"); else uiDefButI(block, NUM, B_PART_ALLOC, "Amount:", butx,(buty-=buth),butw,buth, &part->totpart, 0.0, 100000.0, 0, 0, "The total number of particles"); diff --git a/source/blender/src/buttons_scene.c b/source/blender/src/buttons_scene.c index 1c98950080a..af90d01fb59 100644 --- a/source/blender/src/buttons_scene.c +++ b/source/blender/src/buttons_scene.c @@ -499,7 +499,7 @@ static char* seq_panel_blend_modes() so that would collide also. */ - if (!(last_seq->type & SEQ_EFFECT)) { + if ( seq_can_blend(last_seq) ) { int i; for (i = SEQ_EFFECT; i <= SEQ_EFFECT_MAX; i++) { diff --git a/source/blender/src/buttons_shading.c b/source/blender/src/buttons_shading.c index 04a497ffdea..1b580381ca5 100644 --- a/source/blender/src/buttons_shading.c +++ b/source/blender/src/buttons_shading.c @@ -2803,6 +2803,42 @@ static void lamp_panel_yafray(Object *ob, Lamp *la) } +static void lamp_panel_atmosphere(Object *ob, Lamp *la) +{ + uiBlock *block; + int y; + block= uiNewBlock(&curarea->uiblocks, "lamp_panel_atm", UI_EMBOSS, UI_HELV, curarea->win); + uiNewPanelTabbed("Shadow and Spot", "Lamp"); + if(uiNewPanel(curarea, block, "Sky/Atmosphere", "Lamp", 3*PANELX, PANELY, PANELW, PANELH)==0) return; + + uiSetButLock(la->id.lib!=0, ERROR_LIBDATA_MESSAGE); + + uiDefButBitS(block, TOG, LA_SUN_EFFECT_SKY, REDRAWVIEW3D, "Sky", 10,205,BUTW2,20,&(la->sun_effect_type), 0, 0, 0, 0, "Apply sun light effect on sky."); + uiDefButBitS(block, TOG, LA_SUN_EFFECT_AP, REDRAWVIEW3D, "Atmosphere", 20+BUTW2,205,BUTW2,20,&(la->sun_effect_type), 0, 0, 0, 0, "Apply sun light effect on atmosphere."); + + if(la->sun_effect_type & (LA_SUN_EFFECT_SKY|LA_SUN_EFFECT_AP)){ + uiDefButF(block, NUM, B_LAMPREDRAW, "Turbidity:",10,180,BUTW1,19, &(la->atm_turbidity), 1.000f, 30.0f, 1, 0, "Sky Turbidity"); + } + + y = 180; + if(la->sun_effect_type & LA_SUN_EFFECT_SKY) + { + uiDefButF(block, NUM, B_LAMPREDRAW, "Hor.Bright:",10,y-25,BUTW2,19, &(la->horizon_brightness), 0.00f, 20.00f, 10, 0, "Sets horizon brightness."); + uiDefButF(block, NUM, B_LAMPREDRAW, "Hor.Spread:",10,y-50,BUTW2,19, &(la->spread), 0.00f, 10.00f, 10, 0, "Sets horizon spread."); + uiDefButF(block, NUM, B_LAMPREDRAW, "Sun Bright:",10,y-75,BUTW2,19, &(la->sun_brightness), 0.00f, 10.0f, 10, 0, "Sets sun brightness."); + uiDefButF(block, NUM, B_LAMPREDRAW, "Sun Size:",10,y-100,BUTW2,19, &(la->sun_size), 0.00f, 10.00f, 10, 0, "Sets sun size."); + uiDefButF(block, NUM, B_LAMPREDRAW, "Back Light:",10,y-125,BUTW2,19, &(la->backscattered_light), -1.00f, 1.00f, 10, 0, "Sets backscatter light."); + } + + if(la->sun_effect_type & LA_SUN_EFFECT_AP) + { + uiDefButF(block, NUM, B_LAMPREDRAW, "Sun Intens.:",20+BUTW2,y-25,BUTW2,19, &(la->sun_intensity), 0.00f, 10.00f, 10, 0, "Sets sun intensity."); + uiDefButF(block, NUM, B_LAMPREDRAW, "Inscattering:",20+BUTW2,y-50,BUTW2,19, &(la->atm_inscattering_factor), 0.00f, 1.00f, 10, 0, "In Scattering Contribution Factor."); + uiDefButF(block, NUM, B_LAMPREDRAW, "Extinction:",20+BUTW2,y-75,BUTW2,19, &(la->atm_extinction_factor), 0.00f, 1.00f, 10, 0, "Extinction Scattering Contribution Factor."); + uiDefButF(block, NUM, B_LAMPREDRAW, "Distance:",20+BUTW2,y-100,BUTW2,19, &(la->atm_distance_factor), 0.000f, 500.0f, 10, 0, "Scale blender distance to real distance."); + } +} + static void lamp_panel_falloff(Object *ob, Lamp *la) { uiBlock *block; @@ -2864,15 +2900,15 @@ static void lamp_panel_lamp(Object *ob, Lamp *la) uiBlockSetCol(block, TH_BUT_SETTING1); uiDefButS(block, MENU, B_LAMPREDRAW, "Falloff %t|Constant %x0|Inverse Linear %x1|Inverse Square %x2|Custom Curve %x3|Lin/Quad Weighted %x4|", 10,150,100,19, &la->falloff_type, 0,0,0,0, "Lamp falloff - intensity decay with distance"); - uiDefButBitS(block, TOG, LA_SPHERE, REDRAWVIEW3D,"Sphere", 10,130,100,19,&la->mode, 0, 0, 0, 0, "Sets light intensity to zero for objects beyond the distance value"); + uiDefButBitS(block, TOG, LA_SPHERE, B_LAMPPRV,"Sphere", 10,130,100,19,&la->mode, 0, 0, 0, 0, "Sets light intensity to zero for objects beyond the distance value"); } uiBlockBeginAlign(block); uiBlockSetCol(block, TH_BUT_SETTING1); uiDefButBitS(block, TOG, LA_LAYER, 0,"Layer", 10,70,100,19,&la->mode, 0, 0, 0, 0, "Illuminates objects in the same layer as the lamp only"); uiDefButBitS(block, TOG, LA_NEG, B_LAMPPRV,"Negative", 10,50,100,19,&la->mode, 0, 0, 0, 0, "Sets lamp to cast negative light"); - uiDefButBitS(block, TOG, LA_NO_DIFF, 0,"No Diffuse", 10,30,100,19,&la->mode, 0, 0, 0, 0, "Disables diffuse shading of material illuminated by this lamp"); - uiDefButBitS(block, TOG, LA_NO_SPEC, 0,"No Specular", 10,10,100,19,&la->mode, 0, 0, 0, 0, "Disables specular shading of material illuminated by this lamp"); + uiDefButBitS(block, TOG, LA_NO_DIFF, B_LAMPPRV,"No Diffuse", 10,30,100,19,&la->mode, 0, 0, 0, 0, "Disables diffuse shading of material illuminated by this lamp"); + uiDefButBitS(block, TOG, LA_NO_SPEC, B_LAMPPRV,"No Specular", 10,10,100,19,&la->mode, 0, 0, 0, 0, "Disables specular shading of material illuminated by this lamp"); uiBlockEndAlign(block); uiBlockSetCol(block, TH_AUTO); @@ -4354,6 +4390,11 @@ void lamp_panels() /* spherelight radius default is zero, so nothing to do */ lamp_panel_yafray(ob, la); } + + if(la->type == LA_SUN){ + lamp_panel_atmosphere(ob, ob->data); + } + lamp_panel_texture(ob, ob->data); lamp_panel_mapto(ob, ob->data); diff --git a/source/blender/src/drawaction.c b/source/blender/src/drawaction.c index 89466151a39..6fe37c1c6e5 100644 --- a/source/blender/src/drawaction.c +++ b/source/blender/src/drawaction.c @@ -32,6 +32,7 @@ #include <math.h> #include <stdlib.h> +#include <string.h> #ifdef HAVE_CONFIG_H #include <config.h> @@ -56,6 +57,7 @@ #include "DNA_space_types.h" #include "DNA_constraint_types.h" #include "DNA_key_types.h" +#include "DNA_userdef_types.h" #include "BKE_action.h" #include "BKE_depsgraph.h" @@ -928,12 +930,55 @@ static void draw_channel_strips(void) void do_actionbuts(unsigned short event) { switch(event) { + /* general */ case REDRAWVIEW3D: allqueue(REDRAWVIEW3D, 0); break; case B_REDR: allqueue(REDRAWACTION, 0); break; + + /* action-groups */ + case B_ACTCUSTCOLORS: /* only when of the color wells is edited */ + { + bActionGroup *agrp= get_active_actiongroup(G.saction->action); + + if (agrp) + agrp->customCol= -1; + + allqueue(REDRAWACTION, 0); + } + break; + case B_ACTCOLSSELECTOR: /* sync color set after using selector */ + { + bActionGroup *agrp= get_active_actiongroup(G.saction->action); + + if (agrp) + actionbone_group_copycolors(agrp, 1); + + allqueue(REDRAWACTION, 0); + } + break; + case B_ACTGRP_SELALL: /* select all grouped channels */ + { + bAction *act= G.saction->action; + bActionGroup *agrp= get_active_actiongroup(act); + + /* select all in group, then reselect/activate group as the previous operation clears that */ + select_action_group_channels(act, agrp); + agrp->flag |= (AGRP_ACTIVE|AGRP_SELECTED); + + allqueue(REDRAWACTION, 0); + } + break; + case B_ACTGRP_ADDTOSELF: /* add all selected action channels to self */ + action_groups_group(0); + break; + case B_ACTGRP_UNGROUP: /* remove channels from active group */ + // FIXME: todo... + printf("FIXME: remove achans from active Action-Group not implemented yet! \n"); + break; + } } @@ -941,14 +986,68 @@ void do_actionbuts(unsigned short event) static void action_panel_properties(short cntrl) // ACTION_HANDLER_PROPERTIES { uiBlock *block; - + void *data; + short datatype; + block= uiNewBlock(&curarea->uiblocks, "action_panel_properties", UI_EMBOSS, UI_HELV, curarea->win); uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl); uiSetPanelHandler(ACTION_HANDLER_PROPERTIES); // for close and esc - if (uiNewPanel(curarea, block, "Transform Properties", "Action", 10, 230, 318, 204)==0) + + /* get datatype */ + data= get_action_context(&datatype); + //if (data == NULL) return; + + if (uiNewPanel(curarea, block, "Active Channel Properties", "Action", 10, 230, 318, 204)==0) return; - - uiDefBut(block, LABEL, 0, "test text", 10,180,300,19, 0, 0, 0, 0, 0, ""); + + /* currently, only show data for actions */ + if (datatype == ACTCONT_ACTION) { + bActionGroup *agrp= get_active_actiongroup(data); + //bActionChannel *achan= get_hilighted_action_channel(data); + char *menustr; + + /* only for action-groups */ + if (agrp) { + /* general stuff */ + uiDefBut(block, LABEL, 1, "Action Group:", 10, 180, 150, 19, NULL, 0.0, 0.0, 0, 0, ""); + + uiDefBut(block, TEX, B_REDR, "Name: ", 10,160,150,20, agrp->name, 0.0, 31.0, 0, 0, ""); + uiBlockBeginAlign(block); + uiDefButBitI(block, TOG, AGRP_EXPANDED, B_REDR, "Expanded", 170, 160, 75, 20, &agrp->flag, 0, 0, 0, 0, "Action Group is expanded"); + uiDefButBitI(block, TOG, AGRP_PROTECTED, B_REDR, "Protected", 245, 160, 75, 20, &agrp->flag, 0, 0, 0, 0, "Action Group is protected"); + uiBlockEndAlign(block); + + /* color stuff */ + uiDefBut(block, LABEL, 1, "Group Colors:", 10, 107, 150, 19, NULL, 0.0, 0.0, 0, 0, ""); + uiBlockBeginAlign(block); + menustr= BIF_ThemeColorSetsPup(1); + uiDefButI(block, MENU,B_ACTCOLSSELECTOR, menustr, 10,85,150,19, &agrp->customCol, -1, 20, 0.0, 0.0, "Index of set of Custom Colors to shade Group's bones with. 0 = Use Default Color Scheme, -1 = Use Custom Color Scheme"); + MEM_freeN(menustr); + + /* show color-selection/preview */ + if (agrp->customCol) { + /* do color copying/init (to stay up to date) */ + actionbone_group_copycolors(agrp, 1); + + /* color changing */ + uiDefButC(block, COL, B_ACTCUSTCOLORS, "", 10, 65, 50, 19, agrp->cs.active, 0, 0, 0, 0, "Color to use for 'top-level' channels"); + uiDefButC(block, COL, B_ACTCUSTCOLORS, "", 60, 65, 50, 19, agrp->cs.select, 0, 0, 0, 0, "Color to use for '2nd-level' channels"); + uiDefButC(block, COL, B_ACTCUSTCOLORS, "", 110, 65, 50, 19, agrp->cs.solid, 0, 0, 0, 0, "Color to use for '3rd-level' channels"); + } + uiBlockEndAlign(block); + + /* commands for active group */ + uiDefBut(block, BUT, B_ACTGRP_SELALL, "Select Grouped", 170,85,150,20, 0, 21, 0, 0, 0, "Select all action-channels belonging to this group (same as doing Ctrl-Shift-LMB)"); + + uiBlockBeginAlign(block); + uiDefBut(block, BUT, B_ACTGRP_ADDTOSELF, "Add to Group", 170,60,150,20, 0, 21, 0, 0, 0, "Add selected action-channels to this group"); + uiDefBut(block, BUT, B_ACTGRP_UNGROUP, "Un-Group", 170,40,150,20, 0, 21, 0, 0, 0, "Remove selected action-channels from this group (unimplemented)"); + uiBlockEndAlign(block); + } + } + else { + /* Currently, there isn't anything to display for these types ... */ + } } static void action_blockhandlers(ScrArea *sa) diff --git a/source/blender/src/drawarmature.c b/source/blender/src/drawarmature.c index 73915a69139..6d78b21dfbb 100644 --- a/source/blender/src/drawarmature.c +++ b/source/blender/src/drawarmature.c @@ -2500,7 +2500,7 @@ static void draw_ghost_poses(Base *base) /* ********************************** Armature Drawing - Main ************************* */ /* called from drawobject.c, return 1 if nothing was drawn */ -int draw_armature(Base *base, int dt) +int draw_armature(Base *base, int dt, int flag) { Object *ob= base->object; bArmature *arm= ob->data; @@ -2544,15 +2544,16 @@ int draw_armature(Base *base, int dt) if (arm->ghostep) draw_ghost_poses(base); } + if ((flag & DRAW_SCENESET)==0) { + if(ob==OBACT) + arm->flag |= ARM_POSEMODE; + else if(G.f & G_WEIGHTPAINT) + arm->flag |= ARM_POSEMODE; - if(ob==OBACT) - arm->flag |= ARM_POSEMODE; - else if(G.f & G_WEIGHTPAINT) - arm->flag |= ARM_POSEMODE; - - draw_pose_paths(ob); + draw_pose_paths(ob); + } } - } + } draw_pose_channels(base, dt); arm->flag &= ~ARM_POSEMODE; diff --git a/source/blender/src/drawimage.c b/source/blender/src/drawimage.c index 547de85e856..14849cdd450 100644 --- a/source/blender/src/drawimage.c +++ b/source/blender/src/drawimage.c @@ -422,7 +422,7 @@ int draw_uvs_face_check(void) return 1; } } else { - if (G.sima->flag & SI_SELACTFACE) { + if (G.sima->selectmode == SI_SELECT_FACE) { return 1; } } diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c index 96ba8c71755..045bf292446 100644 --- a/source/blender/src/drawobject.c +++ b/source/blender/src/drawobject.c @@ -4620,7 +4620,7 @@ static void drawSolidSelect(Base *base) } else if(ob->type==OB_ARMATURE) { if(!(ob->flag & OB_POSEMODE)) { - draw_armature(base, OB_WIRE); + draw_armature(base, OB_WIRE, 0); } } @@ -4741,7 +4741,7 @@ void drawRBpivot(bRigidBodyJointConstraint *data){ setlinestyle(0); } -/* flag can be DRAW_PICKING and/or DRAW_CONSTCOLOR */ +/* flag can be DRAW_PICKING and/or DRAW_CONSTCOLOR, DRAW_SCENESET */ void draw_object(Base *base, int flag) { static int warning_recursive= 0; @@ -4943,7 +4943,7 @@ void draw_object(Base *base, int flag) /* draw outline for selected solid objects, mesh does itself */ if((G.vd->flag & V3D_SELECT_OUTLINE) && ob->type!=OB_MESH) { - if(dt>OB_WIRE && dt<OB_TEXTURE && ob!=G.obedit) { + if(dt>OB_WIRE && dt<OB_TEXTURE && ob!=G.obedit && (flag && DRAW_SCENESET)==0) { if (!(ob->dtx&OB_DRAWWIRE) && (ob->flag&SELECT) && !(flag&DRAW_PICKING)) { drawSolidSelect(base); } @@ -5090,7 +5090,7 @@ void draw_object(Base *base, int flag) break; case OB_ARMATURE: if(dt>OB_WIRE) set_gl_material(0); // we use defmaterial - empty_object= draw_armature(base, dt); + empty_object= draw_armature(base, dt, flag); break; default: drawaxes(1.0, flag, OB_ARROWS); diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c index 2f1cdb8b951..f595a101f63 100644 --- a/source/blender/src/drawview.c +++ b/source/blender/src/drawview.c @@ -3097,7 +3097,7 @@ void drawview3dspace(ScrArea *sa, void *spacedata) if(v3d->lay & base->lay) { BIF_ThemeColorBlend(TH_WIRE, TH_BACK, 0.6f); - draw_object(base, DRAW_CONSTCOLOR); + draw_object(base, DRAW_CONSTCOLOR|DRAW_SCENESET); if(base->object->transflag & OB_DUPLI) { draw_dupli_objects_color(v3d, base, TH_WIRE); @@ -3319,7 +3319,7 @@ void drawview3d_render(struct View3D *v3d, int winx, int winy, float winmat[][4] where_is_object(base->object); BIF_ThemeColorBlend(TH_WIRE, TH_BACK, 0.6f); - draw_object(base, DRAW_CONSTCOLOR); + draw_object(base, DRAW_CONSTCOLOR|DRAW_SCENESET); if(base->object->transflag & OB_DUPLI) { draw_dupli_objects(v3d, base); diff --git a/source/blender/src/editaction.c b/source/blender/src/editaction.c index f93a1526e3c..4cc0e52ce3f 100644 --- a/source/blender/src/editaction.c +++ b/source/blender/src/editaction.c @@ -1114,6 +1114,38 @@ void action_groups_ungroup (void) allqueue(REDRAWACTION, 0); } +/* Copy colors from a specified theme's color set to an Action/Bone Group */ +void actionbone_group_copycolors (bActionGroup *grp, short init_new) +{ + /* error checking */ + if (grp == NULL) + return; + + /* only do color copying if using a custom color */ + if (grp->customCol) { + if (grp->customCol > 0) { + /* copy theme colors on-to group's custom color in case user tries to edit color */ + bTheme *btheme= U.themes.first; + ThemeWireColor *col_set= &btheme->tarm[(grp->customCol - 1)]; + + memcpy(&grp->cs, col_set, sizeof(ThemeWireColor)); + } + else if (init_new) { + /* init custom colors with a generic multi-color rgb set, if not initialised already (and allowed to do so) */ + if (grp->cs.solid[0] == 0) { + /* define for setting colors in theme below */ + #define SETCOL(col, r, g, b, a) col[0]=r; col[1]=g; col[2]= b; col[3]= a; + + SETCOL(grp->cs.solid, 0xff, 0x00, 0x00, 255); + SETCOL(grp->cs.select, 0x81, 0xe6, 0x14, 255); + SETCOL(grp->cs.active, 0x18, 0xb6, 0xe0, 255); + + #undef SETCOL + } + } + } +} + /* This function is used when inserting keyframes for pose-channels. It assigns the * action-channel with the nominated name to a group with the same name as that of * the pose-channel with the nominated name. @@ -1160,34 +1192,9 @@ void verify_pchan2achan_grouping (bAction *act, bPose *pose, char name[]) /* copy name */ sprintf(grp->name, agrp->name); - /* deal with group-color copying */ - if (agrp->customCol) { - if (agrp->customCol > 0) { - /* copy theme colors on-to group's custom color in case user tries to edit color */ - bTheme *btheme= U.themes.first; - ThemeWireColor *col_set= &btheme->tarm[(agrp->customCol - 1)]; - - memcpy(&grp->cs, col_set, sizeof(ThemeWireColor)); - } - else { - /* init custom colors with a generic multi-color rgb set, if not initialised already */ - if (agrp->cs.solid[0] == 0) { - /* define for setting colors in theme below */ - #define SETCOL(col, r, g, b, a) col[0]=r; col[1]=g; col[2]= b; col[3]= a; - - SETCOL(grp->cs.solid, 0xff, 0x00, 0x00, 255); - SETCOL(grp->cs.select, 0x81, 0xe6, 0x14, 255); - SETCOL(grp->cs.active, 0x18, 0xb6, 0xe0, 255); - - #undef SETCOL - } - else { - /* just copy color set specified */ - memcpy(&grp->cs, &agrp->cs, sizeof(ThemeWireColor)); - } - } - } - grp->customCol= agrp->customCol; + /* deal with group-color copying (grp is destination, agrp is source) */ + memcpy(grp, agrp, sizeof(bActionGroup)); + actionbone_group_copycolors(grp, 1); BLI_addtail(&act->groups, grp); } @@ -2697,6 +2704,28 @@ int select_icu_channel(bAction *act, IpoCurve *icu, int selectmode) return flag; } + +/* select only the active action-group's action channels */ +void select_action_group_channels (bAction *act, bActionGroup *agrp) +{ + bActionChannel *achan; + + /* error checking */ + if (ELEM(NULL, act, agrp)) + return; + + /* deselect all other channels */ + deselect_actionchannels(act, 0); + + /* only select channels in group */ + for (achan= agrp->channels.first; achan && achan->grp==agrp; achan= achan->next) { + select_channel(act, achan, SELECT_ADD); + + /* messy... set active bone */ + select_poseelement_by_name(achan->name, 1); + } +} + /* ----------------------------------------- */ /* De-selects or inverts the selection of Channels in a given Action @@ -3672,17 +3701,8 @@ static void mouse_actionchannels (short mval[]) select_action_group(act, agrp, SELECT_INVERT); } else if (G.qual == (LR_CTRLKEY|LR_SHIFTKEY)) { - bActionChannel *achan; - /* select all in group (and deselect everthing else) */ - deselect_actionchannels(act, 0); - - for (achan= agrp->channels.first; achan && achan->grp==agrp; achan= achan->next) { - select_channel(act, achan, SELECT_ADD); - - /* messy... set active bone */ - select_poseelement_by_name(achan->name, 1); - } + select_action_group_channels(act, agrp); select_action_group(act, agrp, SELECT_ADD); } else { @@ -4682,11 +4702,13 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt) case NKEY: if (G.qual==0) { - numbuts_action(); - - /* no panel (yet). current numbuts are not easy to put in panel... */ - //add_blockhandler(curarea, ACTION_HANDLER_PROPERTIES, UI_PNL_TO_MOUSE); - //scrarea_queue_winredraw(curarea); + /* panel will not always show useful info! */ + if (mval[0] > ACTWIDTH) { + add_blockhandler(curarea, ACTION_HANDLER_PROPERTIES, UI_PNL_TO_MOUSE); + scrarea_queue_winredraw(curarea); + } + else + numbuts_action(); } break; diff --git a/source/blender/src/editarmature.c b/source/blender/src/editarmature.c index 39f93510358..6310dd0a262 100644 --- a/source/blender/src/editarmature.c +++ b/source/blender/src/editarmature.c @@ -1646,8 +1646,9 @@ void load_editArmature(void) } /* toggle==0: deselect - toggle==1: swap + toggle==1: swap (based on test) toggle==2: only active tag + toggle==3: swap (no test) */ void deselectall_armature(int toggle, int doundo) { @@ -1670,18 +1671,30 @@ void deselectall_armature(int toggle, int doundo) else sel= toggle; /* Set the flags */ - for (eBone=G.edbo.first;eBone;eBone=eBone->next){ - if (sel==1) { + for (eBone=G.edbo.first;eBone;eBone=eBone->next) { + if (sel==3) { + /* invert selection of bone */ + if ((arm->layer & eBone->layer) && (eBone->flag & BONE_HIDDEN_A)==0) { + eBone->flag ^= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); + eBone->flag &= ~BONE_ACTIVE; + } + } + else if (sel==1) { + /* select bone */ if(arm->layer & eBone->layer && (eBone->flag & BONE_HIDDEN_A)==0) { eBone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); if(eBone->parent) eBone->parent->flag |= (BONE_TIPSEL); } } - else if (sel==2) + else if (sel==2) { + /* clear active flag */ eBone->flag &= ~(BONE_ACTIVE); - else + } + else { + /* deselect bone */ eBone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL | BONE_ACTIVE); + } } allqueue(REDRAWVIEW3D, 0); @@ -3276,8 +3289,9 @@ int do_pose_selectbuffer(Base *base, unsigned int *buffer, short hits) } /* test==0: deselect all - test==1: swap select - test==2: only clear active tag + test==1: swap select (apply to all the opposite of current situation) + test==2: only clear active tag + test==3: swap select (no test / inverse selection status of all independently) */ void deselectall_posearmature (Object *ob, int test, int doundo) { @@ -3307,16 +3321,27 @@ void deselectall_posearmature (Object *ob, int test, int doundo) /* Set the flags accordingly */ for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { if ((pchan->bone->layer & arm->layer) && !(pchan->bone->flag & BONE_HIDDEN_P)) { - if (selectmode==0) pchan->bone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL|BONE_ACTIVE); - else if (selectmode==1) pchan->bone->flag |= BONE_SELECTED; - else pchan->bone->flag &= ~BONE_ACTIVE; + if (test==3) { + pchan->bone->flag ^= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL); + pchan->bone->flag &= ~BONE_ACTIVE; + } + else { + if (selectmode==0) pchan->bone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL|BONE_ACTIVE); + else if (selectmode==1) pchan->bone->flag |= BONE_SELECTED; + else pchan->bone->flag &= ~BONE_ACTIVE; + } } } /* action editor */ - deselect_actionchannels(ob->action, 0); /* deselects for sure */ - if (selectmode == 1) - deselect_actionchannels(ob->action, 1); /* swaps */ + if (test == 3) { + deselect_actionchannels(ob->action, 2); /* inverts selection */ + } + else { + deselect_actionchannels(ob->action, 0); /* deselects for sure */ + if (selectmode == 1) + deselect_actionchannels(ob->action, 1); /* swaps */ + } allqueue(REDRAWBUTSEDIT, 0); allqueue(REDRAWBUTSOBJECT, 0); diff --git a/source/blender/src/editmesh_add.c b/source/blender/src/editmesh_add.c index 952ae957f34..9516f39b05c 100644 --- a/source/blender/src/editmesh_add.c +++ b/source/blender/src/editmesh_add.c @@ -379,7 +379,7 @@ static EditFace *addface_from_edges(void) /* find the 4 edges */ for(eed= em->edges.first; eed; eed= eed->next) { - if(eed->f & SELECT) { + if( (eed->f & SELECT) || (eed->v1->f & eed->v2->f & SELECT) ) { if(eedar[0]==NULL) eedar[0]= eed; else if(eedar[1]==NULL) eedar[1]= eed; else if(eedar[2]==NULL) eedar[2]= eed; @@ -765,6 +765,7 @@ void addedgeface_mesh(void) /* if 4 edges exist, we just create the face, convex or not */ efa= addface_from_edges(); if(efa==NULL) { + /* the order of vertices can be anything, 6 cases to check */ if( convex(neweve[0]->co, neweve[1]->co, neweve[2]->co, neweve[3]->co) ) { efa= addfacelist(neweve[0], neweve[1], neweve[2], neweve[3], NULL, NULL); @@ -775,17 +776,16 @@ void addedgeface_mesh(void) else if( convex(neweve[0]->co, neweve[2]->co, neweve[1]->co, neweve[3]->co) ) { efa= addfacelist(neweve[0], neweve[2], neweve[1], neweve[3], NULL, NULL); } - - else if( convex(neweve[1]->co, neweve[2]->co, neweve[3]->co, neweve[0]->co) ) { - efa= addfacelist(neweve[1], neweve[2], neweve[3], neweve[0], NULL, NULL); + else if( convex(neweve[0]->co, neweve[1]->co, neweve[3]->co, neweve[2]->co) ) { + efa= addfacelist(neweve[0], neweve[1], neweve[3], neweve[2], NULL, NULL); } - else if( convex(neweve[1]->co, neweve[3]->co, neweve[0]->co, neweve[2]->co) ) { - efa= addfacelist(neweve[1], neweve[3], neweve[0], neweve[2], NULL, NULL); + else if( convex(neweve[0]->co, neweve[3]->co, neweve[2]->co, neweve[1]->co) ) { + efa= addfacelist(neweve[0], neweve[3], neweve[2], neweve[1], NULL, NULL); } - else if( convex(neweve[1]->co, neweve[3]->co, neweve[2]->co, neweve[0]->co) ) { - efa= addfacelist(neweve[1], neweve[3], neweve[2], neweve[0], NULL, NULL); + else if( convex(neweve[0]->co, neweve[3]->co, neweve[1]->co, neweve[2]->co) ) { + efa= addfacelist(neweve[0], neweve[3], neweve[1], neweve[2], NULL, NULL); } - else error("The selected vertices form a concave quad"); + else printf("cannot find nice quad from concave set of vertices\n"); } } } diff --git a/source/blender/src/editnla.c b/source/blender/src/editnla.c index d758f34949a..dbc0deecb2c 100644 --- a/source/blender/src/editnla.c +++ b/source/blender/src/editnla.c @@ -501,26 +501,47 @@ static void set_active_strip(Object *ob, bActionStrip *act) { bActionStrip *strip; + /* make sure all other strips are not active */ for (strip = ob->nlastrips.first; strip; strip=strip->next) strip->flag &= ~ACTSTRIP_ACTIVE; - if(act) { + /* act is new active strip */ + if (act) { + /* set active flag for this strip */ act->flag |= ACTSTRIP_ACTIVE; - - if(ob->action!=act->act) { - if(ob->action) ob->action->id.us--; - if(act->act->id.lib) { + + /* check if active action will still be the same one */ + if (ob->action != act->act) { + /* clear object's links with its current action (if present) */ + if (ob->action) { + ob->action->id.us--; + } + + /* only set object's action to active strip's action if possible */ + if (act->act->id.lib) { ob->action= NULL; } else { ob->action= act->act; id_us_plus(&ob->action->id); - } + } + + /* request redrawing in relevant spaces */ allqueue(REDRAWIPO, 0); allqueue(REDRAWVIEW3D, 0); allqueue(REDRAWACTION, 0); allqueue(REDRAWNLA, 0); - ob->ctime= -1234567.0f; // eveil! + + /* when only showing action (i.e. nla-override off), + * reset pose to restpose for armatures + */ + if ((ob->nlaflag & OB_NLA_OVERRIDE)==0) { + if (ob->type == OB_ARMATURE) + rest_pose(ob->pose); + } + + /* flush depsgraph */ + ob->ctime= -1234567.0f; // evil! DAG_object_flush_update(G.scene, ob, OB_RECALC_OB|OB_RECALC_DATA); } } diff --git a/source/blender/src/editseq.c b/source/blender/src/editseq.c index b9351f82d1e..f9432f8e69a 100644 --- a/source/blender/src/editseq.c +++ b/source/blender/src/editseq.c @@ -2135,12 +2135,25 @@ void del_seq(void) Sequence *seq; MetaStack *ms; Editing *ed; - - if(okee("Erase selected")==0) return; + int nothingSelected = TRUE; ed= G.scene->ed; if(ed==0) return; + seq=get_last_seq(); + if (seq && seq->flag & SELECT) { /* avoid a loop since this is likely to be selected */ + nothingSelected = FALSE; + } else { + for (seq = ed->seqbasep->first; seq; seq = seq->next) { + if (seq->flag & SELECT) { + nothingSelected = FALSE; + break; + } + } + } + + if(nothingSelected || okee("Erase selected")==0) return; + /* free imbufs of all dependent strips */ for(seq=ed->seqbasep->first; seq; seq=seq->next) if(seq->flag & SELECT) diff --git a/source/blender/src/editsima.c b/source/blender/src/editsima.c index 18a9803dcae..69070d61bf0 100644 --- a/source/blender/src/editsima.c +++ b/source/blender/src/editsima.c @@ -694,7 +694,7 @@ void mouse_select_sima(void) EditFace *efa; MTFace *tf, *nearesttf; EditFace *nearestefa=NULL; - int a, selectsticky, edgeloop, actface, nearestuv, nearestedge, i, shift; + int a, selectsticky, edgeloop, actface, nearestuv, nearestedge, i, shift, island=0; char sticky= 0; int flush = 0; /* 0 == dont flush, 1 == sel, -1 == desel; only use when selection sync is enabled */ unsigned int hitv[4], nearestv; @@ -706,7 +706,7 @@ void mouse_select_sima(void) edgeloop= G.qual & LR_ALTKEY; shift= G.qual & LR_SHIFTKEY; - + if (G.sima->flag & SI_SYNC_UVSEL) { /* copy from mesh */ if (G.scene->selectmode == SCE_SELECT_FACE) { @@ -718,7 +718,8 @@ void mouse_select_sima(void) } } else { /* normal operation */ - actface= G.sima->flag & SI_SELACTFACE; + actface= G.sima->selectmode == SI_SELECT_FACE; + island= G.sima->selectmode == SI_SELECT_ISLAND; switch(G.sima->sticky) { case SI_STICKY_LOC: @@ -761,6 +762,9 @@ void mouse_select_sima(void) if (nearestefa->v4) hitv[3]= nearestefa->v4->tmp.l; else hitv[3]= 0xFFFFFFFF; } + else if (island) { + + } else { find_nearest_uv(&nearesttf, &nearestefa, &nearestv, &nearestuv); if(nearesttf==NULL) @@ -774,7 +778,11 @@ void mouse_select_sima(void) } } - if(!edgeloop && shift) { + if (island) { + if(shift) select_linked_tface_uv(1); + else select_linked_tface_uv(0); + } + else if(!edgeloop && shift) { /* (de)select face */ if(actface) { if(simaFaceSel_Check(nearestefa, nearesttf)) { diff --git a/source/blender/src/editsound.c b/source/blender/src/editsound.c index 1cb7ec276cb..05eb094a7c2 100644 --- a/source/blender/src/editsound.c +++ b/source/blender/src/editsound.c @@ -148,7 +148,7 @@ void winqreadsoundspace(ScrArea *sa, void *spacedata, BWinEvent *evt) first= 0; CFRA= cfra; update_for_newframe(); - force_draw_plus(SPACE_VIEW3D, 1); + force_draw_all(0); } else PIL_sleep_ms(30); diff --git a/source/blender/src/edittime.c b/source/blender/src/edittime.c index 5a10ea65738..2c37a0eb20f 100644 --- a/source/blender/src/edittime.c +++ b/source/blender/src/edittime.c @@ -803,11 +803,11 @@ static void timeline_force_draw(short val) if(sa->spacetype==SPACE_VIEW3D) { if(sa==samin || (val & TIME_ALL_3D_WIN)) dodraw= 1; } - else if(ELEM6(sa->spacetype, SPACE_NLA, SPACE_IPO, SPACE_SEQ, SPACE_BUTS, SPACE_ACTION, SPACE_SOUND)) { + else if(ELEM5(sa->spacetype, SPACE_NLA, SPACE_IPO, SPACE_SEQ, SPACE_ACTION, SPACE_SOUND)) { if(val & TIME_ALL_ANIM_WIN) dodraw= 1; } else if(sa->spacetype==SPACE_BUTS) { - if(val & TIME_ALL_BUTS_WIN) dodraw= 1; + if(val & TIME_ALL_BUTS_WIN) dodraw= 2; } else if(sa->spacetype==SPACE_IMAGE) { if (val & TIME_ALL_IMAGE_WIN) dodraw = 1; diff --git a/source/blender/src/header_image.c b/source/blender/src/header_image.c index 7ac57cb839b..fac9e3af1af 100644 --- a/source/blender/src/header_image.c +++ b/source/blender/src/header_image.c @@ -1214,28 +1214,31 @@ void image_buttons(void) uiBlockBeginAlign(block); /* B_SEL_VERT & B_SEL_FACE are not defined here which is a bit bad, BUT it works even if image editor is fullscreen */ - uiDefIconButBitS(block, TOG, SCE_SELECT_VERTEX, B_SEL_VERT, ICON_VERTEXSEL, xco,0,XIC,YIC, &G.scene->selectmode, 1.0, 0.0, 0, 0, "Vertex select mode (Ctrl Tab 1)"); - xco+= XIC; + uiDefIconButBitS(block, TOG, SCE_SELECT_VERTEX, B_SEL_VERT, ICON_VERTEXSEL, + xco,0,XIC,YIC, &G.scene->selectmode, 1.0, 0.0, 0, 0, "Vertex select mode (Ctrl Tab 1)"); /* no edge */ /*uiDefIconButBitS(block, TOG, SCE_SELECT_EDGE, B_SEL_EDGE, ICON_EDGESEL, xco,0,XIC,YIC, &G.scene->selectmode, 1.0, 0.0, 0, 0, "Edge select mode (Ctrl Tab 2)"); xco+= XIC; */ - uiDefIconButBitS(block, TOG, SCE_SELECT_FACE, B_SEL_FACE, ICON_FACESEL, xco,0,XIC,YIC, &G.scene->selectmode, 1.0, 0.0, 0, 0, "Face select mode (Ctrl Tab 3)"); - xco+= XIC+8; + uiDefIconButBitS(block, TOG, SCE_SELECT_FACE, B_SEL_FACE, ICON_FACESEL, + xco+=XIC,0,XIC,YIC, &G.scene->selectmode, 1.0, 0.0, 0, 0, "Face select mode (Ctrl Tab 3)"); uiBlockEndAlign(block); } else { uiBlockBeginAlign(block); - uiDefIconButBitI(block, TOGN, SI_SELACTFACE, B_REDR, ICON_VERTEXSEL, xco,0,XIC,YIC, &G.sima->flag, 1.0, 0.0, 0, 0, "UV Vertex select mode"); - xco+= XIC; - uiDefIconButBitI(block, TOG, SI_SELACTFACE, B_REDR, ICON_FACESEL, xco,0,XIC,YIC, &G.sima->flag, 0, 0, 0, 0, "UV Face select mode"); - xco+= XIC+8; - uiBlockEndAlign(block); + uiDefIconButS(block, ROW, B_REDR, ICON_VERTEXSEL, + xco,0,XIC,YIC, &G.sima->selectmode, 0.0, SI_SELECT_VERTEX, 0, 0, "UV vertex select mode"); + uiDefIconButS(block, ROW, B_REDR, ICON_FACESEL, + xco+=XIC,0,XIC,YIC, &G.sima->selectmode, 0.0, SI_SELECT_FACE, 0, 0, "UV Face select mode"); + uiDefIconButS(block, ROW, B_REDR, ICON_MESH, + xco+=XIC,0,XIC,YIC, &G.sima->selectmode, 0.0, SI_SELECT_ISLAND, 0, 0, "UV Island select mode"); + uiBlockEndAlign(block); + /* would use these if const's could go in strings * SI_STICKY_LOC SI_STICKY_DISABLE SI_STICKY_VERTEX */ ubut = uiDefIconTextButC(block, ICONTEXTROW, B_REDR, ICON_STICKY_UVS_LOC, "Sticky UV Selection: %t|Disable%x1|Shared Location%x0|Shared Vertex%x2", - xco,0,XIC+10,YIC, &(G.sima->sticky), 0, 3.0, 0, 0, + xco+=XIC+10,0,XIC+10,YIC, &(G.sima->sticky), 0, 3.0, 0, 0, "Sticky UV Selection (Hotkeys: Shift C, Alt C, Ctrl C)"); } diff --git a/source/blender/src/header_view3d.c b/source/blender/src/header_view3d.c index 1ada2729289..0f3a46c8a8c 100644 --- a/source/blender/src/header_view3d.c +++ b/source/blender/src/header_view3d.c @@ -1313,6 +1313,9 @@ static void do_view3d_select_armaturemenu(void *arg, int event) case 3: /* Select Parent(s) */ select_bone_parent(); break; + case 4: /* Swap Select All */ + deselectall_armature(3, 1); + break; } allqueue(REDRAWVIEW3D, 0); } @@ -1331,6 +1334,8 @@ static uiBlock *view3d_select_armaturemenu(void *arg_unused) uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Select/Deselect All|A", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Swap Select All|Ctrl I", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Select Parent(s)|P", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, ""); if(curarea->headertype==HEADERTOP) { @@ -1356,12 +1361,15 @@ static void do_view3d_select_pose_armaturemenu(void *arg, int event) case 2: /* Select/Deselect all */ deselectall_posearmature(OBACT, 1, 1); break; - case 3: + case 3: /* Select Target(s) of Constraint(s) */ pose_select_constraint_target(); break; - case 4: + case 4: /* Select Bone's Parent */ select_bone_parent(); break; + case 5: /* Swap Select All */ + deselectall_posearmature(OBACT, 3, 1); + break; } allqueue(REDRAWVIEW3D, 0); } @@ -1379,6 +1387,7 @@ static uiBlock *view3d_select_pose_armaturemenu(void *arg_unused) uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Select/Deselect All|A", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Swap Select All|Ctrl I", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, ""); uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Select Constraint Target|W", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, ""); uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Select Parent(s)|P", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, ""); @@ -4106,7 +4115,7 @@ static uiBlock *view3d_pose_armature_ikmenu(void *arg_unused) block= uiNewBlock(&curarea->uiblocks, "view3d_pose_armature_ikmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin); uiBlockSetButmFunc(block, do_view3d_pose_armature_ikmenu, NULL); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Add IK to Bone...|Ctrl I", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Add IK to Bone...|Shift I", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, ""); uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Clear IK...|Alt I", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, ""); uiBlockSetDirection(block, UI_RIGHT); diff --git a/source/blender/src/headerbuttons.c b/source/blender/src/headerbuttons.c index 81ad135f514..1a91ada1562 100644 --- a/source/blender/src/headerbuttons.c +++ b/source/blender/src/headerbuttons.c @@ -1628,6 +1628,7 @@ void do_global_buttons(unsigned short event) allqueue(REDRAWOOPS, 1); allqueue(REDRAWACTION, 1); allqueue(REDRAWNLA, 1); + allqueue(REDRAWVIEW3D, 1); /* name scene also in set PUPmenu */ allqueue(REDRAWBUTSALL, 0); allqueue(REDRAWIMAGE, 0); diff --git a/source/blender/src/interface_draw.c b/source/blender/src/interface_draw.c index 83f1221b1fb..e7041e60003 100644 --- a/source/blender/src/interface_draw.c +++ b/source/blender/src/interface_draw.c @@ -180,8 +180,12 @@ static void ui_draw_icon(uiBut *but, BIFIconID icon, int blend) height= ICON_HEIGHT; if(but->flag & UI_ICON_LEFT) { - if (but->type==BUT_TOGDUAL && but->drawstr[0]) { - xs= but->x1-1.0; + if (but->type==BUT_TOGDUAL) { + if (but->drawstr[0]) { + xs= but->x1-1.0; + } else { + xs= (but->x1+but->x2- height)/2.0; + } } else if (but->type==BUTM ) { xs= but->x1+1.0; diff --git a/source/blender/src/poselib.c b/source/blender/src/poselib.c index 2d8b0c81175..fb2bfe5b605 100644 --- a/source/blender/src/poselib.c +++ b/source/blender/src/poselib.c @@ -756,6 +756,13 @@ static void poselib_keytag_pose (tPoseLib_PreviewData *pld) */ static void poselib_preview_get_next (tPoseLib_PreviewData *pld, int step) { + /* check if we no longer have search-string, but don't have any marker */ + if (pld->marker == NULL) { + if ((step) && (pld->searchstr[0] == 0)) + pld->marker= pld->act->markers.first; + } + + /* the following operations assume that there is a starting point and direction */ if ((pld->marker) && (step)) { /* search-string dictates a special approach */ if (pld->searchstr[0]) { @@ -1262,9 +1269,14 @@ void poselib_preview_poses (Object *ob, short apply_active) /* get search-string */ index= pld.search_cursor; - memcpy(&tempstr[0], &pld.searchstr[0], index); - tempstr[index]= '|'; - memcpy(&tempstr[index+1], &pld.searchstr[index], 64-index); + if (IN_RANGE(index, 0, 64)) { + memcpy(&tempstr[0], &pld.searchstr[0], index); + tempstr[index]= '|'; + memcpy(&tempstr[index+1], &pld.searchstr[index], 64-index); + } + else { + strncpy(tempstr, pld.searchstr, 64); + } /* get marker name */ if (pld.marker) diff --git a/source/blender/src/resources.c b/source/blender/src/resources.c index 046d14c990d..f47f14a605c 100644 --- a/source/blender/src/resources.c +++ b/source/blender/src/resources.c @@ -52,6 +52,7 @@ #include "BIF_interface_icons.h" #include "BLI_blenlib.h" +#include "BLI_dynstr.h" #include "blendef.h" // CLAMP #include "datatoc.h" @@ -784,6 +785,33 @@ char *BIF_ThemeColorsPup(int spacetype) return cp; } +char *BIF_ThemeColorSetsPup (short inc_custom) +{ + DynStr *pupds= BLI_dynstr_new(); + char *str; + char buf[48]; + int i; + + /* add title first (and the "default" entry) */ + BLI_dynstr_append(pupds, "Bone Color Set%t|Default Colors%x0|"); + + /* loop through set indices, adding them */ + for (i=1; i<21; i++) { + sprintf(buf, "%d - Theme Color Set%%x%d|", i, i); + BLI_dynstr_append(pupds, buf); + } + + /* add the 'custom' entry */ + if (inc_custom) + BLI_dynstr_append(pupds, "Custom Set %x-1"); + + /* convert to normal MEM_malloc'd string */ + str= BLI_dynstr_get_cstring(pupds); + BLI_dynstr_free(pupds); + + return str; +} + void BIF_SetTheme(ScrArea *sa) { if(sa==NULL) { // called for safety, when delete themes diff --git a/source/blender/src/sequence.c b/source/blender/src/sequence.c index 6851929bbc2..9426548dc38 100644 --- a/source/blender/src/sequence.c +++ b/source/blender/src/sequence.c @@ -2380,6 +2380,16 @@ ImBuf *give_ibuf_seq(int rectx, int recty, int cfra, int chanshown) return i; } +/* check used when we need to change seq->blend_mode but not to effect or audio strips */ +int seq_can_blend(Sequence *seq) +{ + if (ELEM4(seq->type, SEQ_IMAGE, SEQ_META, SEQ_SCENE, SEQ_MOVIE)) { + return 1; + } else { + return 0; + } +} + /* threading api */ static ListBase running_threads; diff --git a/source/blender/src/space.c b/source/blender/src/space.c index 4422411b1c5..58420604c83 100644 --- a/source/blender/src/space.c +++ b/source/blender/src/space.c @@ -2189,10 +2189,14 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt) break; case IKEY: if(G.qual==LR_CTRLKEY) { - if(ob && (ob->flag & OB_POSEMODE) && ob->type==OB_ARMATURE) - pose_add_IK(); - else if(ob && G.obedit) - selectswap_mesh(); + if((ob) && (ob->flag & OB_POSEMODE) && (ob->type==OB_ARMATURE)) + deselectall_posearmature(ob, 3, 1); + else if(ob && G.obedit) { + if(G.obedit->type == OB_ARMATURE) + deselectall_armature(3, 1); + else + selectswap_mesh(); + } else selectswap(); } @@ -2200,6 +2204,10 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt) if(ob && (ob->flag & OB_POSEMODE) && ob->type==OB_ARMATURE) pose_clear_IK(); } + else if(G.qual==LR_SHIFTKEY) { + if(ob && (ob->flag & OB_POSEMODE) && ob->type==OB_ARMATURE) + pose_add_IK(); + } break; case JKEY: @@ -4432,7 +4440,10 @@ static void winqreadinfospace(ScrArea *sa, void *spacedata, BWinEvent *evt) switch(event) { case UI_BUT_EVENT: - if(val==REDRAWTIME) allqueue(REDRAWTIME, 0); + if(val==REDRAWTIME) { + allqueue(REDRAWTIME, 0); + addqueue(sa->win, REDRAW, 1); + } else if(val==B_ADD_THEME) { bTheme *btheme, *new; @@ -4833,9 +4844,9 @@ static void winqreadseqspace(ScrArea *sa, void *spacedata, BWinEvent *evt) if( cfra!=CFRA || first ) { first= 0; - + CFRA= cfra; - force_draw(0); + force_draw_all(0); update_for_newframe(); /* for audio scrubbing */ } else PIL_sleep_ms(30); diff --git a/source/blender/src/transform_conversions.c b/source/blender/src/transform_conversions.c index dcebf6b7557..10e49cdd218 100644 --- a/source/blender/src/transform_conversions.c +++ b/source/blender/src/transform_conversions.c @@ -3610,6 +3610,7 @@ void special_aftertrans_update(TransInfo *t) Base *base; short redrawipo=0, resetslowpar=1; int cancelled= (t->state == TRANS_CANCEL); + short duplicate= (t->undostr && strstr(t->undostr, "Duplicate")) ? 1 : 0; if (t->spacetype==SPACE_VIEW3D) { if (G.obedit) { @@ -3622,7 +3623,7 @@ void special_aftertrans_update(TransInfo *t) } } } - if (t->spacetype == SPACE_ACTION) { + else if (t->spacetype == SPACE_ACTION) { void *data; short datatype; @@ -3644,7 +3645,7 @@ void special_aftertrans_update(TransInfo *t) /* Do curve cleanups? */ if ( (G.saction->flag & SACTION_NOTRANSKEYCULL)==0 && - (cancelled == 0) ) + ((cancelled == 0) || (duplicate)) ) { posttrans_action_clean((bAction *)data); } @@ -3659,7 +3660,7 @@ void special_aftertrans_update(TransInfo *t) IpoCurve *icu; if ( (G.saction->flag & SACTION_NOTRANSKEYCULL)==0 && - (cancelled == 0) ) + ((cancelled == 0) || (duplicate)) ) { posttrans_ipo_clean(key->ipo); } @@ -3685,7 +3686,7 @@ void special_aftertrans_update(TransInfo *t) /* after transform, remove duplicate keyframes on a frame that resulted from transform */ if ( (G.snla->flag & SNLA_NOTRANSKEYCULL)==0 && - (cancelled == 0) ) + ((cancelled == 0) || (duplicate)) ) { posttrans_nla_clean(t); } diff --git a/source/blender/src/transform_snap.c b/source/blender/src/transform_snap.c index d16308f17ae..3c17d0c1da8 100644 --- a/source/blender/src/transform_snap.c +++ b/source/blender/src/transform_snap.c @@ -814,7 +814,7 @@ int snapDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float ray_sta { efa = EM_get_face_for_index(index); - if (efa && efa->f & SELECT) + if (efa && ((efa->v1->f & SELECT) || (efa->v2->f & SELECT) || (efa->v3->f & SELECT) || (efa->v4 && efa->v4->f & SELECT))) { test = 0; } diff --git a/source/blender/src/usiblender.c b/source/blender/src/usiblender.c index 2a4672e3052..4aea0df74b9 100644 --- a/source/blender/src/usiblender.c +++ b/source/blender/src/usiblender.c @@ -34,6 +34,8 @@ #include <stdio.h> #include <string.h> +#include "GL/glew.h" + #ifdef WIN32 #include <windows.h> /* need to include windows.h so _WIN32_IE is defined */ #ifndef _WIN32_IE diff --git a/source/blender/src/view.c b/source/blender/src/view.c index f457f9203ff..12450bee9de 100644 --- a/source/blender/src/view.c +++ b/source/blender/src/view.c @@ -1154,7 +1154,7 @@ void viewmoveNDOF(int mode) float q1[4]; float obofs[3]; float reverse; - float diff[4]; + //float diff[4]; float d, curareaX, curareaY; float mat[3][3]; float upvec[3]; diff --git a/source/blender/src/vpaint.c b/source/blender/src/vpaint.c index 4e883caba55..935c546a235 100644 --- a/source/blender/src/vpaint.c +++ b/source/blender/src/vpaint.c @@ -566,9 +566,9 @@ static unsigned int mcol_blend(unsigned int col1, unsigned int col2, int fac) cp= (char *)&col; cp[0]= 255; - cp[1]= (mfac*cp1[1]+fac*cp2[1])>>8; - cp[2]= (mfac*cp1[2]+fac*cp2[2])>>8; - cp[3]= (mfac*cp1[3]+fac*cp2[3])>>8; + cp[1]= (mfac*cp1[1]+fac*cp2[1])/255; + cp[2]= (mfac*cp1[2]+fac*cp2[2])/255; + cp[3]= (mfac*cp1[3]+fac*cp2[3])/255; return col; } @@ -586,11 +586,11 @@ static unsigned int mcol_add(unsigned int col1, unsigned int col2, int fac) cp= (char *)&col; cp[0]= 255; - temp= cp1[1] + ((fac*cp2[1])>>8); + temp= cp1[1] + ((fac*cp2[1])/255); if(temp>254) cp[1]= 255; else cp[1]= temp; - temp= cp1[2] + ((fac*cp2[2])>>8); + temp= cp1[2] + ((fac*cp2[2])/255); if(temp>254) cp[2]= 255; else cp[2]= temp; - temp= cp1[3] + ((fac*cp2[3])>>8); + temp= cp1[3] + ((fac*cp2[3])/255); if(temp>254) cp[3]= 255; else cp[3]= temp; return col; @@ -609,11 +609,11 @@ static unsigned int mcol_sub(unsigned int col1, unsigned int col2, int fac) cp= (char *)&col; cp[0]= 255; - temp= cp1[1] - ((fac*cp2[1])>>8); + temp= cp1[1] - ((fac*cp2[1])/255); if(temp<0) cp[1]= 0; else cp[1]= temp; - temp= cp1[2] - ((fac*cp2[2])>>8); + temp= cp1[2] - ((fac*cp2[2])/255); if(temp<0) cp[2]= 0; else cp[2]= temp; - temp= cp1[3] - ((fac*cp2[3])>>8); + temp= cp1[3] - ((fac*cp2[3])/255); if(temp<0) cp[3]= 0; else cp[3]= temp; return col; @@ -635,9 +635,9 @@ static unsigned int mcol_mul(unsigned int col1, unsigned int col2, int fac) /* first mul, then blend the fac */ cp[0]= 255; - cp[1]= (mfac*cp1[1] + fac*((cp2[1]*cp1[1])>>8) )>>8; - cp[2]= (mfac*cp1[2] + fac*((cp2[2]*cp1[2])>>8) )>>8; - cp[3]= (mfac*cp1[3] + fac*((cp2[3]*cp1[3])>>8) )>>8; + cp[1]= (mfac*cp1[1] + fac*((cp2[1]*cp1[1])/255) )/255; + cp[2]= (mfac*cp1[2] + fac*((cp2[2]*cp1[2])/255) )/255; + cp[3]= (mfac*cp1[3] + fac*((cp2[3]*cp1[3])/255) )/255; return col; @@ -664,9 +664,9 @@ static unsigned int mcol_lighten(unsigned int col1, unsigned int col2, int fac) return col1; cp[0]= 255; - cp[1]= (mfac*cp1[1]+fac*cp2[1])>>8; - cp[2]= (mfac*cp1[2]+fac*cp2[2])>>8; - cp[3]= (mfac*cp1[3]+fac*cp2[3])>>8; + cp[1]= (mfac*cp1[1]+fac*cp2[1])/255; + cp[2]= (mfac*cp1[2]+fac*cp2[2])/255; + cp[3]= (mfac*cp1[3]+fac*cp2[3])/255; return col; } @@ -692,9 +692,9 @@ static unsigned int mcol_darken(unsigned int col1, unsigned int col2, int fac) return col1; cp[0]= 255; - cp[1]= (mfac*cp1[1]+fac*cp2[1])>>8; - cp[2]= (mfac*cp1[2]+fac*cp2[2])>>8; - cp[3]= (mfac*cp1[3]+fac*cp2[3])>>8; + cp[1]= (mfac*cp1[1]+fac*cp2[1])/255; + cp[2]= (mfac*cp1[2]+fac*cp2[2])/255; + cp[3]= (mfac*cp1[3]+fac*cp2[3])/255; return col; } |