diff options
author | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2010-06-03 19:39:02 +0400 |
---|---|---|
committer | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2010-06-03 19:39:02 +0400 |
commit | ca6f7ddd991940d6d26162e242a70c232475a3d2 (patch) | |
tree | bda3e56b795606b93892023c3c5701995ff9be20 /source/blender | |
parent | 052cc71c4011adff7c748f283fe0d6b70ebfa0fa (diff) | |
parent | 2beef23a9bc131ed182e92f009df56d6838a13c0 (diff) |
Merged changes in the trunk up to revision 29184.
Diffstat (limited to 'source/blender')
103 files changed, 1415 insertions, 590 deletions
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h index 7ca6bbe67a7..ce4286f01c8 100644 --- a/source/blender/blenkernel/BKE_customdata.h +++ b/source/blender/blenkernel/BKE_customdata.h @@ -292,6 +292,8 @@ void CustomData_external_write(struct CustomData *data, struct ID *id, CustomDataMask mask, int totelem, int free); void CustomData_external_read(struct CustomData *data, struct ID *id, CustomDataMask mask, int totelem); +void CustomData_external_reload(struct CustomData *data, + struct ID *id, CustomDataMask mask, int totelem); #endif diff --git a/source/blender/blenkernel/BKE_multires.h b/source/blender/blenkernel/BKE_multires.h index 258fb6f1b3f..8716794bbd4 100644 --- a/source/blender/blenkernel/BKE_multires.h +++ b/source/blender/blenkernel/BKE_multires.h @@ -42,6 +42,7 @@ void multires_mark_as_modified(struct Object *ob); void multires_force_update(struct Object *ob); void multires_force_render_update(struct Object *ob); +void multires_force_external_reload(struct Object *ob); struct DerivedMesh *multires_dm_create_from_derived(struct MultiresModifierData*, int local_mmd, struct DerivedMesh*, struct Object *, int, int); diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index fcef00ae9b3..33a41821fe2 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -255,9 +255,11 @@ void psys_threads_free(ParticleThread *threads); void psys_make_billboard(ParticleBillboardData *bb, float xvec[3], float yvec[3], float zvec[3], float center[3]); /* particle_system.c */ +void psys_update_path_cache(struct ParticleSimulationData *sim, float cfra); struct ParticleSystem *psys_get_target_system(struct Object *ob, struct ParticleTarget *pt); void psys_count_keyed_targets(struct ParticleSimulationData *sim); void psys_update_particle_tree(struct ParticleSystem *psys, float cfra); +void psys_update_children(struct ParticleSimulationData *sim); void psys_make_temp_pointcache(struct Object *ob, struct ParticleSystem *psys); void psys_get_pointcache_start_end(struct Scene *scene, ParticleSystem *psys, int *sfra, int *efra); diff --git a/source/blender/blenkernel/BKE_report.h b/source/blender/blenkernel/BKE_report.h index 62381bbc1f5..d7b7801d697 100644 --- a/source/blender/blenkernel/BKE_report.h +++ b/source/blender/blenkernel/BKE_report.h @@ -59,6 +59,8 @@ void BKE_report_store_level_set(ReportList *reports, ReportType level); char *BKE_reports_string(ReportList *reports, ReportType level); void BKE_reports_print(ReportList *reports, ReportType level); +Report *BKE_reports_last_displayable(ReportList *reports); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/BKE_subsurf.h b/source/blender/blenkernel/BKE_subsurf.h index ef3ad3ad2e9..940a0027d0b 100644 --- a/source/blender/blenkernel/BKE_subsurf.h +++ b/source/blender/blenkernel/BKE_subsurf.h @@ -72,6 +72,7 @@ typedef struct CCGDerivedMesh { char *faceFlags; struct PBVH *pbvh; + int pbvh_draw; struct ListBase *fmap; struct IndexNode *fmap_mem; diff --git a/source/blender/blenkernel/intern/CCGSubSurf.c b/source/blender/blenkernel/intern/CCGSubSurf.c index 6778c9eb8ad..8fad398f00a 100644 --- a/source/blender/blenkernel/intern/CCGSubSurf.c +++ b/source/blender/blenkernel/intern/CCGSubSurf.c @@ -1159,7 +1159,7 @@ static void ccgSubSurf__calcVertNormals(CCGSubSurf *ss, int normalDataOffset = ss->normalDataOffset; int vertDataSize = ss->meshIFC.vertDataSize; - #pragma omp parallel for private(ptrIdx) schedule(static) + //#pragma omp parallel for private(ptrIdx) schedule(static) for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) { CCGFace *f = (CCGFace*) effectedF[ptrIdx]; int S, x, y; @@ -1285,7 +1285,7 @@ static void ccgSubSurf__calcVertNormals(CCGSubSurf *ss, } } - #pragma omp parallel for private(ptrIdx) schedule(static) + //#pragma omp parallel for private(ptrIdx) schedule(static) for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) { CCGFace *f = (CCGFace*) effectedF[ptrIdx]; int S, x, y; @@ -1351,7 +1351,7 @@ static void ccgSubSurf__calcSubdivLevel(CCGSubSurf *ss, int vertDataSize = ss->meshIFC.vertDataSize; void *q = ss->q, *r = ss->r; - #pragma omp parallel for private(ptrIdx) schedule(static) + //#pragma omp parallel for private(ptrIdx) schedule(static) for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) { CCGFace *f = (CCGFace*) effectedF[ptrIdx]; int S, x, y; @@ -1685,17 +1685,17 @@ static void ccgSubSurf__calcSubdivLevel(CCGSubSurf *ss, } } - #pragma omp parallel private(ptrIdx) + //#pragma omp parallel private(ptrIdx) { void *q, *r; - #pragma omp critical + //#pragma omp critical { q = MEM_mallocN(ss->meshIFC.vertDataSize, "CCGSubsurf q"); r = MEM_mallocN(ss->meshIFC.vertDataSize, "CCGSubsurf r"); } - #pragma omp for schedule(static) + //#pragma omp for schedule(static) for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) { CCGFace *f = (CCGFace*) effectedF[ptrIdx]; int S, x, y; @@ -1779,7 +1779,7 @@ static void ccgSubSurf__calcSubdivLevel(CCGSubSurf *ss, } } - #pragma omp critical + //#pragma omp critical { MEM_freeN(q); MEM_freeN(r); @@ -1791,14 +1791,14 @@ static void ccgSubSurf__calcSubdivLevel(CCGSubSurf *ss, gridSize = 1 + (1<<((nextLvl)-1)); cornerIdx = gridSize-1; - #pragma omp parallel for private(i) schedule(static) + //#pragma omp parallel for private(i) schedule(static) for (i=0; i<numEffectedE; i++) { CCGEdge *e = effectedE[i]; VertDataCopy(EDGE_getCo(e, nextLvl, 0), VERT_getCo(e->v0, nextLvl)); VertDataCopy(EDGE_getCo(e, nextLvl, edgeSize-1), VERT_getCo(e->v1, nextLvl)); } - #pragma omp parallel for private(i) schedule(static) + //#pragma omp parallel for private(i) schedule(static) for (i=0; i<numEffectedF; i++) { CCGFace *f = effectedF[i]; int S, x; diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 85791d5024d..9d649edd81a 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -1870,10 +1870,6 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos /* grab modifiers until index i */ if((index >= 0) && (modifiers_indexInObject(ob, md) >= index)) break; - - /*don't allow other modifiers past multires if in sculpt mode*/ - if (!useRenderParams && ((ob->mode & OB_MODE_SCULPT) && ob->sculpt)) - break; } for(md=firstmd; md; md=md->next) diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index 82168fddd8f..20afc715c77 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -1188,11 +1188,21 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p BLI_srandom(31415926 + psys->seed); lay= scene->lay; - if((psys->renderdata || part->draw_as==PART_DRAW_REND) && - ((part->ren_as == PART_DRAW_OB && part->dup_ob) || - (part->ren_as == PART_DRAW_GR && part->dup_group && part->dup_group->gobject.first))) { + if((psys->renderdata || part->draw_as==PART_DRAW_REND) && ELEM(part->ren_as, PART_DRAW_OB, PART_DRAW_GR)) { - psys_check_group_weights(part); + /* first check for loops (particle system object used as dupli object) */ + if(part->ren_as == PART_DRAW_OB) { + if(ELEM(part->dup_ob, NULL, par)) + return; + } + else { /*PART_DRAW_GR */ + if(part->dup_group == NULL || part->dup_group->gobject.first == NULL) + return; + + for(go=part->dup_group->gobject.first; go; go=go->next) + if(go->ob == par) + return; + } /* if we have a hair particle system, use the path cache */ if(part->type == PART_HAIR) { @@ -1206,6 +1216,8 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p totpart = psys->totcached; } + psys_check_group_weights(part); + psys->lattice = psys_get_lattice(&sim); /* gather list of objects or single object */ diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index 204ff2a0369..e15e5bc9b45 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -74,6 +74,7 @@ typedef struct { /* Cached */ struct PBVH *pbvh; + int pbvh_draw; /* Mesh connectivity */ struct ListBase *fmap; struct IndexNode *fmap_mem; @@ -188,6 +189,7 @@ static ListBase *cdDM_getFaceMap(Object *ob, DerivedMesh *dm) static struct PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm) { CDDerivedMesh *cddm = (CDDerivedMesh*) dm; + Mesh *me= (ob)? ob->data: NULL; if(!ob) { cddm->pbvh= NULL; @@ -196,13 +198,17 @@ static struct PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm) if(!ob->sculpt) return NULL; - if(ob->sculpt->pbvh) + if(ob->sculpt->pbvh) { cddm->pbvh= ob->sculpt->pbvh; + cddm->pbvh_draw = (cddm->mvert == me->mvert); + } + /* always build pbvh from original mesh, and only use it for drawing if + this derivedmesh is just original mesh. it's the multires subsurf dm + that this is actually for, to support a pbvh on a modified mesh */ if(!cddm->pbvh && ob->type == OB_MESH) { - Mesh *me= ob->data; - cddm->pbvh = BLI_pbvh_new(); + cddm->pbvh_draw = (cddm->mvert == me->mvert); BLI_pbvh_build_mesh(cddm->pbvh, me->mface, me->mvert, me->totface, me->totvert); } @@ -417,7 +423,7 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm, glVertex3fv(mvert[index].co); \ } - if(cddm->pbvh) { + if(cddm->pbvh && cddm->pbvh_draw) { if(dm->numFaceData) { float (*face_nors)[3] = CustomData_get_layer(&dm->faceData, CD_NORMAL); diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index 361e6f3fd22..dcc0a0b876f 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -2316,12 +2316,31 @@ int CustomData_verify_versions(struct CustomData *data, int index) static void customdata_external_filename(char filename[FILE_MAX], ID *id, CustomDataExternal *external) { - char *path = (id->lib)? id->lib->filename: G.sce; + char *path = (id->lib)? id->lib->filepath: G.sce; BLI_strncpy(filename, external->filename, FILE_MAX); BLI_path_abs(filename, path); } +void CustomData_external_reload(CustomData *data, ID *id, CustomDataMask mask, int totelem) +{ + CustomDataLayer *layer; + const LayerTypeInfo *typeInfo; + int i; + + for(i=0; i<data->totlayer; i++) { + layer = &data->layers[i]; + typeInfo = layerType_getInfo(layer->type); + + if(!(mask & (1<<layer->type))); + else if((layer->flag & CD_FLAG_EXTERNAL) && (layer->flag & CD_FLAG_IN_MEMORY)) { + if(typeInfo->free) + typeInfo->free(layer->data, totelem, typeInfo->size); + layer->flag &= ~CD_FLAG_IN_MEMORY; + } + } +} + void CustomData_external_read(CustomData *data, ID *id, CustomDataMask mask, int totelem) { CustomDataExternal *external= data->external; diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 0568050950f..bdeacdf6946 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -2286,11 +2286,7 @@ void DAG_id_flush_update(ID *id, short flag) /* no point in trying in this cases */ if(!id || id->us <= 1) id= NULL; - /* curves and surfaces only need to mark one object, since - otherwise cu->displist would be computed multiple times */ - else if(ob->type==OB_CURVE || ob->type==OB_SURF) - id= NULL; - /* also for locked shape keys we make an exception */ + /* for locked shape keys we make an exception */ else if(ob_get_key(ob) && (ob->shapeflag & OB_SHAPE_LOCK)) id= NULL; } @@ -2301,15 +2297,23 @@ void DAG_id_flush_update(ID *id, short flag) idtype= GS(id->name); if(ELEM7(idtype, ID_ME, ID_CU, ID_MB, ID_LA, ID_LT, ID_CA, ID_AR)) { + int first_ob= 1; for(obt=bmain->object.first; obt; obt= obt->id.next) { if(!(ob && obt == ob) && obt->data == id) { + + /* try to avoid displist recalculation for linked curves */ + if (!first_ob && ELEM(obt->type, OB_CURVE, OB_SURF)) { + /* if curve object has got derivedFinal it means this + object has got constructive modifiers and object + should be recalculated anyhow */ + if (!obt->derivedFinal) + continue; + } + obt->recalc |= OB_RECALC_DATA; BKE_ptcache_object_reset(sce, obt, PTCACHE_RESET_DEPSGRAPH); - /* for these we only flag one object, otherwise cu->displist - would be computed multiple times */ - if(obt->type==OB_CURVE || obt->type==OB_SURF) - break; + first_ob= 0; } } } diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c index 619bb1a58f9..43f01199b69 100644 --- a/source/blender/blenkernel/intern/fcurve.c +++ b/source/blender/blenkernel/intern/fcurve.c @@ -1418,7 +1418,7 @@ static float evaluate_driver (ChannelDriver *driver, float evaltime) /* this evaluates the expression using Python,and returns its result: * - on errors it reports, then returns 0.0f */ - driver->curval= BPY_pydriver_eval(driver); + driver->curval= BPY_eval_driver(driver); } #endif /* DISABLE_PYTHON*/ } diff --git a/source/blender/blenkernel/intern/fmodifier.c b/source/blender/blenkernel/intern/fmodifier.c index 868b06f2348..6fcc49f9ec1 100644 --- a/source/blender/blenkernel/intern/fmodifier.c +++ b/source/blender/blenkernel/intern/fmodifier.c @@ -44,7 +44,7 @@ #include "BKE_utildefines.h" #ifndef DISABLE_PYTHON -#include "BPY_extern.h" /* for BPY_pydriver_eval() */ +#include "BPY_extern.h" /* for BPY_eval_driver() */ #endif #define SMALL -1.0e-10 diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 39efd9fe72e..f860f579930 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -1562,7 +1562,7 @@ static ImBuf *image_load_sequence_file(Image *ima, ImageUser *iuser, int frame) BLI_strncpy(name, ima->name, sizeof(name)); if(ima->id.lib) - BLI_path_abs(name, ima->id.lib->filename); + BLI_path_abs(name, ima->id.lib->filepath); else BLI_path_abs(name, G.sce); @@ -1669,7 +1669,7 @@ static ImBuf *image_load_movie_file(Image *ima, ImageUser *iuser, int frame) BLI_strncpy(str, ima->name, FILE_MAX); if(ima->id.lib) - BLI_path_abs(str, ima->id.lib->filename); + BLI_path_abs(str, ima->id.lib->filepath); else BLI_path_abs(str, G.sce); @@ -1727,7 +1727,7 @@ static ImBuf *image_load_image_file(Image *ima, ImageUser *iuser, int cfra) /* get the right string */ BLI_strncpy(str, ima->name, sizeof(str)); if(ima->id.lib) - BLI_path_abs(str, ima->id.lib->filename); + BLI_path_abs(str, ima->id.lib->filepath); else BLI_path_abs(str, G.sce); diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 1381a3b19dd..5931bf973af 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -1225,7 +1225,7 @@ static void image_fix_relative_path(Image *ima) { if(ima->id.lib==NULL) return; if(strncmp(ima->name, "//", 2)==0) { - BLI_path_abs(ima->name, ima->id.lib->filename); + BLI_path_abs(ima->name, ima->id.lib->filepath); BLI_path_rel(ima->name, G.sce); } } diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index d8c39abc44a..ee8a74d6fbb 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -139,6 +139,14 @@ void multires_force_update(Object *ob) } } +void multires_force_external_reload(Object *ob) +{ + Mesh *me = get_mesh(ob); + + CustomData_external_reload(&me->fdata, &me->id, CD_MASK_MDISPS, me->totface); + multires_force_update(ob); +} + void multires_force_render_update(Object *ob) { if(ob && (ob->mode & OB_MODE_SCULPT) && modifiers_findByType(ob, eModifierType_Multires)) @@ -552,7 +560,7 @@ static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, int invert, int dGridSize = multires_side_tot[totlvl]; dSkip = (dGridSize-1)/(gridSize-1); - #pragma omp parallel for private(i) schedule(static) + //#pragma omp parallel for private(i) schedule(static) for(i = 0; i < me->totface; ++i) { const int numVerts = mface[i].v4 ? 4 : 3; MDisps *mdisp = &mdisps[i]; @@ -560,7 +568,7 @@ static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, int invert, int /* when adding new faces in edit mode, need to allocate disps */ if(!mdisp->disps) - #pragma omp critical + //#pragma omp critical { multires_reallocate_mdisps(me, mdisps, totlvl); } @@ -646,7 +654,9 @@ static void multiresModifier_update(DerivedMesh *dm) int i, j, numGrids, highGridSize, lowGridSize; /* create subsurf DM from original mesh at high level */ - cddm = CDDM_from_mesh(me, NULL); + if (ob->derivedDeform) cddm = CDDM_copy(ob->derivedDeform); + else cddm = CDDM_from_mesh(me, NULL); + highdm = subsurf_dm_create_local(ob, cddm, totlvl, mmd->simple, 0); /* create multires DM from original mesh and displacements */ @@ -697,7 +707,9 @@ static void multiresModifier_update(DerivedMesh *dm) else { DerivedMesh *cddm, *subdm; - cddm = CDDM_from_mesh(me, NULL); + if (ob->derivedDeform) cddm = CDDM_copy(ob->derivedDeform); + else cddm = CDDM_from_mesh(me, NULL); + subdm = subsurf_dm_create_local(ob, cddm, mmd->totlvl, mmd->simple, 0); cddm->release(cddm); diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index fffbd31aa02..0c55cc2aaac 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -433,7 +433,7 @@ void free_keyed_keys(ParticleSystem *psys) } } } -static void free_child_path_cache(ParticleSystem *psys) +void psys_free_child_path_cache(ParticleSystem *psys) { psys_free_path_cache_buffers(psys->childcache, &psys->childcachebufs); psys->childcache = NULL; @@ -451,7 +451,7 @@ void psys_free_path_cache(ParticleSystem *psys, PTCacheEdit *edit) psys->pathcache= NULL; psys->totcached= 0; - free_child_path_cache(psys); + psys_free_child_path_cache(psys); } } void psys_free_children(ParticleSystem *psys) @@ -462,7 +462,7 @@ void psys_free_children(ParticleSystem *psys) psys->totchild=0; } - free_child_path_cache(psys); + psys_free_child_path_cache(psys); } void psys_free_particles(ParticleSystem *psys) { @@ -1037,6 +1037,7 @@ typedef struct ParticleInterpolationData { ParticleKey *kkey[2]; PointCache *cache; + PTCacheMem *pm; PTCacheEditPoint *epoint; PTCacheEditKey *ekey[2]; @@ -1045,31 +1046,74 @@ typedef struct ParticleInterpolationData { int bspline; } ParticleInterpolationData; /* Assumes pointcache->mem_cache exists, so for disk cached particles call psys_make_temp_pointcache() before use */ -static void get_pointcache_keys_for_time(Object *ob, PointCache *cache, int index, float t, ParticleKey *key1, ParticleKey *key2) +/* It uses ParticleInterpolationData->pm to store the current memory cache frame so it's thread safe. */ +static void get_pointcache_keys_for_time(Object *ob, PointCache *cache, PTCacheMem **cur, int index, float t, ParticleKey *key1, ParticleKey *key2) { - static PTCacheMem *pm = NULL; /* not thread safe */ + static PTCacheMem *pm = NULL; if(index < 0) { /* initialize */ - pm = cache->mem_cache.first; + *cur = cache->mem_cache.first; - if(pm) - pm = pm->next; + if(*cur) + *cur = (*cur)->next; } else { - if(pm) { - while(pm && pm->next && (float)pm->frame < t) - pm = pm->next; + if(*cur) { + while(*cur && (*cur)->next && (float)(*cur)->frame < t) + *cur = (*cur)->next; + + pm = *cur; BKE_ptcache_make_particle_key(key2, pm->index_array ? pm->index_array[index] - 1 : index, pm->data, (float)pm->frame); - BKE_ptcache_make_particle_key(key1, pm->prev->index_array ? pm->prev->index_array[index] - 1 : index, pm->prev->data, (float)pm->prev->frame); + if(pm->prev->index_array && pm->prev->index_array[index] == 0) + copy_particle_key(key1, key2, 1); + else + BKE_ptcache_make_particle_key(key1, pm->prev->index_array ? pm->prev->index_array[index] - 1 : index, pm->prev->data, (float)pm->prev->frame); } else if(cache->mem_cache.first) { - PTCacheMem *pm2 = cache->mem_cache.first; - BKE_ptcache_make_particle_key(key2, pm2->index_array ? pm2->index_array[index] - 1 : index, pm2->data, (float)pm2->frame); + pm = cache->mem_cache.first; + BKE_ptcache_make_particle_key(key2, pm->index_array ? pm->index_array[index] - 1 : index, pm->data, (float)pm->frame); copy_particle_key(key1, key2, 1); } } } +static int get_pointcache_times_for_particle(PointCache *cache, int index, float *start, float *end) +{ + PTCacheMem *pm; + int ret = 0; + + for(pm=cache->mem_cache.first; pm; pm=pm->next) { + if(pm->index_array) { + if(pm->index_array[index]) { + *start = pm->frame; + ret++; + break; + } + } + else { + *start = pm->frame; + ret++; + break; + } + } + + for(pm=cache->mem_cache.last; pm; pm=pm->prev) { + if(pm->index_array) { + if(pm->index_array[index]) { + *end = pm->frame; + ret++; + break; + } + } + else { + *end = pm->frame; + ret++; + break; + } + } + + return ret == 2; +} static void init_particle_interpolation(Object *ob, ParticleSystem *psys, ParticleData *pa, ParticleInterpolationData *pind) { @@ -1091,10 +1135,15 @@ static void init_particle_interpolation(Object *ob, ParticleSystem *psys, Partic pind->dietime = (key + pa->totkey - 1)->time; } else if(pind->cache) { - get_pointcache_keys_for_time(ob, pind->cache, -1, 0.0f, NULL, NULL); - + float start, end; + get_pointcache_keys_for_time(ob, pind->cache, &pind->pm, -1, 0.0f, NULL, NULL); pind->birthtime = pa ? pa->time : pind->cache->startframe; pind->dietime = pa ? pa->dietime : pind->cache->endframe; + + if(get_pointcache_times_for_particle(pind->cache, pa - psys->particles, &start, &end)) { + pind->birthtime = MAX2(pind->birthtime, start); + pind->dietime = MIN2(pind->dietime, end); + } } else { HairKey *key = pa->hair; @@ -1224,7 +1273,7 @@ static void do_particle_interpolation(ParticleSystem *psys, int p, ParticleData memcpy(keys + 2, pind->kkey[1], sizeof(ParticleKey)); } else if(pind->cache) { - get_pointcache_keys_for_time(NULL, pind->cache, p, real_t, keys+1, keys+2); + get_pointcache_keys_for_time(NULL, pind->cache, &pind->pm, p, real_t, keys+1, keys+2); } else { hair_to_particle(keys + 1, pind->hkey[0]); @@ -2672,7 +2721,7 @@ void psys_cache_child_paths(ParticleSimulationData *sim, float cfra, int editupd } else { /* clear out old and create new empty path cache */ - free_child_path_cache(sim->psys); + psys_free_child_path_cache(sim->psys); sim->psys->childcache= psys_alloc_path_cache_buffers(&sim->psys->childcachebufs, totchild, ctx->steps+1); sim->psys->totchildcache = totchild; } @@ -2743,7 +2792,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra) int keyed, baked; /* we don't have anything valid to create paths from so let's quit here */ - if((psys->flag & PSYS_HAIR_DONE || psys->flag & PSYS_KEYED || psys->pointcache->flag & PTCACHE_BAKED)==0) + if((psys->flag & PSYS_HAIR_DONE || psys->flag & PSYS_KEYED || psys->pointcache)==0) return; if(psys_in_edit_mode(sim->scene, psys)) @@ -2753,7 +2802,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra) BLI_srandom(psys->seed); keyed = psys->flag & PSYS_KEYED; - baked = !hair_dm && psys->pointcache->flag & PTCACHE_BAKED; + baked = !hair_dm && psys->pointcache->mem_cache.first; /* clear out old and create new empty path cache */ psys_free_path_cache(psys, psys->edit); @@ -3148,7 +3197,7 @@ void psys_cache_edit_paths(Scene *scene, Object *ob, PTCacheEdit *edit, float cf edit->totcached = totpart; - if(psys && psys->part->type == PART_HAIR) { + if(psys) { ParticleSimulationData sim = {scene, ob, psys, psys_get_modifier(ob, psys), NULL}; psys_cache_child_paths(&sim, cfra, 1); } diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 25328a06328..ce84ee96d01 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -3075,66 +3075,18 @@ static void deflect_particle(ParticleSimulationData *sim, int p, float dfra, flo /* Hair */ /************************************************/ /* check if path cache or children need updating and do it if needed */ -static void psys_update_path_cache(ParticleSimulationData *sim, float cfra) +void psys_update_path_cache(ParticleSimulationData *sim, float cfra) { ParticleSystem *psys = sim->psys; ParticleSettings *part = psys->part; - ParticleEditSettings *pset = &sim->scene->toolsettings->particle; - int distr=0, alloc=0, skip=0; - - if((psys->part->childtype && psys->totchild != get_psys_tot_child(sim->scene, psys)) || psys->recalc&PSYS_RECALC_RESET) - alloc=1; - - if(alloc || psys->recalc&PSYS_RECALC_CHILD || (psys->vgroup[PSYS_VG_DENSITY] && (sim->ob && sim->ob->mode & OB_MODE_WEIGHT_PAINT))) - distr=1; - - if(distr){ - if(alloc) - realloc_particles(sim, sim->psys->totpart); - - if(get_psys_tot_child(sim->scene, psys)) { - /* don't generate children while computing the hair keys */ - if(!(psys->part->type == PART_HAIR) || (psys->flag & PSYS_HAIR_DONE)) { - distribute_particles(sim, PART_FROM_CHILD); - - if(part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES && part->parents!=0.0) - psys_find_parents(sim); - } - } - else - psys_free_children(psys); - } - - if((part->type==PART_HAIR || psys->flag&PSYS_KEYED || psys->pointcache->flag & PTCACHE_BAKED)==0) - skip = 1; /* only hair, keyed and baked stuff can have paths */ - else if(part->ren_as != PART_DRAW_PATH && !(part->type==PART_HAIR && ELEM(part->ren_as, PART_DRAW_OB, PART_DRAW_GR))) - skip = 1; /* particle visualization must be set as path */ - else if(!psys->renderdata) { - if(part->draw_as != PART_DRAW_REND) - skip = 1; /* draw visualization */ - else if(psys->pointcache->flag & PTCACHE_BAKING) - skip = 1; /* no need to cache paths while baking dynamics */ - else if(psys_in_edit_mode(sim->scene, psys)) { - if((pset->flag & PE_DRAW_PART)==0) - skip = 1; - else if(part->childtype==0 && (psys->flag & PSYS_HAIR_DYNAMICS && psys->pointcache->flag & PTCACHE_BAKED)==0) - skip = 1; /* in edit mode paths are needed for child particles and dynamic hair */ - } - } - - if(!skip) { + + /* only hair, keyed and baked stuff can have paths */ + if(part->type==PART_HAIR || psys->flag&PSYS_KEYED || psys->pointcache->mem_cache.first) { psys_cache_paths(sim, cfra); /* for render, child particle paths are computed on the fly */ - if(part->childtype) { - if(!psys->totchild) - skip = 1; - else if((psys->part->type == PART_HAIR && psys->flag & PSYS_HAIR_DONE)==0) - skip = 1; - - if(!skip) - psys_cache_child_paths(sim, cfra, 0); - } + if(part->childtype && psys->totchild) + psys_cache_child_paths(sim, cfra, 0); } else if(psys->pathcache) psys_free_path_cache(psys, NULL); @@ -3249,6 +3201,8 @@ static void do_hair_dynamics(ParticleSimulationData *sim) psys->hair_out_dm = clothModifier_do(psys->clmd, sim->scene, sim->ob, dm, 0, 0); psys->clmd->sim_parms->effector_weights = NULL; + + psys_free_path_cache(psys, NULL); } static void hair_step(ParticleSimulationData *sim, float cfra) { @@ -3278,10 +3232,6 @@ static void hair_step(ParticleSimulationData *sim, float cfra) if(psys->part->type==PART_HAIR && psys->flag & PSYS_HAIR_DYNAMICS) do_hair_dynamics(sim); - psys_update_effectors(sim); - - psys_update_path_cache(sim, cfra); - psys->flag |= PSYS_HAIR_UPDATED; } @@ -3500,14 +3450,19 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra) } free_collider_cache(&sim->colliders); + + if(psys->pathcache) + psys_free_path_cache(psys, NULL); } -static void update_children(ParticleSimulationData *sim) +void psys_update_children(ParticleSimulationData *sim) { if((sim->psys->part->type == PART_HAIR) && (sim->psys->flag & PSYS_HAIR_DONE)==0) /* don't generate children while growing hair - waste of time */ psys_free_children(sim->psys); - else if(sim->psys->part->childtype && sim->psys->totchild != get_psys_tot_child(sim->scene, sim->psys)) - distribute_particles(sim, PART_FROM_CHILD); + else if(sim->psys->part->childtype) { + if(sim->psys->totchild != get_psys_tot_child(sim->scene, sim->psys)) + distribute_particles(sim, PART_FROM_CHILD); + } else psys_free_children(sim->psys); } @@ -3762,8 +3717,6 @@ static void system_step(ParticleSimulationData *sim, float cfra) if(ELEM(cache_result, PTCACHE_READ_EXACT, PTCACHE_READ_INTERPOLATED)) { cached_step(sim, cfra); - update_children(sim); - psys_update_path_cache(sim, cfra); BKE_ptcache_validate(cache, framenr); @@ -3827,9 +3780,6 @@ static void system_step(ParticleSimulationData *sim, float cfra) BKE_ptcache_write_cache(use_cache, framenr); } - if(init) - update_children(sim); - /* cleanup */ if(psys->lattice){ end_latt_deform(psys->lattice); @@ -3992,6 +3942,13 @@ void particle_system_update(Scene *scene, Object *ob, ParticleSystem *psys) /* execute drivers only, as animation has already been done */ BKE_animsys_evaluate_animdata(&part->id, part->adt, cfra, ADT_RECALC_DRIVERS); + /* TODO: only free child paths in case of PSYS_RECALC_CHILD */ + if(psys->recalc & PSYS_RECALC) + psys_free_path_cache(psys, NULL); + + if(psys->recalc & PSYS_RECALC_CHILD) + psys_free_children(psys); + if(psys->recalc & PSYS_RECALC_TYPE) psys_changed_type(&sim); else if(psys->recalc & PSYS_RECALC_PHYS) @@ -4048,7 +4005,6 @@ void particle_system_update(Scene *scene, Object *ob, ParticleSystem *psys) if(part->phystype == PART_PHYS_KEYED) { psys_count_keyed_targets(&sim); set_keyed_keys(&sim); - psys_update_path_cache(&sim,(int)cfra); } break; } diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index cb596622431..e14828d0f20 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -1080,7 +1080,7 @@ static int ptcache_path(PTCacheID *pid, char *filename) char file[MAX_PTCACHE_PATH]; /* we dont want the dir, only the file */ char *blendfilename; - blendfilename= (lib && (pid->cache->flag & PTCACHE_IGNORE_LIBPATH)==0) ? lib->filename: G.sce; + blendfilename= (lib && (pid->cache->flag & PTCACHE_IGNORE_LIBPATH)==0) ? lib->filepath: G.sce; BLI_split_dirfile(blendfilename, NULL, file); i = strlen(file); diff --git a/source/blender/blenkernel/intern/report.c b/source/blender/blenkernel/intern/report.c index da8b018d3f8..d5990ce81ec 100644 --- a/source/blender/blenkernel/intern/report.c +++ b/source/blender/blenkernel/intern/report.c @@ -32,6 +32,7 @@ #include "BKE_report.h" #include "BKE_global.h" /* G.background only */ +#include "BKE_utildefines.h" #include <stdarg.h> #include <stdio.h> @@ -262,3 +263,14 @@ void BKE_reports_print(ReportList *reports, ReportType level) MEM_freeN(cstring); } +Report *BKE_reports_last_displayable(ReportList *reports) +{ + Report *report=NULL; + + for (report= (Report *)reports->list.last; report; report=report->prev) { + if (ELEM3(report->type, RPT_ERROR, RPT_WARNING, RPT_INFO)) + return report; + } + + return NULL; +}
\ No newline at end of file diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c index 24e5014a741..6402f908422 100644 --- a/source/blender/blenkernel/intern/sound.c +++ b/source/blender/blenkernel/intern/sound.c @@ -256,7 +256,7 @@ void sound_load(struct Main *bmain, struct bSound* sound) BLI_strncpy(fullpath, sound->name, sizeof(fullpath)); if(sound->id.lib) - path = sound->id.lib->filename; + path = sound->id.lib->filepath; else path = bmain ? bmain->name : G.sce; diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 72236a76032..53206bb3970 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -44,6 +44,7 @@ #include "BKE_cdderivedmesh.h" #include "BKE_global.h" #include "BKE_mesh.h" +#include "BKE_modifier.h" #include "BKE_paint.h" #include "BKE_scene.h" #include "BKE_subsurf.h" @@ -2229,10 +2230,28 @@ static ListBase *ccgDM_getFaceMap(Object *ob, DerivedMesh *dm) return ccgdm->fmap; } +static int ccgDM_use_grid_pbvh(CCGDerivedMesh *ccgdm) +{ + ModifierData *md; + MultiresModifierData *mmd= ccgdm->multires.mmd; + + /* in sync with sculpt mode, only use multires grid pbvh if we are + the last enabled modifier in the stack, otherwise we use the base + mesh */ + if(!mmd) + return 0; + + for(md=mmd->modifier.next; md; md= md->next) + if(modifier_isEnabled(mmd->modifier.scene, md, eModifierMode_Realtime)) + return 0; + + return 1; +} + static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm) { CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm; - int gridSize, numGrids; + int gridSize, numGrids, grid_pbvh; if(!ob) { ccgdm->pbvh= NULL; @@ -2241,13 +2260,30 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm) if(!ob->sculpt) return NULL; - if(ob->sculpt->pbvh) - ccgdm->pbvh= ob->sculpt->pbvh; + + grid_pbvh = ccgDM_use_grid_pbvh(ccgdm); + + if(ob->sculpt->pbvh) { + if(grid_pbvh) { + /* pbvh's grids, gridadj and gridfaces points to data inside ccgdm + but this can be freed on ccgdm release, this updates the pointers + when the ccgdm gets remade, the assumption is that the topology + does not change. */ + ccgdm_create_grids(dm); + BLI_pbvh_grids_update(ob->sculpt->pbvh, ccgdm->gridData, ccgdm->gridAdjacency, (void**)ccgdm->gridFaces); + } + + ccgdm->pbvh = ob->sculpt->pbvh; + ccgdm->pbvh_draw = grid_pbvh; + } if(ccgdm->pbvh) return ccgdm->pbvh; - if(ccgdm->multires.mmd) { + /* no pbvh exists yet, we need to create one. only in case of multires + we build a pbvh over the modified mesh, in other cases the base mesh + is being sculpted, so we build a pbvh from that. */ + if(grid_pbvh) { ccgdm_create_grids(dm); gridSize = ccgDM_getGridSize(dm); @@ -2256,6 +2292,7 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm) ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new(); BLI_pbvh_build_grids(ccgdm->pbvh, ccgdm->gridData, ccgdm->gridAdjacency, numGrids, gridSize, (void**)ccgdm->gridFaces); + ccgdm->pbvh_draw = 1; } else if(ob->type == OB_MESH) { Mesh *me= ob->data; @@ -2263,6 +2300,7 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm) ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new(); BLI_pbvh_build_mesh(ccgdm->pbvh, me->mface, me->mvert, me->totface, me->totvert); + ccgdm->pbvh_draw = 0; } return ccgdm->pbvh; diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index 873a4103e3e..6d8c339d2b9 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -1149,7 +1149,8 @@ void BKE_free_pointdensity(PointDensity *pd) void BKE_free_voxeldatadata(struct VoxelData *vd) { if (vd->dataset) { - MEM_freeN(vd->dataset); + if(vd->file_format != TEX_VD_SMOKE) + MEM_freeN(vd->dataset); vd->dataset = NULL; } @@ -1173,6 +1174,8 @@ struct VoxelData *BKE_add_voxeldata(void) vd->int_multiplier = 1.0; vd->extend = TEX_CLIP; vd->object = NULL; + vd->cachedframe = -1; + vd->ok = 0; return vd; } diff --git a/source/blender/blenlib/BLI_pbvh.h b/source/blender/blenlib/BLI_pbvh.h index 0da5b8529bb..e32e85e70ec 100644 --- a/source/blender/blenlib/BLI_pbvh.h +++ b/source/blender/blenlib/BLI_pbvh.h @@ -111,6 +111,8 @@ void BLI_pbvh_node_get_original_BB(PBVHNode *node, float bb_min[3], float bb_max void BLI_pbvh_update(PBVH *bvh, int flags, float (*face_nors)[3]); void BLI_pbvh_redraw_BB(PBVH *bvh, float bb_min[3], float bb_max[3]); void BLI_pbvh_get_grid_updates(PBVH *bvh, int clear, void ***gridfaces, int *totface); +void BLI_pbvh_grids_update(PBVH *bvh, struct DMGridData **grids, + struct DMGridAdjacency *gridadj, void **gridfaces); /* Vertex Iterator */ diff --git a/source/blender/blenlib/intern/bpath.c b/source/blender/blenlib/intern/bpath.c index a2bdcfd0076..9b1d29e6e12 100644 --- a/source/blender/blenlib/intern/bpath.c +++ b/source/blender/blenlib/intern/bpath.c @@ -335,7 +335,7 @@ void BLI_bpathIterator_step( struct BPathIterator *bpi) { /* get the path info from this datatype */ Image *ima = (Image *)bpi->data; - bpi->lib = ima->id.lib ? ima->id.lib->filename : NULL; + bpi->lib = ima->id.lib ? ima->id.lib->filepath : NULL; bpi->path = ima->name; bpi->name = ima->id.name+2; bpi->len = sizeof(ima->name); @@ -356,7 +356,7 @@ void BLI_bpathIterator_step( struct BPathIterator *bpi) { /* get the path info from this datatype */ bSound *snd = (bSound *)bpi->data; - bpi->lib = snd->id.lib ? snd->id.lib->filename : NULL; + bpi->lib = snd->id.lib ? snd->id.lib->filepath : NULL; bpi->path = snd->name; bpi->name = snd->id.name+2; bpi->len = sizeof(snd->name); @@ -377,7 +377,7 @@ void BLI_bpathIterator_step( struct BPathIterator *bpi) { /* get the path info from this datatype */ VFont *vf = (VFont *)bpi->data; - bpi->lib = vf->id.lib ? vf->id.lib->filename : NULL; + bpi->lib = vf->id.lib ? vf->id.lib->filepath : NULL; bpi->path = vf->name; bpi->name = vf->id.name+2; bpi->len = sizeof(vf->name); @@ -424,7 +424,7 @@ void BLI_bpathIterator_step( struct BPathIterator *bpi) { if (bpi->data) { Mesh *me = (Mesh *)bpi->data; - bpi->lib = me->id.lib ? me->id.lib->filename : NULL; + bpi->lib = me->id.lib ? me->id.lib->filepath : NULL; bpi->path = me->fdata.external->filename; bpi->name = me->id.name+2; bpi->len = sizeof(me->fdata.external->filename); diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index f973d4e894b..0a06cd10e1e 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -1669,9 +1669,9 @@ void polarview_m4(float Vm[][4],float dist, float azimuth, float incidence, floa unit_m4(Vm); translate_m4(Vm,0.0, 0.0, -dist); - rotate_m4(Vm,'z',-twist); - rotate_m4(Vm,'x',-incidence); - rotate_m4(Vm,'z',-azimuth); + rotate_m4(Vm,'Z',-twist); + rotate_m4(Vm,'X',-incidence); + rotate_m4(Vm,'Z',-azimuth); } void lookat_m4(float mat[][4],float vx, float vy, float vz, float px, float py, float pz, float twist) @@ -1682,7 +1682,7 @@ void lookat_m4(float mat[][4],float vx, float vy, float vz, float px, float py, unit_m4(mat); unit_m4(mat1); - rotate_m4(mat,'z',-twist); + rotate_m4(mat, 'Z', -twist); dx = px - vx; dy = py - vy; diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c index 85d18d99f96..301b981cdc7 100644 --- a/source/blender/blenlib/intern/path_util.c +++ b/source/blender/blenlib/intern/path_util.c @@ -354,8 +354,6 @@ void BLI_cleanup_file(const char *relabase, char *dir) void BLI_path_rel(char *file, const char *relfile) { - char * p; - char * q; char * lslash; char temp[FILE_MAXDIR+FILE_MAXFILE]; char res[FILE_MAXDIR+FILE_MAXFILE]; @@ -403,11 +401,18 @@ void BLI_path_rel(char *file, const char *relfile) { /* find the prefix of the filename that is equal for both filenames. This is replaced by the two slashes at the beginning */ - p = temp; - q = file; - while (*p == *q) { + char *p= temp; + char *q= file; + + while ((*p == *q)) { ++p; ++q; + /* dont search beyond the end of the string + * in the rare case they match */ + if ((*p=='\0') || (*q=='\0')) { + break; + } } + /* we might have passed the slash when the beginning of a dir matches so we rewind. Only check on the actual filename */ @@ -839,11 +844,12 @@ static int gethome_path_local(char *targetpath, char *folder_name) i = s - bprogname + 1; BLI_strncpy(bprogdir, bprogname, i); - /* try release/folder_name (CWD relative) */ - if(test_data_path(targetpath, BLI_getwdN(cwd), "release", folder_name)) + /* try release/folder_name (BIN relative) */ + if(test_data_path(targetpath, bprogdir, "release", folder_name)) return 1; - if(test_data_path(targetpath, bprogdir, "release", folder_name)) + /* try release/folder_name (CWD relative) */ + if(test_data_path(targetpath, BLI_getwdN(cwd), "release", folder_name)) return 1; /* try ./.blender/folder_name */ diff --git a/source/blender/blenlib/intern/pbvh.c b/source/blender/blenlib/intern/pbvh.c index 8aff062c1d4..1fd18e2967c 100644 --- a/source/blender/blenlib/intern/pbvh.c +++ b/source/blender/blenlib/intern/pbvh.c @@ -1323,3 +1323,10 @@ void BLI_pbvh_draw(PBVH *bvh, float (*planes)[4], float (*face_nors)[3], int smo } } +void BLI_pbvh_grids_update(PBVH *bvh, DMGridData **grids, DMGridAdjacency *gridadj, void **gridfaces) +{ + bvh->grids= grids; + bvh->gridadj= gridadj; + bvh->gridfaces= gridfaces; +} + diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index c74b1e7b374..145d0a9c0c8 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -507,7 +507,7 @@ static Main *blo_find_main(FileData *fd, ListBase *mainlist, const char *name, c // printf("blo_find_main: converted to %s\n", name1); for (m= mainlist->first; m; m= m->next) { - char *libname= (m->curlib)?m->curlib->filename:m->name; + char *libname= (m->curlib)?m->curlib->filepath:m->name; if (BLI_streq(name1, libname)) { if(G.f & G_DEBUG) printf("blo_find_main: found library %s\n", libname); @@ -520,7 +520,7 @@ static Main *blo_find_main(FileData *fd, ListBase *mainlist, const char *name, c lib= alloc_libblock(&m->library, ID_LI, "lib"); strncpy(lib->name, name, sizeof(lib->name)-1); - BLI_strncpy(lib->filename, name1, sizeof(lib->filename)); + BLI_strncpy(lib->filepath, name1, sizeof(lib->filepath)); m->curlib= lib; @@ -2839,6 +2839,7 @@ static void direct_link_texture(FileData *fd, Tex *tex) tex->vd= newdataadr(fd, tex->vd); if(tex->vd) { tex->vd->dataset = NULL; + tex->vd->ok = 0; } tex->nodetree= newdataadr(fd, tex->nodetree); @@ -4174,7 +4175,7 @@ static void lib_link_scene(FileData *fd, Main *main) if(seq->ipo) seq->ipo= newlibadr_us(fd, sce->id.lib, seq->ipo); if(seq->scene) { seq->scene= newlibadr(fd, sce->id.lib, seq->scene); - seq->scene_sound = sound_scene_add_scene_sound(sce, seq, seq->startdisp, seq->enddisp, seq->startofs); + seq->scene_sound = sound_scene_add_scene_sound(sce, seq, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs); } if(seq->scene_camera) seq->scene_camera= newlibadr(fd, sce->id.lib, seq->scene_camera); if(seq->sound) { @@ -4185,7 +4186,7 @@ static void lib_link_scene(FileData *fd, Main *main) seq->sound= newlibadr(fd, sce->id.lib, seq->sound); if (seq->sound) { seq->sound->id.us++; - seq->scene_sound = sound_add_scene_sound(sce, seq, seq->startdisp, seq->enddisp, seq->startofs); + seq->scene_sound = sound_add_scene_sound(sce, seq, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs); } } seq->anim= 0; @@ -5237,8 +5238,8 @@ static void direct_link_library(FileData *fd, Library *lib, Main *main) for(newmain= fd->mainlist.first; newmain; newmain= newmain->next) { if(newmain->curlib) { - if(strcmp(newmain->curlib->filename, lib->filename)==0) { - printf("Fixed error in file; multiple instances of lib:\n %s\n", lib->filename); + if(strcmp(newmain->curlib->filepath, lib->filepath)==0) { + printf("Fixed error in file; multiple instances of lib:\n %s\n", lib->filepath); change_idid_adr(&fd->mainlist, fd, lib, newmain->curlib); // change_idid_adr_fd(fd, lib, newmain->curlib); @@ -5253,8 +5254,8 @@ static void direct_link_library(FileData *fd, Library *lib, Main *main) } } /* make sure we have full path in lib->filename */ - BLI_strncpy(lib->filename, lib->name, sizeof(lib->name)); - cleanup_path(fd->relabase, lib->filename); + BLI_strncpy(lib->filepath, lib->name, sizeof(lib->name)); + cleanup_path(fd->relabase, lib->filepath); // printf("direct_link_library: name %s\n", lib->name); // printf("direct_link_library: filename %s\n", lib->filename); @@ -5287,7 +5288,7 @@ static void fix_relpaths_library(const char *basepath, Main *main) /* Libraries store both relative and abs paths, recreate relative paths, * relative to the blend file since indirectly linked libs will be relative to their direct linked library */ if (strncmp(lib->name, "//", 2)==0) { /* if this is relative to begin with? */ - strncpy(lib->name, lib->filename, sizeof(lib->name)); + strncpy(lib->name, lib->filepath, sizeof(lib->name)); BLI_path_rel(lib->name, basepath); } } @@ -12220,7 +12221,7 @@ static void library_append_end(const bContext *C, Main *mainl, FileData **fd, in if(flag & FILE_RELPATH) { /* use the full path, this could have been read by other library even */ - BLI_strncpy(mainl->curlib->name, mainl->curlib->filename, sizeof(mainl->curlib->name)); + BLI_strncpy(mainl->curlib->name, mainl->curlib->filepath, sizeof(mainl->curlib->name)); /* uses current .blend file as reference */ BLI_path_rel(mainl->curlib->name, G.sce); @@ -12337,10 +12338,10 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) if(fd==NULL) { /* printf and reports for now... its important users know this */ - BKE_reportf(basefd->reports, RPT_INFO, "read library: '%s', '%s'\n", mainptr->curlib->filename, mainptr->curlib->name); - if(!G.background && basefd->reports) printf("read library: '%s', '%s'\n", mainptr->curlib->filename, mainptr->curlib->name); + BKE_reportf(basefd->reports, RPT_INFO, "read library: '%s', '%s'\n", mainptr->curlib->filepath, mainptr->curlib->name); + if(!G.background && basefd->reports) printf("read library: '%s', '%s'\n", mainptr->curlib->filepath, mainptr->curlib->name); - fd= blo_openblenderfile(mainptr->curlib->filename, basefd->reports); + fd= blo_openblenderfile(mainptr->curlib->filepath, basefd->reports); /* allow typing in a new lib path */ if(G.rt==-666) { @@ -12348,19 +12349,19 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) char newlib_path[240] = { 0 }; printf("Missing library...'\n"); printf(" current file: %s\n", G.sce); - printf(" absolute lib: %s\n", mainptr->curlib->filename); + printf(" absolute lib: %s\n", mainptr->curlib->filepath); printf(" relative lib: %s\n", mainptr->curlib->name); printf(" enter a new path:\n"); if(scanf("%s", newlib_path) > 0) { strcpy(mainptr->curlib->name, newlib_path); - strcpy(mainptr->curlib->filename, newlib_path); - cleanup_path(G.sce, mainptr->curlib->filename); + strcpy(mainptr->curlib->filepath, newlib_path); + cleanup_path(G.sce, mainptr->curlib->filepath); - fd= blo_openblenderfile(mainptr->curlib->filename, basefd->reports); + fd= blo_openblenderfile(mainptr->curlib->filepath, basefd->reports); if(fd) { - printf("found: '%s', party on macuno!\n", mainptr->curlib->filename); + printf("found: '%s', party on macuno!\n", mainptr->curlib->filepath); } } } @@ -12383,8 +12384,8 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) else mainptr->curlib->filedata= NULL; if (fd==NULL) { - BKE_reportf(basefd->reports, RPT_ERROR, "Can't find lib '%s'\n", mainptr->curlib->filename); - if(!G.background && basefd->reports) printf("ERROR: can't find lib %s \n", mainptr->curlib->filename); + BKE_reportf(basefd->reports, RPT_ERROR, "Can't find lib '%s'\n", mainptr->curlib->filepath); + if(!G.background && basefd->reports) printf("ERROR: can't find lib %s \n", mainptr->curlib->filepath); } } if(fd) { @@ -12401,8 +12402,8 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) append_id_part(fd, mainptr, id, &realid); if (!realid) { - BKE_reportf(fd->reports, RPT_ERROR, "LIB ERROR: %s:'%s' missing from '%s'\n", BLO_idcode_to_name(GS(id->name)), id->name+2, mainptr->curlib->filename); - if(!G.background && basefd->reports) printf("LIB ERROR: %s:'%s' missing from '%s'\n", BLO_idcode_to_name(GS(id->name)), id->name+2, mainptr->curlib->filename); + BKE_reportf(fd->reports, RPT_ERROR, "LIB ERROR: %s:'%s' missing from '%s'\n", BLO_idcode_to_name(GS(id->name)), id->name+2, mainptr->curlib->filepath); + if(!G.background && basefd->reports) printf("LIB ERROR: %s:'%s' missing from '%s'\n", BLO_idcode_to_name(GS(id->name)), id->name+2, mainptr->curlib->filepath); } change_idid_adr(mainlist, basefd, id, realid); @@ -12437,8 +12438,8 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) ID *idn= id->next; if(id->flag & LIB_READ) { BLI_remlink(lbarray[a], id); - BKE_reportf(basefd->reports, RPT_ERROR, "LIB ERROR: %s:'%s' unread libblock missing from '%s'\n", BLO_idcode_to_name(GS(id->name)), id->name+2, mainptr->curlib->filename); - if(!G.background && basefd->reports)printf("LIB ERROR: %s:'%s' unread libblock missing from '%s'\n", BLO_idcode_to_name(GS(id->name)), id->name+2, mainptr->curlib->filename); + BKE_reportf(basefd->reports, RPT_ERROR, "LIB ERROR: %s:'%s' unread libblock missing from '%s'\n", BLO_idcode_to_name(GS(id->name)), id->name+2, mainptr->curlib->filepath); + if(!G.background && basefd->reports)printf("LIB ERROR: %s:'%s' unread libblock missing from '%s'\n", BLO_idcode_to_name(GS(id->name)), id->name+2, mainptr->curlib->filepath); change_idid_adr(mainlist, basefd, id, NULL); MEM_freeN(id); diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index c62963c5b3b..db479b45472 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -693,7 +693,7 @@ void uiTemplateRunningJobs(uiLayout *layout, struct bContext *C); void uiTemplateOperatorSearch(uiLayout *layout); void uiTemplateHeader3D(uiLayout *layout, struct bContext *C); void uiTemplateTextureImage(uiLayout *layout, struct bContext *C, struct Tex *tex); -void uiTemplateReportsBanner(uiLayout *layout, struct bContext *C, struct wmOperator *op); +void uiTemplateReportsBanner(uiLayout *layout, struct bContext *C); void uiTemplateList(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname, struct PointerRNA *activeptr, char *activeprop, int rows, int maxrows, int type); diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 7f8d6e8e3cb..3f0cd3bee78 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -1633,7 +1633,7 @@ int ui_set_but_string(bContext *C, uiBut *but, const char *str) bUnit_ReplaceString(str_unit_convert, sizeof(str_unit_convert), but->drawstr, ui_get_but_scale_unit(but, 1.0), scene->unit.system, unit_type); } - if(BPY_button_eval(C, str_unit_convert, &value)) { + if(BPY_eval_button(C, str_unit_convert, &value)) { value = ui_get_but_val(but); /* use its original value */ if(str[0]) diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 4e3ffad48ae..1f9c2bb9ce0 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -176,6 +176,7 @@ typedef struct uiAfterFunc { int autokey; } uiAfterFunc; +static int ui_but_contains_pt(uiBut *but, int mx, int my); static int ui_mouse_inside_button(ARegion *ar, uiBut *but, int x, int y); static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState state); static int ui_handler_region_menu(bContext *C, wmEvent *event, void *userdata); @@ -1659,7 +1660,7 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle my= event->y; ui_window_to_block(data->region, block, &mx, &my); - if (ui_mouse_inside_button(data->region, but, mx, my)) { + if (ui_but_contains_pt(but, mx, my)) { ui_textedit_set_cursor_pos(but, data, mx); but->selsta = but->selend = but->pos; data->selstartx= mx; diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index 30f2ee7b923..0e58f73c87e 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -1559,12 +1559,21 @@ void ui_set_but_hsv(uiBut *but) } /* also used by small picker, be careful with name checks below... */ -void ui_update_block_buts_rgb(uiBlock *block, float *rgb) +void ui_update_block_buts_rgb(uiBlock *block, float *rgb, float *rhsv) { uiBut *bt; float hsv[3]; - rgb_to_hsv(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2); + /* this is to keep the H and S value when V is equal to zero + * and we are working in HSV mode, of course! + */ + if (rhsv) { + hsv[0]= rhsv[0]; + hsv[1]= rhsv[1]; + hsv[2]= rhsv[2]; + } + else + rgb_to_hsv(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2); // this updates button strings, is hackish... but button pointers are on stack of caller function for(bt= block->buttons.first; bt; bt= bt->next) { @@ -1630,7 +1639,7 @@ static void do_picker_rna_cb(bContext *C, void *bt1, void *unused) if (prop) { RNA_property_float_get_array(&ptr, prop, rgb); - ui_update_block_buts_rgb(but->block, rgb); + ui_update_block_buts_rgb(but->block, rgb, NULL); } if(popup) @@ -1646,7 +1655,7 @@ static void do_hsv_rna_cb(bContext *C, void *bt1, void *hsv_arg) hsv_to_rgb(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2); - ui_update_block_buts_rgb(but->block, rgb); + ui_update_block_buts_rgb(but->block, rgb, hsv); if(popup) popup->menuretval= UI_RETURN_UPDATE; @@ -1667,7 +1676,7 @@ static void do_hex_rna_cb(bContext *C, void *bt1, void *hexcl) srgb_to_linearrgb_v3_v3(rgb, rgb); } - ui_update_block_buts_rgb(but->block, rgb); + ui_update_block_buts_rgb(but->block, rgb, NULL); if(popup) popup->menuretval= UI_RETURN_UPDATE; @@ -1876,7 +1885,7 @@ static int ui_picker_small_wheel(const bContext *C, uiBlock *block, wmEvent *eve ui_set_but_vectorf(but, col); - ui_update_block_buts_rgb(block, col); + ui_update_block_buts_rgb(block, col, NULL); if(popup) popup->menuretval= UI_RETURN_UPDATE; diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 4183ff49e51..05c162ef639 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -30,6 +30,7 @@ #include "DNA_scene_types.h" #include "DNA_userdef_types.h" +#include "DNA_windowmanager_types.h" #include "BLI_string.h" @@ -53,6 +54,8 @@ #include "UI_interface.h" #include "interface_intern.h" +#include "BLF_api.h" + void ui_template_fix_linking() { } @@ -2455,49 +2458,59 @@ void uiTemplateRunningJobs(uiLayout *layout, bContext *C) uiDefIconTextBut(block, BUT, B_STOPCAST, ICON_CANCEL, "Capture", 0,0,85,UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "Stop screencast"); if(screen->animtimer) uiDefIconTextBut(block, BUT, B_STOPANIM, ICON_CANCEL, "Anim Player", 0,0,100,UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "Stop animation playback"); - - uiItemS(layout); } /************************* Reports for Last Operator Template **************************/ -void uiTemplateReportsBanner(uiLayout *layout, bContext *C, wmOperator *op) +void uiTemplateReportsBanner(uiLayout *layout, bContext *C) { - ReportList *reports = op->reports; - uiLayout *box; + ReportList *reports = CTX_wm_reports(C); + Report *report= BKE_reports_last_displayable(reports); + ReportTimerInfo *rti; - /* sanity checks */ - if (ELEM(NULL, op, reports)) { - printf("uiTemplateReportsBanner: no operator with reports!\n"); - return; - } + uiLayout *abs; + uiBlock *block; + uiBut *but; + uiStyle *style= U.uistyles.first; + int width; + float hsv[3]; + + /* if the report display has timed out, don't show */ + if (!reports->reporttimer) return; + + rti= (ReportTimerInfo *)reports->reporttimer->customdata; + + if (!rti || rti->widthfac==0.0 || !report) return; + + abs = uiLayoutAbsolute(layout, 0); + block= uiLayoutGetBlock(abs); + + rgb_to_hsv(rti->col[0], rti->col[1], rti->col[2], hsv+0, hsv+1, hsv+2); + + width = BLF_width(style->widget.uifont_id, report->message); + width = MIN2(rti->widthfac*width, width); + width = MAX2(width, 10); /* make a box around the report to make it stand out */ - box = uiLayoutBox(layout); - uiLayoutSetScaleY(box, 0.48); /* experimentally determined value to reduce execessive padding... */ + uiBlockBeginAlign(block); + but= uiDefBut(block, ROUNDBOX, 0, "", 0, 0, UI_UNIT_X+10, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, ""); + copy_v3_v3(but->hsv, hsv); /* set the report's bg colour in but->hsv - ROUNDBOX feature */ - /* if more than one report, we need to show the popup when user clicks on the temp label... */ - if (reports->list.first != reports->list.last) { - int numReports = BLI_countlist(&reports->list); - char buf[64]; - - // XXX: we need uiItem* to return uiBut pointer so that we can use it to set callbacks - // used to call uiPupMenuReports... as alternative, we could fall back to the "old ways" - //sprintf(buf, "Last Operator had %d errors. Click to see more...", numReports); - sprintf(buf, "Last Operator had %d errors", numReports); - uiItemL(box, buf, ICON_INFO); - } - else { - /* single report, so show report directly */ - // XXX: what if the report is too long? should we truncate the text? - Report *report= (Report *)reports->list.first; - - if(report->type >= RPT_ERROR) - uiItemL(box, report->message, ICON_ERROR); - else if(report->type >= RPT_WARNING) - uiItemL(box, report->message, ICON_ERROR); - else if(report->type >= RPT_INFO) - uiItemL(box, report->message, ICON_INFO); - } + but= uiDefBut(block, ROUNDBOX, 0, "", UI_UNIT_X+10, 0, UI_UNIT_X+width, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, ""); + but->hsv[0] = but->hsv[1] = 0.0; /* set a greyscale bg colour in but->hsv - ROUNDBOX feature */ + but->hsv[2] = rti->greyscale; + uiBlockEndAlign(block); + + + /* icon and report message on top */ + if(report->type & RPT_ERROR_ALL) + uiDefIconBut(block, LABEL, 0, ICON_ERROR, 2, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, ""); + else if(report->type & RPT_WARNING_ALL) + uiDefIconBut(block, LABEL, 0, ICON_ERROR, 2, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, ""); + else if(report->type & RPT_INFO_ALL) + uiDefIconBut(block, LABEL, 0, ICON_INFO, 2, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, ""); + + uiDefBut(block, LABEL, 0, report->message, UI_UNIT_X+10, 0, UI_UNIT_X+width, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, ""); + } diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index c419c73c1e0..dfca12b1d49 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -2368,9 +2368,21 @@ static void widget_radiobut(uiWidgetColors *wcol, rcti *rect, int state, int rou static void widget_box(uiBut *but, uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign) { uiWidgetBase wtb; + char old_col[3]; widget_init(&wtb); + VECCOPY(old_col, wcol->inner); + + /* abuse but->hsv - if it's non-zero, use this colour as the box's background */ + if ((but->hsv[0] != 0.0) || (but->hsv[1] != 0.0) || (but->hsv[2] != 0.0)) { + float rgb[3]; + hsv_to_rgb(but->hsv[0], but->hsv[1], but->hsv[2], rgb+0, rgb+1, rgb+2); + wcol->inner[0] = rgb[0] * 255; + wcol->inner[1] = rgb[1] * 255; + wcol->inner[2] = rgb[2] * 255; + } + /* half rounded */ round_box_edges(&wtb, roundboxalign, rect, 4.0f); @@ -2379,6 +2391,8 @@ static void widget_box(uiBut *but, uiWidgetColors *wcol, rcti *rect, int state, /* store the box bg as gl clearcolor, to retrieve later when drawing semi-transparent rects * over the top to indicate disabled buttons */ glClearColor(wcol->inner[0]/255.0, wcol->inner[1]/255.0, wcol->inner[2]/255.0, 1.0); + + VECCOPY(wcol->inner, old_col); } static void widget_but(uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign) diff --git a/source/blender/editors/mesh/editmesh_mods.c b/source/blender/editors/mesh/editmesh_mods.c index 612facb85c1..4bc5030094e 100644 --- a/source/blender/editors/mesh/editmesh_mods.c +++ b/source/blender/editors/mesh/editmesh_mods.c @@ -4317,6 +4317,10 @@ static int smooth_vertex(bContext *C, wmOperator *op) if(eve->f & SELECT) { if(eve->f1) { + int xaxis= RNA_boolean_get(op->ptr, "xaxis"); + int yaxis= RNA_boolean_get(op->ptr, "yaxis"); + int zaxis= RNA_boolean_get(op->ptr, "zaxis"); + if (((Mesh *)obedit->data)->editflag & ME_EDIT_MIRROR_X) { eve_mir= editmesh_get_x_mirror_vert(obedit, em, eve, eve->co, index); } @@ -4324,9 +4328,12 @@ static int smooth_vertex(bContext *C, wmOperator *op) adr = eve->tmp.p; fac= 0.5/(float)eve->f1; - eve->co[0]= 0.5*eve->co[0]+fac*adr[0]; - eve->co[1]= 0.5*eve->co[1]+fac*adr[1]; - eve->co[2]= 0.5*eve->co[2]+fac*adr[2]; + if(xaxis) + eve->co[0]= 0.5*eve->co[0]+fac*adr[0]; + if(yaxis) + eve->co[1]= 0.5*eve->co[1]+fac*adr[1]; + if(zaxis) + eve->co[2]= 0.5*eve->co[2]+fac*adr[2]; /* clip if needed by mirror modifier */ @@ -4395,6 +4402,9 @@ void MESH_OT_vertices_smooth(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; RNA_def_int(ot->srna, "repeat", 1, 1, 100, "Smooth Iterations", "", 1, INT_MAX); + RNA_def_boolean(ot->srna, "xaxis", 1, "X-Axis", "Smooth along the X axis."); + RNA_def_boolean(ot->srna, "yaxis", 1, "Y-Axis", "Smooth along the Y axis."); + RNA_def_boolean(ot->srna, "zaxis", 1, "Z-Axis", "Smooth along the Z axis."); } void vertexnoise(Object *obedit, EditMesh *em) diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 8cd8688d448..13656ca1b7e 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -481,15 +481,11 @@ static int removedoublesflag_exec(bContext *C, wmOperator *op) { Object *obedit= CTX_data_edit_object(C); EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data)); - /*char msg[100];*/ - - /*int cnt =*/ removedoublesflag(em,1,0,RNA_float_get(op->ptr, "limit")); - /*XXX this messes up last operator panel - if(cnt) - { - sprintf(msg, "Removed %d vertices", cnt); - BKE_report(op->reports, RPT_INFO, msg); - }*/ + + int count = removedoublesflag(em,1,0,RNA_float_get(op->ptr, "limit")); + + if(count) + BKE_reportf(op->reports, RPT_INFO, "Removed %d vertices", count); DAG_id_flush_update(obedit->data, OB_RECALC_DATA); WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 28b9fa241ca..8afed42758a 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -2151,6 +2151,7 @@ static int game_property_new(bContext *C, wmOperator *op) BLI_addtail(&ob->prop, prop); unique_property(NULL, prop, 0); // make_unique_prop_names(prop->name); + WM_event_add_notifier(C, NC_LOGIC, NULL); return OPERATOR_FINISHED; } @@ -2183,6 +2184,8 @@ static int game_property_remove(bContext *C, wmOperator *op) if(prop) { BLI_remlink(&ob->prop, prop); free_property(prop); + + WM_event_add_notifier(C, NC_LOGIC, NULL); return OPERATOR_FINISHED; } else { @@ -2208,13 +2211,11 @@ void OBJECT_OT_game_property_remove(wmOperatorType *ot) #define COPY_PROPERTIES_REPLACE 1 #define COPY_PROPERTIES_MERGE 2 -#define COPY_PROPERTIES_CLEAR 3 -#define COPY_PROPERTIES_COPY 4 +#define COPY_PROPERTIES_COPY 3 static EnumPropertyItem game_properties_copy_operations[] ={ {COPY_PROPERTIES_REPLACE, "REPLACE", 0, "Replace Properties", ""}, {COPY_PROPERTIES_MERGE, "MERGE", 0, "Merge Properties", ""}, - {COPY_PROPERTIES_CLEAR, "CLEAR", 0, "Clear All", ""}, {COPY_PROPERTIES_COPY, "COPY", 0, "Copy a Property", ""}, {0, NULL, 0, NULL, NULL}}; @@ -2264,7 +2265,7 @@ static int game_property_copy_exec(bContext *C, wmOperator *op) } CTX_DATA_END; } } - else if (ELEM3(type, COPY_PROPERTIES_REPLACE, COPY_PROPERTIES_MERGE, COPY_PROPERTIES_CLEAR)) { + else if (ELEM(type, COPY_PROPERTIES_REPLACE, COPY_PROPERTIES_MERGE)) { CTX_DATA_BEGIN(C, Object*, ob_iter, selected_editable_objects) { if (ob != ob_iter) { if (ob->data != ob_iter->data){ @@ -2272,7 +2273,7 @@ static int game_property_copy_exec(bContext *C, wmOperator *op) for(prop = ob->prop.first; prop; prop= prop->next ) { set_ob_property(ob_iter, prop); } - } else /* replace or clear */ + } else /* replace */ copy_properties( &ob_iter->prop, &ob->prop ); } } @@ -2297,12 +2298,39 @@ void OBJECT_OT_game_property_copy(wmOperatorType *ot) /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - RNA_def_enum(ot->srna, "operation", game_properties_copy_operations, 4, "Operation", ""); + RNA_def_enum(ot->srna, "operation", game_properties_copy_operations, 3, "Operation", ""); prop=RNA_def_enum(ot->srna, "property", gameprops_items, 0, "Property", "Properties to copy"); RNA_def_enum_funcs(prop, gameprops_itemf); ot->prop=prop; } +static int game_property_clear_exec(bContext *C, wmOperator *op) +{ + Object *ob=ED_object_active_context(C); + bProperty *prop; + + CTX_DATA_BEGIN(C, Object*, ob_iter, selected_editable_objects) { + free_properties(&ob_iter->prop); + } + CTX_DATA_END; + + WM_event_add_notifier(C, NC_LOGIC, NULL); + return OPERATOR_FINISHED; +} +void OBJECT_OT_game_property_clear(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Clear Game Property"; + ot->idname= "OBJECT_OT_game_property_clear"; + + /* api callbacks */ + ot->exec= game_property_clear_exec; + ot->poll= ED_operator_object_active_editable; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + /************************ Copy Logic Bricks ***********************/ static int logicbricks_copy_exec(bContext *C, wmOperator *op) diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index 5b446b3a828..f82b4e0324f 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -88,6 +88,7 @@ void OBJECT_OT_paths_clear(struct wmOperatorType *ot); void OBJECT_OT_game_property_new(struct wmOperatorType *ot); void OBJECT_OT_game_property_remove(struct wmOperatorType *ot); void OBJECT_OT_game_property_copy(struct wmOperatorType *ot); +void OBJECT_OT_game_property_clear(struct wmOperatorType *ot); void OBJECT_OT_logic_bricks_copy(struct wmOperatorType *ot); /* object_select.c */ diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 602b94034bd..274e8ff2d73 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -184,6 +184,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_game_property_new); WM_operatortype_append(OBJECT_OT_game_property_remove); WM_operatortype_append(OBJECT_OT_game_property_copy); + WM_operatortype_append(OBJECT_OT_game_property_clear); WM_operatortype_append(OBJECT_OT_logic_bricks_copy); WM_operatortype_append(OBJECT_OT_shape_key_add); diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index 6ec744ad027..541b0cf494f 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -160,7 +160,7 @@ void PE_free_ptcache_edit(PTCacheEdit *edit) edit->emitter_field= 0; } - psys_free_path_cache(NULL, edit); + psys_free_path_cache(edit->psys, edit); MEM_freeN(edit); } diff --git a/source/blender/editors/physics/physics_fluid.c b/source/blender/editors/physics/physics_fluid.c index 3cf6ed24807..4d62d823345 100644 --- a/source/blender/editors/physics/physics_fluid.c +++ b/source/blender/editors/physics/physics_fluid.c @@ -297,6 +297,8 @@ static void set_vertex_channel(float *channel, float time, struct Scene *scene, static void free_domain_channels(FluidAnimChannels *channels) { + if (!channels->timeAtFrame) + return; MEM_freeN(channels->timeAtFrame); channels->timeAtFrame = NULL; MEM_freeN(channels->DomainGravity); @@ -781,6 +783,26 @@ int runSimulationCallback(void *data, int status, int frame) { return FLUIDSIM_CBRET_CONTINUE; } +static void fluidbake_free_data(FluidAnimChannels *channels, ListBase *fobjects, elbeemSimulationSettings *fsset, FluidBakeJob *fb) +{ + free_domain_channels(channels); + MEM_freeN(channels); + channels = NULL; + + free_all_fluidobject_channels(fobjects); + BLI_freelistN(fobjects); + MEM_freeN(fobjects); + fobjects = NULL; + + MEM_freeN(fsset); + fsset = NULL; + + if (fb) { + MEM_freeN(fb); + fb = NULL; + } +} + int fluidsimBake(bContext *C, ReportList *reports, Object *fsDomain) { Scene *scene= CTX_data_scene(C); @@ -827,13 +849,14 @@ int fluidsimBake(bContext *C, ReportList *reports, Object *fsDomain) noFrames = scene->r.efra - 0; if(noFrames<=0) { BKE_report(reports, RPT_ERROR, "No frames to export - check your animation range settings."); + fluidbake_free_data(channels, fobjects, fsset, fb); return 0; } /* check scene for sane object/modifier settings */ - if (!fluid_validate_scene(reports, scene, fsDomain)) { + if (!fluid_validate_scene(reports, scene, fsDomain)) + fluidbake_free_data(channels, fobjects, fsset, fb); return 0; - } /* these both have to be valid, otherwise we wouldnt be here */ @@ -928,12 +951,7 @@ int fluidsimBake(bContext *C, ReportList *reports, Object *fsDomain) elbeemDebugOut(debugStrBuffer); BKE_report(reports, RPT_ERROR, "Invalid object matrix."); - free_domain_channels(channels); - MEM_freeN(channels); - - free_all_fluidobject_channels(fobjects); - BLI_freelistN(fobjects); - MEM_freeN(fobjects); + fluidbake_free_data(channels, fobjects, fsset, fb); return 0; } @@ -1023,12 +1041,7 @@ int fluidsimBake(bContext *C, ReportList *reports, Object *fsDomain) WM_jobs_start(CTX_wm_manager(C), steve); /* ******** free stored animation data ******** */ - free_domain_channels(channels); - MEM_freeN(channels); - - free_all_fluidobject_channels(fobjects); - BLI_freelistN(fobjects); - MEM_freeN(fobjects); + fluidbake_free_data(channels, fobjects, fsset, NULL); // elbeemFree(); return 1; diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 8b1c0045fd3..6004820e5c8 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -2393,8 +2393,8 @@ static int match_region_with_redraws(int spacetype, int regiontype, int redraws) static int screen_animation_step(bContext *C, wmOperator *op, wmEvent *event) { bScreen *screen= CTX_wm_screen(C); - - if(screen->animtimer==event->customdata) { + + if(screen->animtimer && screen->animtimer==event->customdata) { Scene *scene= CTX_data_scene(C); wmTimer *wt= screen->animtimer; ScreenAnimData *sad= wt->customdata; @@ -2998,7 +2998,7 @@ void ED_keymap_screen(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "SCREEN_OT_repeat_last", RKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_verify_item(keymap, "SCREEN_OT_region_flip", F5KEY, KM_PRESS, 0, 0); WM_keymap_verify_item(keymap, "SCREEN_OT_redo_last", F6KEY, KM_PRESS, 0, 0); - WM_keymap_verify_item(keymap, "WM_OT_reload_scripts", F8KEY, KM_PRESS, 0, 0); + WM_keymap_verify_item(keymap, "SCRIPT_OT_reload", F8KEY, KM_PRESS, 0, 0); /* files */ WM_keymap_add_item(keymap, "FILE_OT_execute", RETKEY, KM_PRESS, 0, 0); diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index 2da638fca41..64f00caf479 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -5488,7 +5488,7 @@ static int texture_paint_image_from_view_exec(bContext *C, wmOperator *op) int h= settings->imapaint.screen_grab_size[1]; int maxsize; - RNA_string_get(op->ptr, "filename", filename); + RNA_string_get(op->ptr, "filepath", filename); glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize); @@ -5541,5 +5541,5 @@ void PAINT_OT_image_from_view(wmOperatorType *ot) /* flags */ ot->flag= OPTYPE_REGISTER; - RNA_def_string_file_name(ot->srna, "filename", "", FILE_MAX, "File Name", "Name of the file"); + RNA_def_string_file_name(ot->srna, "filepath", "", FILE_MAX, "File Path", "Name of the file"); } diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 85c33500c5d..cf760f345b5 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -286,10 +286,21 @@ static void update_cb(PBVHNode *node, void *data) static int sculpt_modifiers_active(Scene *scene, Object *ob) { ModifierData *md; + MultiresModifierData *mmd = sculpt_multires_active(scene, ob); + + /* check if there are any modifiers after what we are sculpting, + for a multires modifier with a deform modifier in front, we + do no need to recalculate the modifier stack. note that this + needs to be in sync with ccgDM_use_grid_pbvh! */ + if(mmd) + md= mmd->modifier.next; + else + md= modifiers_getVirtualModifierList(ob); - for(md= modifiers_getVirtualModifierList(ob); md; md= md->next) { + /* exception for shape keys because we can edit those */ + for(; md; md= md->next) { if(modifier_isEnabled(scene, md, eModifierMode_Realtime)) - if(!ELEM(md->type, eModifierType_Multires, eModifierType_ShapeKey)) + if(md->type != eModifierType_ShapeKey) return 1; } @@ -363,7 +374,7 @@ static void sculpt_undo_restore(bContext *C, ListBase *lb) BLI_pbvh_search_callback(ss->pbvh, NULL, NULL, update_cb, NULL); BLI_pbvh_update(ss->pbvh, PBVH_UpdateBB|PBVH_UpdateOriginalBB|PBVH_UpdateRedraw, NULL); - if((mmd=sculpt_multires_active(ob))) + if((mmd=sculpt_multires_active(scene, ob))) multires_mark_as_modified(ob); if(sculpt_modifiers_active(scene, ob)) @@ -772,7 +783,7 @@ static void calc_area_normal(Sculpt *sd, SculptSession *ss, float area_normal[3] copy_v3_v3(out_dir, cache->view_normal_symmetry); /* threaded loop over nodes */ - #pragma omp parallel for private(n) schedule(static) + //#pragma omp parallel for private(n) schedule(static) for(n=0; n<totnode; n++) { PBVHVertexIter vd; SculptBrushTest test; @@ -809,7 +820,7 @@ static void calc_area_normal(Sculpt *sd, SculptSession *ss, float area_normal[3] BLI_pbvh_vertex_iter_end; } - #pragma omp critical + //#pragma omp critical { /* we sum per node and add together later for threads */ add_v3_v3(out, nout); @@ -847,7 +858,7 @@ static void do_draw_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int t offset[2]= area_normal[2]*ss->cache->radius*ss->cache->scale[2]*bstrength; /* threaded loop over nodes */ - #pragma omp parallel for private(n) schedule(static) + //#pragma omp parallel for private(n) schedule(static) for(n=0; n<totnode; n++) { PBVHVertexIter vd; SculptBrushTest test; @@ -961,7 +972,7 @@ static void do_multires_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *no BLI_pbvh_node_get_grids(ss->pbvh, node, &grid_indices, &totgrid, NULL, &gridsize, &griddata, &gridadj); - #pragma omp critical + //#pragma omp critical tmpgrid= MEM_mallocN(sizeof(float)*3*gridsize*gridsize, "tmpgrid"); for(i = 0; i < totgrid; ++i) { @@ -1020,7 +1031,7 @@ static void do_multires_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *no } } - #pragma omp critical + //#pragma omp critical MEM_freeN(tmpgrid); } @@ -1029,7 +1040,7 @@ static void do_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int int iteration, n; for(iteration = 0; iteration < 2; ++iteration) { - #pragma omp parallel for private(n) schedule(static) + //#pragma omp parallel for private(n) schedule(static) for(n=0; n<totnode; n++) { sculpt_undo_push_node(ss, nodes[n]); @@ -1052,7 +1063,7 @@ static void do_pinch_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int float bstrength= ss->cache->bstrength; int n; - #pragma omp parallel for private(n) schedule(static) + //#pragma omp parallel for private(n) schedule(static) for(n=0; n<totnode; n++) { PBVHVertexIter vd; SculptBrushTest test; @@ -1086,7 +1097,7 @@ static void do_grab_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int t copy_v3_v3(grab_delta, ss->cache->grab_delta_symmetry); - #pragma omp parallel for private(n) schedule(static) + //#pragma omp parallel for private(n) schedule(static) for(n=0; n<totnode; n++) { PBVHVertexIter vd; SculptBrushTest test; @@ -1129,7 +1140,7 @@ static void do_layer_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int offset[1]= ss->cache->scale[1]*area_normal[1]; offset[2]= ss->cache->scale[2]*area_normal[2]; - #pragma omp parallel for private(n) schedule(static) + //#pragma omp parallel for private(n) schedule(static) for(n=0; n<totnode; n++) { PBVHVertexIter vd; SculptBrushTest test; @@ -1186,7 +1197,7 @@ static void do_inflate_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, in float bstrength= ss->cache->bstrength; int n; - #pragma omp parallel for private(n) schedule(static) + //#pragma omp parallel for private(n) schedule(static) for(n=0; n<totnode; n++) { PBVHVertexIter vd; SculptBrushTest test; @@ -1229,7 +1240,7 @@ static void calc_flatten_center(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, outer_dist[i]= -1.0f; } - #pragma omp parallel for private(n) schedule(static) + //#pragma omp parallel for private(n) schedule(static) for(n=0; n<totnode; n++) { PBVHVertexIter vd; SculptBrushTest test; @@ -1473,7 +1484,7 @@ static void sculpt_update_tex(Sculpt *sd, SculptSession *ss) /* Sculpt mode handles multires differently from regular meshes, but only if it's the last modifier on the stack and it is not on the first level */ -struct MultiresModifierData *sculpt_multires_active(Object *ob) +struct MultiresModifierData *sculpt_multires_active(Scene *scene, Object *ob) { ModifierData *md, *nmd; @@ -1483,8 +1494,8 @@ struct MultiresModifierData *sculpt_multires_active(Object *ob) /* Check if any of the modifiers after multires are active * if not it can use the multires struct */ - for (nmd= md->next; nmd; nmd= nmd->next) - if(nmd->mode & eModifierMode_Realtime) + for(nmd= md->next; nmd; nmd= nmd->next) + if(modifier_isEnabled(scene, nmd, eModifierMode_Realtime)) break; if(!nmd && mmd->sculptlvl > 0) @@ -1514,10 +1525,11 @@ void sculpt_update_mesh_elements(Scene *scene, Object *ob, int need_fmap) { DerivedMesh *dm = mesh_get_derived_final(scene, ob, 0); SculptSession *ss = ob->sculpt; - + MultiresModifierData *mmd= sculpt_multires_active(scene, ob); + ss->ob= ob; - if((ob->shapeflag & OB_SHAPE_LOCK) && !sculpt_multires_active(ob)) { + if((ob->shapeflag & OB_SHAPE_LOCK) && !mmd) { ss->kb= ob_get_keyblock(ob); ss->refkb= ob_get_reference_keyblock(ob); } @@ -1529,7 +1541,8 @@ void sculpt_update_mesh_elements(Scene *scene, Object *ob, int need_fmap) /* need to make PBVH with shape key coordinates */ if(ss->kb) sculpt_key_to_mesh(ss->kb, ss->ob); - if((ss->multires = sculpt_multires_active(ob))) { + if(mmd) { + ss->multires = mmd; ss->totvert = dm->getNumVerts(dm); ss->totface = dm->getNumFaces(dm); ss->mvert= NULL; @@ -1543,6 +1556,7 @@ void sculpt_update_mesh_elements(Scene *scene, Object *ob, int need_fmap) ss->mvert = me->mvert; ss->mface = me->mface; ss->face_normals = NULL; + ss->multires = NULL; } ss->pbvh = dm->getPBVH(ob, dm); @@ -1951,7 +1965,7 @@ static void sculpt_restore_mesh(Sculpt *sd, SculptSession *ss) BLI_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode); - #pragma omp parallel for private(n) schedule(static) + //#pragma omp parallel for private(n) schedule(static) for(n=0; n<totnode; n++) { SculptUndoNode *unode; @@ -2221,13 +2235,19 @@ static int sculpt_toggle_mode(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); ToolSettings *ts = CTX_data_tool_settings(C); Object *ob = CTX_data_active_object(C); - MultiresModifierData *mmd = sculpt_multires_active(ob); + MultiresModifierData *mmd = sculpt_multires_active(scene, ob); + int flush_recalc= 0; + + /* multires in sculpt mode could have different from object mode subdivision level */ + flush_recalc |= mmd && mmd->sculptlvl != mmd->lvl; + /* if object has got active modifiers, it's dm could be different in sculpt mode */ + //flush_recalc |= sculpt_modifiers_active(scene, ob); if(ob->mode & OB_MODE_SCULPT) { - if(sculpt_multires_active(ob)) + if(mmd) multires_force_update(ob); - if(mmd && mmd->sculptlvl != mmd->lvl) + if(flush_recalc) DAG_id_flush_update(&ob->id, OB_RECALC_DATA); /* Leave sculptmode */ @@ -2239,7 +2259,7 @@ static int sculpt_toggle_mode(bContext *C, wmOperator *op) /* Enter sculptmode */ ob->mode |= OB_MODE_SCULPT; - if(mmd && mmd->sculptlvl != mmd->lvl) + if(flush_recalc) DAG_id_flush_update(&ob->id, OB_RECALC_DATA); /* Create persistent sculpt mode data */ diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index d3553c008b2..d8043d2c988 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -49,7 +49,7 @@ void sculptmode_draw_mesh(int); void sculpt_paint_brush(char clear); void sculpt_stroke_draw(struct SculptStroke *); void sculpt_radialcontrol_start(int mode); -struct MultiresModifierData *sculpt_multires_active(struct Object *ob); +struct MultiresModifierData *sculpt_multires_active(struct Scene *scene, struct Object *ob); struct Brush *sculptmode_brush(void); //void do_symmetrical_brush_actions(struct Sculpt *sd, struct wmOperator *wm, struct BrushAction *a, short *, short *); diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c index be4f6ff0570..8f195b819ea 100644 --- a/source/blender/editors/sound/sound_ops.c +++ b/source/blender/editors/sound/sound_ops.c @@ -118,7 +118,7 @@ static int open_exec(bContext *C, wmOperator *op) RNA_property_update(C, &pprop->ptr, pprop->prop); } - MEM_freeN(op->customdata); + if(op->customdata) MEM_freeN(op->customdata); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c index 55b899bc1cd..b08ea810a33 100644 --- a/source/blender/editors/space_image/image_buttons.c +++ b/source/blender/editors/space_image/image_buttons.c @@ -841,7 +841,7 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propn if(ima->source != IMA_SRC_GENERATED) { row= uiLayoutRow(layout, 1); - uiItemR(row, &imaptr, "filename", 0, "", 0); + uiItemR(row, &imaptr, "filepath", 0, "", 0); uiItemO(row, "", ICON_FILE_REFRESH, "image.reload"); } diff --git a/source/blender/editors/space_info/info_intern.h b/source/blender/editors/space_info/info_intern.h index 128c0dace20..4053bbf5a1f 100644 --- a/source/blender/editors/space_info/info_intern.h +++ b/source/blender/editors/space_info/info_intern.h @@ -39,5 +39,7 @@ void FILE_OT_make_paths_absolute(struct wmOperatorType *ot); void FILE_OT_report_missing_files(struct wmOperatorType *ot); void FILE_OT_find_missing_files(struct wmOperatorType *ot); +void INFO_OT_reports_display_update(struct wmOperatorType *ot); + #endif /* ED_INFO_INTERN_H */ diff --git a/source/blender/editors/space_info/info_ops.c b/source/blender/editors/space_info/info_ops.c index e2baeb9abac..64d2c6138c7 100644 --- a/source/blender/editors/space_info/info_ops.c +++ b/source/blender/editors/space_info/info_ops.c @@ -36,6 +36,7 @@ #include "MEM_guardedalloc.h" #include "BLI_blenlib.h" +#include "BLI_math.h" #include "BLI_bpath.h" #include "BKE_context.h" @@ -300,3 +301,100 @@ void FILE_OT_find_missing_files(wmOperatorType *ot) /* properties */ WM_operator_properties_filesel(ot, 0, FILE_SPECIAL, FILE_OPENFILE); } + +/********************* report box operator *********************/ + +/* Hard to decide whether to keep this as an operator, + * or turn it into a hardcoded ui control feature, + * handling TIMER events for all regions in interface_handlers.c + * Not sure how good that is to be accessing UI data from + * inactive regions, so use this for now. --matt + */ + +#define INFO_TIMEOUT 5.0 +#define INFO_COLOR_TIMEOUT 3.0 +#define ERROR_TIMEOUT 10.0 +#define ERROR_COLOR_TIMEOUT 6.0 +#define COLLAPSE_TIMEOUT 0.2 +static int update_reports_display_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + wmWindowManager *wm= CTX_wm_manager(C); + ReportList *reports= CTX_wm_reports(C); + Report *report; + ReportTimerInfo *rti; + float progress=0.0, color_progress=0.0; + float neutral_col[3] = {0.35, 0.35, 0.35}; + float neutral_grey= 0.6; + float timeout=0.0, color_timeout=0.0; + + /* escape if not our timer */ + if(reports->reporttimer==NULL || reports->reporttimer != event->customdata) + return OPERATOR_PASS_THROUGH; + + report= BKE_reports_last_displayable(reports); + rti = (ReportTimerInfo *)reports->reporttimer->customdata; + + timeout = (report->type & RPT_ERROR_ALL)?ERROR_TIMEOUT:INFO_TIMEOUT; + color_timeout = (report->type & RPT_ERROR_ALL)?ERROR_COLOR_TIMEOUT:INFO_COLOR_TIMEOUT; + + /* clear the report display after timeout */ + if (reports->reporttimer->duration > timeout) { + WM_event_remove_timer(wm, NULL, reports->reporttimer); + reports->reporttimer = NULL; + + WM_event_add_notifier(C, NC_SPACE|ND_SPACE_INFO, NULL); + + return (OPERATOR_FINISHED|OPERATOR_PASS_THROUGH); + } + + if (rti->widthfac == 0.0) { + /* initialise colours based on report type */ + if(report->type & RPT_ERROR_ALL) { + rti->col[0] = 1.0; + rti->col[1] = 0.2; + rti->col[2] = 0.0; + } else if(report->type & RPT_WARNING_ALL) { + rti->col[0] = 1.0; + rti->col[1] = 1.0; + rti->col[2] = 0.0; + } else if(report->type & RPT_INFO_ALL) { + rti->col[0] = 0.3; + rti->col[1] = 0.45; + rti->col[2] = 0.7; + } + rti->greyscale = 0.75; + rti->widthfac=1.0; + } + + progress = reports->reporttimer->duration / timeout; + color_progress = reports->reporttimer->duration / color_timeout; + + /* fade colours out sharply according to progress through fade-out duration */ + interp_v3_v3v3(rti->col, rti->col, neutral_col, color_progress); + rti->greyscale = interpf(neutral_grey, rti->greyscale, color_progress); + + /* collapse report at end of timeout */ + if (progress*timeout > timeout - COLLAPSE_TIMEOUT) { + rti->widthfac = (progress*timeout - (timeout - COLLAPSE_TIMEOUT)) / COLLAPSE_TIMEOUT; + rti->widthfac = 1.0 - rti->widthfac; + } + + WM_event_add_notifier(C, NC_SPACE|ND_SPACE_INFO, NULL); + + return (OPERATOR_FINISHED|OPERATOR_PASS_THROUGH); +} + +void INFO_OT_reports_display_update(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Update Reports Display"; + ot->idname= "INFO_OT_reports_display_update"; + + /* api callbacks */ + ot->invoke= update_reports_display_invoke; + + /* flags */ + ot->flag= 0; + + /* properties */ +}
\ No newline at end of file diff --git a/source/blender/editors/space_info/space_info.c b/source/blender/editors/space_info/space_info.c index 4370d2cbc16..0d9f1c90489 100644 --- a/source/blender/editors/space_info/space_info.c +++ b/source/blender/editors/space_info/space_info.c @@ -125,11 +125,15 @@ void info_operatortypes(void) WM_operatortype_append(FILE_OT_make_paths_absolute); WM_operatortype_append(FILE_OT_report_missing_files); WM_operatortype_append(FILE_OT_find_missing_files); + + WM_operatortype_append(INFO_OT_reports_display_update); } void info_keymap(struct wmKeyConfig *keyconf) { + wmKeyMap *keymap= WM_keymap_find(keyconf, "Window", 0, 0); + WM_keymap_verify_item(keymap, "INFO_OT_reports_display_update", TIMER, KM_ANY, KM_ANY, 0); } /* add handlers, stuff you only do once or on area/region changes */ diff --git a/source/blender/editors/space_logic/logic_window.c b/source/blender/editors/space_logic/logic_window.c index d5c11c58b61..a73902d6a2b 100644 --- a/source/blender/editors/space_logic/logic_window.c +++ b/source/blender/editors/space_logic/logic_window.c @@ -3245,9 +3245,12 @@ static void draw_sensor_armature(uiLayout *layout, PointerRNA *ptr) uiItemR(row, ptr, "value", 0, NULL, 0); } -static void draw_sensor_collision(uiLayout *layout, PointerRNA *ptr) +static void draw_sensor_collision(uiLayout *layout, PointerRNA *ptr, bContext *C) { uiLayout *row, *split; + PointerRNA main_ptr; + + RNA_main_pointer_create(CTX_data_main(C), &main_ptr); split = uiLayoutSplit(layout, 0.3, 0); row = uiLayoutRow(split, 1); @@ -3259,7 +3262,7 @@ static void draw_sensor_collision(uiLayout *layout, PointerRNA *ptr) uiItemR(split, ptr, "property", 0, NULL, 0); break; case SENS_COLLISION_MATERIAL: - uiItemR(split, ptr, "material", 0, NULL, 0); + uiItemPointerR(split, ptr, "material", &main_ptr, "materials", NULL, ICON_MATERIAL_DATA); break; } } @@ -3343,9 +3346,6 @@ static void draw_sensor_keyboard(uiLayout *layout, PointerRNA *ptr) RNA_pointer_create((ID *)ob, &RNA_GameObjectSettings, ob, &settings_ptr); uiItemPointerR(layout, ptr, "target", &settings_ptr, "properties", NULL, 0); uiItemPointerR(layout, ptr, "log", &settings_ptr, "properties", NULL, 0); - -// uiItemR(layout, ptr, "target", 0, NULL, 0); -// uiItemR(layout, ptr, "log", 0, NULL, 0); } static void draw_sensor_message(uiLayout *layout, PointerRNA *ptr) @@ -3414,17 +3414,21 @@ static void draw_sensor_random(uiLayout *layout, PointerRNA *ptr) uiItemR(layout, ptr, "seed", 0, NULL, 0); } -static void draw_sensor_ray(uiLayout *layout, PointerRNA *ptr) +static void draw_sensor_ray(uiLayout *layout, PointerRNA *ptr, bContext *C) { uiLayout *split, *row; + PointerRNA main_ptr; + RNA_main_pointer_create(CTX_data_main(C), &main_ptr); split= uiLayoutSplit(layout, 0.3, 0); uiItemR(split, ptr, "ray_type", 0, "", 0); switch (RNA_enum_get(ptr, "ray_type")) { case SENS_RAY_PROPERTY: - uiItemR(split, ptr, "property", 0, "", 0); break; + uiItemR(split, ptr, "property", 0, "", 0); + break; case SENS_RAY_MATERIAL: - uiItemR(split, ptr, "material", 0, "", 0); break; + uiItemPointerR(split, ptr, "material", &main_ptr, "materials", "", ICON_MATERIAL_DATA); + break; } split= uiLayoutSplit(layout, 0.3, 0); @@ -3439,7 +3443,7 @@ static void draw_sensor_touch(uiLayout *layout, PointerRNA *ptr) uiItemR(layout, ptr, "material", 0, NULL, 0); } -void draw_brick_sensor(uiLayout *layout, PointerRNA *ptr) +void draw_brick_sensor(uiLayout *layout, PointerRNA *ptr, bContext *C) { uiLayout *box; @@ -3461,7 +3465,7 @@ void draw_brick_sensor(uiLayout *layout, PointerRNA *ptr) draw_sensor_armature(box, ptr); break; case SENS_COLLISION: - draw_sensor_collision(box, ptr); + draw_sensor_collision(box, ptr, C); break; case SENS_DELAY: draw_sensor_delay(box, ptr); @@ -3491,7 +3495,7 @@ void draw_brick_sensor(uiLayout *layout, PointerRNA *ptr) draw_sensor_random(box, ptr); break; case SENS_RAY: - draw_sensor_ray(box, ptr); + draw_sensor_ray(box, ptr, C); break; case SENS_TOUCH: draw_sensor_touch(box, ptr); @@ -3696,9 +3700,12 @@ static void draw_actuator_camera(uiLayout *layout, PointerRNA *ptr) uiItemR(row, ptr, "max", 0, NULL, 0); } -static void draw_actuator_constraint(uiLayout *layout, PointerRNA *ptr) +static void draw_actuator_constraint(uiLayout *layout, PointerRNA *ptr, bContext *C) { uiLayout *row, *col, *subcol, *split; + PointerRNA main_ptr; + + RNA_main_pointer_create(CTX_data_main(C), &main_ptr); uiItemR(layout, ptr, "mode", 0, NULL, 0); switch (RNA_enum_get(ptr, "mode")) @@ -3736,7 +3743,7 @@ static void draw_actuator_constraint(uiLayout *layout, PointerRNA *ptr) split = uiLayoutSplit(layout, 0.15, 0); uiItemR(split, ptr, "detect_material", UI_ITEM_R_TOGGLE, NULL, 0); if (RNA_boolean_get(ptr, "detect_material")) - uiItemR(split, ptr, "material", 0, NULL, 0); + uiItemPointerR(split, ptr, "material", &main_ptr, "materials", NULL, ICON_MATERIAL_DATA); else uiItemR(split, ptr, "property", 0, NULL, 0); @@ -3780,7 +3787,7 @@ static void draw_actuator_constraint(uiLayout *layout, PointerRNA *ptr) split = uiLayoutSplit(layout, 0.15, 0); uiItemR(split, ptr, "detect_material", UI_ITEM_R_TOGGLE, NULL, 0); if (RNA_boolean_get(ptr, "detect_material")) - uiItemR(split, ptr, "material", 0, NULL, 0); + uiItemPointerR(split, ptr, "material", &main_ptr, "materials", NULL, ICON_MATERIAL_DATA); else uiItemR(split, ptr, "property", 0, NULL, 0); @@ -3913,16 +3920,18 @@ static void draw_actuator_ipo(uiLayout *layout, PointerRNA *ptr) uiItemPointerR(row, ptr, "frame_property", &settings_ptr, "properties", NULL, 0); } -static void draw_actuator_message(uiLayout *layout, PointerRNA *ptr) +static void draw_actuator_message(uiLayout *layout, PointerRNA *ptr, bContext *C) { Object *ob; - PointerRNA settings_ptr; + PointerRNA main_ptr, settings_ptr; uiLayout *row; + RNA_main_pointer_create(CTX_data_main(C), &main_ptr); + ob = (Object *)ptr->id.data; RNA_pointer_create((ID *)ob, &RNA_GameObjectSettings, ob, &settings_ptr); - uiItemR(layout, ptr, "to_property", 0, NULL, 0); + uiItemPointerR(layout, ptr, "to_property", &main_ptr, "objects", NULL, ICON_OBJECT_DATA); uiItemR(layout, ptr, "subject", 0, NULL, 0); row= uiLayoutRow(layout, 1); @@ -4281,7 +4290,7 @@ void draw_brick_actuator(uiLayout *layout, PointerRNA *ptr, bContext *C) draw_actuator_camera(box, ptr); break; case ACT_CONSTRAINT: - draw_actuator_constraint(box, ptr); + draw_actuator_constraint(box, ptr, C); break; case ACT_EDIT_OBJECT: draw_actuator_edit_object(box, ptr); @@ -4296,7 +4305,7 @@ void draw_brick_actuator(uiLayout *layout, PointerRNA *ptr, bContext *C) draw_actuator_ipo(box, ptr); break; case ACT_MESSAGE: - draw_actuator_message(box, ptr); + draw_actuator_message(box, ptr, C); break; case ACT_OBJECT: draw_actuator_motion(box, ptr); @@ -4523,7 +4532,7 @@ static void logic_buttons_new(bContext *C, ARegion *ar) draw_sensor_header(col, &ptr); /* draw the brick contents */ - draw_brick_sensor(col, &ptr); + draw_brick_sensor(col, &ptr, C); /* put link button to the right */ col = uiLayoutColumn(split, 0); diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 7e79b4b822e..629b1008aa0 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -891,7 +891,7 @@ static void node_composit_buts_file_output(uiLayout *layout, bContext *C, Pointe uiLayout *col, *row; col= uiLayoutColumn(layout, 0); - uiItemR(col, ptr, "filename", 0, "", 0); + uiItemR(col, ptr, "filepath", 0, "", 0); uiItemR(col, ptr, "image_type", 0, "", 0); row= uiLayoutRow(layout, 0); diff --git a/source/blender/editors/space_outliner/outliner.c b/source/blender/editors/space_outliner/outliner.c index ccc535a68e6..510bb69c7d4 100644 --- a/source/blender/editors/space_outliner/outliner.c +++ b/source/blender/editors/space_outliner/outliner.c @@ -132,7 +132,9 @@ static void error(const char *dummy, ...) {} static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene, ARegion *ar, SpaceOops *soops, TreeElement *te, int startx, int *starty); static void outliner_do_object_operation(bContext *C, Scene *scene, SpaceOops *soops, ListBase *lb, void (*operation_cb)(bContext *C, Scene *scene, TreeElement *, TreeStoreElem *, TreeStoreElem *)); - +static void outliner_do_group_operation(bContext *C, Scene *scene, SpaceOops *soops, ListBase *lb, + void (*operation_cb)(bContext *C, Scene *scene, TreeElement *, TreeStoreElem *, TreeStoreElem *)); +static int group_select_flag(Group *gr); /* ******************** PERSISTANT DATA ***************** */ @@ -1632,8 +1634,6 @@ void OUTLINER_OT_selectability_toggle(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } -/* --- */ - void object_toggle_renderability_cb(bContext *C, Scene *scene, TreeElement *te, TreeStoreElem *tsep, TreeStoreElem *tselem) { Base *base= (Base *)te->directdata; @@ -2347,7 +2347,6 @@ static int tree_element_active_keymap_item(bContext *C, TreeElement *te, TreeSto /* Context can be NULL when set==0 */ static int tree_element_type_active(bContext *C, Scene *scene, SpaceOops *soops, TreeElement *te, TreeStoreElem *tselem, int set) { - switch(tselem->type) { case TSE_DEFGROUP: return tree_element_active_defgroup(C, scene, te, tselem, set); @@ -2425,6 +2424,34 @@ static int do_outliner_item_activate(bContext *C, Scene *scene, ARegion *ar, Spa ED_screen_set_scene(C, (Scene *)tselem->id); } } + else if(te->idcode==ID_GR) { + Group *gr= (Group *)tselem->id; + GroupObject *gob; + + if(extend) { + int sel= BA_SELECT; + for(gob= gr->gobject.first; gob; gob= gob->next) { + if(gob->ob->flag & SELECT) { + sel= BA_DESELECT; + break; + } + } + + for(gob= gr->gobject.first; gob; gob= gob->next) { + ED_base_object_select(object_in_scene(gob->ob, scene), sel); + } + } + else { + scene_deselect_all(scene); + + for(gob= gr->gobject.first; gob; gob= gob->next) { + if((gob->ob->flag & SELECT) == 0) + ED_base_object_select(object_in_scene(gob->ob, scene), BA_SELECT); + } + } + + WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene); + } else if(ELEM5(te->idcode, ID_ME, ID_CU, ID_MB, ID_LT, ID_AR)) { Object *obedit= CTX_data_edit_object(C); if(obedit) @@ -3297,6 +3324,31 @@ static void outliner_do_data_operation(SpaceOops *soops, int type, int event, Li } } +static void outliner_do_group_operation(bContext *C, Scene *scene, SpaceOops *soops, ListBase *lb, + void (*operation_cb)(bContext *C, Scene *scene, TreeElement *, TreeStoreElem *, TreeStoreElem *)) + { + TreeElement *te; + TreeStoreElem *tselem; + + for(te=lb->first; te; te= te->next) { + tselem= TREESTORE(te); + if(tselem->flag & TSE_SELECTED) { + if(tselem->type==0 && te->idcode==ID_GR) { + /* when objects selected in other scenes... dunno if that should be allowed */ + Scene *sce= (Scene *)outliner_search_back(soops, te, ID_SCE); + if(sce && scene != sce) { + ED_screen_set_scene(C, sce); + } + + operation_cb(C, scene, te, NULL, tselem); + } + } + if((tselem->flag & TSE_CLOSED)==0) { + outliner_do_group_operation(C, scene, soops, &te->subtree, operation_cb); + } + } +} + void outliner_del(bContext *C, Scene *scene, ARegion *ar, SpaceOops *soops) { @@ -3400,6 +3452,9 @@ static EnumPropertyItem prop_group_op_types[] = { {1, "UNLINK", 0, "Unlink", ""}, {2, "LOCAL", 0, "Make Local", ""}, {3, "LINK", 0, "Link Group Objects to Scene", ""}, + {4, "TOGVIS", 0, "Toggle Visible", ""}, + {5, "TOGSEL", 0, "Toggle Selectable", ""}, + {6, "TOGREN", 0, "Toggle Renderable", ""}, {0, NULL, 0, NULL, NULL} }; @@ -3426,7 +3481,7 @@ static int outliner_group_operation_exec(bContext *C, wmOperator *op) else if(event==3) { outliner_do_libdata_operation(C, scene, soops, &soops->tree, group_linkobs2scene_cb); ED_undo_push(C, "Link Group Objects to Scene"); - } + } WM_event_add_notifier(C, NC_GROUP, NULL); @@ -4496,6 +4551,18 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene active= 2; } } + else if(te->idcode==ID_GR) { + Group *gr = (Group *)tselem->id; + + if(group_select_flag(gr)) { + char col[4]; + UI_GetThemeColorType4ubv(TH_SELECT, SPACE_VIEW3D, col); + col[3]= 100; + glColor4ubv((GLubyte *)col); + + active= 2; + } + } else if(te->idcode==ID_OB) { Object *ob= (Object *)tselem->id; @@ -4853,6 +4920,73 @@ static void restrictbutton_bone_cb(bContext *C, void *poin, void *poin2) WM_event_add_notifier(C, NC_OBJECT|ND_POSE, NULL); } + +static int group_restrict_flag(Group *gr, int flag) +{ + GroupObject *gob; + + for(gob= gr->gobject.first; gob; gob= gob->next) { + if((gob->ob->restrictflag & flag) == 0) + return 0; + } + + return 1; +} + +static int group_select_flag(Group *gr) +{ + GroupObject *gob; + + for(gob= gr->gobject.first; gob; gob= gob->next) + if((gob->ob->flag & SELECT)) + return 1; + + return 0; +} + +static void restrictbutton_gr_restrict_flag(bContext *C, void *poin, void *poin2, int flag) +{ + Scene *scene = (Scene *)poin; + GroupObject *gob; + Group *gr = (Group *)poin2; + + if(group_restrict_flag(gr, flag)) { + for(gob= gr->gobject.first; gob; gob= gob->next) { + gob->ob->restrictflag &= ~flag; + + if(flag==OB_RESTRICT_VIEW) + if(gob->ob->flag & SELECT) + ED_base_object_select(object_in_scene(gob->ob, scene), BA_DESELECT); + } + } + else { + for(gob= gr->gobject.first; gob; gob= gob->next) { + gob->ob->restrictflag |= flag; + + if(flag==OB_RESTRICT_VIEW) + if((gob->ob->flag & SELECT) == 0) + ED_base_object_select(object_in_scene(gob->ob, scene), BA_SELECT); + } + } +} + +static void restrictbutton_gr_restrict_view(bContext *C, void *poin, void *poin2) +{ + restrictbutton_gr_restrict_flag(C, poin, poin2, OB_RESTRICT_VIEW); + WM_event_add_notifier(C, NC_GROUP, NULL); +} +static void restrictbutton_gr_restrict_select(bContext *C, void *poin, void *poin2) +{ + restrictbutton_gr_restrict_flag(C, poin, poin2, OB_RESTRICT_SELECT); + WM_event_add_notifier(C, NC_GROUP, NULL); +} +static void restrictbutton_gr_restrict_render(bContext *C, void *poin, void *poin2) +{ + restrictbutton_gr_restrict_flag(C, poin, poin2, OB_RESTRICT_RENDER); + WM_event_add_notifier(C, NC_GROUP, NULL); +} + + static void namebutton_cb(bContext *C, void *tsep, char *oldname) { SpaceOops *soops= CTX_wm_space_outliner(C); @@ -4970,6 +5104,7 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar TreeElement *te; TreeStoreElem *tselem; Object *ob = NULL; + Group *gr = NULL; for(te= lb->first; te; te= te->next) { tselem= TREESTORE(te); @@ -5000,6 +5135,26 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar uiBlockSetEmboss(block, UI_EMBOSS); } + if(tselem->type==0 && te->idcode==ID_GR){ + int restrict_bool; + gr = (Group *)tselem->id; + + uiBlockSetEmboss(block, UI_EMBOSSN); + + restrict_bool= group_restrict_flag(gr, OB_RESTRICT_VIEW); + bt = uiDefIconBut(block, BUT, 0, restrict_bool ? ICON_RESTRICT_VIEW_ON : ICON_RESTRICT_VIEW_OFF, (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (short)te->ys, 17, OL_H-1, 0, 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View"); + uiButSetFunc(bt, restrictbutton_gr_restrict_view, scene, gr); + + restrict_bool= group_restrict_flag(gr, OB_RESTRICT_SELECT); + bt = uiDefIconBut(block, BUT, 0, restrict_bool ? ICON_RESTRICT_SELECT_ON : ICON_RESTRICT_SELECT_OFF, (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, (short)te->ys, 17, OL_H-1, 0, 0, 0, 0, 0, "Restrict/Allow selection in the 3D View"); + uiButSetFunc(bt, restrictbutton_gr_restrict_select, scene, gr); + + restrict_bool= group_restrict_flag(gr, OB_RESTRICT_RENDER); + bt = uiDefIconBut(block, BUT, 0, restrict_bool ? ICON_RESTRICT_RENDER_ON : ICON_RESTRICT_RENDER_OFF, (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_RENDERX, (short)te->ys, 17, OL_H-1, 0, 0, 0, 0, 0, "Restrict/Allow renderability"); + uiButSetFunc(bt, restrictbutton_gr_restrict_render, scene, gr); + + uiBlockSetEmboss(block, UI_EMBOSS); + } /* scene render layers and passes have toggle-able flags too! */ else if(tselem->type==TSE_R_LAYER) { uiBlockSetEmboss(block, UI_EMBOSSN); diff --git a/source/blender/editors/space_script/script_edit.c b/source/blender/editors/space_script/script_edit.c index 6ef9a96b478..02993549c94 100644 --- a/source/blender/editors/space_script/script_edit.c +++ b/source/blender/editors/space_script/script_edit.c @@ -84,3 +84,23 @@ void SCRIPT_OT_python_file_run(wmOperatorType *ot) RNA_def_string_file_path(ot->srna, "path", "", 512, "Path", ""); } + +static int script_reload_exec(bContext *C, wmOperator *op) +{ +#ifndef DISABLE_PYTHON + BPY_eval_string(C, "__import__('bpy').utils.load_scripts(reload_scripts=True)"); + return OPERATOR_FINISHED; +#endif + return OPERATOR_CANCELLED; +} + +void SCRIPT_OT_reload(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Reload Scripts"; + ot->description= "Reload Scripts"; + ot->idname= "SCRIPT_OT_reload"; + + /* api callbacks */ + ot->exec= script_reload_exec; +} diff --git a/source/blender/editors/space_script/script_intern.h b/source/blender/editors/space_script/script_intern.h index 57e4cc6c793..ed625bb8ec6 100644 --- a/source/blender/editors/space_script/script_intern.h +++ b/source/blender/editors/space_script/script_intern.h @@ -39,6 +39,7 @@ void script_operatortypes(void); void script_keymap(struct wmKeyConfig *keyconf); /* script_edit.c */ +void SCRIPT_OT_reload(struct wmOperatorType *ot); void SCRIPT_OT_python_file_run(struct wmOperatorType *ot); #endif /* ED_SCRIPT_INTERN_H */ diff --git a/source/blender/editors/space_script/script_ops.c b/source/blender/editors/space_script/script_ops.c index 353d80f1921..61f7cf425d4 100644 --- a/source/blender/editors/space_script/script_ops.c +++ b/source/blender/editors/space_script/script_ops.c @@ -55,6 +55,7 @@ void script_operatortypes(void) { WM_operatortype_append(SCRIPT_OT_python_file_run); + WM_operatortype_append(SCRIPT_OT_reload); } void script_keymap(wmKeyConfig *keyconf) diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 89a82e51cd8..d3b70f4553a 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -3466,12 +3466,11 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv select=1; } + psys_update_children(&sim); + psys->flag|=PSYS_DRAWING; - if(part->type==PART_HAIR && !psys->childcache) - totchild=0; - else - totchild=psys->totchild*part->disp/100; + totchild=psys->totchild*part->disp/100; ma= give_current_material(ob,part->omat); @@ -3506,11 +3505,18 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv totpart=psys->totpart; - //if(part->flag&PART_GLOB_TIME) cfra=bsystem_time(scene, 0, (float)CFRA, 0.0f); - if(draw_as==PART_DRAW_PATH && psys->pathcache==NULL && psys->childcache==NULL) - draw_as=PART_DRAW_DOT; + if(draw_as==PART_DRAW_PATH) { + if(psys->pathcache==NULL && psys->childcache==NULL) + psys_update_path_cache(&sim, cfra); + + /* can't create pathcache for some reason*/ + if(psys->pathcache==NULL && psys->childcache==NULL) + draw_as=PART_DRAW_DOT; + else if(psys->childcache==NULL) + totchild = 0; + } /* 3. */ switch(draw_as){ @@ -3862,7 +3868,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv UI_ThemeColor(TH_WIRE); }*/ - if(totchild && (part->draw&PART_DRAW_PARENT)==0) + if(totchild && ((part->draw&PART_DRAW_PARENT)==0 || psys_in_edit_mode(scene, psys))) totpart=0; else if(psys->pathcache==NULL) totpart=0; diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 8a3029c8218..8396f880357 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -691,8 +691,15 @@ static int viewrotate_invoke(bContext *C, wmOperator *op, wmEvent *event) if (U.uiflag & USER_AUTOPERSP) vod->rv3d->persp= RV3D_PERSP; - else if(vod->rv3d->persp==RV3D_CAMOB) + else if(vod->rv3d->persp==RV3D_CAMOB) { + + /* changed since 2.4x, use the camera view */ + View3D *v3d = CTX_wm_view3d(C); + if(v3d->camera) + view3d_settings_from_ob(v3d->camera, rv3d->ofs, rv3d->viewquat, &rv3d->dist, NULL); + vod->rv3d->persp= RV3D_PERSP; + } ED_region_tag_redraw(vod->ar); } diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index 53bc5b7c5d5..69e4006770d 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -139,6 +139,8 @@ void VIEW3D_OT_select_border(struct wmOperatorType *ot); void VIEW3D_OT_select_lasso(struct wmOperatorType *ot); /* view3d_view.c */ +void view3d_settings_from_ob(struct Object *ob, float *ofs, float *quat, float *dist, float *lens); + void VIEW3D_OT_smoothview(struct wmOperatorType *ot); void VIEW3D_OT_setcameratoview(struct wmOperatorType *ot); void VIEW3D_OT_setobjectascamera(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c index 5bce1992b53..ff716a640d8 100644 --- a/source/blender/editors/space_view3d/view3d_snap.c +++ b/source/blender/editors/space_view3d/view3d_snap.c @@ -780,7 +780,7 @@ static int snap_curs_to_sel(bContext *C, wmOperator *op) } } else { - CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { + CTX_DATA_BEGIN(C, Object*, ob, selected_objects) { VECCOPY(vec, ob->obmat[3]); add_v3_v3(centroid, vec); DO_MINMAX(vec, min, max); diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index 31ddc442cc2..9790e928188 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -138,37 +138,32 @@ static void object_lens_clip_settings(Object *ob, float *lens, float *clipsta, f * * The dist is not modified for this function, if NULL its assimed zero * */ -static void view_settings_from_ob(Object *ob, float *ofs, float *quat, float *dist, float *lens) -{ - float bmat[4][4]; - float imat[4][4]; - float tmat[3][3]; - +void view3d_settings_from_ob(Object *ob, float *ofs, float *quat, float *dist, float *lens) +{ if (!ob) return; - + /* Offset */ if (ofs) negate_v3_v3(ofs, ob->obmat[3]); /* Quat */ if (quat) { - copy_m4_m4(bmat, ob->obmat); - normalize_m4(bmat); - invert_m4_m4(imat, bmat); - copy_m3_m4(tmat, imat); - mat3_to_quat( quat,tmat); + float imat[4][4]; + invert_m4_m4(imat, ob->obmat); + mat4_to_quat(quat, imat); } - + if (dist) { - float vec[3]; - copy_m3_m4(tmat, ob->obmat); - - vec[0]= vec[1] = 0.0; - vec[2]= -(*dist); - mul_m3_v3(tmat, vec); + float vec[3] = {0.0f, 0.0f, -(*dist)}; + float tquat[4]; + + mat4_to_quat(tquat, ob->obmat); + + mul_qt_v3(tquat, vec); + sub_v3_v3(ofs, vec); } - + /* Lens */ if (lens) object_lens_clip_settings(ob, lens, NULL, NULL); @@ -212,7 +207,7 @@ void smooth_view(bContext *C, Object *oldcamera, Object *camera, float *ofs, flo if(lens) sms.new_lens= *lens; if (camera) { - view_settings_from_ob(camera, sms.new_ofs, sms.new_quat, &sms.new_dist, &sms.new_lens); + view3d_settings_from_ob(camera, sms.new_ofs, sms.new_quat, &sms.new_dist, &sms.new_lens); sms.to_camera= 1; /* restore view3d values in end */ } @@ -259,7 +254,7 @@ void smooth_view(bContext *C, Object *oldcamera, Object *camera, float *ofs, flo /* original values */ if (oldcamera) { sms.orig_dist= rv3d->dist; // below function does weird stuff with it... - view_settings_from_ob(oldcamera, sms.orig_ofs, sms.orig_quat, &sms.orig_dist, &sms.orig_lens); + view3d_settings_from_ob(oldcamera, sms.orig_ofs, sms.orig_quat, &sms.orig_dist, &sms.orig_lens); } else { VECCOPY(sms.orig_ofs, rv3d->ofs); @@ -1122,7 +1117,7 @@ static void obmat_to_viewmat(View3D *v3d, RegionView3D *rv3d, Object *ob, short rv3d->persp=RV3D_PERSP; rv3d->dist= 0.0; - view_settings_from_ob(v3d->camera, rv3d->ofs, NULL, NULL, &v3d->lens); + view3d_settings_from_ob(v3d->camera, rv3d->ofs, NULL, NULL, &v3d->lens); smooth_view(NULL, NULL, NULL, orig_ofs, new_quat, &orig_dist, &orig_lens); // XXX rv3d->persp=RV3D_CAMOB; /* just to be polite, not needed */ @@ -2688,7 +2683,7 @@ void view3d_align_axis_to_vector(View3D *v3d, RegionView3D *rv3d, int axisidx, f VECCOPY(orig_ofs, rv3d->ofs); rv3d->persp= RV3D_PERSP; rv3d->dist= 0.0; - view_settings_from_ob(v3d->camera, rv3d->ofs, NULL, NULL, &v3d->lens); + view3d_settings_from_ob(v3d->camera, rv3d->ofs, NULL, NULL, &v3d->lens); smooth_view(NULL, NULL, NULL, orig_ofs, new_quat, &orig_dist, &orig_lens); // XXX } else { if (rv3d->persp==RV3D_CAMOB) rv3d->persp= RV3D_PERSP; /* switch out of camera mode */ diff --git a/source/blender/imbuf/IMB_thumbs.h b/source/blender/imbuf/IMB_thumbs.h index ecb0ba8abd1..9248b768cb6 100644 --- a/source/blender/imbuf/IMB_thumbs.h +++ b/source/blender/imbuf/IMB_thumbs.h @@ -73,6 +73,8 @@ void IMB_thumb_makedirs(); /* special function for loading a thumbnail embedded into a blend file */ ImBuf *IMB_loadblend_thumb(const char *path); +void IMB_overlayblend_thumb(unsigned int *thumb, int width, int height, float aspect); + #endif /* _IMB_THUMBS_H */ diff --git a/source/blender/imbuf/intern/IMB_filetype.h b/source/blender/imbuf/intern/IMB_filetype.h index f6afe20cb5c..9fd4108bee9 100644 --- a/source/blender/imbuf/intern/IMB_filetype.h +++ b/source/blender/imbuf/intern/IMB_filetype.h @@ -109,6 +109,7 @@ struct ImBuf *imb_loadhdr(unsigned char *mem, int size, int flags); int imb_savehdr(struct ImBuf * ibuf, char *name, int flags); /* tiff */ +void imb_inittiff(void); int imb_is_a_tiff(unsigned char *buf); struct ImBuf *imb_loadtiff(unsigned char *mem, int size, int flags); void imb_loadtiletiff(struct ImBuf *ibuf, unsigned char *mem, int size, diff --git a/source/blender/imbuf/intern/filetype.c b/source/blender/imbuf/intern/filetype.c index a0ff4476556..c2140e12013 100644 --- a/source/blender/imbuf/intern/filetype.c +++ b/source/blender/imbuf/intern/filetype.c @@ -54,9 +54,6 @@ void quicktime_init(void); void quicktime_exit(void); #endif -void libtiff_init(void); -void libtiff_exit(void); - ImFileType IMB_FILE_TYPES[]= { {NULL, NULL, imb_is_a_iris, imb_ftype_iris, imb_loadiris, imb_saveiris, NULL, 0, IMAGIC}, {NULL, NULL, imb_is_a_jpeg, imb_ftype_default, imb_load_jpeg, imb_savejpeg, NULL, 0, JPG}, @@ -66,7 +63,7 @@ ImFileType IMB_FILE_TYPES[]= { {NULL, NULL, imb_is_dpx, imb_ftype_default, imb_loaddpx, imb_save_dpx, NULL, IM_FTYPE_FLOAT, DPX}, {NULL, NULL, imb_is_cineon, imb_ftype_default, imb_loadcineon, imb_savecineon, NULL, IM_FTYPE_FLOAT, CINEON}, #ifdef WITH_TIFF - {NULL, NULL, imb_is_a_tiff, imb_ftype_default, imb_loadtiff, imb_savetiff, imb_loadtiletiff, 0, TIF}, + {imb_inittiff, NULL, imb_is_a_tiff, imb_ftype_default, imb_loadtiff, imb_savetiff, imb_loadtiletiff, 0, TIF}, #elif defined(__APPLE__) && defined(IMBUF_COCOA) {NULL, NULL, imb_is_a_cocoa, imb_ftype_cocoa, imb_imb_cocoaLoadImage, imb_savecocoa, NULL, 0, TIF}, #endif diff --git a/source/blender/imbuf/intern/thumbs.c b/source/blender/imbuf/intern/thumbs.c index 8c75f5ab1ab..234c8837b35 100644 --- a/source/blender/imbuf/intern/thumbs.c +++ b/source/blender/imbuf/intern/thumbs.c @@ -347,7 +347,7 @@ ImBuf* IMB_thumb_create(const char* path, ThumbSize size, ThumbSource source, Im if (IMB_saveiff(img, temp, IB_rect | IB_metadata)) { #ifndef WIN32 chmod(temp, S_IRUSR | S_IWUSR); -#endif +#endif BLI_rename(temp, tpath); } diff --git a/source/blender/imbuf/intern/thumbs_blend.c b/source/blender/imbuf/intern/thumbs_blend.c index 6e7bd4e6ca7..4ad983cdff9 100644 --- a/source/blender/imbuf/intern/thumbs_blend.c +++ b/source/blender/imbuf/intern/thumbs_blend.c @@ -127,3 +127,59 @@ thumb_error: if(rect) MEM_freeN(rect); return NULL; } + +/* add a fake passepartout overlay to a byte buffer, use for blend file thumbnails */ +#define MARGIN 2 + +void IMB_overlayblend_thumb(unsigned int *thumb, int width, int height, float aspect) +{ + unsigned char *px= (unsigned char *)thumb; + int margin_l = MARGIN; + int margin_b = MARGIN; + int margin_r = width - MARGIN; + int margin_t = height - MARGIN; + + if(aspect < 1.0f) { + margin_l= (int)((width - ((float)width * aspect)) / 2.0f); + margin_l += MARGIN; + CLAMP(margin_l, MARGIN, (width/2)); + margin_r = width - margin_l; + } + else if (aspect > 1.0f) { + margin_b= (int)((height - ((float)height / aspect)) / 2.0f); + margin_b += MARGIN; + CLAMP(margin_b, MARGIN, (height/2)); + margin_t = height - margin_b; + } + + { + int x, y; + int hline, vline; + int stride_x= (margin_r - margin_l) - 2; + + for(y=0; y < height; y++) { + for(x=0; x < width; x++, px+=4) { + if((x > margin_l && x < margin_r) && (y > margin_b && y < margin_t)) { + /* interior. skip */ + x += stride_x; + px += stride_x * 4; + } else if( (hline=(((x == margin_l || x == margin_r)) && y >= margin_b && y <= margin_t)) || + (vline=(((y == margin_b || y == margin_t)) && x >= margin_l && x <= margin_r)) + ) { + /* dashed line */ + if((hline && y % 2) || (vline && x % 2)) { + px[0]= px[1]= px[2]= 0; + px[3] = 255; + } + } + else { + /* outside, fill in alpha, like passepartout */ + px[0] *= 0.5f; + px[1] *= 0.5f; + px[2] *= 0.5f; + px[3] = (px[3] * 0.5f) + 96; + } + } + } + } +} diff --git a/source/blender/imbuf/intern/tiff.c b/source/blender/imbuf/intern/tiff.c index 488340aec88..99f74fea640 100644 --- a/source/blender/imbuf/intern/tiff.c +++ b/source/blender/imbuf/intern/tiff.c @@ -356,6 +356,7 @@ static void scanline_separate_32bit(float *rectf, float *fbuf, int scanline_w, i } +#if 0 /* * Use the libTIFF RGBAImage API to read a TIFF image. * This function uses the "RGBA Image" support from libtiff, which enables @@ -387,6 +388,7 @@ static int imb_read_tiff_pixels_rgba(ImBuf *ibuf, TIFF *image, int premul) return success; } +#endif /* * Use the libTIFF scanline API to read a TIFF image. @@ -409,12 +411,6 @@ static int imb_read_tiff_pixels(ImBuf *ibuf, TIFF *image, int premul) TIFFGetField(image, TIFFTAG_PLANARCONFIG, &config); scanline = TIFFScanlineSize(image); - /* if file has an unsupported channel count, use libTIFF to - * convert to an 8 bit RGBA image */ - if (!ELEM(spp, 3, 4)) - return imb_read_tiff_pixels_rgba(ibuf, image, premul); - - if (bitspersample == 32) { ib_flag = IB_rectfloat; fbuf = (float *)_TIFFmalloc(scanline); @@ -427,7 +423,7 @@ static int imb_read_tiff_pixels(ImBuf *ibuf, TIFF *image, int premul) } tmpibuf= IMB_allocImBuf(ibuf->x, ibuf->y, ibuf->depth, ib_flag, 0); - + /* contiguous channels: RGBRGBRGB */ if (config == PLANARCONFIG_CONTIG) { for (row = 0; row < ibuf->y; row++) { @@ -512,6 +508,12 @@ static int imb_read_tiff_pixels(ImBuf *ibuf, TIFF *image, int premul) return success; } +void imb_inittiff(void) +{ + if (!(G.f & G_DEBUG)) + TIFFSetErrorHandler(NULL); +} + /** * Loads a TIFF file. * diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index 55b8374656a..7c3641db379 100644 --- a/source/blender/makesdna/DNA_ID.h +++ b/source/blender/makesdna/DNA_ID.h @@ -117,7 +117,7 @@ typedef struct Library { ID *idblock; struct FileData *filedata; char name[240]; /* path name used for reading, can be relative and edited in the outliner */ - char filename[240]; /* temp. absolute filepath, only used while reading */ + char filepath[240]; /* temp. absolute filepath, only used while reading */ int tot, pad; /* tot, idblock and filedata are only fo read and write */ struct Library *parent; /* set for indirectly linked libs, used in the outliner and while reading */ } Library; diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h index 2c5c50d7dc2..b6f72875c29 100644 --- a/source/blender/makesdna/DNA_texture_types.h +++ b/source/blender/makesdna/DNA_texture_types.h @@ -190,8 +190,12 @@ typedef struct VoxelData { float int_multiplier; int still_frame; char source_path[240]; + + /* temporary data */ float *dataset; - + int cachedframe; + int ok; + } VoxelData; typedef struct Tex { diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h index e1c3dcf82c4..ed52316990e 100644 --- a/source/blender/makesdna/DNA_windowmanager_types.h +++ b/source/blender/makesdna/DNA_windowmanager_types.h @@ -96,7 +96,16 @@ typedef struct ReportList { int printlevel; /* ReportType */ int storelevel; /* ReportType */ int flag, pad; + struct wmTimer *reporttimer; } ReportList; + +/* timer customdata to control reports display */ +typedef struct ReportTimerInfo { + float col[3]; + float greyscale; + float widthfac; +} ReportTimerInfo; + /* reports need to be before wmWindowManager */ diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c index 50ab36bd4a4..467eb237b9a 100644 --- a/source/blender/makesrna/intern/rna_ID.c +++ b/source/blender/makesrna/intern/rna_ID.c @@ -399,9 +399,9 @@ static void rna_def_library(BlenderRNA *brna) RNA_def_struct_ui_text(srna, "Library", "External .blend file from which data is linked"); RNA_def_struct_ui_icon(srna, ICON_LIBRARY_DATA_DIRECT); - prop= RNA_def_property(srna, "filename", PROP_STRING, PROP_FILEPATH); + prop= RNA_def_property(srna, "filepath", PROP_STRING, PROP_FILEPATH); RNA_def_property_string_sdna(prop, NULL, "name"); - RNA_def_property_ui_text(prop, "Filename", "Path to the library .blend file"); + RNA_def_property_ui_text(prop, "File Path", "Path to the library .blend file"); /* TODO - lib->filename isnt updated, however the outliner also skips this, probably only needed on read. */ prop= RNA_def_property(srna, "parent", PROP_POINTER, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_actuator.c b/source/blender/makesrna/intern/rna_actuator.c index 72208217984..2ca327f8907 100644 --- a/source/blender/makesrna/intern/rna_actuator.c +++ b/source/blender/makesrna/intern/rna_actuator.c @@ -284,6 +284,21 @@ static void rna_ConstraintActuator_spring_set(struct PointerRNA *ptr, float valu *fp = value; } +/* ConstraintActuator uses the same property for Material and Property. + Therefore we need to clear the property when "detect_material" mode changes */ +static void rna_Actuator_constraint_detect_material_set(struct PointerRNA *ptr, int value) +{ + bActuator *act = (bActuator*)ptr->data; + bConstraintActuator *ca = act->data; + + short old_value = (ca->flag & ACT_CONST_MATERIAL? 1:0); + + if (old_value != value) { + ca->flag ^= ACT_CONST_MATERIAL; + ca->matprop[0] = '\0'; + } +} + static void rna_FcurveActuator_add_set(struct PointerRNA *ptr, int value) { bActuator *act = (bActuator *)ptr->data; @@ -1172,6 +1187,7 @@ static void rna_def_constraint_actuator(BlenderRNA *brna) prop= RNA_def_property(srna, "detect_material", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", ACT_CONST_MATERIAL); RNA_def_property_ui_text(prop, "M/P", "Detect material instead of property"); + RNA_def_property_boolean_funcs(prop, NULL, "rna_Actuator_constraint_detect_material_set"); RNA_def_property_update(prop, NC_LOGIC, NULL); prop= RNA_def_property(srna, "fh_paralel_axis", PROP_BOOLEAN, PROP_NONE); @@ -1564,7 +1580,7 @@ static void rna_def_visibility_actuator(BlenderRNA *brna) RNA_def_struct_sdna_from(srna, "bVisibilityActuator", "data"); prop= RNA_def_property(srna, "visible", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", ACT_VISIBILITY_INVISIBLE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", ACT_VISIBILITY_INVISIBLE); RNA_def_property_ui_text(prop, "Visible", "Set the objects visible. Initialized from the objects render restriction toggle (access in the outliner)"); RNA_def_property_update(prop, NC_LOGIC, NULL); diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c index b1c5cac1865..d126f8543c6 100644 --- a/source/blender/makesrna/intern/rna_constraint.c +++ b/source/blender/makesrna/intern/rna_constraint.c @@ -64,10 +64,10 @@ EnumPropertyItem constraint_type_items[] ={ {CONSTRAINT_TYPE_CHILDOF, "CHILD_OF", ICON_CONSTRAINT_DATA, "Child Of", ""}, {CONSTRAINT_TYPE_MINMAX, "FLOOR", ICON_CONSTRAINT_DATA, "Floor", ""}, {CONSTRAINT_TYPE_FOLLOWPATH, "FOLLOW_PATH", ICON_CONSTRAINT_DATA, "Follow Path", ""}, + {CONSTRAINT_TYPE_PIVOT, "PIVOT", ICON_CONSTRAINT_DATA, "Pivot", ""}, {CONSTRAINT_TYPE_RIGIDBODYJOINT, "RIGID_BODY_JOINT", ICON_CONSTRAINT_DATA, "Rigid Body Joint", ""}, {CONSTRAINT_TYPE_PYTHON, "SCRIPT", ICON_CONSTRAINT_DATA, "Script", ""}, {CONSTRAINT_TYPE_SHRINKWRAP, "SHRINKWRAP", ICON_CONSTRAINT_DATA, "Shrinkwrap", ""}, - {CONSTRAINT_TYPE_PIVOT, "PIVOT", ICON_CONSTRAINT_DATA, "Pivot", ""}, {0, NULL, 0, NULL, NULL}}; EnumPropertyItem space_pchan_items[] = { diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c index c4137d5379b..c9b25bf47a6 100644 --- a/source/blender/makesrna/intern/rna_image.c +++ b/source/blender/makesrna/intern/rna_image.c @@ -296,15 +296,15 @@ static void rna_def_image(BlenderRNA *brna) RNA_def_struct_ui_text(srna, "Image", "Image datablock referencing an external or packed image"); RNA_def_struct_ui_icon(srna, ICON_IMAGE_DATA); - prop= RNA_def_property(srna, "filename", PROP_STRING, PROP_FILEPATH); + prop= RNA_def_property(srna, "filepath", PROP_STRING, PROP_FILEPATH); RNA_def_property_string_sdna(prop, NULL, "name"); - RNA_def_property_ui_text(prop, "Filename", "Image/Movie file name"); + RNA_def_property_ui_text(prop, "File Name", "Image/Movie file name"); RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, "rna_Image_reload_update"); /* eek. this is horrible but needed so we can save to a new name without blanking the data :( */ - prop= RNA_def_property(srna, "filename_raw", PROP_STRING, PROP_FILEPATH); + prop= RNA_def_property(srna, "filepath_raw", PROP_STRING, PROP_FILEPATH); RNA_def_property_string_sdna(prop, NULL, "name"); - RNA_def_property_ui_text(prop, "Filename", "Image/Movie file name (without data refreshing)"); + RNA_def_property_ui_text(prop, "File Name", "Image/Movie file name (without data refreshing)"); prop= RNA_def_property(srna, "file_format", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, image_type_items); diff --git a/source/blender/makesrna/intern/rna_main.c b/source/blender/makesrna/intern/rna_main.c index b683f5dc4b1..052c9fb3453 100644 --- a/source/blender/makesrna/intern/rna_main.c +++ b/source/blender/makesrna/intern/rna_main.c @@ -55,20 +55,20 @@ static int rna_Main_fileissaved_get(PointerRNA *ptr) return G.relbase_valid; } -static void rna_Main_filename_get(PointerRNA *ptr, char *value) +static void rna_Main_filepath_get(PointerRNA *ptr, char *value) { Main *bmain= (Main*)ptr->data; BLI_strncpy(value, bmain->name, sizeof(bmain->name)); } -static int rna_Main_filename_length(PointerRNA *ptr) +static int rna_Main_filepath_length(PointerRNA *ptr) { Main *bmain= (Main*)ptr->data; return strlen(bmain->name); } #if 0 -static void rna_Main_filename_set(PointerRNA *ptr, const char *value) +static void rna_Main_filepath_set(PointerRNA *ptr, const char *value) { Main *bmain= (Main*)ptr->data; BLI_strncpy(bmain->name, value, sizeof(bmain->name)); @@ -308,9 +308,9 @@ void RNA_def_main(BlenderRNA *brna) RNA_def_struct_ui_text(srna, "Main", "Main data structure representing a .blend file and all its datablocks"); RNA_def_struct_ui_icon(srna, ICON_BLENDER); - prop= RNA_def_property(srna, "filename", PROP_STRING, PROP_FILEPATH); + prop= RNA_def_property(srna, "filepath", PROP_STRING, PROP_FILEPATH); RNA_def_property_string_maxlength(prop, 240); - RNA_def_property_string_funcs(prop, "rna_Main_filename_get", "rna_Main_filename_length", "rna_Main_filename_set"); + RNA_def_property_string_funcs(prop, "rna_Main_filepath_get", "rna_Main_filepath_length", "rna_Main_filepath_set"); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Filename", "Path to the .blend file"); diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c index 34eef0bb459..c9e17a562af 100644 --- a/source/blender/makesrna/intern/rna_main_api.c +++ b/source/blender/makesrna/intern/rna_main_api.c @@ -260,9 +260,9 @@ Image *rna_Main_images_new(Main *bmain, char* name, int width, int height, int f image->id.us--; return image; } -Image *rna_Main_images_load(Main *bmain, char *filename) +Image *rna_Main_images_load(Main *bmain, char *filepath) { - return BKE_add_image_file(filename, 0); + return BKE_add_image_file(filepath, 0); } void rna_Main_images_remove(Main *bmain, ReportList *reports, Image *image) { @@ -316,9 +316,9 @@ void rna_Main_metaballs_remove(Main *bmain, ReportList *reports, struct MetaBall BKE_reportf(reports, RPT_ERROR, "MetaBall \"%s\" must have zero users to be removed, found %d.", mb->id.name+2, ID_REAL_USERS(mb)); } -VFont *rna_Main_fonts_load(Main *bmain, char *filename) +VFont *rna_Main_fonts_load(Main *bmain, char *filepath) { - return load_vfont(filename); + return load_vfont(filepath); } void rna_Main_fonts_remove(Main *bmain, ReportList *reports, VFont *vfont) { @@ -465,7 +465,7 @@ void RNA_api_main(StructRNA *srna) /* func= RNA_def_function(srna, "add_image", "rna_Main_add_image"); RNA_def_function_ui_description(func, "Add a new image."); - parm= RNA_def_string(func, "filename", "", 0, "", "Filename to load image from."); + parm= RNA_def_string(func, "filepath", "", 0, "", "File path to load image from."); RNA_def_property_flag(parm, PROP_REQUIRED); parm= RNA_def_pointer(func, "image", "Image", "", "New image."); RNA_def_function_return(func, parm); @@ -692,7 +692,7 @@ void RNA_def_main_images(BlenderRNA *brna, PropertyRNA *cprop) func= RNA_def_function(srna, "load", "rna_Main_images_load"); RNA_def_function_ui_description(func, "Load a new image into the main database"); - parm= RNA_def_string(func, "filename", "File Name", 0, "", "path of the file to load."); + parm= RNA_def_string(func, "filepath", "File Path", 0, "", "path of the file to load."); RNA_def_property_flag(parm, PROP_REQUIRED); /* return type */ parm= RNA_def_pointer(func, "image", "Image", "", "New image datablock."); @@ -791,7 +791,7 @@ void RNA_def_main_fonts(BlenderRNA *brna, PropertyRNA *cprop) func= RNA_def_function(srna, "load", "rna_Main_fonts_load"); RNA_def_function_ui_description(func, "Load a new font into the main database"); - parm= RNA_def_string(func, "filename", "File Name", 0, "", "path of the font to load."); + parm= RNA_def_string(func, "filepath", "File Path", 0, "", "path of the font to load."); RNA_def_property_flag(parm, PROP_REQUIRED); /* return type */ parm= RNA_def_pointer(func, "vfont", "VectorFont", "", "New font datablock."); diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index d2bf791fb67..0ee2360a787 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -40,6 +40,7 @@ #include "BKE_animsys.h" #include "BKE_bmesh.h" /* For BevelModifierData */ +#include "BKE_multires.h" #include "BKE_smoke.h" /* For smokeModifier_free & smokeModifier_createType */ #include "WM_api.h" @@ -369,7 +370,7 @@ static int rna_MultiresModifier_external_get(PointerRNA *ptr) return CustomData_external_test(&me->fdata, CD_MDISPS); } -static void rna_MultiresModifier_filename_get(PointerRNA *ptr, char *value) +static void rna_MultiresModifier_filepath_get(PointerRNA *ptr, char *value) { Object *ob= (Object*)ptr->id.data; CustomDataExternal *external= ((Mesh*)ob->data)->fdata.external; @@ -377,16 +378,18 @@ static void rna_MultiresModifier_filename_get(PointerRNA *ptr, char *value) BLI_strncpy(value, (external)? external->filename: "", sizeof(external->filename)); } -static void rna_MultiresModifier_filename_set(PointerRNA *ptr, const char *value) +static void rna_MultiresModifier_filepath_set(PointerRNA *ptr, const char *value) { Object *ob= (Object*)ptr->id.data; CustomDataExternal *external= ((Mesh*)ob->data)->fdata.external; - if(external) + if(external && strcmp(external->filename, value)) { BLI_strncpy(external->filename, value, sizeof(external->filename)); + multires_force_external_reload(ob); + } } -static int rna_MultiresModifier_filename_length(PointerRNA *ptr) +static int rna_MultiresModifier_filepath_length(PointerRNA *ptr) { Object *ob= (Object*)ptr->id.data; CustomDataExternal *external= ((Mesh*)ob->data)->fdata.external; @@ -603,9 +606,9 @@ static void rna_def_modifier_multires(BlenderRNA *brna) RNA_def_property_boolean_funcs(prop, "rna_MultiresModifier_external_get", NULL); RNA_def_property_ui_text(prop, "External", "Store multires displacements outside the .blend file, to save memory"); - prop= RNA_def_property(srna, "filename", PROP_STRING, PROP_FILEPATH); - RNA_def_property_string_funcs(prop, "rna_MultiresModifier_filename_get", "rna_MultiresModifier_filename_length", "rna_MultiresModifier_filename_set"); - RNA_def_property_ui_text(prop, "Filename", "Path to external displacements file"); + prop= RNA_def_property(srna, "filepath", PROP_STRING, PROP_FILEPATH); + RNA_def_property_string_funcs(prop, "rna_MultiresModifier_filepath_get", "rna_MultiresModifier_filepath_length", "rna_MultiresModifier_filepath_set"); + RNA_def_property_ui_text(prop, "File Path", "Path to external displacements file"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "optimal_display", PROP_BOOLEAN, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index d6825959083..efa2c3d0027 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -31,6 +31,7 @@ #include "DNA_group_types.h" #include "DNA_modifier_types.h" +#include "DNA_particle_types.h" #include "DNA_scene_types.h" #include "DNA_userdef_types.h" @@ -798,10 +799,14 @@ static void rna_Scene_editmesh_select_mode_update(Main *bmain, Scene *scene, Poi static void object_simplify_update(Object *ob) { ModifierData *md; + ParticleSystem *psys; for(md=ob->modifiers.first; md; md=md->next) if(ELEM3(md->type, eModifierType_Subsurf, eModifierType_Multires, eModifierType_ParticleSystem)) - ob->recalc |= OB_RECALC_DATA; + ob->recalc |= OB_RECALC_DATA|PSYS_RECALC_CHILD; + + for(psys=ob->particlesystem.first; psys; psys=psys->next) + psys->recalc |= PSYS_RECALC_CHILD; if(ob->dup_group) { GroupObject *gob; @@ -811,17 +816,24 @@ static void object_simplify_update(Object *ob) } } -static void rna_Scene_simplify_update(Main *bmain, Scene *scene, PointerRNA *ptr) +static void rna_Scene_use_simplify_update(Main *bmain, Scene *scene, PointerRNA *ptr) { + Scene *sce; Base *base; - for(base= scene->base.first; base; base= base->next) + for(SETLOOPER(scene, base)) object_simplify_update(base->object); DAG_ids_flush_update(0); WM_main_add_notifier(NC_GEOM|ND_DATA, NULL); } +static void rna_Scene_simplify_update(Main *bmain, Scene *scene, PointerRNA *ptr) +{ + if(scene->r.mode & R_SIMPLIFY) + rna_Scene_use_simplify_update(bmain, scene, ptr); +} + static int rna_Scene_sync_mode_get(PointerRNA *ptr) { Scene *scene= (Scene*)ptr->data; @@ -2815,7 +2827,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna) prop= RNA_def_property(srna, "use_simplify", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", R_SIMPLIFY); RNA_def_property_ui_text(prop, "Use Simplify", "Enable simplification of scene for quicker preview renders"); - RNA_def_property_update(prop, 0, "rna_Scene_simplify_update"); + RNA_def_property_update(prop, 0, "rna_Scene_use_simplify_update"); prop= RNA_def_property(srna, "simplify_subdivision", PROP_INT, PROP_UNSIGNED); RNA_def_property_int_sdna(prop, NULL, "simplify_subsurf"); diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c index bbcc1f82826..f1f4a252c16 100644 --- a/source/blender/makesrna/intern/rna_sequencer.c +++ b/source/blender/makesrna/intern/rna_sequencer.c @@ -40,9 +40,20 @@ #include "MEM_guardedalloc.h" #include "WM_types.h" +#include "BLI_math.h" #ifdef RNA_RUNTIME +static float to_dB(float x) +{ + return logf(x * x + 1e-30f) * 4.34294480f; +} + +static float from_dB(float x) +{ + return expf(x * 0.11512925f); +} + /* build a temp referene to the parent */ static void meta_tmp_ref(Sequence *seq_par, Sequence *seq) { @@ -393,6 +404,20 @@ static int rna_Sequence_proxy_filepath_length(PointerRNA *ptr) return strlen(path)+1; } +static float rna_Sequence_attenuation_get(PointerRNA *ptr) +{ + Sequence *seq= (Sequence*)(ptr->data); + + return to_dB(seq->volume); +} + +static void rna_Sequence_attenuation_set(PointerRNA *ptr, float value) +{ + Sequence *seq= (Sequence*)(ptr->data); + + seq->volume = from_dB(value); +} + /*static void rna_SoundSequence_filename_set(PointerRNA *ptr, const char *value) { @@ -1045,10 +1070,17 @@ static void rna_def_sound(BlenderRNA *brna) prop= RNA_def_property(srna, "volume", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "volume"); - RNA_def_property_range(prop, 0.0f, 2.0f); + RNA_def_property_range(prop, 0.0f, 100.0f); RNA_def_property_ui_text(prop, "Volume", "Playback volume of the sound"); RNA_def_property_update(prop, NC_SCENE|ND_SEQUENCER, "rna_Sequence_update"); + prop= RNA_def_property(srna, "attenuation", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, -100.0f, +40.0f); + RNA_def_property_ui_text(prop, "Attenuation/db", "Attenuation in dezibel"); + RNA_def_property_float_funcs(prop, "rna_Sequence_attenuation_get", "rna_Sequence_attenuation_set", NULL); + + RNA_def_property_update(prop, NC_SCENE|ND_SEQUENCER, "rna_Sequence_update"); + prop= RNA_def_property(srna, "filepath", PROP_STRING, PROP_FILEPATH); RNA_def_property_ui_text(prop, "File", ""); RNA_def_property_string_funcs(prop, "rna_Sequence_filepath_get", "rna_Sequence_filepath_length", diff --git a/source/blender/makesrna/intern/rna_sound.c b/source/blender/makesrna/intern/rna_sound.c index 3ff81df02f8..b3c9e36e7b9 100644 --- a/source/blender/makesrna/intern/rna_sound.c +++ b/source/blender/makesrna/intern/rna_sound.c @@ -36,7 +36,7 @@ #include "BKE_sound.h" #include "BKE_context.h" -static void rna_Sound_filename_update(Main *bmain, Scene *scene, PointerRNA *ptr) +static void rna_Sound_filepath_update(Main *bmain, Scene *scene, PointerRNA *ptr) { sound_load(bmain, (bSound*)ptr->data); } @@ -70,10 +70,10 @@ static void rna_def_sound(BlenderRNA *brna) //rna_def_ipo_common(srna); - prop= RNA_def_property(srna, "filename", PROP_STRING, PROP_FILEPATH); + prop= RNA_def_property(srna, "filepath", PROP_STRING, PROP_FILEPATH); RNA_def_property_string_sdna(prop, NULL, "name"); RNA_def_property_ui_text(prop, "Filename", "Sound sample file used by this Sound datablock"); - RNA_def_property_update(prop, 0, "rna_Sound_filename_update"); + RNA_def_property_update(prop, 0, "rna_Sound_filepath_update"); prop= RNA_def_property(srna, "packed_file", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "packedfile"); @@ -82,7 +82,7 @@ static void rna_def_sound(BlenderRNA *brna) prop= RNA_def_property(srna, "caching", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_funcs(prop, "rna_Sound_caching_get", "rna_Sound_caching_set"); RNA_def_property_ui_text(prop, "Caching", "The sound file is decoded and loaded into RAM"); - RNA_def_property_update(prop, 0, "rna_Sound_filename_update"); + RNA_def_property_update(prop, 0, "rna_Sound_filepath_update"); } void RNA_def_sound(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_text.c b/source/blender/makesrna/intern/rna_text.c index ad90afb84a6..ccd3b432163 100644 --- a/source/blender/makesrna/intern/rna_text.c +++ b/source/blender/makesrna/intern/rna_text.c @@ -174,9 +174,9 @@ static void rna_def_text(BlenderRNA *brna) RNA_def_struct_ui_icon(srna, ICON_TEXT); RNA_def_struct_clear_flag(srna, STRUCT_ID_REFCOUNT); - prop= RNA_def_property(srna, "filename", PROP_STRING, PROP_NONE); + prop= RNA_def_property(srna, "filepath", PROP_STRING, PROP_NONE); RNA_def_property_string_funcs(prop, "rna_Text_filename_get", "rna_Text_filename_length", "rna_Text_filename_set"); - RNA_def_property_ui_text(prop, "Filename", "Filename of the text file"); + RNA_def_property_ui_text(prop, "File Path", "Filename of the text file"); prop= RNA_def_property(srna, "dirty", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", TXT_ISDIRTY); diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c index 5e58403e41b..32221e51cb9 100644 --- a/source/blender/makesrna/intern/rna_texture.c +++ b/source/blender/makesrna/intern/rna_texture.c @@ -75,6 +75,7 @@ EnumPropertyItem texture_type_items[] = { #include "RNA_access.h" #include "BKE_depsgraph.h" +#include "BKE_image.h" #include "BKE_texture.h" #include "BKE_main.h" @@ -131,6 +132,22 @@ static void rna_Texture_update(Main *bmain, Scene *scene, PointerRNA *ptr) WM_main_add_notifier(NC_TEXTURE, tex); } +static void rna_Texture_voxeldata_update(Main *bmain, Scene *scene, PointerRNA *ptr) +{ + Tex *tex= ptr->id.data; + + tex->vd->ok = 0; + rna_Texture_update(bmain, scene, ptr); +} + +static void rna_Texture_voxeldata_image_update(Main *bmain, Scene *scene, PointerRNA *ptr) +{ + Tex *tex= ptr->id.data; + + tex->ima->source = IMA_SRC_SEQUENCE; + rna_Texture_voxeldata_update(bmain, scene, ptr); +} + /* Used for Texture Properties, used (also) for/in Nodes */ static void rna_Texture_nodes_update(Main *bmain, Scene *scene, PointerRNA *ptr) { @@ -1593,7 +1610,7 @@ static void rna_def_texture_voxeldata(BlenderRNA *brna) RNA_def_property_enum_sdna(prop, NULL, "smoked_type"); RNA_def_property_enum_items(prop, smoked_type_items); RNA_def_property_ui_text(prop, "Source", "Simulation value to be used as a texture"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); + RNA_def_property_update(prop, 0, "rna_Texture_voxeldata_update"); prop= RNA_def_property(srna, "extension", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "extend"); @@ -1611,34 +1628,34 @@ static void rna_def_texture_voxeldata(BlenderRNA *brna) RNA_def_property_enum_sdna(prop, NULL, "file_format"); RNA_def_property_enum_items(prop, file_format_items); RNA_def_property_ui_text(prop, "File Format", "Format of the source data set to render "); - RNA_def_property_update(prop, 0, "rna_Texture_update"); + RNA_def_property_update(prop, 0, "rna_Texture_voxeldata_update"); prop= RNA_def_property(srna, "source_path", PROP_STRING, PROP_FILEPATH); RNA_def_property_string_sdna(prop, NULL, "source_path"); RNA_def_property_ui_text(prop, "Source Path", "The external source data file to use"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); + RNA_def_property_update(prop, 0, "rna_Texture_voxeldata_update"); prop= RNA_def_property(srna, "resolution", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "resol"); RNA_def_property_ui_text(prop, "Resolution", "Resolution of the voxel grid"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); + RNA_def_property_update(prop, 0, "rna_Texture_voxeldata_update"); prop= RNA_def_property(srna, "still", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", TEX_VD_STILL); RNA_def_property_ui_text(prop, "Still Frame Only", "Always render a still frame from the voxel data sequence"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); + RNA_def_property_update(prop, 0, "rna_Texture_voxeldata_update"); prop= RNA_def_property(srna, "still_frame_number", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "still_frame"); RNA_def_property_range(prop, -MAXFRAME, MAXFRAME); RNA_def_property_ui_text(prop, "Still Frame Number", "The frame number to always use"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); + RNA_def_property_update(prop, 0, "rna_Texture_voxeldata_update"); prop= RNA_def_property(srna, "domain_object", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "object"); RNA_def_property_ui_text(prop, "Domain Object", "Object used as the smoke simulation domain"); RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_update(prop, 0, "rna_Texture_update"); + RNA_def_property_update(prop, 0, "rna_Texture_voxeldata_update"); srna= RNA_def_struct(brna, "VoxelDataTexture", "Texture"); @@ -1656,12 +1673,12 @@ static void rna_def_texture_voxeldata(BlenderRNA *brna) RNA_def_property_struct_type(prop, "Image"); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Image", ""); - RNA_def_property_update(prop, 0, "rna_Texture_update"); + RNA_def_property_update(prop, 0, "rna_Texture_voxeldata_image_update"); prop= RNA_def_property(srna, "image_user", PROP_POINTER, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "iuser"); RNA_def_property_ui_text(prop, "Image User", "Parameters defining which layer, pass and frame of the image is displayed"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); + RNA_def_property_update(prop, 0, "rna_Texture_voxeldata_update"); } static void rna_def_texture(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c index 7c78d8a74e7..ccea5fbdf93 100644 --- a/source/blender/makesrna/intern/rna_ui_api.c +++ b/source/blender/makesrna/intern/rna_ui_api.c @@ -398,10 +398,6 @@ void RNA_api_ui_layout(StructRNA *srna) func= RNA_def_function(srna, "template_reports_banner", "uiTemplateReportsBanner"); RNA_def_function_flag(func, FUNC_USE_CONTEXT); - parm= RNA_def_pointer(func, "operator", "Operator", "", ""); - RNA_def_property_flag(parm, PROP_REQUIRED); - - func= RNA_def_function(srna, "introspect", "uiLayoutIntrospect"); parm= RNA_def_string(func, "string", "", 1024*1024, "Descr", "DESCR"); diff --git a/source/blender/makesrna/intern/rna_vfont.c b/source/blender/makesrna/intern/rna_vfont.c index 1f8be906eb3..c19fbd7d5d3 100644 --- a/source/blender/makesrna/intern/rna_vfont.c +++ b/source/blender/makesrna/intern/rna_vfont.c @@ -44,10 +44,10 @@ void RNA_def_vfont(BlenderRNA *brna) RNA_def_struct_sdna(srna, "VFont"); RNA_def_struct_ui_icon(srna, ICON_FILE_FONT); - prop= RNA_def_property(srna, "filename", PROP_STRING, PROP_FILEPATH); + prop= RNA_def_property(srna, "filepath", PROP_STRING, PROP_FILEPATH); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_string_sdna(prop, NULL, "name"); - RNA_def_property_ui_text(prop, "Filename", ""); + RNA_def_property_ui_text(prop, "File Path", ""); prop= RNA_def_property(srna, "packed_file", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "packedfile"); diff --git a/source/blender/modifiers/intern/MOD_multires.c b/source/blender/modifiers/intern/MOD_multires.c index 945f17494f0..71e31656799 100644 --- a/source/blender/modifiers/intern/MOD_multires.c +++ b/source/blender/modifiers/intern/MOD_multires.c @@ -30,6 +30,8 @@ * */ +#include <stddef.h> + #include "BKE_cdderivedmesh.h" #include "BKE_multires.h" #include "BKE_modifier.h" @@ -60,6 +62,8 @@ static void copyData(ModifierData *md, ModifierData *target) static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc) { + SculptSession *ss= ob->sculpt; + int sculpting= (ob->mode & OB_MODE_SCULPT) && ss; MultiresModifierData *mmd = (MultiresModifierData*)md; DerivedMesh *result; @@ -73,10 +77,10 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *dm, result->release(result); result= cddm; } - else if((ob->mode & OB_MODE_SCULPT) && ob->sculpt) { + else if(sculpting) { /* would be created on the fly too, just nicer this way on first stroke after e.g. switching levels */ - ob->sculpt->pbvh= result->getPBVH(ob, result); + ss->pbvh= result->getPBVH(ob, result); } return result; diff --git a/source/blender/modifiers/intern/MOD_screw.c b/source/blender/modifiers/intern/MOD_screw.c index b70f145b67b..a1deaa140db 100644 --- a/source/blender/modifiers/intern/MOD_screw.c +++ b/source/blender/modifiers/intern/MOD_screw.c @@ -137,7 +137,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, int totvert= dm->getNumVerts(dm); int totedge= dm->getNumEdges(dm); - char axis_char, close; + char axis_char= 'X', close; float angle= ltmd->angle; float screw_ofs= ltmd->screw_ofs; float axis_vec[3]= {0.0f, 0.0f, 0.0f}; @@ -177,7 +177,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, other_axis_1=0; other_axis_2=2; break; - case 2: + default: /* 2, use default to quiet warnings */ other_axis_1=0; other_axis_2=1; break; @@ -248,7 +248,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, } else { /* exis char is used by i_rotate*/ - axis_char= 'X' + ltmd->axis; + axis_char += ltmd->axis; /* 'X' + axis */ /* useful to be able to use the axis vec in some cases still */ zero_v3(axis_vec); diff --git a/source/blender/python/BPY_extern.h b/source/blender/python/BPY_extern.h index 11208d54a73..40d544ac17e 100644 --- a/source/blender/python/BPY_extern.h +++ b/source/blender/python/BPY_extern.h @@ -119,9 +119,11 @@ extern "C" { // short eventValue, unsigned short space_event); // // void BPY_pydriver_update(void); - float BPY_pydriver_eval(struct ChannelDriver *driver); + float BPY_eval_driver(struct ChannelDriver *driver); // - int BPY_button_eval(struct bContext *C, char *expr, double *value); + int BPY_eval_button(struct bContext *C, const char *expr, double *value); + + int BPY_eval_string(struct bContext *C, const char *expr); /* format importer hook */ int BPY_call_importloader( char *name ); diff --git a/source/blender/python/doc/sphinx_doc_gen.py b/source/blender/python/doc/sphinx_doc_gen.py index 69aa68acdc9..3e81f989d79 100644 --- a/source/blender/python/doc/sphinx_doc_gen.py +++ b/source/blender/python/doc/sphinx_doc_gen.py @@ -36,6 +36,7 @@ For PDF generation make ''' +# import rpdb2; rpdb2.start_embedded_debugger('test') import os import inspect @@ -134,7 +135,7 @@ def py_descr2sphinx(ident, fw, descr, module_name, type_name, identifier): if type(descr) == GetSetDescriptorType: fw(ident + ".. attribute:: %s\n\n" % identifier) - write_indented_lines(ident, fw, doc, False) + write_indented_lines(ident + " ", fw, doc, False) elif type(descr) == MethodDescriptorType: # GetSetDescriptorType, GetSetDescriptorType's are not documented yet write_indented_lines(ident, fw, doc, False) else: @@ -522,7 +523,7 @@ def rna2sphinx(BASEPATH): if prop.description: fw(" %s\n\n" % prop.description) type_descr = prop.get_type_description(class_fmt=":class:`%s`") - fw(" *type* %s\n\n" % type_descr) + fw(" :type: %s\n\n" % type_descr) # python attributes py_properties = struct.get_py_properties() diff --git a/source/blender/python/generic/bpy_internal_import.c b/source/blender/python/generic/bpy_internal_import.c index 6b79945ccd8..6ac63499988 100644 --- a/source/blender/python/generic/bpy_internal_import.c +++ b/source/blender/python/generic/bpy_internal_import.c @@ -32,6 +32,7 @@ #include "MEM_guardedalloc.h" #include "BKE_text.h" /* txt_to_buf */ #include "BKE_main.h" +#include "BKE_global.h" /* grr, only for G.sce */ #include "BLI_listbase.h" #include <stddef.h> @@ -55,6 +56,12 @@ void bpy_import_main_set(struct Main *maggie) bpy_import_main= maggie; } +/* returns a dummy filename for a textblock so we can tell what file a text block comes from */ +void bpy_text_filename_get(char *fn, Text *text) +{ + sprintf(fn, "%s/%s", text->id.lib ? text->id.lib->filepath : G.sce, text->id.name+2); +} + PyObject *bpy_text_import( Text *text ) { char *buf = NULL; @@ -62,8 +69,11 @@ PyObject *bpy_text_import( Text *text ) int len; if( !text->compiled ) { + char fn_dummy[256]; + bpy_text_filename_get(fn_dummy, text); + buf = txt_to_buf( text ); - text->compiled = Py_CompileString( buf, text->id.name+2, Py_file_input ); + text->compiled = Py_CompileString( buf, fn_dummy, Py_file_input ); MEM_freeN( buf ); if( PyErr_Occurred( ) ) { diff --git a/source/blender/python/generic/bpy_internal_import.h b/source/blender/python/generic/bpy_internal_import.h index 947e0dfc29d..37136d46c9e 100644 --- a/source/blender/python/generic/bpy_internal_import.h +++ b/source/blender/python/generic/bpy_internal_import.h @@ -50,6 +50,9 @@ PyObject* bpy_text_import( struct Text *text ); PyObject* bpy_text_import_name( char *name, int *found ); PyObject* bpy_text_reimport( PyObject *module, int *found ); /* void bpy_text_clear_modules( int clear_all );*/ /* Clear user modules */ + +void bpy_text_filename_get(char *fn, struct Text *text); + extern PyMethodDef bpy_import_meth[]; extern PyMethodDef bpy_reload_meth[]; diff --git a/source/blender/python/generic/mathutils_vector.c b/source/blender/python/generic/mathutils_vector.c index af549762756..a9bcdacdb03 100644 --- a/source/blender/python/generic/mathutils_vector.c +++ b/source/blender/python/generic/mathutils_vector.c @@ -255,8 +255,11 @@ static PyObject *Vector_ToTuple(VectorObject *self, PyObject *args) { int ndigits= 0; - if(!PyArg_ParseTuple(args, "|i:to_tuple", &ndigits) || (ndigits > 22 || ndigits < 0)) { - PyErr_SetString(PyExc_TypeError, "vector.to_tuple(ndigits): ndigits must be between 0 and 21"); + if(!PyArg_ParseTuple(args, "|i:to_tuple", &ndigits)) + return NULL; + + if(ndigits > 22 || ndigits < 0) { + PyErr_SetString(PyExc_ValueError, "vector.to_tuple(ndigits): ndigits must be between 0 and 21"); return NULL; } @@ -288,10 +291,9 @@ static PyObject *Vector_ToTrackQuat(VectorObject *self, PyObject *args ) char *strack, *sup; short track = 2, up = 1; - if(!PyArg_ParseTuple( args, "|ss:to_track_quat", &strack, &sup)) { - PyErr_SetString( PyExc_TypeError, "expected optional two strings\n" ); + if(!PyArg_ParseTuple( args, "|ss:to_track_quat", &strack, &sup)) return NULL; - } + if (self->size != 3) { PyErr_SetString( PyExc_TypeError, "only for 3D vectors\n" ); return NULL; @@ -498,21 +500,28 @@ static PyObject *Vector_Dot(VectorObject *self, VectorObject *value ) return PyFloat_FromDouble(dot); } -static char Vector_Angle_doc[] = -".. function:: angle(other)\n" +static char Vector_angle_doc[] = +".. function:: angle(other, fallback)\n" "\n" " Return the angle between two vectors.\n" "\n" +" :arg other: another vector to compare the angle with\n" " :type other: :class:`Vector`\n" -" :return angle: angle in radians\n" +" :arg fallback: return this value when the angle cant be calculated (zero length vector)\n" +" :return angle: angle in radians or fallback when given\n" " :rtype: float\n" "\n" " .. note:: Zero length vectors raise an :exc:`AttributeError`.\n"; -static PyObject *Vector_Angle(VectorObject *self, VectorObject *value) +static PyObject *Vector_angle(VectorObject *self, PyObject *args) { + VectorObject *value; double dot = 0.0f, angleRads, test_v1 = 0.0f, test_v2 = 0.0f; int x, size; + PyObject *fallback= NULL; + if(!PyArg_ParseTuple(args, "O!|O:angle", &vector_Type, &value, &fallback)) + return NULL; + if (!VectorObject_Check(value)) { PyErr_SetString( PyExc_TypeError, "vec.angle(value): expected a vector argument" ); return NULL; @@ -534,8 +543,15 @@ static PyObject *Vector_Angle(VectorObject *self, VectorObject *value) test_v2 += value->vec[x] * value->vec[x]; } if (!test_v1 || !test_v2){ - PyErr_SetString(PyExc_AttributeError, "vector.angle(other): zero length vectors are not acceptable arguments\n"); - return NULL; + /* avoid exception */ + if(fallback) { + Py_INCREF(fallback); + return fallback; + } + else { + PyErr_SetString(PyExc_ValueError, "vector.angle(other): zero length vectors have no valid angle\n"); + return NULL; + } } //dot product @@ -649,10 +665,9 @@ static PyObject *Vector_Lerp(VectorObject *self, PyObject *args) float fac, ifac, vec[4]; int x; - if(!PyArg_ParseTuple(args, "O!f:lerp", &vector_Type, &vec2, &fac)) { - PyErr_SetString(PyExc_TypeError, "vector.lerp(): expects a vector of the same size and float"); + if(!PyArg_ParseTuple(args, "O!f:lerp", &vector_Type, &vec2, &fac)) return NULL; - } + if(self->size != vec2->size) { PyErr_SetString(PyExc_AttributeError, "vector.lerp(): expects (2) vector objects of the same size"); return NULL; @@ -2037,7 +2052,7 @@ static struct PyMethodDef Vector_methods[] = { {"reflect", ( PyCFunction ) Vector_Reflect, METH_O, Vector_Reflect_doc}, {"cross", ( PyCFunction ) Vector_Cross, METH_O, Vector_Cross_doc}, {"dot", ( PyCFunction ) Vector_Dot, METH_O, Vector_Dot_doc}, - {"angle", ( PyCFunction ) Vector_Angle, METH_O, Vector_Angle_doc}, + {"angle", ( PyCFunction ) Vector_angle, METH_VARARGS, Vector_angle_doc}, {"difference", ( PyCFunction ) Vector_Difference, METH_O, Vector_Difference_doc}, {"project", ( PyCFunction ) Vector_Project, METH_O, Vector_Project_doc}, {"lerp", ( PyCFunction ) Vector_Lerp, METH_VARARGS, Vector_Lerp_doc}, diff --git a/source/blender/python/intern/bpy_driver.c b/source/blender/python/intern/bpy_driver.c index afe6b63458f..8f49263b375 100644 --- a/source/blender/python/intern/bpy_driver.c +++ b/source/blender/python/intern/bpy_driver.c @@ -103,7 +103,7 @@ static int bpy_pydriver_create_dict(void) } /* Update function, it gets rid of pydrivers global dictionary, forcing - * BPY_pydriver_eval to recreate it. This function is used to force + * BPY_eval_driver to recreate it. This function is used to force * reloading the Blender text module "pydrivers.py", if available, so * updates in it reach pydriver evaluation. */ @@ -153,7 +153,7 @@ static float pydriver_error(ChannelDriver *driver) * bake operator which intern starts a thread which calls scene update which * does a driver update. to avoid a deadlock check PyThreadState_Get() if PyGILState_Ensure() is needed. */ -float BPY_pydriver_eval (ChannelDriver *driver) +float BPY_eval_driver (ChannelDriver *driver) { PyObject *driver_vars=NULL; PyObject *retval= NULL; @@ -246,11 +246,11 @@ float BPY_pydriver_eval (ChannelDriver *driver) /* this target failed - bad name */ if (targets_ok) { /* first one - print some extra info for easier identification */ - fprintf(stderr, "\nBPY_pydriver_eval() - Error while evaluating PyDriver:\n"); + fprintf(stderr, "\nBPY_eval_driver() - Error while evaluating PyDriver:\n"); targets_ok= 0; } - fprintf(stderr, "\tBPY_pydriver_eval() - couldn't add variable '%s' to namespace\n", dvar->name); + fprintf(stderr, "\tBPY_eval_driver() - couldn't add variable '%s' to namespace\n", dvar->name); // BPy_errors_to_report(NULL); // TODO - reports PyErr_Print(); PyErr_Clear(); @@ -290,7 +290,7 @@ float BPY_pydriver_eval (ChannelDriver *driver) return (float)result; } else { - fprintf(stderr, "\tBPY_pydriver_eval() - driver '%s' evaluates to '%f'\n", dvar->name, result); + fprintf(stderr, "\tBPY_eval_driver() - driver '%s' evaluates to '%f'\n", dvar->name, result); return 0.0f; } } diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index 285dbb78874..680c5165575 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -327,16 +327,17 @@ int BPY_run_python_script( bContext *C, const char *fn, struct Text *text, struc } bpy_context_set(C, &gilstate); - - py_dict = CreateGlobalDictionary(C, text?text->id.name+2:fn); if (text) { + char fn_dummy[FILE_MAXDIR]; + bpy_text_filename_get(fn_dummy, text); + py_dict = CreateGlobalDictionary(C, fn_dummy); if( !text->compiled ) { /* if it wasn't already compiled, do it now */ char *buf = txt_to_buf( text ); text->compiled = - Py_CompileString( buf, text->id.name+2, Py_file_input ); + Py_CompileString( buf, fn_dummy, Py_file_input ); MEM_freeN( buf ); @@ -347,8 +348,12 @@ int BPY_run_python_script( bContext *C, const char *fn, struct Text *text, struc if(text->compiled) py_result = PyEval_EvalCode( text->compiled, py_dict, py_dict ); - } else { - FILE *fp= fopen(fn, "r"); + } + else { + FILE *fp= fopen(fn, "r"); + + py_dict = CreateGlobalDictionary(C, fn); + if(fp) { #ifdef _WIN32 /* Previously we used PyRun_File to run directly the code on a FILE @@ -528,7 +533,7 @@ int BPY_run_python_script_space(const char *modulename, const char *func) #endif -int BPY_button_eval(bContext *C, char *expr, double *value) +int BPY_eval_button(bContext *C, const char *expr, double *value) { PyGILState_STATE gilstate; PyObject *dict, *mod, *retval; @@ -599,6 +604,40 @@ int BPY_button_eval(bContext *C, char *expr, double *value) return error_ret; } +int BPY_eval_string(bContext *C, const char *expr) +{ + PyGILState_STATE gilstate; + PyObject *dict, *retval; + int error_ret = 0; + + if (!expr) return -1; + + if(expr[0]=='\0') { + return error_ret; + } + + bpy_context_set(C, &gilstate); + + dict= CreateGlobalDictionary(C, NULL); + + retval = PyRun_String(expr, Py_eval_input, dict, dict); + + if (retval == NULL) { + error_ret= -1; + + BPy_errors_to_report(CTX_wm_reports(C)); + } + else { + Py_DECREF(retval); + } + + Py_DECREF(dict); + bpy_context_clear(C, &gilstate); + + return error_ret; +} + + void BPY_load_user_modules(bContext *C) { PyGILState_STATE gilstate; diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index f6be316dcfd..deb3d99f9ed 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -1532,8 +1532,6 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem /* 1. check that everything is ok & updated */ if(psys==NULL) return 0; - - totchild=psys->totchild; part=psys->part; pars=psys->particles; @@ -1554,6 +1552,8 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem if(part->phystype==PART_PHYS_KEYED) psys_count_keyed_targets(&sim); + psys_update_children(&sim); + totchild=psys->totchild; if(G.rendering == 0) { /* preview render */ totchild = (int)((float)totchild * (float)part->disp / 100.0f); @@ -1657,6 +1657,9 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem transpose_m3(nmat); /* 2.6 setup strand rendering */ + if(part->ren_as == PART_DRAW_PATH && psys->pathcache==NULL) + psys_update_path_cache(&sim, cfra); + if(part->ren_as == PART_DRAW_PATH && psys->pathcache){ path_nbr=(int)pow(2.0,(double) part->ren_step); @@ -4592,7 +4595,6 @@ void RE_Database_Free(Render *re) end_render_textures(); free_pointdensities(re); - free_voxeldata(re); free_camera_inside_volumes(re); diff --git a/source/blender/render/intern/source/voxeldata.c b/source/blender/render/intern/source/voxeldata.c index 3ac806f320a..64ba206bb86 100644 --- a/source/blender/render/intern/source/voxeldata.c +++ b/source/blender/render/intern/source/voxeldata.c @@ -57,58 +57,72 @@ #include "texture.h" #include "voxeldata.h" -static int load_frame_blendervoxel(FILE *fp, float *F, int size, int frame, int offset) +static int load_frame_blendervoxel(VoxelData *vd, FILE *fp, int frame) { - if(fseek(fp,frame*size*sizeof(float)+offset,0) == -1) + size_t offset = sizeof(VoxelDataHeader); + int size = (vd->resol[0])*(vd->resol[1])*(vd->resol[2]); + + vd->dataset = MEM_mapallocN(sizeof(float)*size, "voxel dataset"); + + if(fseek(fp, frame*size*sizeof(float)+offset, 0) == -1) return 0; - if(fread(F,sizeof(float),size,fp) != size) + if(fread(vd->dataset, sizeof(float), size, fp) != size) return 0; + vd->cachedframe = frame; + vd->ok = 1; return 1; } -static int load_frame_raw8(FILE *fp, float *F, int size, int frame) +static int load_frame_raw8(VoxelData *vd, FILE *fp, int frame) { - char *tmp; + int size = (vd->resol[0])*(vd->resol[1])*(vd->resol[2]); + char *data_c; int i; - tmp = (char *)MEM_mallocN(sizeof(char)*size, "temporary voxel file reading storage"); + vd->dataset = MEM_mapallocN(sizeof(float)*size, "voxel dataset"); + data_c = (char *)MEM_mallocN(sizeof(char)*size, "temporary voxel file reading storage"); if(fseek(fp,(frame-1)*size*sizeof(char),0) == -1) { - MEM_freeN(tmp); + MEM_freeN(data_c); return 0; } - if(fread(tmp, sizeof(char), size, fp) != size) { - MEM_freeN(tmp); + if(fread(data_c, sizeof(char), size, fp) != size) { + MEM_freeN(data_c); return 0; } for (i=0; i<size; i++) { - F[i] = (float)tmp[i] / 256.f; + vd->dataset[i] = (float)data_c[i] / 255.f; } - MEM_freeN(tmp); + MEM_freeN(data_c); + + vd->cachedframe = frame; + vd->ok = 1; return 1; } -static void load_frame_image_sequence(Render *re, VoxelData *vd, Tex *tex) +static void load_frame_image_sequence(VoxelData *vd, Tex *tex) { ImBuf *ibuf; Image *ima = tex->ima; - ImageUser *iuser = &tex->iuser; + ImageUser *tiuser = &tex->iuser; + ImageUser iuser = *(tiuser); int x=0, y=0, z=0; float *rf; - if (!ima || !iuser) return; + if (!ima || !tiuser) return; + if (iuser.frames == 0) return; ima->source = IMA_SRC_SEQUENCE; - iuser->framenr = 1 + iuser->offset; + iuser.framenr = 1 + iuser.offset; /* find the first valid ibuf and use it to initialise the resolution of the data set */ /* need to do this in advance so we know how much memory to allocate */ - ibuf= BKE_image_get_ibuf(ima, iuser); - while (!ibuf && (iuser->framenr < iuser->frames)) { - iuser->framenr++; - ibuf= BKE_image_get_ibuf(ima, iuser); + ibuf= BKE_image_get_ibuf(ima, &iuser); + while (!ibuf && (iuser.framenr < iuser.frames)) { + iuser.framenr++; + ibuf= BKE_image_get_ibuf(ima, &iuser); } if (!ibuf) return; if (!ibuf->rect_float) IMB_float_from_rect(ibuf); @@ -116,15 +130,15 @@ static void load_frame_image_sequence(Render *re, VoxelData *vd, Tex *tex) vd->flag |= TEX_VD_STILL; vd->resol[0] = ibuf->x; vd->resol[1] = ibuf->y; - vd->resol[2] = iuser->frames; + vd->resol[2] = iuser.frames; vd->dataset = MEM_mapallocN(sizeof(float)*(vd->resol[0])*(vd->resol[1])*(vd->resol[2]), "voxel dataset"); - for (z=0; z < iuser->frames; z++) + for (z=0; z < iuser.frames; z++) { /* get a new ibuf for each frame */ if (z > 0) { - iuser->framenr++; - ibuf= BKE_image_get_ibuf(ima, iuser); + iuser.framenr++; + ibuf= BKE_image_get_ibuf(ima, &iuser); if (!ibuf) break; if (!ibuf->rect_float) IMB_float_from_rect(ibuf); } @@ -134,14 +148,17 @@ static void load_frame_image_sequence(Render *re, VoxelData *vd, Tex *tex) { for (x=0; x < ibuf->x; x++) { - /* currently converted to monchrome */ + /* currently averaged to monchrome */ vd->dataset[ V_I(x, y, z, vd->resol) ] = (rf[0] + rf[1] + rf[2])*0.333f; rf +=4; } } - BKE_image_free_anim_ibufs(ima, iuser->framenr); + BKE_image_free_anim_ibufs(ima, iuser.framenr); } + + vd->ok = 1; + return; } static int read_voxeldata_header(FILE *fp, struct VoxelData *vd) @@ -162,7 +179,7 @@ static int read_voxeldata_header(FILE *fp, struct VoxelData *vd) return 1; } -static void init_frame_smoke(Render *re, VoxelData *vd, Tex *tex) +static void init_frame_smoke(VoxelData *vd, Tex *tex) { Object *ob; ModifierData *md; @@ -232,53 +249,65 @@ static void init_frame_smoke(Render *re, VoxelData *vd, Tex *tex) } // end of fluid condition } } + + vd->ok = 1; + return; } static void cache_voxeldata(struct Render *re,Tex *tex) { VoxelData *vd = tex->vd; FILE *fp; - int size; int curframe; if (!vd) return; - /* image sequence gets special treatment */ - if (vd->file_format == TEX_VD_IMAGE_SEQUENCE) { - load_frame_image_sequence(re, vd, tex); - return; - } else if (vd->file_format == TEX_VD_SMOKE) { - init_frame_smoke(re, vd, tex); - return; + /* only re-cache if dataset needs updating */ + if ((vd->flag & TEX_VD_STILL) || (vd->cachedframe == re->r.cfra)) + if (vd->ok) return; + + /* clear out old cache, ready for new */ + if (vd->dataset) { + if(vd->file_format != TEX_VD_SMOKE) + MEM_freeN(vd->dataset); + vd->dataset = NULL; } - if (!BLI_exists(vd->source_path)) return; - fp = fopen(vd->source_path,"rb"); - if (!fp) return; - - if (vd->file_format == TEX_VD_BLENDERVOXEL) { - if(!read_voxeldata_header(fp, vd)) { - fclose(fp); - return; - } - } - - size = (vd->resol[0])*(vd->resol[1])*(vd->resol[2]); - vd->dataset = MEM_mapallocN(sizeof(float)*size, "voxel dataset"); - - if (vd->flag & TEX_VD_STILL) curframe = vd->still_frame; - else curframe = re->r.cfra; + if (vd->flag & TEX_VD_STILL) + curframe = vd->still_frame; + else + curframe = re->r.cfra; switch(vd->file_format) { + case TEX_VD_IMAGE_SEQUENCE: + load_frame_image_sequence(vd, tex); + return; + case TEX_VD_SMOKE: + init_frame_smoke(vd, tex); + return; case TEX_VD_BLENDERVOXEL: - load_frame_blendervoxel(fp, vd->dataset, size, curframe-1, sizeof(VoxelDataHeader)); - break; + if (!BLI_exists(vd->source_path)) return; + fp = fopen(vd->source_path,"rb"); + if (!fp) return; + + if(read_voxeldata_header(fp, vd)) + load_frame_blendervoxel(vd, fp, curframe-1); + else + fclose(fp); + + return; case TEX_VD_RAW_8BIT: - load_frame_raw8(fp, vd->dataset, size, curframe); - break; + if (!BLI_exists(vd->source_path)) return; + fp = fopen(vd->source_path,"rb"); + if (!fp) return; + + if (load_frame_raw8(vd, fp, curframe)) + ; + else + fclose(fp); + + return; } - - fclose(fp); } void make_voxeldata(struct Render *re) @@ -300,29 +329,6 @@ void make_voxeldata(struct Render *re) } -static void free_voxeldata_one(Render *re, Tex *tex) -{ - VoxelData *vd = tex->vd; - - if (vd->dataset) { - if(vd->file_format != TEX_VD_SMOKE) - MEM_freeN(vd->dataset); - vd->dataset = NULL; - } -} - - -void free_voxeldata(Render *re) -{ - Tex *tex; - - for (tex= G.main->tex.first; tex; tex= tex->id.next) { - if(tex->id.us && tex->type==TEX_VOXELDATA) { - free_voxeldata_one(re, tex); - } - } -} - int voxeldatatex(struct Tex *tex, float *texvec, struct TexResult *texres) { int retval = TEX_INT; diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 40186f40e9d..2b159daf6a1 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -324,5 +324,9 @@ void WM_jobs_stop_all(struct wmWindowManager *wm); char *WM_clipboard_text_get(int selection); void WM_clipboard_text_set(char *buf, int selection); + /* progress */ +void WM_progress_set(struct wmWindow *win, float progress); +void WM_progress_clear(struct wmWindow *win); + #endif /* WM_API_H */ diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c index 452c37dbe77..fcf8951d796 100644 --- a/source/blender/windowmanager/intern/wm.c +++ b/source/blender/windowmanager/intern/wm.c @@ -98,13 +98,18 @@ void WM_operator_free(wmOperator *op) MEM_freeN(op); } +static void wm_reports_free(wmWindowManager *wm) +{ + BKE_reports_clear(&wm->reports); + WM_event_remove_timer(wm, NULL, wm->reports.reporttimer); +} + /* all operations get registered in the windowmanager here */ /* called on event handling by event_system.c */ void wm_operator_register(bContext *C, wmOperator *op) { wmWindowManager *wm= CTX_wm_manager(C); int tot; - char *buf; BLI_addtail(&wm->operators, op); tot= BLI_countlist(&wm->operators); @@ -116,12 +121,6 @@ void wm_operator_register(bContext *C, wmOperator *op) tot--; } - - /* Report the string representation of the operator */ - buf = WM_operator_pystring(C, op->type, op->ptr, 1); - BKE_report(CTX_wm_reports(C), RPT_OPERATOR, buf); - MEM_freeN(buf); - /* so the console is redrawn */ WM_event_add_notifier(C, NC_SPACE|ND_SPACE_CONSOLE_REPORT, NULL); WM_event_add_notifier(C, NC_WM|ND_HISTORY, NULL); @@ -309,7 +308,8 @@ void wm_close_and_free(bContext *C, wmWindowManager *wm) BLI_freelistN(&wm->paintcursors); BLI_freelistN(&wm->drags); - BKE_reports_clear(&wm->reports); + + wm_reports_free(wm); if(C && CTX_wm_manager(C)==wm) CTX_wm_manager_set(C, NULL); } diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 84a6b3598d7..b55c68ce029 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -372,15 +372,56 @@ int WM_operator_poll(bContext *C, wmOperatorType *ot) return 1; } +static void wm_operator_print(wmOperator *op) +{ + char *buf = WM_operator_pystring(NULL, op->type, op->ptr, 1); + printf("%s\n", buf); + MEM_freeN(buf); +} + +static void wm_operator_reports(bContext *C, wmOperator *op, int retval, int popup) +{ + wmWindowManager *wm = CTX_wm_manager(C); + ReportList *reports = CTX_wm_reports(C); + char *buf; + + if(popup) + if(op->reports->list.first) + uiPupMenuReports(C, op->reports); + + if(retval & OPERATOR_FINISHED) { + if(G.f & G_DEBUG) + wm_operator_print(op); /* todo - this print may double up, might want to check more flags then the FINISHED */ + + /* Report the python string representation of the operator */ + buf = WM_operator_pystring(C, op->type, op->ptr, 1); + BKE_report(CTX_wm_reports(C), RPT_OPERATOR, buf); + MEM_freeN(buf); + } + + if (op->reports->list.first) { + ReportTimerInfo *rti; + + /* add reports to the global list, otherwise they are not seen */ + addlisttolist(&CTX_wm_reports(C)->list, &op->reports->list); + + /* After adding reports to the global list, reset the report timer. */ + WM_event_remove_timer(wm, NULL, reports->reporttimer); + + /* Records time since last report was added */ + reports->reporttimer= WM_event_add_timer(wm, CTX_wm_window(C), TIMER, 0.02); + + rti = MEM_callocN(sizeof(ReportTimerInfo), "ReportTimerInfo"); + reports->reporttimer->customdata = rti; + } +} + static void wm_operator_finished(bContext *C, wmOperator *op, int repeat) { wmWindowManager *wm= CTX_wm_manager(C); op->customdata= NULL; - /* add reports to the global list, otherwise they are not seen */ - addlisttolist(&CTX_wm_reports(C)->list, &op->reports->list); - /* we don't want to do undo pushes for operators that are being called from operators that already do an undo push. usually this will happen for python operators that call C operators */ @@ -424,9 +465,8 @@ static int wm_operator_exec(bContext *C, wmOperator *op, int repeat) wm->op_undo_depth--; } - if(retval & (OPERATOR_FINISHED|OPERATOR_CANCELLED)) - if(op->reports->list.first) - uiPupMenuReports(C, op->reports); + if (retval & (OPERATOR_FINISHED|OPERATOR_CANCELLED) && repeat == 0) + wm_operator_reports(C, op, retval, 0); if(retval & OPERATOR_FINISHED) wm_operator_finished(C, op, repeat); @@ -534,13 +574,6 @@ static wmOperator *wm_operator_create(wmWindowManager *wm, wmOperatorType *ot, P return op; } -static void wm_operator_print(wmOperator *op) -{ - char *buf = WM_operator_pystring(NULL, op->type, op->ptr, 1); - printf("%s\n", buf); - MEM_freeN(buf); -} - static void wm_region_mouse_co(bContext *C, wmEvent *event) { ARegion *ar= CTX_wm_region(C); @@ -584,18 +617,14 @@ int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, PointerR } else printf("invalid operator call %s\n", ot->idname); /* debug, important to leave a while, should never happen */ - + /* Note, if the report is given as an argument then assume the caller will deal with displaying them * currently python only uses this */ - if((retval & (OPERATOR_FINISHED|OPERATOR_CANCELLED)) && reports==NULL) - if(op->reports->list.first) /* only show the report if the report list was not given in the function */ - uiPupMenuReports(C, op->reports); + if (!(retval & OPERATOR_HANDLED) && retval & (OPERATOR_FINISHED|OPERATOR_CANCELLED)) + /* only show the report if the report list was not given in the function */ + wm_operator_reports(C, op, retval, (reports==NULL)); + - if (retval & OPERATOR_FINISHED) { /* todo - this may conflict with the other wm_operator_print, if theres ever 2 prints for 1 action will may need to add modal check here */ - if(G.f & G_DEBUG) - wm_operator_print(op); - } - if(retval & OPERATOR_HANDLED) ; /* do nothing, wm_operator_exec() has been called somewhere */ else if(retval & OPERATOR_FINISHED) { @@ -1084,17 +1113,11 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand /* this special cases is for areas and regions that get removed */ CTX_wm_area_set(C, NULL); CTX_wm_region_set(C, NULL); - } - - if(retval & (OPERATOR_FINISHED|OPERATOR_CANCELLED)) - if(op->reports->list.first) - uiPupMenuReports(C, op->reports); - - if (retval & OPERATOR_FINISHED) { - if(G.f & G_DEBUG) - wm_operator_print(op); /* todo - this print may double up, might want to check more flags then the FINISHED */ - } + } + if(retval & (OPERATOR_CANCELLED|OPERATOR_FINISHED)) + wm_operator_reports(C, op, retval, 0); + if(retval & OPERATOR_FINISHED) { wm_operator_finished(C, op, 0); handler->op= NULL; diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index a6e59cde402..44768116c7c 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -491,8 +491,7 @@ static void do_history(char *name, ReportList *reports) BKE_report(reports, RPT_ERROR, "Unable to make version backup"); } -/* writes a thumbnail for a blendfile */ -static void writeThumb(const char *path, Scene *scene, int **thumb_pt) +static ImBuf *blend_file_thumb(const char *path, Scene *scene, int **thumb_pt) { /* will be scaled down, but gives some nice oversampling */ ImBuf *ibuf; @@ -501,15 +500,19 @@ static void writeThumb(const char *path, Scene *scene, int **thumb_pt) *thumb_pt= NULL; if(G.background || scene->camera==NULL) - return; + return NULL; /* gets scaled to BLEN_THUMB_SIZE */ ibuf= ED_view3d_draw_offscreen_imbuf_simple(scene, BLEN_THUMB_SIZE * 2, BLEN_THUMB_SIZE * 2, OB_SOLID); if(ibuf) { - + float aspect= (scene->r.xsch*scene->r.xasp) / (scene->r.ysch*scene->r.yasp); + /* dirty oversampling */ IMB_scaleImBuf(ibuf, BLEN_THUMB_SIZE, BLEN_THUMB_SIZE); + + /* add pretty overlay */ + IMB_overlayblend_thumb(ibuf->rect, ibuf->x, ibuf->y, aspect); /* first write into thumb buffer */ thumb= MEM_mallocN(((2 + (BLEN_THUMB_SIZE * BLEN_THUMB_SIZE))) * sizeof(int), "write_file thumb"); @@ -518,14 +521,6 @@ static void writeThumb(const char *path, Scene *scene, int **thumb_pt) thumb[1] = BLEN_THUMB_SIZE; memcpy(thumb + 2, ibuf->rect, BLEN_THUMB_SIZE * BLEN_THUMB_SIZE * sizeof(int)); - - /* the image is scaled here */ - ibuf= IMB_thumb_create(path, THB_NORMAL, THB_SOURCE_BLEND, ibuf); - - if (ibuf) - IMB_freeImBuf(ibuf); - - ibuf= NULL; } else { /* '*thumb_pt' needs to stay NULL to prevent a bad thumbnail from being handled */ @@ -534,6 +529,8 @@ static void writeThumb(const char *path, Scene *scene, int **thumb_pt) /* must be freed by caller */ *thumb_pt= thumb; + + return ibuf; } int WM_write_file(bContext *C, char *target, int fileflags, ReportList *reports) @@ -543,6 +540,7 @@ int WM_write_file(bContext *C, char *target, int fileflags, ReportList *reports) char di[FILE_MAX]; int *thumb= NULL; + ImBuf *ibuf_thumb= NULL; len = strlen(target); @@ -585,7 +583,7 @@ int WM_write_file(bContext *C, char *target, int fileflags, ReportList *reports) do_history(di, reports); /* blend file thumbnail */ - writeThumb(di, CTX_data_scene(C), &thumb); + ibuf_thumb= blend_file_thumb(di, CTX_data_scene(C), &thumb); if (BLO_write_file(CTX_data_main(C), di, fileflags, reports, thumb)) { strcpy(G.sce, di); @@ -602,9 +600,16 @@ int WM_write_file(bContext *C, char *target, int fileflags, ReportList *reports) writeBlog(); + /* run this function after because the file cant be written before the blend is */ + if (ibuf_thumb) { + ibuf_thumb= IMB_thumb_create(di, THB_NORMAL, THB_SOURCE_BLEND, ibuf_thumb); + IMB_freeImBuf(ibuf_thumb); + } + if(thumb) MEM_freeN(thumb); } else { + if(ibuf_thumb) IMB_freeImBuf(ibuf_thumb); if(thumb) MEM_freeN(thumb); return -1; } diff --git a/source/blender/windowmanager/intern/wm_jobs.c b/source/blender/windowmanager/intern/wm_jobs.c index a92a3d746ad..e7df703ba79 100644 --- a/source/blender/windowmanager/intern/wm_jobs.c +++ b/source/blender/windowmanager/intern/wm_jobs.c @@ -381,6 +381,9 @@ void wm_jobs_timer_ended(wmWindowManager *wm, wmTimer *wt) void wm_jobs_timer(const bContext *C, wmWindowManager *wm, wmTimer *wt) { wmJob *steve= wm->jobs.first, *stevenext; + float total_progress= 0.f; + float jobs_progress=0; + for(; steve; steve= stevenext) { stevenext= steve->next; @@ -434,6 +437,10 @@ void wm_jobs_timer(const bContext *C, wmWindowManager *wm, wmTimer *wt) BLI_remlink(&wm->jobs, steve); MEM_freeN(steve); } + } else if (steve->flag & WM_JOB_PROGRESS) { + /* accumulate global progress for running jobs */ + jobs_progress++; + total_progress += steve->progress; } } else if(steve->suspended) { @@ -441,5 +448,13 @@ void wm_jobs_timer(const bContext *C, wmWindowManager *wm, wmTimer *wt) } } } + + /* if there are running jobs, set the global progress indicator */ + if (jobs_progress > 0) { + float progress = total_progress / (float)jobs_progress; + WM_progress_set(wm->winactive, progress); + } else { + WM_progress_clear(wm->winactive); + } } diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index de748d204ff..842e43b98cf 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -1202,11 +1202,11 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *arg_unuse split = uiLayoutSplit(layout, 0, 0); col = uiLayoutColumn(split, 0); uiItemL(col, "Links", 0); - uiItemO(col, NULL, ICON_URL, "HELP_OT_release_logs"); - uiItemO(col, NULL, ICON_URL, "HELP_OT_manual"); - uiItemO(col, NULL, ICON_URL, "HELP_OT_blender_website"); - uiItemO(col, NULL, ICON_URL, "HELP_OT_user_community"); - uiItemO(col, NULL, ICON_URL, "HELP_OT_python_api"); + uiItemStringO(col, "Release Log", ICON_URL, "WM_OT_url_open", "url", "http://www.blender.org/development/release-logs/blender-250/"); + uiItemStringO(col, "Manual", ICON_URL, "WM_OT_url_open", "url", "http://wiki.blender.org/index.php/Doc:Manual"); + uiItemStringO(col, "Blender Website", ICON_URL, "WM_OT_url_open", "url", "http://www.blender.org/"); + uiItemStringO(col, "User Community", ICON_URL, "WM_OT_url_open", "url", "http://www.blender.org/community/user-community/"); + uiItemStringO(col, "Python API Reference", ICON_URL, "WM_OT_url_open", "url", "http://www.blender.org/documentation/250PythonDoc/contents.html"); uiItemL(col, "", 0); col = uiLayoutColumn(split, 0); @@ -1518,7 +1518,7 @@ static void wm_link_make_library_local(Main *main, const char *libname) /* and now find the latest append lib file */ for(lib= main->library.first; lib; lib=lib->id.next) - if(BLI_streq(libname, lib->filename)) + if(BLI_streq(libname, lib->filepath)) break; /* make local */ diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index b4270aa9a94..b730d1a6483 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -1018,6 +1018,18 @@ void WM_clipboard_text_set(char *buf, int selection) #endif } +/* ******************* progress bar **************** */ + +void WM_progress_set(wmWindow *win, float progress) +{ + GHOST_SetProgressBar(win->ghostwin, progress); +} + +void WM_progress_clear(wmWindow *win) +{ + GHOST_EndProgressBar(win->ghostwin); +} + /* ************************************ */ void wm_window_get_position(wmWindow *win, int *posx_r, int *posy_r) |