diff options
author | Joseph Eagar <joeedh@gmail.com> | 2009-11-02 09:33:16 +0300 |
---|---|---|
committer | Joseph Eagar <joeedh@gmail.com> | 2009-11-02 09:33:16 +0300 |
commit | e3a410d224380a82099cfd7e9f47074293df001b (patch) | |
tree | 7054dac876ffe8cb33cce426696c3b5373842608 /source | |
parent | 71d2ceb69147aeead0800cb3b66c37fd132e8c48 (diff) |
shapekeys are now stored as customdata in editmode, so edit operations like subdivide work (mostly) correctly. tesselated faces now store correct normals in more situations. and added more missing files from the last merge, there may be more though.
Diffstat (limited to 'source')
21 files changed, 468 insertions, 50 deletions
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h index 17513b1b7c3..a253d18486f 100644 --- a/source/blender/blenkernel/BKE_customdata.h +++ b/source/blender/blenkernel/BKE_customdata.h @@ -227,6 +227,7 @@ void *CustomData_get_layer_n(const struct CustomData *data, int type, int n); void *CustomData_get_layer_named(const struct CustomData *data, int type, char *name); int CustomData_get_layer_index(const struct CustomData *data, int type); +int CustomData_get_layer_index_n(const struct CustomData *data, int type, int n); int CustomData_get_named_layer_index(const struct CustomData *data, int type, char *name); int CustomData_get_active_layer_index(const struct CustomData *data, int type); int CustomData_get_render_layer_index(const struct CustomData *data, int type); diff --git a/source/blender/blenkernel/BKE_tessmesh.h b/source/blender/blenkernel/BKE_tessmesh.h index daad8665d1a..1045295ae92 100644 --- a/source/blender/blenkernel/BKE_tessmesh.h +++ b/source/blender/blenkernel/BKE_tessmesh.h @@ -2,8 +2,9 @@ struct BMesh; struct BMLoop; -struct DerivedMesh; struct BMFace; +struct Mesh; +struct DerivedMesh; /* ok: the EDBM module is for editmode bmesh stuff. in contrast, the @@ -49,6 +50,10 @@ typedef struct BMEditMesh { int selectmode; int mat_nr; + + /*Mesh structure this editmesh came from, if it came from one*/ + struct Mesh *me; + struct Object *ob; } BMEditMesh; void BMEdit_RecalcTesselation(BMEditMesh *tm); diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index fa1a7da669a..d6cc785b146 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -2453,6 +2453,16 @@ static void lib_link_key(FileData *fd, Main *main) key= main->key.first; while(key) { + /*check if we need to generate unique ids for the shapekeys*/ + if (!key->uidgen) { + KeyBlock *block; + + key->uidgen = 1; + for (block=key->block.first; block; block=block->next) { + block->uid = key->uidgen++; + } + } + if(key->id.flag & LIB_NEEDLINK) { if(key->adt) lib_link_animdata(fd, &key->id, key->adt); diff --git a/source/blender/bmesh/operators/mesh_conv.c b/source/blender/bmesh/operators/mesh_conv.c index d9c8bd63c5c..53a358a824c 100644 --- a/source/blender/bmesh/operators/mesh_conv.c +++ b/source/blender/bmesh/operators/mesh_conv.c @@ -56,7 +56,7 @@ void mesh_to_bmesh_exec(BMesh *bm, BMOperator *op) { MEdge *medge; MLoop *ml; MPoly *mpoly; - KeyBlock *actkey; + KeyBlock *actkey, *block; BMVert *v, **vt=NULL; BMEdge *e, **fedges=NULL, **et = NULL; BMFace *f; @@ -77,19 +77,37 @@ void mesh_to_bmesh_exec(BMesh *bm, BMOperator *op) { CustomData_add_layer(&bm->vdata, CD_SHAPE_KEYINDEX, CD_ASSIGN, NULL, 0); - 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]); - actkey = ob_get_keyblock(ob); if(actkey && actkey->totelem == me->totvert) { + /*check if we need to generate unique ids for the shapekeys. + this also exists in the file reading code, but is here for + a sanity check*/ + if (!me->key->uidgen) { + printf("yeek! had to generate shape key uid's in a situation we shouldn't need to!\n"); + me->key->uidgen = 1; + for (block=me->key->block.first; block; block=block->next) { + block->uid = me->key->uidgen++; + } + } + keyco= actkey->data; bm->shapenr= ob->shapenr; + for (i=0, block=me->key->block.first; block; block=block->next, i++) { + CustomData_add_layer_named(&bm->vdata, CD_SHAPEKEY, + CD_ASSIGN, NULL, 0, block->name); + + j = CustomData_get_layer_index_n(&bm->vdata, CD_SHAPEKEY, i); + bm->vdata.layers[j].uid = block->uid; + } } else if (actkey) { printf("shapekey<->mesh mismatch!\n"); } + 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]); + for (i=0; i<me->totvert; i++, mvert++) { v = BM_Make_Vert(bm, keyco ? keyco[i] : mvert->co, NULL); VECCOPY(v->no, mvert->no); @@ -110,6 +128,15 @@ void mesh_to_bmesh_exec(BMesh *bm, BMOperator *op) { /*set shape key original index*/ keyi = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_SHAPE_KEYINDEX); *keyi = i; + + /*set shapekey data*/ + if (me->key) { + for (block=me->key->block.first, j=0; block; block=block->next, j++) { + float *co = CustomData_bmesh_get_n(&bm->vdata, v->head.data, + CD_SHAPEKEY, j); + VECCOPY(co, ((float*)block->data)+3*i); + } + } } if (!me->totedge) { @@ -262,6 +289,7 @@ void bmesh_to_mesh_exec(BMesh *bm, BMOperator *op) { Mesh *me = BMO_Get_Pnt(op, "mesh"); Object *ob = BMO_Get_Pnt(op, "object"); MLoop *mloop; + KeyBlock *block; MPoly *mpoly; MVert *mvert, *oldverts; MEdge *medge; @@ -271,6 +299,7 @@ void bmesh_to_mesh_exec(BMesh *bm, BMOperator *op) { BMLoop *l; BMFace *f; BMIter iter, liter; + float *facenors = NULL; int i, j, *keyi, ototvert, totloop, totface, numTex, numCol; int dotess = !BMO_Get_Int(op, "notesselation"); @@ -328,7 +357,7 @@ void bmesh_to_mesh_exec(BMesh *bm, BMOperator *op) { CustomData_add_layer(&me->edata, CD_MEDGE, CD_ASSIGN, medge, me->totedge); CustomData_add_layer(&me->ldata, CD_MLOOP, CD_ASSIGN, mloop, me->totloop); CustomData_add_layer(&me->pdata, CD_MPOLY, CD_ASSIGN, mpoly, me->totpoly); - + i = 0; BM_ITER(v, &iter, bm, BM_VERTS_OF_MESH, NULL) { VECCOPY(mvert->co, v->co); @@ -402,9 +431,13 @@ void bmesh_to_mesh_exec(BMesh *bm, BMOperator *op) { /* new tess face block */ if(totface==0) mface= NULL; - else mface= MEM_callocN(totface*sizeof(MFace), "loadeditbMesh face"); + else { + mface= MEM_callocN(totface*sizeof(MFace), "loadeditbMesh face"); + facenors = MEM_callocN(totface*sizeof(float)*3, "facenors"); + } CustomData_add_layer(&me->fdata, CD_MFACE, CD_ASSIGN, mface, me->totface); + CustomData_add_layer(&me->fdata, CD_NORMAL, CD_ASSIGN, facenors, me->totface); CustomData_from_bmeshpoly(&me->fdata, &bm->pdata, &bm->ldata, totface); mesh_update_customdata_pointers(me); @@ -457,7 +490,10 @@ void bmesh_to_mesh_exec(BMesh *bm, BMOperator *op) { test_index_face(mface, &me->fdata, i, 1); loops_to_corners(bm, me, i, f, ls, numTex, numCol); + VECCOPY(facenors, ls[0]->f->no); + mface++; + facenors += 3; i++; } BLI_end_edgefill(); @@ -561,7 +597,73 @@ void bmesh_to_mesh_exec(BMesh *bm, BMOperator *op) { mesh_update_customdata_pointers(me); - /* are there keys? */ + if (me->key) { + KeyBlock *actkey= BLI_findlink(&me->key->block, bm->shapenr-1); + + /*go through and find any shapekey customdata layers + that might not have corrusponding KeyBlocks, and add them if + necassary.*/ + j = 0; + for (i=0; i<bm->vdata.totlayer; i++) { + if (bm->vdata.layers[i].type != CD_SHAPEKEY) + continue; + + for (block=me->key->block.first; block; block=block->next) { + if (block->uid == bm->vdata.layers[i].uid) + break; + } + + if (!block) { + block = MEM_callocN(sizeof(KeyBlock), "KeyBlock mesh_conv.c"); + block->type = KEY_LINEAR; + block->slidermin = 0.0f; + block->slidermax = 1.0f; + + BLI_addtail(&me->key->block, block); + me->key->totkey++; + } + + j++; + } + + for (block=me->key->block.first; block; block=block->next) { + j = 0; + + for (i=0; i<bm->vdata.totlayer; i++) { + if (bm->vdata.layers[i].type != CD_SHAPEKEY) + continue; + + if (block->uid == bm->vdata.layers[i].uid) { + float *fp, *co; + + if (block->data) + MEM_freeN(block->data); + block->data = fp = MEM_mallocN(sizeof(float)*3*bm->totvert, "shape key data"); + block->totelem = bm->totvert; + + BM_ITER(eve, &iter, bm, BM_VERTS_OF_MESH, NULL) { + co = block==actkey ? eve->co : CustomData_bmesh_get_n(&bm->vdata, eve->head.data, CD_SHAPEKEY, j); + + VECCOPY(fp, co); + fp += 3; + } + break; + } + + j++; + } + + /*if we didn't find a shapekey, tag the block to be reconstructed + via the old method below*/ + if (j == CustomData_number_of_layers(&bm->vdata, CD_SHAPEKEY)) { + block->flag |= KEYBLOCK_MISSING; + } + } + } + + /* old method of reconstructing keys via vertice's original key indices, + currently used if the new method above fails (which is theoretically + possible in certain cases of undo).*/ if(me->key) { float *fp, *newkey, *oldkey; KeyBlock *currkey; @@ -571,6 +673,16 @@ void bmesh_to_mesh_exec(BMesh *bm, BMOperator *op) { * with the way things were before editmode */ currkey = me->key->block.first; while(currkey) { + if (!(currkey->flag & KEYBLOCK_MISSING)) { + currkey = currkey->next; + continue; + } + + printf("warning: had to hackishly reconstruct shape key \"%s\"," + " it may not be correct anymore.\n", currkey->name); + + currkey->flag &= ~KEYBLOCK_MISSING; + fp= newkey= MEM_callocN(me->key->elemsize*bm->totvert, "currkey->data"); oldkey = currkey->data; diff --git a/source/blender/editors/mesh/bmeshutils.c b/source/blender/editors/mesh/bmeshutils.c index 984c93a3a79..beac07b6415 100644 --- a/source/blender/editors/mesh/bmeshutils.c +++ b/source/blender/editors/mesh/bmeshutils.c @@ -267,6 +267,8 @@ void EDBM_MakeEditBMesh(ToolSettings *ts, Scene *scene, Object *ob) me->edit_btmesh = BMEdit_Create(bm); me->edit_btmesh->selectmode = ts->selectmode; + me->edit_btmesh->me = me; + me->edit_btmesh->ob = ob; } void EDBM_LoadEditBMesh(Scene *scene, Object *ob) @@ -557,6 +559,9 @@ static void *editbtMesh_to_undoMesh(void *emv) { BMEditMesh *em = emv; undomesh *me = MEM_callocN(sizeof(undomesh), "undo Mesh"); + + /*make sure shape keys work*/ + me->me.key = em->me->key; /*we recalc the tesselation here, to avoid seeding calls to BMEdit_RecalcTesselation throughout the code.*/ @@ -578,7 +583,7 @@ static void undoMesh_to_editbtMesh(void *umv, void *emv) BMEdit_Free(em); bm = BM_Make_Mesh(allocsize); - BMO_CallOpf(bm, "mesh_to_bmesh mesh=%p", me); + BMO_CallOpf(bm, "mesh_to_bmesh mesh=%p object=%p", me, em->ob); em2 = BMEdit_Create(bm); *em = *em2; diff --git a/source/blender/editors/object/object_shapekey.c b/source/blender/editors/object/object_shapekey.c index c9fb3351af9..eb27486b93c 100644 --- a/source/blender/editors/object/object_shapekey.c +++ b/source/blender/editors/object/object_shapekey.c @@ -139,9 +139,11 @@ static KeyBlock *add_keyblock(Scene *scene, Key *key) // XXX this is old anim system stuff? (i.e. the 'index' of the shapekey) kb->adrcode= tot-1; + kb->uid = key->uidgen++; + key->totkey++; if(key->totkey==1) key->refkey= kb; - + kb->slidermin= 0.0f; kb->slidermax= 1.0f; @@ -241,7 +243,8 @@ static void insert_lattkey(Scene *scene, Object *ob) } kb= add_keyblock(scene, key); - + kb->uid = key->uidgen++; + if(newkey) { /* create from lattice */ latt_to_key(lt, kb); @@ -372,6 +375,7 @@ static void insert_curvekey(Scene *scene, Object *ob) } kb= add_keyblock(scene, key); + kb->uid = key->uidgen++; if(newkey) { /* create from curve */ diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h index dbaa6f40cbf..b4feb3c4d16 100644 --- a/source/blender/makesdna/DNA_customdata_types.h +++ b/source/blender/makesdna/DNA_customdata_types.h @@ -39,7 +39,7 @@ typedef struct CustomDataLayer { int active_rnd; /* number of the layer to render*/ int active_clone; /* number of the layer to render*/ int active_mask; /* number of the layer to render*/ - char pad[4]; + int uid; /*shape keyblock unique id reference*/ char name[32]; /* layer name */ void *data; /* layer data */ } CustomDataLayer; diff --git a/source/blender/makesdna/DNA_key_types.h b/source/blender/makesdna/DNA_key_types.h index e86abf12424..02d3e8efb00 100644 --- a/source/blender/makesdna/DNA_key_types.h +++ b/source/blender/makesdna/DNA_key_types.h @@ -43,7 +43,7 @@ typedef struct KeyBlock { float pos; float curval; short type, adrcode, relative, flag; /* relative == 0 means first key is reference */ - int totelem, pad2; + int totelem, pad; void *data; float *weights; @@ -52,6 +52,8 @@ typedef struct KeyBlock { float slidermin; float slidermax; + + int uid, pad2; } KeyBlock; @@ -71,6 +73,9 @@ typedef struct Key { short type, totkey; short slurph, flag; + + /*can never be 0, this is used for detecting old data*/ + int uidgen, pad; /*current free uid for keyblocks*/ } Key; /* **************** KEY ********************* */ @@ -91,6 +96,6 @@ typedef struct Key { #define KEYBLOCK_MUTE (1<<0) #define KEYBLOCK_SEL (1<<1) #define KEYBLOCK_LOCKED (1<<2) - +#define KEYBLOCK_MISSING (1<<3) /*temporary flag*/ #endif diff --git a/source/blender/render/intern/include/raycounter.h b/source/blender/render/intern/include/raycounter.h new file mode 100644 index 00000000000..5f721a596c0 --- /dev/null +++ b/source/blender/render/intern/include/raycounter.h @@ -0,0 +1,55 @@ +/** + * $Id: raycounter.h 23649 2009-10-06 02:56:11Z jaguarandi $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): André Pinto. + * + * ***** END GPL LICENSE BLOCK ***** + */ +#ifndef RE_RAYCOUNTER_H +#define RE_RAYCOUNTER_H + +#include "RE_raytrace.h" + + +#ifdef RE_RAYCOUNTER + +/* #define RE_RC_INIT(isec, shi) (isec).count = re_rc_counter+(shi).thread */ +#define RE_RC_INIT(isec, shi) (isec).raycounter = &((shi).raycounter) +void RE_RC_INFO (RayCounter *rc); +void RE_RC_MERGE(RayCounter *rc, RayCounter *tmp); +#define RE_RC_COUNT(var) (var)++ + +extern RayCounter re_rc_counter[]; + +#else + +# define RE_RC_INIT(isec,shi) +# define RE_RC_INFO(rc) +# define RE_RC_MERGE(dest,src) +# define RE_RC_COUNT(var) + +#endif + + +#endif diff --git a/source/blender/render/intern/include/rayobject.h b/source/blender/render/intern/include/rayobject.h new file mode 100644 index 00000000000..8dc2281bd3b --- /dev/null +++ b/source/blender/render/intern/include/rayobject.h @@ -0,0 +1,208 @@ +/** + * $Id: rayobject.h 23651 2009-10-06 03:40:50Z aligorith $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): André Pinto. + * + * ***** END GPL LICENSE BLOCK ***** + */ +#ifndef RE_RAYOBJECT_H +#define RE_RAYOBJECT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "RE_raytrace.h" +#include "render_types.h" +#include <stdio.h> +#include <float.h> + + +/* RayObject + + A ray object is everything where we can cast rays like: + * a face/triangle + * an octree + * a bvh tree + * an octree of bvh's + * a bvh of bvh's + + + All types of RayObjects can be created by implementing the + callbacks of the RayObject. + + Due to high computing time evolved with casting on faces + there is a special type of RayObject (named RayFace) + which won't use callbacks like other generic nodes. + + In order to allow a mixture of RayFace+RayObjects, + all RayObjects must be 4byte aligned, allowing us to use the + 2 least significant bits (with the mask 0x03) to define the + type of RayObject. + + This leads to 4 possible types of RayObject: + + addr&3 - type of object + 0 Self (reserved for each structure) + 1 RayFace (tri/quad primitive) + 2 RayObject (generic with API callbacks) + 3 VlakPrimitive + (vlak primitive - to be used when we have a vlak describing the data + eg.: on render code) + + 0 means it's reserved and has it own meaning inside each ray acceleration structure + (this way each structure can use the allign offset to determine if a node represents a + RayObject primitive, which can be used to save memory) + + You actually don't need to care about this if you are only using the API + described on RE_raytrace.h + */ + +/* used to align a given ray object */ +#define RE_rayobject_align(o) ((RayObject*)(((intptr_t)o)&(~3))) + +/* used to unalign a given ray object */ +#define RE_rayobject_unalignRayFace(o) ((RayObject*)(((intptr_t)o)|1)) +#define RE_rayobject_unalignRayAPI(o) ((RayObject*)(((intptr_t)o)|2)) +#define RE_rayobject_unalignVlakPrimitive(o) ((RayObject*)(((intptr_t)o)|3)) + +/* used to test the type of ray object */ +#define RE_rayobject_isAligned(o) ((((intptr_t)o)&3) == 0) +#define RE_rayobject_isRayFace(o) ((((intptr_t)o)&3) == 1) +#define RE_rayobject_isRayAPI(o) ((((intptr_t)o)&3) == 2) +#define RE_rayobject_isVlakPrimitive(o) ((((intptr_t)o)&3) == 3) + + + +/* + * This class is intended as a place holder for control, configuration of the rayobject like: + * - stop building (TODO maybe when porting build to threads this could be implemented with some thread_cancel function) + * - max number of threads and threads callback to use during build + * ... + */ +typedef int (*RE_rayobjectcontrol_test_break_callback)(void *data); +typedef struct RayObjectControl RayObjectControl; +struct RayObjectControl +{ + void *data; + RE_rayobjectcontrol_test_break_callback test_break; +}; + +/* + * This rayobject represents a generic object. With it's own callbacks for raytrace operations. + * It's suitable to implement things like LOD. + */ +struct RayObject +{ + struct RayObjectAPI *api; + + struct RayObjectControl control; +}; + + + + +typedef int (*RE_rayobject_raycast_callback)(RayObject *, Isect *); +typedef void (*RE_rayobject_add_callback)(RayObject *raytree, RayObject *rayobject); +typedef void (*RE_rayobject_done_callback)(RayObject *); +typedef void (*RE_rayobject_free_callback)(RayObject *); +typedef void (*RE_rayobject_merge_bb_callback)(RayObject *, float *min, float *max); +typedef float (*RE_rayobject_cost_callback)(RayObject *); +typedef void (*RE_rayobject_hint_bb_callback)(RayObject *, RayHint *, float *, float *); + +typedef struct RayObjectAPI +{ + RE_rayobject_raycast_callback raycast; + RE_rayobject_add_callback add; + RE_rayobject_done_callback done; + RE_rayobject_free_callback free; + RE_rayobject_merge_bb_callback bb; + RE_rayobject_cost_callback cost; + RE_rayobject_hint_bb_callback hint_bb; + +} RayObjectAPI; + + +/* + * This function differs from RE_rayobject_raycast + * RE_rayobject_intersect does NOT perform last-hit optimization + * So this is probably a function to call inside raytrace structures + */ +int RE_rayobject_intersect(RayObject *r, Isect *i); + +/* + * Returns distance ray must travel to hit the given bounding box + * BB should be in format [2][3] + */ +/* float RE_rayobject_bb_intersect(const Isect *i, const float *bb); */ +int RE_rayobject_bb_intersect_test(const Isect *i, const float *bb); /* same as bb_intersect but doens't calculates distance */ + +/* + * Returns the expected cost of raycast on this node, primitives have a cost of 1 + */ +float RE_rayobject_cost(RayObject *r); + + +/* + * Returns true if for some reason a heavy processing function should stop + * (eg.: user asked to stop during a tree a build) + */ +int RE_rayobjectcontrol_test_break(RayObjectControl *c); + + +#define ISECT_EPSILON ((float)FLT_EPSILON) + + + +#if !defined(_WIN32) && !defined(_WIN64) + +#include <sys/time.h> +#include <time.h> + +#define BENCH(a,name) \ + do { \ + double _t1, _t2; \ + struct timeval _tstart, _tend; \ + clock_t _clock_init = clock(); \ + gettimeofday ( &_tstart, NULL); \ + (a); \ + gettimeofday ( &_tend, NULL); \ + _t1 = ( double ) _tstart.tv_sec + ( double ) _tstart.tv_usec/ ( 1000*1000 ); \ + _t2 = ( double ) _tend.tv_sec + ( double ) _tend.tv_usec/ ( 1000*1000 ); \ + printf("BENCH:%s: %fs (real) %fs (cpu)\n", #name, _t2-_t1, (float)(clock()-_clock_init)/CLOCKS_PER_SEC);\ + } while(0) +#else + +#define BENCH(a,name) (a) + +#endif + + + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index 1a91e4cf8f3..5f352e1d67b 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -207,6 +207,7 @@ IF(APPLE) ADD_CUSTOM_COMMAND( TARGET blender POST_BUILD MAIN_DEPENDENCY blender COMMAND find ${TARGETDIR} -name .svn -prune -exec rm -rf {} "\;" + COMMAND find ${TARGETDIR} -name __MACOSX -prune -exec rm -rf {} "\;" ) @@ -325,11 +326,16 @@ IF(WIN32) ENDIF(WITH_INTERNATIONAL) IF(WITH_PYTHON) + IF(WITH_LIBS10.5) + SET(PYTHON_ZIP "python_${CMAKE_OSX_ARCHITECTURES}.zip") + ELSE(WITH_LIBS10.5) + SET(PYTHON_ZIP "python.zip") + ENDIF(WITH_LIBS10.5) ADD_CUSTOM_COMMAND( TARGET blender POST_BUILD MAIN_DEPENDENCY blender COMMAND cp -Rf ${CMAKE_SOURCE_DIR}/release/scripts ${TARGETDIR}/blender.app/Contents/MacOS/.blender/ COMMAND mkdir ${TARGETDIR}/blender.app/Contents/MacOS/.blender/python/ - COMMAND unzip -q ${LIBDIR}/release/python.zip -d ${TARGETDIR}/blender.app/Contents/MacOS/.blender/python/ + COMMAND unzip -q ${LIBDIR}/release/${PYTHON_ZIP} -d ${TARGETDIR}/blender.app/Contents/MacOS/.blender/python/ COMMAND find ${TARGETDIR}/blender.app -name "*.py?" -prune -exec rm -rf {} "\;" ) ENDIF(WITH_PYTHON) diff --git a/source/creator/SConscript b/source/creator/SConscript index 7b3d1493ed2..6c95f25a0b2 100644 --- a/source/creator/SConscript +++ b/source/creator/SConscript @@ -36,5 +36,7 @@ else: if env['WITH_BF_FHS']: # /usr -> /usr/share/blender/2.5 defs.append('BLENDERPATH=\\"' + os.path.join(env['BF_INSTALLDIR'], 'share', 'blender', env['BF_VERSION']) + '\\"') +if env['BF_BUILDINFO']: + defs.append('BUILD_DATE') env.BlenderLib ( libname = 'bf_creator', sources = Split(sources), includes = Split(incs), defines = defs, libtype='core', priority = 0 ) diff --git a/source/creator/buildinfo.c b/source/creator/buildinfo.c index cef98915d79..db24b50b82d 100644 --- a/source/creator/buildinfo.c +++ b/source/creator/buildinfo.c @@ -31,14 +31,13 @@ #include <config.h> #endif +#define STRINGIFY(x) XSTRINGIFY(x) +#define XSTRINGIFY(x) #x + #ifdef BUILD_DATE -#ifndef WIN32 -const char * build_date=BUILD_DATE; -const char * build_time=BUILD_TIME; -const char * build_rev=BUILD_REV; -const char * build_platform=BUILD_PLATFORM; -const char * build_type=BUILD_TYPE; -#else -#include "winbuildinfo.h" -#endif +const char * build_date=STRINGIFY(BUILD_DATE); +const char * build_time=STRINGIFY(BUILD_TIME); +const char * build_rev=STRINGIFY(BUILD_REV); +const char * build_platform=STRINGIFY(BUILD_PLATFORM); +const char * build_type=STRINGIFY(BUILD_TYPE); #endif diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp index df7f35d7773..ca5faf00bb6 100644 --- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp +++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp @@ -356,7 +356,7 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, int alw if(GLEW_ARB_multitexture && GLEW_VERSION_1_1) usemat = true; - if(GPU_extensions_minimum_support()) + if(GPU_glsl_support()) useglslmat = true; else if(blscene->gm.matmode == GAME_MAT_GLSL) usemat = false; diff --git a/source/gameengine/Converter/BL_ArmatureActuator.cpp b/source/gameengine/Converter/BL_ArmatureActuator.cpp index 4105eb57d5f..46c63f5e9a9 100644 --- a/source/gameengine/Converter/BL_ArmatureActuator.cpp +++ b/source/gameengine/Converter/BL_ArmatureActuator.cpp @@ -31,9 +31,9 @@ #include "DNA_constraint_types.h" #include "DNA_actuator_types.h" #include "BKE_constraint.h" -#include "BLI_arithb.h" #include "BL_ArmatureActuator.h" #include "BL_ArmatureObject.h" +#include "BLI_arithb.h" /** * This class is the conversion of the Pose channel constraint. diff --git a/source/gameengine/Converter/BL_ShapeDeformer.cpp b/source/gameengine/Converter/BL_ShapeDeformer.cpp index 20ca7f07f2b..125e91e0e0a 100644 --- a/source/gameengine/Converter/BL_ShapeDeformer.cpp +++ b/source/gameengine/Converter/BL_ShapeDeformer.cpp @@ -148,10 +148,13 @@ bool BL_ShapeDeformer::Update(void) // make sure the vertex weight cache is in line with this object m_pMeshObject->CheckWeightCache(blendobj); - /* we will blend the key directly in mvert array: it is used by armature as the start position */ + /* we will blend the key directly in m_transverts array: it is used by armature as the start position */ /* m_bmesh->key can be NULL in case of Modifier deformer */ if (m_bmesh->key) { - do_rel_key(0, m_bmesh->totvert, m_bmesh->totvert, (char *)m_bmesh->mvert->co, m_bmesh->key, 0); + /* store verts locally */ + VerifyStorage(); + + do_rel_key(0, m_bmesh->totvert, m_bmesh->totvert, (char *)(float *)m_transverts, m_bmesh->key, NULL, 0); m_bDynamic = true; } @@ -167,18 +170,12 @@ bool BL_ShapeDeformer::Update(void) bShapeUpdate = true; } // check for armature deform - bSkinUpdate = BL_SkinDeformer::Update(); + bSkinUpdate = BL_SkinDeformer::UpdateInternal(bShapeUpdate && m_bDynamic); // non dynamic deformer = Modifer without armature and shape keys, no need to create storage if (!bSkinUpdate && bShapeUpdate && m_bDynamic) { - // this means that there is no armature, we still need to copy the vertex to m_transverts - // and update the normal (was not done after shape key calculation) - - /* store verts locally */ - VerifyStorage(); - - for (int v =0; v<m_bmesh->totvert; v++) - VECCOPY(m_transverts[v], m_bmesh->mvert[v].co); + // this means that there is no armature, we still need to + // update the normal (was not done after shape key calculation) #ifdef __NLA_DEFNORMALS if (m_recalcNormal) diff --git a/source/gameengine/Converter/BL_SkinDeformer.cpp b/source/gameengine/Converter/BL_SkinDeformer.cpp index a13f78e1b27..f166a7252ad 100644 --- a/source/gameengine/Converter/BL_SkinDeformer.cpp +++ b/source/gameengine/Converter/BL_SkinDeformer.cpp @@ -172,7 +172,7 @@ void BL_SkinDeformer::ProcessReplica() //void where_is_pose (Object *ob); //void armature_deform_verts(Object *armOb, Object *target, float (*vertexCos)[3], int numVerts, int deformflag); -bool BL_SkinDeformer::Update(void) +bool BL_SkinDeformer::UpdateInternal(bool shape_applied) { /* See if the armature has been updated for this frame */ if (PoseUpdated()){ @@ -182,12 +182,14 @@ bool BL_SkinDeformer::Update(void) /* but it requires the blender object pointer... */ Object* par_arma = m_armobj->GetArmatureObject(); - /* store verts locally */ - VerifyStorage(); - - /* duplicate */ - for (int v =0; v<m_bmesh->totvert; v++) - VECCOPY(m_transverts[v], m_bmesh->mvert[v].co); + if(!shape_applied) { + /* store verts locally */ + VerifyStorage(); + + /* duplicate */ + for (int v =0; v<m_bmesh->totvert; v++) + VECCOPY(m_transverts[v], m_bmesh->mvert[v].co); + } m_armobj->ApplyPose(); @@ -219,6 +221,11 @@ bool BL_SkinDeformer::Update(void) return false; } +bool BL_SkinDeformer::Update(void) +{ + return UpdateInternal(false); +} + /* XXX note: I propose to drop this function */ void BL_SkinDeformer::SetArmature(BL_ArmatureObject *armobj) { diff --git a/source/gameengine/Converter/BL_SkinDeformer.h b/source/gameengine/Converter/BL_SkinDeformer.h index b83895d5609..9c6f5db2b95 100644 --- a/source/gameengine/Converter/BL_SkinDeformer.h +++ b/source/gameengine/Converter/BL_SkinDeformer.h @@ -72,6 +72,7 @@ public: virtual ~BL_SkinDeformer(); bool Update (void); + bool UpdateInternal (bool shape_applied); bool Apply (class RAS_IPolyMaterial *polymat); bool UpdateBuckets(void) { diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp index 3c989293c94..e771d12988c 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp +++ b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp @@ -539,7 +539,7 @@ bool GPG_Application::initEngine(GHOST_IWindow* window, const int stereoMode) if(GLEW_ARB_multitexture && GLEW_VERSION_1_1) m_blendermat = (SYS_GetCommandLineInt(syshandle, "blender_material", 1) != 0); - if(GPU_extensions_minimum_support()) + if(GPU_glsl_support()) m_blenderglslmat = (SYS_GetCommandLineInt(syshandle, "blender_glsl_material", 1) != 0); else if(gm->matmode == GAME_MAT_GLSL) m_blendermat = false; diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 9bb261fcba9..d516d3e03ff 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -46,7 +46,6 @@ typedef unsigned long uint_ptr; #define KX_INERTIA_INFINITE 10000 -#include "BLI_arithb.h" #include "RAS_IPolygonMaterial.h" #include "KX_BlenderMaterial.h" #include "KX_GameObject.h" @@ -80,6 +79,8 @@ typedef unsigned long uint_ptr; #include "KX_SG_NodeRelationships.h" +#include "BLI_arithb.h" + static MT_Point3 dummy_point= MT_Point3(0.0, 0.0, 0.0); static MT_Vector3 dummy_scaling = MT_Vector3(1.0, 1.0, 1.0); static MT_Matrix3x3 dummy_orientation = MT_Matrix3x3( 1.0, 0.0, 0.0, diff --git a/source/nan_compile.mk b/source/nan_compile.mk index 8d4da1e2790..6a1263e286c 100644 --- a/source/nan_compile.mk +++ b/source/nan_compile.mk @@ -73,8 +73,8 @@ ifeq ($(OS),darwin) CC ?= gcc CCC ?= g++ ifeq ($(CPU),powerpc) - CFLAGS += -pipe -fPIC -ffast-math -mcpu=7450 -mtune=G5 -funsigned-char -fno-strict-aliasing - CCFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing + CFLAGS += -pipe -fPIC -ffast-math -mcpu=7450 -mtune=G5 -funsigned-char -fno-strict-aliasing -Wno-long-double + CCFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing -Wno-long-double else CFLAGS += -pipe -fPIC -ffast-math -march=pentium-m -funsigned-char -fno-strict-aliasing CCFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing |