diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2009-06-09 00:08:19 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2009-06-09 00:08:19 +0400 |
commit | c8b4cf92067ffeb625aa39003baf5d8f7c3f0025 (patch) | |
tree | c6c50dbc3d90a65fca6c1ca56a93e4a57cf7e154 /source/blender | |
parent | e93db433a086a3e739c0f4026cd500f0b595b0f1 (diff) | |
parent | d76a6f5231c015c35123d22e1f5c3ffcdfbf9bbd (diff) |
2.50:
svn merge https://svn.blender.org/svnroot/bf-blender/trunk/blender -r19820:HEAD
Notes:
* Game and sequencer RNA, and sequencer header are now out of date
a bit after changes in trunk.
* I didn't know how to port these bugfixes, most likely they are
not needed anymore.
* Fix "duplicate strip" always increase the user count for ipo.
* IPO pinning on sequencer strips was lost during Undo.
Diffstat (limited to 'source/blender')
106 files changed, 1260 insertions, 499 deletions
diff --git a/source/blender/CMakeLists.txt b/source/blender/CMakeLists.txt index 344d51db248..a53b15673e2 100644 --- a/source/blender/CMakeLists.txt +++ b/source/blender/CMakeLists.txt @@ -24,20 +24,37 @@ # # ***** END GPL LICENSE BLOCK ***** -SUBDIRS(windowmanager editors avi nodes blenkernel blenlib blenloader blenpluginapi imbuf imbuf/intern/cineon gpu makesdna makesrna radiosity readblenfile render blenfont) +ADD_SUBDIRECTORY(windowmanager) +ADD_SUBDIRECTORY(editors) +ADD_SUBDIRECTORY(avi) +ADD_SUBDIRECTORY(nodes) +ADD_SUBDIRECTORY(blenkernel) +ADD_SUBDIRECTORY(blenlib) +ADD_SUBDIRECTORY(blenloader) +ADD_SUBDIRECTORY(blenpluginapi) +ADD_SUBDIRECTORY(imbuf) +ADD_SUBDIRECTORY(imbuf/intern/cineon) +ADD_SUBDIRECTORY(gpu) +ADD_SUBDIRECTORY(makesdna) +ADD_SUBDIRECTORY(makesrna) +ADD_SUBDIRECTORY(radiosity) +ADD_SUBDIRECTORY(readblenfile) +ADD_SUBDIRECTORY(render) +ADD_SUBDIRECTORY(blenfont) IF(WITH_OPENEXR) - SUBDIRS(imbuf/intern/openexr) + ADD_SUBDIRECTORY(imbuf/intern/openexr) ENDIF(WITH_OPENEXR) IF(WITH_DDS) - SUBDIRS(imbuf/intern/dds) + ADD_SUBDIRECTORY(imbuf/intern/dds) ENDIF(WITH_DDS) IF(WITH_QUICKTIME) - SUBDIRS(quicktime) + ADD_SUBDIRECTORY(quicktime) ENDIF(WITH_QUICKTIME) IF(WITH_PYTHON) - SUBDIRS(python) + ADD_SUBDIRECTORY(python) ENDIF(WITH_PYTHON) + diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index 8c54c35473c..06103596be1 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -445,6 +445,9 @@ DerivedMesh *mesh_create_derived_no_deform(struct Scene *scene, struct Object *o DerivedMesh *mesh_create_derived_no_deform_render(struct Scene *scene, struct Object *ob, float (*vertCos)[3], CustomDataMask dataMask); +/* for gameengine */ +DerivedMesh *mesh_create_derived_no_virtual(struct Scene *scene, struct Object *ob, float (*vertCos)[3], + CustomDataMask dataMask); DerivedMesh *editmesh_get_derived_base(struct Object *, struct EditMesh *em); DerivedMesh *editmesh_get_derived_cage(struct Scene *scene, struct Object *, diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h index 70eba5006d6..9bb246f88cc 100644 --- a/source/blender/blenkernel/BKE_scene.h +++ b/source/blender/blenkernel/BKE_scene.h @@ -35,6 +35,7 @@ struct bglMats; struct Scene; struct Object; struct Base; +struct Text; struct AviCodecData; struct QuicktimeCodecData; struct RenderData; diff --git a/source/blender/blenkernel/BKE_sequence.h b/source/blender/blenkernel/BKE_sequence.h index 0960f968c4e..65a3b0216fe 100644 --- a/source/blender/blenkernel/BKE_sequence.h +++ b/source/blender/blenkernel/BKE_sequence.h @@ -142,10 +142,10 @@ void seq_free_strip(struct Strip *strip); void seq_free_editing(struct Editing *ed); struct Editing *seq_give_editing(struct Scene *scene, int alloc); char *give_seqname(struct Sequence *seq); -struct ImBuf *give_ibuf_seq(struct Scene *scene, int rectx, int recty, int cfra, int chanshown); -struct ImBuf *give_ibuf_seq_threaded(struct Scene *scene, int rectx, int recty, int cfra, int chanshown); -struct ImBuf *give_ibuf_seq_direct(struct Scene *scene, int rectx, int recty, int cfra, struct Sequence *seq); -void give_ibuf_prefetch_request(int rectx, int recty, int cfra, int chanshown); +struct ImBuf *give_ibuf_seq(struct Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size); +struct ImBuf *give_ibuf_seq_threaded(struct Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size); +struct ImBuf *give_ibuf_seq_direct(struct Scene *scene, int rectx, int recty, int cfra, int render_size, struct Sequence *seq); +void give_ibuf_prefetch_request(int rectx, int recty, int cfra, int chanshown, int render_size); void calc_sequence(struct Sequence *seq); void calc_sequence_disp(struct Sequence *seq); void new_tstripdata(struct Sequence *seq); diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 25ca0b0f1b1..bc6e549dc6f 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -904,7 +904,7 @@ static void emDM_drawMappedFacesGLSL(DerivedMesh *dm, glShadeModel(GL_SMOOTH); for (i=0,eve=em->verts.first; eve; eve= eve->next) - eve->tmp.l = (long) i++; + eve->tmp.l = (intptr_t) i++; #define PASSATTRIB(efa, eve, vert) { \ if(attribs.totorco) { \ @@ -1581,6 +1581,11 @@ static void add_weight_mcol_dm(Object *ob, DerivedMesh *dm) CustomData_add_layer(&dm->faceData, CD_WEIGHT_MCOL, CD_ASSIGN, wtcol, dm->numFaceData); } +/* new value for useDeform -1 (hack for the gameengine): + * - apply only the modifier stack of the object, skipping the virtual modifiers, + * - don't apply the key + * - apply deform modifiers and input vertexco + */ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos)[3], DerivedMesh **deform_r, DerivedMesh **final_r, int useRenderParams, int useDeform, @@ -1595,7 +1600,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos int numVerts = me->totvert; int required_mode; - md = firstmd = modifiers_getVirtualModifierList(ob); + md = firstmd = (useDeform<0) ? ob->modifiers.first : modifiers_getVirtualModifierList(ob); modifiers_clearErrors(ob); @@ -1612,8 +1617,10 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos else required_mode = eModifierMode_Realtime; if(useDeform) { - if(do_ob_key(scene, ob)) /* shape key makes deform verts */ + if(useDeform > 0 && do_ob_key(scene, ob)) /* shape key makes deform verts */ deformedVerts = mesh_getVertexCos(me, &numVerts); + else if(inputVertexCos) + deformedVerts = inputVertexCos; /* Apply all leading deforming modifiers */ for(;md; md = md->next, curr = curr->next) { @@ -1623,6 +1630,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos if((md->mode & required_mode) != required_mode) continue; if(mti->isDisabled && mti->isDisabled(md)) continue; + if(useDeform < 0 && mti->dependsOnTime && mti->dependsOnTime(md)) continue; if(mti->type == eModifierTypeType_OnlyDeform) { if(!deformedVerts) @@ -1678,6 +1686,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos } if(mti->isDisabled && mti->isDisabled(md)) continue; if(needMapping && !modifier_supportsMapping(md)) continue; + if(useDeform < 0 && mti->dependsOnTime && mti->dependsOnTime(md)) continue; /* add an orco layer if needed by this modifier */ if(dm && mti->requiredDataMask) { @@ -2199,6 +2208,16 @@ DerivedMesh *mesh_create_derived_no_deform(Scene *scene, Object *ob, float (*ver return final; } +DerivedMesh *mesh_create_derived_no_virtual(Scene *scene, Object *ob, float (*vertCos)[3], + CustomDataMask dataMask) +{ + DerivedMesh *final; + + mesh_calc_modifiers(scene, ob, vertCos, NULL, &final, 0, -1, 0, dataMask, -1); + + return final; +} + DerivedMesh *mesh_create_derived_no_deform_render(Scene *scene, Object *ob, float (*vertCos)[3], CustomDataMask dataMask) diff --git a/source/blender/blenkernel/intern/Makefile b/source/blender/blenkernel/intern/Makefile index 1528ec1c86e..a6a5066b574 100644 --- a/source/blender/blenkernel/intern/Makefile +++ b/source/blender/blenkernel/intern/Makefile @@ -82,7 +82,7 @@ CPPFLAGS += -I../../gpu CPPFLAGS += -I.. # path to bullet2, for cloth -CPPFLAGS += -I../../../../extern/bullet2/src +CPPFLAGS += -I$(NAN_BULLET2)/include CPPFLAGS += -I$(NAN_FREETYPE)/include CPPFLAGS += -I$(NAN_FREETYPE)/include/freetype2 diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 3169905b7f5..5fc7d18689d 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -400,7 +400,7 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, char *filename) MEM_freeN(bfd); } -static void handle_subversion_warning(Main *main) +static int handle_subversion_warning(Main *main) { if(main->minversionfile > BLENDER_VERSION || (main->minversionfile == BLENDER_VERSION && @@ -411,7 +411,7 @@ static void handle_subversion_warning(Main *main) sprintf(str, "File written by newer Blender binary: %d.%d , expect loss of data!", main->minversionfile, main->minsubversionfile); // XXX error(str); } - + return 1; } void BKE_userdef_free(void) @@ -438,9 +438,14 @@ int BKE_read_file(bContext *C, char *dir, void *unused, ReportList *reports) if (bfd) { if(bfd->user) retval= 2; - setup_app_data(C, bfd, dir); - - handle_subversion_warning(G.main); + if(0==handle_subversion_warning(bfd->main)) { + free_main(bfd->main); + MEM_freeN(bfd); + bfd= NULL; + retval= 0; + } + else + setup_app_data(C, bfd, dir); // frees BFD } else BKE_reports_prependf(reports, "Loading %s failed: ", dir); diff --git a/source/blender/blenkernel/intern/bmfont.c b/source/blender/blenkernel/intern/bmfont.c index 0af54b86ed6..09770b2b4ba 100644 --- a/source/blender/blenkernel/intern/bmfont.c +++ b/source/blender/blenkernel/intern/bmfont.c @@ -178,7 +178,7 @@ void detectBitmapFont(ImBuf *ibuf) { unsigned char * rect; unsigned short version; - long i; + int i; if (ibuf != NULL) { // bitmap must have an x size that is a power of two diff --git a/source/blender/blenkernel/intern/bullet.c b/source/blender/blenkernel/intern/bullet.c index b389f8c0536..44e8ed1f08c 100644 --- a/source/blender/blenkernel/intern/bullet.c +++ b/source/blender/blenkernel/intern/bullet.c @@ -82,6 +82,7 @@ BulletSoftBody *bsbNew(void) bsb->collisionflags = 0; //bsb->collisionflags = OB_BSB_COL_CL_RS + OB_BSB_COL_CL_SS; bsb->numclusteriterations = 64; + bsb->welding = 0.f; return bsb; } diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 6c9dfe4bf0a..e98d7bb01a4 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -157,7 +157,7 @@ BVHTree *bvhselftree_build_from_cloth (ClothModifierData *clmd, float epsilon) { unsigned int i; BVHTree *bvhtree; - Cloth *cloth = clmd->clothObject; + Cloth *cloth; ClothVertex *verts; MFace *mfaces; float co[12]; @@ -198,7 +198,7 @@ BVHTree *bvhtree_build_from_cloth (ClothModifierData *clmd, float epsilon) { unsigned int i; BVHTree *bvhtree; - Cloth *cloth = clmd->clothObject; + Cloth *cloth; ClothVertex *verts; MFace *mfaces; float co[12]; @@ -787,15 +787,14 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm ) int j = 0; MDeformVert *dvert = NULL; Cloth *clothObj = NULL; - int numverts = dm->getNumVerts ( dm ); + int numverts; float goalfac = 0; ClothVertex *verts = NULL; + if (!clmd || !dm) return; + clothObj = clmd->clothObject; - if ( !dm ) - return; - numverts = dm->getNumVerts ( dm ); verts = clothObj->verts; diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index c055a0ca6a7..a43389a2ef6 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -3430,6 +3430,8 @@ void copy_constraints (ListBase *dst, ListBase *src) /* make a new copy of the constraint's data */ con->data = MEM_dupallocN(con->data); + id_us_plus((ID *)con->ipo); + /* only do specific constraints if required */ if (cti && cti->copy_data) cti->copy_data(con, srccon); diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index 8c1065c1d84..705d0b66d7f 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -33,7 +33,7 @@ */ #include "BKE_customdata.h" - +#include "BKE_utildefines.h" // CLAMP #include "BLI_arithb.h" #include "BLI_blenlib.h" #include "BLI_linklist.h" @@ -573,6 +573,14 @@ static void layerInterp_mloopcol(void **sources, float *weights, col.b += src->b * weight; } } + + /* Subdivide smooth or fractal can cause problems without clamping + * although weights should also not cause this situation */ + CLAMP(col.a, 0.0f, 255.0f); + CLAMP(col.r, 0.0f, 255.0f); + CLAMP(col.g, 0.0f, 255.0f); + CLAMP(col.b, 0.0f, 255.0f); + mc->a = (int)col.a; mc->r = (int)col.r; mc->g = (int)col.g; @@ -648,6 +656,14 @@ static void layerInterp_mcol(void **sources, float *weights, } for(j = 0; j < 4; ++j) { + + /* Subdivide smooth or fractal can cause problems without clamping + * although weights should also not cause this situation */ + CLAMP(col[j].a, 0.0f, 255.0f); + CLAMP(col[j].r, 0.0f, 255.0f); + CLAMP(col[j].g, 0.0f, 255.0f); + CLAMP(col[j].b, 0.0f, 255.0f); + mc[j].a = (int)col[j].a; mc[j].r = (int)col[j].r; mc[j].g = (int)col[j].g; @@ -783,7 +799,7 @@ void CustomData_merge(const struct CustomData *source, struct CustomData *dest, number++; if(layer->flag & CD_FLAG_NOCOPY) continue; - else if(!(mask & (1 << type))) continue; + else if(!((int)mask & (int)(1 << (int)type))) continue; else if(number < CustomData_number_of_layers(dest, type)) continue; if((alloctype == CD_ASSIGN) && (layer->flag & CD_FLAG_NOFREE)) @@ -1301,7 +1317,7 @@ void CustomData_set_only_copy(const struct CustomData *data, int i; for(i = 0; i < data->totlayer; ++i) - if(!(mask & (1 << data->layers[i].type))) + if(!((int)mask & (int)(1 << (int)data->layers[i].type))) data->layers[i].flag |= CD_FLAG_NOCOPY; } diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index 8779ed5404b..fe138407d54 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -940,7 +940,7 @@ void filldisplist(ListBase *dispbase, ListBase *to) DispList *dlnew=0, *dl; float *f1; int colnr=0, charidx=0, cont=1, tot, a, *index; - long totvert; + intptr_t totvert; if(dispbase==0) return; if(dispbase->first==0) return; diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c index 077a0c437d4..9858025af5a 100644 --- a/source/blender/blenkernel/intern/effect.c +++ b/source/blender/blenkernel/intern/effect.c @@ -79,7 +79,6 @@ #include "BKE_screen.h" #include "BKE_utildefines.h" -#include "PIL_time.h" #include "RE_render_ext.h" /* fluid sim particle import */ @@ -162,8 +161,7 @@ static void add_to_effectorcache(ListBase *lb, Scene *scene, Object *ob, Object if(pd->forcefield == PFIELD_WIND) { - pd->rng = rng_new(1); - rng_srandom(pd->rng, (unsigned int)(ceil(PIL_check_seconds_timer()))); // use better seed + pd->rng = rng_new(pd->seed); } ec= MEM_callocN(sizeof(pEffectorCache), "effector cache"); @@ -287,14 +285,14 @@ static float eff_calc_visibility(Scene *scene, Object *ob, float *co, float *dir // noise function for wind e.g. static float wind_func(struct RNG *rng, float strength) { - int random = (rng_getInt(rng)+1) % 65535; // max 2357 + int random = (rng_getInt(rng)+1) % 128; // max 2357 float force = rng_getFloat(rng) + 1.0f; float ret; float sign = 0; - sign = (random > 32000.0) ? 1.0: -1.0; // dividing by 2 is not giving equal sign distribution + sign = ((float)random > 64.0) ? 1.0: -1.0; // dividing by 2 is not giving equal sign distribution - ret = sign*((float)random / force)*strength/65535.0f; + ret = sign*((float)random / force)*strength/128.0f; return ret; } diff --git a/source/blender/blenkernel/intern/exotic.c b/source/blender/blenkernel/intern/exotic.c index 5488d50e226..929d3f942dc 100644 --- a/source/blender/blenkernel/intern/exotic.c +++ b/source/blender/blenkernel/intern/exotic.c @@ -944,7 +944,7 @@ static int iv_finddata(struct IvNode *iv, char *field, int fieldnr) float *fp; int len, stackcount, skipdata=0; char *cpa, terminator, str[64]; - long i; + intptr_t i; len= strlen(field); @@ -2397,7 +2397,7 @@ static void write_videoscape_mesh(Scene *scene, Object *ob, char *str) unsigned int kleur[32]; float co[3]; int a; - long tot; + intptr_t tot; char *cp; if(ob && ob->type==OB_MESH); @@ -2447,17 +2447,17 @@ static void write_videoscape_mesh(Scene *scene, Object *ob, char *str) if(evl->v4==0) { fprintf(fp, "3 %ld %ld %ld 0x%x\n", - (long int) evl->v1->tmp.l, - (long int) evl->v2->tmp.l, - (long int) evl->v3->tmp.l, + (intptr_t) evl->v1->tmp.l, + (intptr_t) evl->v2->tmp.l, + (intptr_t) evl->v3->tmp.l, kleur[evl->mat_nr]); } else { fprintf(fp, "4 %ld %ld %ld %ld 0x%x\n", - (long int) evl->v1->tmp.l, - (long int) evl->v2->tmp.l, - (long int) evl->v3->tmp.l, - (long int) evl->v4->tmp.l, + (intptr_t) evl->v1->tmp.l, + (intptr_t) evl->v2->tmp.l, + (intptr_t) evl->v3->tmp.l, + (intptr_t) evl->v4->tmp.l, kleur[evl->mat_nr]); } evl= evl->next; diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c index b94652eb7c3..c3cf6e06c09 100644 --- a/source/blender/blenkernel/intern/font.c +++ b/source/blender/blenkernel/intern/font.c @@ -1144,14 +1144,12 @@ struct chartrans *BKE_text_to_curve(Scene *scene, Object *ob, int mode) ct= chartransdata; if (cu->sepchar==0) { for (i= 0; i<slen; i++) { - cha = (unsigned long) mem[i]; - info = &(custrinfo[i]); - + cha = (uintptr_t) mem[i]; + info = &(cu->strinfo[i]); if (info->mat_nr > (ob->totcol)) { /* printf("Error: Illegal material index (%d) in text object, setting to 0\n", info->mat_nr); */ info->mat_nr = 0; } - // We do not want to see any character for \n or \r if(cha != '\n' && cha != '\r') buildchar(cu, cha, info, ct->xof, ct->yof, ct->rot, i); diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 629f34518b9..8eef9984c92 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -433,7 +433,7 @@ static ImBuf *add_ibuf_size(int width, int height, char *name, int floatbuf, sho unsigned char *rect= NULL; float *rect_float= NULL; int x, y; - int checkerwidth=21, dark=1; + int checkerwidth=32, dark=1; if (floatbuf) { ibuf= IMB_allocImBuf(width, height, 24, IB_rectfloat, 0); @@ -668,6 +668,11 @@ static uintptr_t image_mem_size(Image *ima) uintptr_t size = 0; size= 0; + + /* viewers have memory depending on other rules, has no valid rect pointer */ + if(ima->source==IMA_SRC_VIEWER) + return 0; + for(ibuf= ima->ibufs.first; ibuf; ibuf= ibuf->next) { if(ibuf->rect) size += MEM_allocN_len(ibuf->rect); else if(ibuf->rect_float) size += MEM_allocN_len(ibuf->rect_float); @@ -1052,7 +1057,7 @@ static void stampdata(Scene *scene, StampData *stamp_data, int do_prefix) } if (scene->r.stamp & R_STAMP_SEQSTRIP) { - Sequence *seq= NULL; //XXX = get_forground_frame_seq(scene->r.cfra); + Sequence *seq= NULL; //XXX = get_foreground_frame_seq(scene->r.cfra); if (seq) strcpy(text, seq->name+2); else strcpy(text, "<none>"); diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c index 9c5560be8f3..8cbf25eaeed 100644 --- a/source/blender/blenkernel/intern/ipo.c +++ b/source/blender/blenkernel/intern/ipo.c @@ -1741,3 +1741,4 @@ void do_versions_ipos_to_animato(Main *main) printf("INFO: Animato convert done \n"); // xxx debug } + diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c index 3e881f2d871..74d56e81a87 100644 --- a/source/blender/blenkernel/intern/mball.c +++ b/source/blender/blenkernel/intern/mball.c @@ -296,7 +296,10 @@ Object *find_basis_mball(Scene *scene, Object *basis) splitIDname(basis->id.name+2, basisname, &basisnr); totelem= 0; - next_object(scene, 0, 0, 0); + /* XXX recursion check, see scene.c, just too simple code this next_object() */ + if(F_ERROR==next_object(scene, 0, 0, 0)) + return NULL; + while(next_object(scene, 1, &base, &ob)) { if (ob->type==OB_MBALL) { diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index e8427a973d0..6ebd68e990f 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -6265,6 +6265,48 @@ static int is_last_displist(Object *ob) return 0; } + +static DerivedMesh *get_original_dm(Scene *scene, Object *ob, float (*vertexCos)[3], int orco) +{ + DerivedMesh *dm= NULL; + + if(ob->type==OB_MESH) { + dm = CDDM_from_mesh((Mesh*)(ob->data), ob); + + if(vertexCos) { + CDDM_apply_vert_coords(dm, vertexCos); + //CDDM_calc_normals(dm); + } + + if(orco) + DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, get_mesh_orco_verts(ob)); + } + else if(ELEM3(ob->type,OB_FONT,OB_CURVE,OB_SURF)) { + Object *tmpobj; + Curve *tmpcu; + + if(is_last_displist(ob)) { + /* copies object and modifiers (but not the data) */ + tmpobj= copy_object(ob); + tmpcu = (Curve *)tmpobj->data; + tmpcu->id.us--; + + /* copies the data */ + tmpobj->data = copy_curve((Curve *) ob->data); + + makeDispListCurveTypes(scene, tmpobj, 1); + nurbs_to_mesh(tmpobj); + + dm = CDDM_from_mesh((Mesh*)(tmpobj->data), tmpobj); + //CDDM_calc_normals(dm); + + free_libblock_us(&G.main->object, tmpobj); + } + } + + return dm; +} + /* saves the current emitter state for a particle system and calculates particles */ static void particleSystemModifier_deformVerts( ModifierData *md, Object *ob, DerivedMesh *derivedData, @@ -6283,43 +6325,13 @@ static void particleSystemModifier_deformVerts( if(!psys_check_enabled(ob, psys)) return; - if(dm==0){ - if(ob->type==OB_MESH){ - dm = CDDM_from_mesh((Mesh*)(ob->data), ob); - - CDDM_apply_vert_coords(dm, vertexCos); - //CDDM_calc_normals(dm); - - DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, get_mesh_orco_verts(ob)); - - needsFree=1; - } - else if(ELEM3(ob->type,OB_FONT,OB_CURVE,OB_SURF)){ - Object *tmpobj; - Curve *tmpcu; - - if(is_last_displist(ob)){ - /* copies object and modifiers (but not the data) */ - tmpobj= copy_object( ob ); - tmpcu = (Curve *)tmpobj->data; - tmpcu->id.us--; - - /* copies the data */ - tmpobj->data = copy_curve( (Curve *) ob->data ); - - makeDispListCurveTypes(md->scene, tmpobj, 1 ); - nurbs_to_mesh( tmpobj ); + if(dm==0) { + dm= get_original_dm(md->scene, ob, vertexCos, 1); - dm = CDDM_from_mesh((Mesh*)(tmpobj->data), tmpobj); - //CDDM_calc_normals(dm); - - free_libblock_us( &G.main->object, tmpobj ); + if(!dm) + return; - needsFree=1; - } - else return; - } - else return; + needsFree= 1; } /* clear old dm */ @@ -7658,6 +7670,14 @@ static void meshdeformModifier_do( } else cagedm= mmd->object->derivedFinal; + + /* if we don't have one computed, use derivedmesh from data + * without any modifiers */ + if(!cagedm) { + cagedm= get_original_dm(md->scene, mmd->object, NULL, 0); + if(cagedm) + cagedm->needsFree= 1; + } if(!cagedm) return; @@ -7951,7 +7971,7 @@ static void shrinkwrapModifier_deformVerts(ModifierData *md, Object *ob, Derived else if(ob->type==OB_LATTICE) dm = NULL; else return; - if(dm != NULL && (dataMask & CD_MVERT)) + if(dm != NULL && (dataMask & (1<<CD_MVERT))) { CDDM_apply_vert_coords(dm, vertexCos); CDDM_calc_normals(dm); @@ -7976,7 +7996,7 @@ static void shrinkwrapModifier_deformVertsEM(ModifierData *md, Object *ob, EditM else if(ob->type==OB_LATTICE) dm = NULL; else return; - if(dm != NULL && (dataMask & CD_MVERT)) + if(dm != NULL && (dataMask & (1<<CD_MVERT))) { CDDM_apply_vert_coords(dm, vertexCos); CDDM_calc_normals(dm); @@ -8906,8 +8926,10 @@ void modifier_freeTemporaryData(ModifierData *md) if(md->type == eModifierType_Armature) { ArmatureModifierData *amd= (ArmatureModifierData*)md; - if(amd->prevCos) + if(amd->prevCos) { MEM_freeN(amd->prevCos); + amd->prevCos= NULL; + } } } diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 43df11335fe..a83b8817580 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -1990,9 +1990,9 @@ static void group_tag_used_outputs(bNode *gnode, bNodeStack *stack) } } +/* notes below are ancient! (ton) */ /* stack indices make sure all nodes only write in allocated data, for making it thread safe */ /* only root tree gets the stack, to enable instances to have own stack entries */ -/* only two threads now! */ /* per tree (and per group) unique indices are created */ /* the index_ext we need to be able to map from groups to the group-node own stack */ @@ -2007,14 +2007,9 @@ static bNodeThreadStack *ntreeGetThreadStack(bNodeTree *ntree, int thread) ListBase *lb= &ntree->threadstack[thread]; bNodeThreadStack *nts; - /* for material shading this is called quite a lot (perhaps too much locking unlocking) - * however without locking we get bug #18058 - Campbell */ - BLI_lock_thread(LOCK_CUSTOM1); - for(nts=lb->first; nts; nts=nts->next) { if(!nts->used) { nts->used= 1; - BLI_unlock_thread(LOCK_CUSTOM1); return nts; } } @@ -2022,7 +2017,7 @@ static bNodeThreadStack *ntreeGetThreadStack(bNodeTree *ntree, int thread) nts->stack= MEM_dupallocN(ntree->stack); nts->used= 1; BLI_addtail(lb, nts); - BLI_unlock_thread(LOCK_CUSTOM1); + return nts; } diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index d7619010808..81bd78f1851 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -977,6 +977,8 @@ Object *add_only_object(int type, char *name) ob->anisotropicFriction[2] = 1.0f; ob->gameflag= OB_PROP|OB_COLLISION; ob->margin = 0.0; + /* ob->pad3 == Contact Processing Threshold */ + ob->m_contactProcessingThreshold = 1.; /* NT fluid sim defaults */ ob->fluidsimFlag = 0; @@ -1131,6 +1133,9 @@ static void copy_object_pose(Object *obn, Object *ob) * is changed to object->proxy_from when evaluating the driver. */ if(con->ipo && !con->ipo->id.lib) { IpoCurve *icu; + + con->ipo= copy_ipo(con->ipo); + for(icu= con->ipo->curve.first; icu; icu= icu->next) { if(icu->driver && icu->driver->ob==ob) icu->driver->ob= obn; diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 6cef9959d8b..74a754c0ca8 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -348,15 +348,17 @@ void free_hair(ParticleSystem *psys, int softbody) } void free_keyed_keys(ParticleSystem *psys) { - if(psys->particles && psys->particles->keys) { - ParticleData *pa; - int i, totpart=psys->totpart; + ParticleData *pa; + int i; + if(psys->particles && psys->particles->keys) { MEM_freeN(psys->particles->keys); - for(i=0, pa=psys->particles; i<totpart; i++,pa++){ - pa->keys = NULL; - pa->totkey = 0; + for(i=0, pa=psys->particles; i<psys->totpart; i++, pa++) { + if(pa->keys) { + pa->keys= NULL; + pa->totkey= 0; + } } } } diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index f097af279b6..c0ef92b489e 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -196,8 +196,11 @@ static void realloc_particles(Object *ob, ParticleSystem *psys, int new_totpart) if(psys->particles->keys) MEM_freeN(psys->particles->keys); - for(i=0, pa=psys->particles; i<totsaved; i++, pa++) - if(pa->keys) pa->keys= NULL; + for(i=0, pa=psys->particles; i<psys->totpart; i++, pa++) + if(pa->keys) { + pa->keys= NULL; + pa->totkey= 0; + } for(i=totsaved, pa=psys->particles+totsaved; i<psys->totpart; i++, pa++) if(pa->hair) MEM_freeN(pa->hair); @@ -2010,7 +2013,6 @@ static void set_keyed_keys(Scene *scene, Object *ob, ParticleSystem *psys) Object *kob = ob; ParticleSystem *kpsys = psys; ParticleData *pa; - ParticleKey state; int totpart = psys->totpart, i, k, totkeys = psys->totkeyed + 1; float prevtime, nexttime, keyedtime; @@ -2034,10 +2036,11 @@ static void set_keyed_keys(Scene *scene, Object *ob, ParticleSystem *psys) } psys->flag &= ~PSYS_KEYED; - state.time=-1.0; for(k=0; k<totkeys; k++) { for(i=0,pa=psys->particles; i<totpart; i++, pa++) { + (pa->keys + k)->time = -1.0; /* use current time */ + if(kpsys->totpart > 0) psys_get_particle_state(scene, kob, kpsys, i%kpsys->totpart, pa->keys + k, 1); diff --git a/source/blender/blenkernel/intern/sca.c b/source/blender/blenkernel/intern/sca.c index e8c6c5c199f..74d2347ec39 100644 --- a/source/blender/blenkernel/intern/sca.c +++ b/source/blender/blenkernel/intern/sca.c @@ -134,7 +134,7 @@ void init_sensor(bSensor *sens) switch(sens->type) { case SENS_ALWAYS: - sens->pulse = 1; + sens->pulse = 0; break; case SENS_TOUCH: sens->data= MEM_callocN(sizeof(bTouchSensor), "touchsens"); @@ -579,6 +579,10 @@ void set_sca_new_poins_ob(Object *ob) bCameraActuator *ca= act->data; ID_NEW(ca->ob); } + else if(act->type==ACT_OBJECT) { + bObjectActuator *oa= act->data; + ID_NEW(oa->reference); + } else if(act->type==ACT_SCENE) { bSceneActuator *sca= act->data; ID_NEW(sca->camera); @@ -606,6 +610,7 @@ void sca_remove_ob_poin(Object *obt, Object *ob) bMessageSensor *ms; bActuator *act; bCameraActuator *ca; + bObjectActuator *oa; bSceneActuator *sa; bEditObjectActuator *eoa; bPropertyActuator *pa; @@ -628,6 +633,10 @@ void sca_remove_ob_poin(Object *obt, Object *ob) ca= act->data; if(ca->ob==ob) ca->ob= NULL; break; + case ACT_OBJECT: + oa= act->data; + if(oa->reference==ob) oa->reference= NULL; + break; case ACT_PROPERTY: pa= act->data; if(pa->ob==ob) pa->ob= NULL; diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 5c936c3ab39..156bdae9b00 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -245,9 +245,9 @@ Scene *add_scene(char *name) sce->r.stereomode = 1; // no stereo sce->r.domeangle = 180; sce->r.domemode = 1; - sce->r.domesize = 1.0f; sce->r.domeres = 4; sce->r.domeresbuf = 1.0f; + sce->r.dometilt = 0; sce->r.simplify_subsurf= 6; sce->r.simplify_particles= 1.0f; @@ -411,16 +411,25 @@ int next_object(Scene *scene, int val, Base **base, Object **ob) { static ListBase *duplilist= NULL; static DupliObject *dupob; - static int fase; + static int fase= F_START, in_next_object= 0; int run_again=1; /* init */ if(val==0) { fase= F_START; dupob= NULL; + + /* XXX particle systems with metas+dupligroups call this recursively */ + /* see bug #18725 */ + if(in_next_object) { + printf("ERROR: MetaBall generation called recursively, not supported\n"); + + return F_ERROR; + } } else { - + in_next_object= 1; + /* run_again is set when a duplilist has been ended */ while(run_again) { run_again= 0; @@ -502,6 +511,9 @@ int next_object(Scene *scene, int val, Base **base, Object **ob) } } + /* reset recursion test */ + in_next_object= 0; + return fase; } @@ -723,4 +735,4 @@ void free_dome_warp_text(struct Text *txt) scene->r.dometext = NULL; scene = scene->id.next; } -}
\ No newline at end of file +} diff --git a/source/blender/blenkernel/intern/sequence.c b/source/blender/blenkernel/intern/sequence.c index 121dfce4980..3365af36f8c 100644 --- a/source/blender/blenkernel/intern/sequence.c +++ b/source/blender/blenkernel/intern/sequence.c @@ -122,6 +122,14 @@ void new_tstripdata(Sequence *seq) /* free */ +static void free_proxy_seq(Sequence *seq) +{ + if (seq->strip && seq->strip->proxy && seq->strip->proxy->anim) { + IMB_free_anim(seq->strip->proxy->anim); + seq->strip->proxy->anim = 0; + } +} + void seq_free_strip(Strip *strip) { strip->us--; @@ -136,6 +144,10 @@ void seq_free_strip(Strip *strip) } if (strip->proxy) { + if (strip->proxy->anim) { + IMB_free_anim(strip->proxy->anim); + } + MEM_freeN(strip->proxy); } if (strip->crop) { @@ -598,6 +610,8 @@ void reload_sequence_new_file(Scene *scene, Sequence * seq) seq->strip->len = seq->len; } + free_proxy_seq(seq); + calc_sequence(seq); } @@ -1112,7 +1126,7 @@ static int get_shown_sequences( ListBase * seqbasep, int cfra, int chanshown, Se #define PROXY_MAXFILE (2*FILE_MAXDIR+FILE_MAXFILE) -static int seq_proxy_get_fname(Scene *scene, Sequence * seq, int cfra, char * name) +static int seq_proxy_get_fname(Scene *scene, Sequence * seq, int cfra, char * name, int render_size) { int frameno; char dir[FILE_MAXDIR]; @@ -1132,12 +1146,20 @@ static int seq_proxy_get_fname(Scene *scene, Sequence * seq, int cfra, char * na } } + if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) { + BLI_join_dirfile(name, dir, seq->strip->proxy->file); + BLI_convertstringcode(name, G.sce); + BLI_convertstringframe(name, cfra); + + return TRUE; + } + /* generate a seperate proxy directory for each preview size */ if (seq->type == SEQ_IMAGE) { StripElem * se = give_stripelem(seq, cfra); snprintf(name, PROXY_MAXFILE, "%s/images/%d/%s_proxy", - dir, scene->r.size, se->name); + dir, render_size, se->name); frameno = 1; } else if (seq->type == SEQ_MOVIE) { TStripElem * tse = give_tstripelem(seq, cfra); @@ -1146,14 +1168,14 @@ static int seq_proxy_get_fname(Scene *scene, Sequence * seq, int cfra, char * na snprintf(name, PROXY_MAXFILE, "%s/%s/%d/####", dir, seq->strip->stripdata->name, - scene->r.size); + render_size); } else { TStripElem * tse = give_tstripelem(seq, cfra); frameno = tse->nr + seq->anim_startofs; snprintf(name, PROXY_MAXFILE, "%s/proxy_misc/%d/####", dir, - scene->r.size); + render_size); } BLI_convertstringcode(name, G.sce); @@ -1165,7 +1187,7 @@ static int seq_proxy_get_fname(Scene *scene, Sequence * seq, int cfra, char * na return TRUE; } -static struct ImBuf * seq_proxy_fetch(Scene *scene, Sequence * seq, int cfra) +static struct ImBuf * seq_proxy_fetch(Scene *scene, Sequence * seq, int cfra, int render_size) { char name[PROXY_MAXFILE]; @@ -1174,11 +1196,28 @@ static struct ImBuf * seq_proxy_fetch(Scene *scene, Sequence * seq, int cfra) } /* rendering at 100% ? No real sense in proxy-ing, right? */ - if (scene->r.size == 100.0) { + if (render_size == 100) { return 0; } - if (!seq_proxy_get_fname(scene, seq, cfra, name)) { + if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) { + TStripElem * tse = give_tstripelem(seq, cfra); + int frameno = tse->nr + seq->anim_startofs; + if (!seq->strip->proxy->anim) { + if (!seq_proxy_get_fname(scene, seq, cfra, name, render_size)) { + return 0; + } + + seq->strip->proxy->anim = openanim(name, IB_rect); + } + if (!seq->strip->proxy->anim) { + return 0; + } + + return IMB_anim_absolute(seq->strip->proxy->anim, frameno); + } + + if (!seq_proxy_get_fname(scene, seq, cfra, name, render_size)) { return 0; } @@ -1190,9 +1229,9 @@ static struct ImBuf * seq_proxy_fetch(Scene *scene, Sequence * seq, int cfra) } static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int cfra, - int build_proxy_run); + int build_proxy_run, int render_size); -static void seq_proxy_build_frame(Scene *scene, Sequence * seq, int cfra) +static void seq_proxy_build_frame(Scene *scene, Sequence * seq, int cfra, int render_size) { char name[PROXY_MAXFILE]; int quality; @@ -1206,11 +1245,16 @@ static void seq_proxy_build_frame(Scene *scene, Sequence * seq, int cfra) } /* rendering at 100% ? No real sense in proxy-ing, right? */ - if (scene->r.size == 100.0) { + if (render_size == 100) { return; } - if (!seq_proxy_get_fname(scene, seq, cfra, name)) { + /* that's why it is called custom... */ + if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) { + return; + } + + if (!seq_proxy_get_fname(scene, seq, cfra, name, render_size)) { return; } @@ -1224,14 +1268,14 @@ static void seq_proxy_build_frame(Scene *scene, Sequence * seq, int cfra) se->ibuf = 0; } - do_build_seq_ibuf(scene, seq, se, cfra, TRUE); + do_build_seq_ibuf(scene, seq, se, cfra, TRUE, render_size); if (!se->ibuf) { return; } - rectx= (scene->r.size*scene->r.xsch)/100; - recty= (scene->r.size*scene->r.ysch)/100; + rectx= (render_size*scene->r.xsch)/100; + recty= (render_size*scene->r.ysch)/100; ibuf = se->ibuf; @@ -1286,7 +1330,7 @@ void seq_proxy_rebuild(Scene *scene, Sequence * seq) TStripElem * tse = give_tstripelem(seq, cfra); if (!(tse->flag & STRIPELEM_PREVIEW_DONE)) { - seq_proxy_build_frame(scene, seq, cfra); + seq_proxy_build_frame(scene, seq, cfra, scene->r.size); tse->flag |= STRIPELEM_PREVIEW_DONE; } if (blender_test_break()) { @@ -1299,7 +1343,7 @@ void seq_proxy_rebuild(Scene *scene, Sequence * seq) TStripElem * tse = give_tstripelem(seq, cfra); if (!(tse->flag & STRIPELEM_PREVIEW_DONE)) { - seq_proxy_build_frame(scene, seq, cfra); + seq_proxy_build_frame(scene, seq, cfra, scene->r.size); tse->flag |= STRIPELEM_PREVIEW_DONE; } if (blender_test_break()) { @@ -1752,11 +1796,46 @@ static void free_metastrip_imbufs(ListBase *seqbasep, int cfra, int chanshown) } +static void check_limiter_refcount(const char * func, TStripElem *se) +{ + if (se && se->ibuf) { + int refcount = IMB_cache_limiter_get_refcount(se->ibuf); + if (refcount != 1) { + /* can happen on complex pipelines */ + if (refcount > 1 && (G.f & G_DEBUG) == 0) { + return; + } + + fprintf(stderr, + "sequencer: (ibuf) %s: " + "suspicious memcache " + "limiter refcount: %d\n", func, refcount); + } + } +} + +static void check_limiter_refcount_comp(const char * func, TStripElem *se) +{ + if (se && se->ibuf_comp) { + int refcount = IMB_cache_limiter_get_refcount(se->ibuf_comp); + if (refcount != 1) { + /* can happen on complex pipelines */ + if (refcount > 1 && (G.f & G_DEBUG) == 0) { + return; + } + fprintf(stderr, + "sequencer: (ibuf comp) %s: " + "suspicious memcache " + "limiter refcount: %d\n", func, refcount); + } + } +} + static TStripElem* do_build_seq_array_recursively(Scene *scene, - ListBase *seqbasep, int cfra, int chanshown); + ListBase *seqbasep, int cfra, int chanshown, int render_size); static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int cfra, - int build_proxy_run) + int build_proxy_run, int render_size) { char name[FILE_MAXDIR+FILE_MAXFILE]; int use_limiter = TRUE; @@ -1766,18 +1845,23 @@ static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int if(seq->type == SEQ_META) { TStripElem * meta_se = 0; + int use_preprocess = FALSE; use_limiter = FALSE; if (!build_proxy_run && se->ibuf == 0) { - se->ibuf = seq_proxy_fetch(scene, seq, cfra); + se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size); if (se->ibuf) { use_limiter = TRUE; + use_preprocess = TRUE; } } if(!se->ibuf && seq->seqbase.first) { meta_se = do_build_seq_array_recursively(scene, - &seq->seqbase, seq->start + se->nr, 0); + &seq->seqbase, seq->start + se->nr, 0, + render_size); + + check_limiter_refcount("do_build_seq_ibuf: for META", meta_se); } se->ok = STRIPELEM_OK; @@ -1799,21 +1883,24 @@ static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int se->ibuf = i; use_limiter = TRUE; + use_preprocess = TRUE; } + } else if (se->ibuf) { + use_limiter = TRUE; } if (meta_se) { free_metastrip_imbufs( &seq->seqbase, seq->start + se->nr, 0); } - if (use_limiter) { + if (use_preprocess) { input_preprocess(scene, seq, se, cfra); } } else if(seq->type & SEQ_EFFECT) { /* should the effect be recalculated? */ if (!build_proxy_run && se->ibuf == 0) { - se->ibuf = seq_proxy_fetch(scene, seq, cfra); + se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size); } if(se->ibuf == 0) { @@ -1834,13 +1921,19 @@ static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int BLI_convertstringcode(name, G.sce); BLI_convertstringframe(name, scene->r.cfra); if (!build_proxy_run) { - se->ibuf = seq_proxy_fetch(scene, seq, cfra); + se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size); } copy_from_ibuf_still(seq, se); if (!se->ibuf) { se->ibuf= IMB_loadiffname( name, IB_rect); + /* we don't need both (speed reasons)! */ + if (se->ibuf && + se->ibuf->rect_float && se->ibuf->rect) { + imb_freerectImBuf(se->ibuf); + } + copy_to_ibuf_still(seq, se); } @@ -1853,7 +1946,7 @@ static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int } else if(seq->type == SEQ_MOVIE) { if(se->ok == STRIPELEM_OK && se->ibuf==0) { if(!build_proxy_run) { - se->ibuf = seq_proxy_fetch(scene, seq, cfra); + se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size); } copy_from_ibuf_still(seq, se); @@ -1871,6 +1964,13 @@ static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int if(seq->anim) { IMB_anim_set_preseek(seq->anim, seq->anim_preseek); se->ibuf = IMB_anim_absolute(seq->anim, se->nr + seq->anim_startofs); + /* we don't need both (speed reasons)! */ + if (se->ibuf + && se->ibuf->rect_float + && se->ibuf->rect) { + imb_freerectImBuf(se->ibuf); + } + } copy_to_ibuf_still(seq, se); } @@ -1894,7 +1994,7 @@ static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int int sce_valid =sce&& (sce->camera || sce->r.scemode & R_DOSEQ); if (se->ibuf == NULL && sce_valid && !build_proxy_run) { - se->ibuf = seq_proxy_fetch(scene, seq, cfra); + se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size); if (se->ibuf) { input_preprocess(scene, seq, se, cfra); } @@ -1910,7 +2010,10 @@ static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int if (!sce_valid) { se->ok = STRIPELEM_FAILED; } else if (se->ibuf==NULL && sce_valid) { - waitcursor(1); + /* no need to display a waitcursor on sequencer + scene strips */ + if (!(sce->r.scemode & R_DOSEQ)) + waitcursor(1); /* Hack! This function can be called from do_render_seq(), in that case the seq->scene can already have a Render initialized with same name, @@ -1960,6 +2063,13 @@ static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int /* restore */ scene->r.scemode |= doseq; + + // XXX +#if 0 + if((G.f & G_PLAYANIM)==0 /* bad, is set on do_render_seq */ + && !(sce->r.scemode & R_DOSEQ)) + waitcursor(0); +#endif CFRA = oldcfra; set_last_seq(oldseq); @@ -1986,9 +2096,9 @@ static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int } } -static TStripElem* do_build_seq_recursively(Scene *scene, Sequence *seq, int cfra); +static TStripElem* do_build_seq_recursively(Scene *scene, Sequence *seq, int cfra, int render_size); -static void do_effect_seq_recursively(Scene *scene, Sequence *seq, TStripElem *se, int cfra) +static void do_effect_seq_recursively(Scene *scene, Sequence *seq, TStripElem *se, int cfra, int render_size) { float fac, facf; struct SeqEffectHandle sh = get_sequence_effect(seq); @@ -2017,22 +2127,22 @@ static void do_effect_seq_recursively(Scene *scene, Sequence *seq, TStripElem *s /* no input needed */ break; case 0: - se->se1 = do_build_seq_recursively(scene, seq->seq1, cfra); - se->se2 = do_build_seq_recursively(scene, seq->seq2, cfra); + se->se1 = do_build_seq_recursively(scene, seq->seq1, cfra, render_size); + se->se2 = do_build_seq_recursively(scene, seq->seq2, cfra, render_size); if (seq->seq3) { - se->se3 = do_build_seq_recursively(scene, seq->seq3, cfra); + se->se3 = do_build_seq_recursively(scene, seq->seq3, cfra, render_size); } break; case 1: - se->se1 = do_build_seq_recursively(scene, seq->seq1, cfra); + se->se1 = do_build_seq_recursively(scene, seq->seq1, cfra, render_size); break; case 2: - se->se2 = do_build_seq_recursively(scene, seq->seq2, cfra); + se->se2 = do_build_seq_recursively(scene, seq->seq2, cfra, render_size); break; } - do_build_seq_ibuf(scene, seq, se, cfra, FALSE); + do_build_seq_ibuf(scene, seq, se, cfra, FALSE, render_size); /* children are not needed anymore ... */ @@ -2045,9 +2155,10 @@ static void do_effect_seq_recursively(Scene *scene, Sequence *seq, TStripElem *s if (se->se3 && se->se3->ibuf) { IMB_cache_limiter_unref(se->se3->ibuf); } + check_limiter_refcount("do_effect_seq_recursively", se); } -static TStripElem* do_build_seq_recursively_impl(Scene *scene, Sequence * seq, int cfra) +static TStripElem* do_build_seq_recursively_impl(Scene *scene, Sequence * seq, int cfra, int render_size) { TStripElem *se; @@ -2055,9 +2166,9 @@ static TStripElem* do_build_seq_recursively_impl(Scene *scene, Sequence * seq, i if(se) { if (seq->type & SEQ_EFFECT) { - do_effect_seq_recursively(scene, seq, se, cfra); + do_effect_seq_recursively(scene, seq, se, cfra, render_size); } else { - do_build_seq_ibuf(scene, seq, se, cfra, FALSE); + do_build_seq_ibuf(scene, seq, se, cfra, FALSE, render_size); } } return se; @@ -2071,7 +2182,7 @@ instead of faking using the blend code below... */ -static TStripElem* do_handle_speed_effect(Scene *scene, Sequence * seq, int cfra) +static TStripElem* do_handle_speed_effect(Scene *scene, Sequence * seq, int cfra, int render_size) { SpeedControlVars * s = (SpeedControlVars *)seq->effectdata; int nr = cfra - seq->start; @@ -2100,7 +2211,7 @@ static TStripElem* do_handle_speed_effect(Scene *scene, Sequence * seq, int cfra test_and_auto_discard_ibuf(se); if (se->ibuf == NULL) { - se1 = do_build_seq_recursively_impl(scene, seq->seq1, cfra_left); + se1 = do_build_seq_recursively_impl(scene, seq->seq1, cfra_left, render_size); if((se1 && se1->ibuf && se1->ibuf->rect_float)) se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0); @@ -2132,8 +2243,8 @@ static TStripElem* do_handle_speed_effect(Scene *scene, Sequence * seq, int cfra } if (se->ibuf == NULL) { - se1 = do_build_seq_recursively_impl(scene, seq->seq1, cfra_left); - se2 = do_build_seq_recursively_impl(scene, seq->seq1, cfra_right); + se1 = do_build_seq_recursively_impl(scene, seq->seq1, cfra_left, render_size); + se2 = do_build_seq_recursively_impl(scene, seq->seq1, cfra_right, render_size); if((se1 && se1->ibuf && se1->ibuf->rect_float)) se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0); @@ -2168,6 +2279,8 @@ static TStripElem* do_handle_speed_effect(Scene *scene, Sequence * seq, int cfra if (se2 && se2->ibuf) IMB_cache_limiter_unref(se2->ibuf); + check_limiter_refcount("do_handle_speed_effect", se); + return se; } @@ -2183,25 +2296,22 @@ static TStripElem* do_handle_speed_effect(Scene *scene, Sequence * seq, int cfra * */ -static TStripElem* do_build_seq_recursively(Scene *scene, Sequence * seq, int cfra) +static TStripElem* do_build_seq_recursively(Scene *scene, Sequence * seq, int cfra, int render_size) { + TStripElem *se; if (seq->type == SEQ_SPEED) { - return do_handle_speed_effect(scene, seq, cfra); + se = do_handle_speed_effect(scene, seq, cfra, render_size); } else { - return do_build_seq_recursively_impl(scene, seq, cfra); + se = do_build_seq_recursively_impl(scene, seq, cfra, render_size); } -} -/* Bug: 18209 - * when dragging the mouse over a metastrip, on mouse-up for some unknown - * reason in some cases the metastrips TStripElem->ibuf->rect is NULL, - * This should be fixed but I had a look and couldnt work out why its - * happening so for now workaround with a NULL check - campbell */ + check_limiter_refcount("do_build_seq_recursively", se); -#define SEQ_SPECIAL_SEQ_UPDATE_WORKAROUND + return se; +} static TStripElem* do_build_seq_array_recursively(Scene *scene, - ListBase *seqbasep, int cfra, int chanshown) + ListBase *seqbasep, int cfra, int chanshown, int render_size) { Sequence* seq_arr[MAXSEQ+1]; int count; @@ -2231,7 +2341,7 @@ static TStripElem* do_build_seq_array_recursively(Scene *scene, if(count == 1) { - se = do_build_seq_recursively(scene, seq_arr[0], cfra); + se = do_build_seq_recursively(scene, seq_arr[0], cfra, render_size); if (se->ibuf) { se->ibuf_comp = se->ibuf; IMB_refImBuf(se->ibuf_comp); @@ -2253,7 +2363,7 @@ static TStripElem* do_build_seq_array_recursively(Scene *scene, break; } if (seq->blend_mode == SEQ_BLEND_REPLACE) { - do_build_seq_recursively(scene, seq, cfra); + do_build_seq_recursively(scene, seq, cfra, render_size); if (se->ibuf) { se->ibuf_comp = se->ibuf; IMB_refImBuf(se->ibuf); @@ -2261,6 +2371,9 @@ static TStripElem* do_build_seq_array_recursively(Scene *scene, se->ibuf_comp = IMB_allocImBuf( (short)seqrectx, (short)seqrecty, 32, IB_rect, 0); + IMB_cache_limiter_insert(se->ibuf_comp); + IMB_cache_limiter_ref(se->ibuf_comp); + IMB_cache_limiter_touch(se->ibuf_comp); } break; } @@ -2285,7 +2398,7 @@ static TStripElem* do_build_seq_array_recursively(Scene *scene, switch (early_out) { case -1: case 2: - do_build_seq_recursively(scene, seq, cfra); + do_build_seq_recursively(scene, seq, cfra, render_size); if (se->ibuf) { se->ibuf_comp = se->ibuf; IMB_refImBuf(se->ibuf_comp); @@ -2293,6 +2406,9 @@ static TStripElem* do_build_seq_array_recursively(Scene *scene, se->ibuf_comp = IMB_allocImBuf( (short)seqrectx, (short)seqrecty, 32, IB_rect, 0); + IMB_cache_limiter_insert(se->ibuf_comp); + IMB_cache_limiter_ref(se->ibuf_comp); + IMB_cache_limiter_touch(se->ibuf_comp); } break; case 1: @@ -2306,11 +2422,14 @@ static TStripElem* do_build_seq_array_recursively(Scene *scene, } break; case 0: - do_build_seq_recursively(scene, seq, cfra); + do_build_seq_recursively(scene, seq, cfra, render_size); if (!se->ibuf) { se->ibuf = IMB_allocImBuf( (short)seqrectx, (short)seqrecty, 32, IB_rect, 0); + IMB_cache_limiter_insert(se->ibuf); + IMB_cache_limiter_ref(se->ibuf); + IMB_cache_limiter_touch(se->ibuf); } if (i == 0) { se->ibuf_comp = se->ibuf; @@ -2369,13 +2488,6 @@ static TStripElem* do_build_seq_array_recursively(Scene *scene, IMB_rect_from_float(se2->ibuf); } -#ifdef SEQ_SPECIAL_SEQ_UPDATE_WORKAROUND - if (se2->ibuf->rect==NULL && se2->ibuf->rect_float==NULL) { - printf("ERROR: sequencer se2->ibuf missing buffer\n"); - } else if (se1->ibuf && se1->ibuf->rect==NULL && se1->ibuf->rect_float==NULL) { - printf("ERROR: sequencer se1->ibuf missing buffer\n"); - } else { -#endif /* bad hack, to fix crazy input ordering of those two effects */ @@ -2397,10 +2509,6 @@ static TStripElem* do_build_seq_array_recursively(Scene *scene, se2->ibuf_comp); } -#ifdef SEQ_SPECIAL_SEQ_UPDATE_WORKAROUND - } -#endif - IMB_cache_limiter_insert(se2->ibuf_comp); IMB_cache_limiter_ref(se2->ibuf_comp); IMB_cache_limiter_touch(se2->ibuf_comp); @@ -2428,7 +2536,7 @@ static TStripElem* do_build_seq_array_recursively(Scene *scene, * you have to unref after usage! */ -static ImBuf *give_ibuf_seq_impl(Scene *scene, int rectx, int recty, int cfra, int chanshown) +static ImBuf *give_ibuf_seq_impl(Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size) { Editing *ed= seq_give_editing(scene, FALSE); int count; @@ -2449,28 +2557,32 @@ static ImBuf *give_ibuf_seq_impl(Scene *scene, int rectx, int recty, int cfra, i seqrectx= rectx; /* bad bad global! */ seqrecty= recty; - se = do_build_seq_array_recursively(scene, seqbasep, cfra, chanshown); + se = do_build_seq_array_recursively(scene, seqbasep, cfra, chanshown, render_size); if(!se) { return 0; } + check_limiter_refcount_comp("give_ibuf_seq_impl", se); + return se->ibuf_comp; } -ImBuf *give_ibuf_seq_direct(Scene *scene, int rectx, int recty, int cfra, Sequence *seq) +ImBuf *give_ibuf_seq_direct(Scene *scene, int rectx, int recty, int cfra, int render_size, Sequence *seq) { TStripElem* se; seqrectx= rectx; /* bad bad global! */ seqrecty= recty; - se = do_build_seq_recursively(scene, seq, cfra); + se = do_build_seq_recursively(scene, seq, cfra, render_size); if(!se) { return 0; } + check_limiter_refcount("give_ibuf_seq_direct", se); + if (se->ibuf) { IMB_cache_limiter_unref(se->ibuf); } @@ -2478,9 +2590,9 @@ ImBuf *give_ibuf_seq_direct(Scene *scene, int rectx, int recty, int cfra, Sequen return se->ibuf; } -ImBuf *give_ibuf_seq(Scene *scene, int rectx, int recty, int cfra, int chanshown) +ImBuf *give_ibuf_seq(Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size) { - ImBuf* i = give_ibuf_seq_impl(scene, rectx, recty, cfra, chanshown); + ImBuf* i = give_ibuf_seq_impl(scene, rectx, recty, cfra, chanshown, render_size); if (i) { IMB_cache_limiter_unref(i); @@ -2535,6 +2647,7 @@ typedef struct PrefetchQueueElem { int recty; int cfra; int chanshown; + int render_size; int monoton_cfra; @@ -2580,7 +2693,8 @@ static void *seq_prefetch_thread(void * This_) if (e->cfra >= s_last) { e->ibuf = give_ibuf_seq_impl(This->scene, - e->rectx, e->recty, e->cfra, e->chanshown); + e->rectx, e->recty, e->cfra, e->chanshown, + e->render_size); } pthread_mutex_lock(&queue_lock); @@ -2689,7 +2803,8 @@ void seq_stop_threads() BLI_end_threads(0); } -void give_ibuf_prefetch_request(int rectx, int recty, int cfra, int chanshown) +void give_ibuf_prefetch_request(int rectx, int recty, int cfra, int chanshown, + int render_size) { PrefetchQueueElem *e; if (seq_thread_shutdown) { @@ -2701,6 +2816,7 @@ void give_ibuf_prefetch_request(int rectx, int recty, int cfra, int chanshown) e->recty = recty; e->cfra = cfra; e->chanshown = chanshown; + e->render_size = render_size; e->monoton_cfra = monoton_cfra++; pthread_mutex_lock(&queue_lock); @@ -2741,13 +2857,13 @@ void seq_wait_for_prefetch_ready() fprintf(stderr, "SEQ-THREAD: prefetch done\n"); } -ImBuf *give_ibuf_seq_threaded(Scene *scene, int rectx, int recty, int cfra, int chanshown) +ImBuf *give_ibuf_seq_threaded(Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size) { PrefetchQueueElem *e = NULL; int found_something = FALSE; if (seq_thread_shutdown) { - return give_ibuf_seq(scene, rectx, recty, cfra, chanshown); + return give_ibuf_seq(scene, rectx, recty, cfra, chanshown, render_size); } while (!e) { @@ -2758,7 +2874,8 @@ ImBuf *give_ibuf_seq_threaded(Scene *scene, int rectx, int recty, int cfra, int if (cfra == e->cfra && chanshown == e->chanshown && rectx == e->rectx && - recty == e->recty) { + recty == e->recty && + render_size == e->render_size) { success = TRUE; found_something = TRUE; break; @@ -2770,7 +2887,8 @@ ImBuf *give_ibuf_seq_threaded(Scene *scene, int rectx, int recty, int cfra, int if (cfra == e->cfra && chanshown == e->chanshown && rectx == e->rectx && - recty == e->recty) { + recty == e->recty && + render_size == e->render_size) { found_something = TRUE; break; } @@ -2786,7 +2904,8 @@ ImBuf *give_ibuf_seq_threaded(Scene *scene, int rectx, int recty, int cfra, int cfra == tslot->current->cfra && chanshown == tslot->current->chanshown && rectx == tslot->current->rectx && - recty == tslot->current->recty) { + recty == tslot->current->recty && + render_size== tslot->current->render_size){ found_something = TRUE; break; } @@ -2887,6 +3006,7 @@ void free_imbuf_seq_except(Scene *scene, int cfra) if(seq->type==SEQ_MOVIE) if(seq->startdisp > cfra || seq->enddisp < cfra) free_anim_seq(seq); + free_proxy_seq(seq); } } SEQ_END @@ -3010,6 +3130,7 @@ void free_imbuf_seq_with_ipo(Scene *scene, struct Ipo *ipo) if(seq->type == SEQ_SPEED) { sequence_effect_speed_rebuild_map(seq, 1); } + free_proxy_seq(seq); } } SEQ_END @@ -3021,7 +3142,7 @@ void do_render_seq(RenderResult *rr, int cfra) { ImBuf *ibuf; - ibuf= give_ibuf_seq(scene, rr->rectx, rr->recty, cfra, 0); + ibuf= give_ibuf_seq(scene, rr->rectx, rr->recty, cfra, 0, scene->r.size); if(ibuf) { if(ibuf->rect_float) { @@ -3076,6 +3197,7 @@ void do_render_seq(RenderResult *rr, int cfra) "user preferences.\n"); free_imbuf_seq(); } + free_proxy_seq(seq); } } else { diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c index 8bf56f136bc..27357d92aae 100644 --- a/source/blender/blenkernel/intern/shrinkwrap.c +++ b/source/blender/blenkernel/intern/shrinkwrap.c @@ -547,7 +547,7 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, Scene *scene, Object calc.vgroup = get_named_vertexgroup_num(calc.ob, smd->vgroup_name); - if(dm != NULL) + if(dm != NULL && smd->shrinkType == MOD_SHRINKWRAP_PROJECT) { //Setup arrays to get vertexs positions, normals and deform weights calc.vert = dm->getVertDataArray(dm, CD_MVERT); diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c index d7accd54fb9..bc6b487080c 100644 --- a/source/blender/blenkernel/intern/softbody.c +++ b/source/blender/blenkernel/intern/softbody.c @@ -3075,8 +3075,8 @@ static void apply_spring_memory(Object *ob) int a; float b,l,r; - b = sb->plastic; if (sb && sb->totspring){ + b = sb->plastic; for(a=0; a<sb->totspring; a++) { bs = &sb->bspring[a]; bp1 =&sb->bpoint[bs->v1]; @@ -3546,9 +3546,9 @@ static void springs_from_particles(Object *ob) int a,k; float hairmat[4][4]; - psys= ob->soft->particles; - sb= ob->soft; - if(ob && sb && psys) { + if(ob && ob->soft && ob->soft->particles) { + psys= ob->soft->particles; + sb= ob->soft; psmd = psys_get_modifier(ob, psys); bp= sb->bpoint; diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c index 8bad269a85e..7fe129ed6fc 100644 --- a/source/blender/blenkernel/intern/world.c +++ b/source/blender/blenkernel/intern/world.c @@ -110,6 +110,10 @@ World *add_world(char *name) wrld->mode = WO_DBVT_CULLING; // DBVT culling by default wrld->occlusionRes = 128; wrld->preview = NULL; + wrld->ticrate = 60; + wrld->maxlogicstep = 5; + wrld->physubstep = 1; + wrld->maxphystep = 5; return wrld; } diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c index 472a6612a50..0277da5f908 100644 --- a/source/blender/blenkernel/intern/writeffmpeg.c +++ b/source/blender/blenkernel/intern/writeffmpeg.c @@ -242,6 +242,9 @@ static void write_video_frame(RenderData *rd, AVFrame* frame) #ifdef FFMPEG_CODEC_TIME_BASE frame->pts = rd->cfra - rd->sfra; #endif + if (G.scene->r.mode & R_FIELDS) { + frame->top_field_first = ((G.scene->r.mode & R_ODDFIELD) != 0); + } outsize = avcodec_encode_video(c, video_buffer, video_buffersize, frame); diff --git a/source/blender/blenlib/BLI_string.h b/source/blender/blenlib/BLI_string.h index ce9dd44601b..4e5bf650196 100644 --- a/source/blender/blenlib/BLI_string.h +++ b/source/blender/blenlib/BLI_string.h @@ -96,6 +96,7 @@ int BLI_strcaseeq(const char *a, const char *b); char *BLI_strcasestr(const char *s, const char *find); int BLI_strcasecmp(const char *s1, const char *s2); int BLI_strncasecmp(const char *s1, const char *s2, int n); +int BLI_natstrcmp(const char *s1, const char *s2); void BLI_timestr(double _time, char *str); /* time var is global */ diff --git a/source/blender/blenlib/BLI_vfontdata.h b/source/blender/blenlib/BLI_vfontdata.h index 8838b1992e4..bd89959801a 100644 --- a/source/blender/blenlib/BLI_vfontdata.h +++ b/source/blender/blenlib/BLI_vfontdata.h @@ -54,7 +54,7 @@ typedef struct VFontData { typedef struct VChar { struct VChar *next, *prev; ListBase nurbsbase; - unsigned long index; + intptr_t index; float resol; float width; float *points; diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c index 9204ab18bfa..688a4ab901b 100644 --- a/source/blender/blenlib/intern/storage.c +++ b/source/blender/blenlib/intern/storage.c @@ -154,7 +154,7 @@ int BLI_compare(struct direntry *entry1, struct direntry *entry2) if( strcmp(entry1->relname, "..")==0 ) return (-1); if( strcmp(entry2->relname, "..")==0 ) return (1); - return (BLI_strcasecmp(entry1->relname,entry2->relname)); + return (BLI_natstrcmp(entry1->relname,entry2->relname)); } @@ -330,7 +330,7 @@ void BLI_builddir(char *dirname, char *relname) void BLI_adddirstrings() { char datum[100]; - char buf[250]; + char buf[512]; char size[250]; static char * types[8] = {"---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx"}; int num, mode; @@ -427,9 +427,6 @@ void BLI_adddirstrings() sprintf(size, "%10d", (int) st_size); } - sprintf(buf,"%s %s %10s %s", files[num].date, files[num].time, size, - files[num].relname); - sprintf(buf,"%s %s %s %7s %s %s %10s %s", file->mode1, file->mode2, file->mode3, files[num].owner, files[num].date, files[num].time, size, files[num].relname); diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c index 843f6b62735..fa4bcbc26bc 100644 --- a/source/blender/blenlib/intern/string.c +++ b/source/blender/blenlib/intern/string.c @@ -170,6 +170,54 @@ int BLI_strncasecmp(const char *s1, const char *s2, int n) { return 0; } +/* natural string compare, keeping numbers in order */ +int BLI_natstrcmp(const char *s1, const char *s2) +{ + int d1= 0, d2= 0; + + /* if both chars are numeric, to a strtol(). + then increase string deltas as long they are + numeric, else do a tolower and char compare */ + + while(1) { + char c1 = tolower(s1[d1]); + char c2 = tolower(s2[d2]); + + if( isdigit(c1) && isdigit(c2) ) { + int val1, val2; + + val1= (int)strtol(s1+d1, (char **)NULL, 10); + val2= (int)strtol(s2+d2, (char **)NULL, 10); + + if (val1<val2) { + return -1; + } else if (val1>val2) { + return 1; + } + d1++; + while( isdigit(s1[d1]) ) + d1++; + d2++; + while( isdigit(s2[d2]) ) + d2++; + + c1 = tolower(s1[d1]); + c2 = tolower(s2[d2]); + } + + if (c1<c2) { + return -1; + } else if (c1>c2) { + return 1; + } else if (c1==0) { + break; + } + d1++; + d2++; + } + return 0; +} + void BLI_timestr(double _time, char *str) { /* format 00:00:00.00 (hr:min:sec) string has to be 12 long */ diff --git a/source/blender/blenlib/intern/util.c b/source/blender/blenlib/intern/util.c index 137a32c4689..df4ad4e7c75 100644 --- a/source/blender/blenlib/intern/util.c +++ b/source/blender/blenlib/intern/util.c @@ -1472,9 +1472,6 @@ char* BLI_getbundle(void) { } #endif - - - #ifdef WITH_ICONV #include "iconv.h" #include "localcharset.h" diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index cf26527e3f0..ce3a35c7194 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -156,6 +156,8 @@ #include "readfile.h" +#include "PIL_time.h" + #include <errno.h> /* @@ -611,10 +613,16 @@ static BHeadN *get_bhead(FileData *fd) BHead bhead; BHeadN *new_bhead = 0; int readsize; - + if (fd) { if ( ! fd->eof) { + /* not strictly needed but shuts valgrind up + * since uninitialized memory gets compared */ + memset(&bhead8, 0, sizeof(BHead8)); + memset(&bhead4, 0, sizeof(BHead4)); + memset(&bhead, 0, sizeof(BHead)); + // First read the bhead structure. // Depending on the platform the file was written on this can // be a big or little endian BHead4 or BHead8 structure. @@ -1489,6 +1497,8 @@ static void lib_link_brush(FileData *fd, Main *main) if(brush->id.flag & LIB_NEEDLINK) { brush->id.flag -= LIB_NEEDLINK; + brush->clone.image= newlibadr_us(fd, brush->id.lib, brush->clone.image); + for(a=0; a<MAX_MTEX; a++) { mtex= brush->mtex[a]; if(mtex) @@ -3146,6 +3156,18 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh) lvl->colfaces= newdataadr(fd, lvl->colfaces); } } + + /* Gracefully handle corrupted mesh */ + if(mesh->mr && !mesh->mr->verts) { + /* If totals match, simply load the current mesh verts into multires */ + if(mesh->totvert == ((MultiresLevel*)mesh->mr->levels.last)->totvert) + mesh->mr->verts = MEM_dupallocN(mesh->mvert); + else { + /* Otherwise, we can't recover the data, silently remove multires */ + multires_free(mesh->mr); + mesh->mr = NULL; + } + } if((fd->flags & FD_FLAGS_SWITCH_ENDIAN) && mesh->tface) { TFace *tf= mesh->tface; @@ -3337,6 +3359,10 @@ static void lib_link_object(FileData *fd, Main *main) bAddObjectActuator *eoa= act->data; if(eoa) eoa->ob= newlibadr(fd, ob->id.lib, eoa->ob); } + else if(act->type==ACT_OBJECT) { + bObjectActuator *oa= act->data; + oa->reference= newlibadr(fd, ob->id.lib, oa->reference); + } else if(act->type==ACT_EDIT_OBJECT) { bEditObjectActuator *eoa= act->data; if(eoa==NULL) { @@ -3347,6 +3373,15 @@ static void lib_link_object(FileData *fd, Main *main) eoa->me= newlibadr(fd, ob->id.lib, eoa->me); } } + else if(act->type==ACT_OBJECT) { + bObjectActuator *oa= act->data; + if(oa==NULL) { + init_actuator(act); + } + else { + oa->reference= newlibadr(fd, ob->id.lib, oa->reference); + } + } else if(act->type==ACT_SCENE) { bSceneActuator *sa= act->data; sa->camera= newlibadr(fd, ob->id.lib, sa->camera); @@ -3451,6 +3486,11 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb) smd->emCache = smd->mCache = 0; } + else if (md->type==eModifierType_Armature) { + ArmatureModifierData *amd = (ArmatureModifierData*) md; + + amd->prevCos= NULL; + } else if (md->type==eModifierType_Cloth) { ClothModifierData *clmd = (ClothModifierData*) md; @@ -3957,6 +3997,7 @@ static void direct_link_scene(FileData *fd, Scene *sce) if (seq->flag & SEQ_USE_PROXY) { seq->strip->proxy = newdataadr( fd, seq->strip->proxy); + seq->strip->proxy->anim = 0; } else { seq->strip->proxy = 0; } @@ -4389,6 +4430,22 @@ void lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *curscene) if((v3d->layact & v3d->lay)==0) v3d->layact= v3d->lay; } + else if(sl->spacetype==SPACE_IPO) { + /* XXX animato */ +#if 0 + SpaceIpo *sipo= (SpaceIpo *)sl; + + sipo->ipo= restore_pointer_by_name(newmain, (ID *)sipo->ipo, 0); + if(sipo->blocktype==ID_SEQ) + sipo->from= (ID *)find_sequence_from_ipo_helper(newmain, sipo->ipo); + else + sipo->from= restore_pointer_by_name(newmain, (ID *)sipo->from, 0); + + // not free sipo->ipokey, creates dependency with src/ + if(sipo->editipo) MEM_freeN(sipo->editipo); + sipo->editipo= NULL; +#endif + } else if(sl->spacetype==SPACE_BUTS) { SpaceButs *sbuts= (SpaceButs *)sl; sbuts->lockpoin= NULL; @@ -8852,7 +8909,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) /* Adjustments needed after Bullets update */ for(ob = main->object.first; ob; ob= ob->id.next) { ob->damping *= 0.635f; - ob->rdamping = 0.1 + (0.59f * ob->rdamping); + ob->rdamping = 0.1 + (0.8f * ob->rdamping); } } @@ -8864,9 +8921,9 @@ static void do_versions(FileData *fd, Library *lib, Main *main) for (sce= main->scene.first; sce; sce= sce->id.next) { sce->r.domeangle = 180; sce->r.domemode = 1; - sce->r.domesize = 1.0f; sce->r.domeres = 4; sce->r.domeresbuf = 1.0f; + sce->r.dometilt = 0; } /* DBVT culling by default */ for(wrld=main->world.first; wrld; wrld= wrld->id.next) { @@ -8875,6 +8932,49 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } + if (main->versionfile < 248 || (main->versionfile == 248 && main->subversionfile < 5)) { + Object *ob; + World *wrld; + for(ob = main->object.first; ob; ob= ob->id.next) { + ob->m_contactProcessingThreshold = 1.; //pad3 is used for m_contactProcessingThreshold + if(ob->parent) { + /* check if top parent has compound shape set and if yes, set this object + to compound shaper as well (was the behaviour before, now it's optional) */ + Object *parent= newlibadr(fd, lib, ob->parent); + while (parent && parent->parent != NULL) { + parent = newlibadr(fd, lib, parent->parent); + } + if(parent) { + if (parent->gameflag & OB_CHILD) + ob->gameflag |= OB_CHILD; + } + } + } + for(wrld=main->world.first; wrld; wrld= wrld->id.next) { + wrld->ticrate = 60; + wrld->maxlogicstep = 5; + wrld->physubstep = 1; + wrld->maxphystep = 5; + } + } + + if (main->versionfile < 249) { + Scene *sce; + for (sce= main->scene.first; sce; sce= sce->id.next) + sce->r.renderer= 0; + + } + + // correct introduce of seed for wind force + if (main->versionfile < 249 && main->subversionfile < 1) { + Object *ob; + for(ob = main->object.first; ob; ob= ob->id.next) { + if(ob->pd) + ob->pd->seed = ((unsigned int)(ceil(PIL_check_seconds_timer()))+1) % 128; + } + + } + if (main->versionfile < 250) { bScreen *screen; Scene *scene; @@ -9021,6 +9121,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } } + /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ /* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */ @@ -9848,6 +9949,10 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob) expand_doit(fd, mainvar, eoa->me); } } + else if(act->type==ACT_OBJECT) { + bObjectActuator *oa= act->data; + expand_doit(fd, mainvar, oa->reference); + } else if(act->type==ACT_SCENE) { bSceneActuator *sa= act->data; expand_doit(fd, mainvar, sa->camera); diff --git a/source/blender/editors/animation/anim_ipo_utils.c b/source/blender/editors/animation/anim_ipo_utils.c index c2a1199f6c6..aecf437a30b 100644 --- a/source/blender/editors/animation/anim_ipo_utils.c +++ b/source/blender/editors/animation/anim_ipo_utils.c @@ -33,6 +33,7 @@ */ +#include <math.h> #include <stdio.h> #include "MEM_guardedalloc.h" diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index 1c113c25720..9c9be51f010 100644 --- a/source/blender/editors/armature/editarmature.c +++ b/source/blender/editors/armature/editarmature.c @@ -734,6 +734,7 @@ int join_armature(Scene *scene, View3D *v3d) VecSubf(delta, curbone->tail, curbone->head); vec_roll_to_mat3(delta, curbone->roll, temp); + Mat4One(premat); /* Mat4MulMat34 only sets 3x3 part */ Mat4MulMat34(premat, temp, mat); Mat4MulVecfl(mat, curbone->head); diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c index 45605ad472d..f010abdb7e7 100644 --- a/source/blender/editors/armature/editarmature_sketch.c +++ b/source/blender/editors/armature/editarmature_sketch.c @@ -2273,6 +2273,7 @@ void sk_applyCutGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch) pt.type = PT_EXACT; pt.mode = PT_PROJECT; /* take mode from neighbouring points */ VECCOPY(pt.p, isect->p); + VECCOPY(pt.no, isect->stroke->points[isect->before].no); sk_insertStrokePoint(isect->stroke, &pt, isect->after); } @@ -2314,6 +2315,7 @@ void sk_applyTrimGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch) pt.type = PT_EXACT; pt.mode = PT_PROJECT; /* take mode from neighbouring points */ VECCOPY(pt.p, isect->p); + VECCOPY(pt.no, isect->stroke->points[isect->before].no); VecSubf(stroke_dir, isect->stroke->points[isect->after].p, isect->stroke->points[isect->before].p); diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c index 3d8d446c579..0d7bb3c63cc 100644 --- a/source/blender/editors/armature/poseobject.c +++ b/source/blender/editors/armature/poseobject.c @@ -1688,18 +1688,25 @@ void pose_clear_user_transforms(Scene *scene, Object *ob) if (ob->pose == NULL) return; - /* find selected bones */ - for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { - if (pchan->bone && (pchan->bone->flag & BONE_SELECTED) && (pchan->bone->layer & arm->layer)) { - /* just clear the BONE_UNKEYED flag, allowing this bone to get overwritten by actions again */ - pchan->bone->flag &= ~BONE_UNKEYED; + /* if the object has an action, restore pose to the pose defined by the action by clearing pose on selected bones */ + if (ob->action) { + /* find selected bones */ + for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { + if (pchan->bone && (pchan->bone->flag & BONE_SELECTED) && (pchan->bone->layer & arm->layer)) { + /* just clear the BONE_UNKEYED flag, allowing this bone to get overwritten by actions again */ + pchan->bone->flag &= ~BONE_UNKEYED; + } } + + /* clear pose locking flag + * - this will only clear the user-defined pose in the selected bones, where BONE_UNKEYED has been cleared + */ + ob->pose->flag |= POSE_DO_UNLOCK; + } + else { + /* no action, so restore entire pose to rest pose (cannot restore only selected bones) */ + rest_pose(ob->pose); } - - /* clear pose locking flag - * - this will only clear the user-defined pose in the selected bones, where BONE_UNKEYED has been cleared - */ - ob->pose->flag |= POSE_DO_UNLOCK; DAG_object_flush_update(scene, ob, OB_RECALC_DATA); BIF_undo_push("Clear User Transform"); diff --git a/source/blender/editors/armature/reeb.c b/source/blender/editors/armature/reeb.c index 7e6c84764ae..ea794b2c7c1 100644 --- a/source/blender/editors/armature/reeb.c +++ b/source/blender/editors/armature/reeb.c @@ -2702,7 +2702,7 @@ static float cotan_weight(float *v1, float *v2, float *v3) return Inpf(a, b)/clen; } -void addTriangle(EditVert *v1, EditVert *v2, EditVert *v3, long e1, long e2, long e3) +void addTriangle(EditVert *v1, EditVert *v2, EditVert *v3, int e1, int e2, int e3) { /* Angle opposite e1 */ float t1= cotan_weight(v1->co, v2->co, v3->co) / e2; diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c index ec4e79a7e5a..1b2c8ea6b11 100644 --- a/source/blender/editors/curve/editfont.c +++ b/source/blender/editors/curve/editfont.c @@ -226,7 +226,7 @@ void update_string(Curve *cu) wcs2utf8s(cu->str, ef->textbuf); } -static int insert_into_textbuf(Object *obedit, unsigned long c) +static int insert_into_textbuf(Object *obedit, uintptr_t c) { Curve *cu= obedit->data; @@ -1290,7 +1290,7 @@ static int insert_text_invoke(bContext *C, wmOperator *op, wmEvent *evt) Curve *cu= obedit->data; EditFont *ef= cu->editfont; static int accentcode= 0; - unsigned long ascii = evt->ascii; + uintptr_t ascii = evt->ascii; int alt= evt->alt, shift= evt->shift, ctrl= evt->ctrl; int event= evt->type, val= evt->val; wchar_t inserted_text[2]= {0}; diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c index e5868338f75..735f1ffddb9 100644 --- a/source/blender/editors/gpencil/drawgpencil.c +++ b/source/blender/editors/gpencil/drawgpencil.c @@ -131,12 +131,14 @@ void gp_ui_delstroke_cb (void *gpd, void *gpl) { bGPDframe *gpf= gpencil_layer_getframe(gpl, CFRA, 0); - if (gpf->framenum != CFRA) return; + if (gpf) { + if (gpf->framenum != CFRA) return; - gpencil_layer_setactive(gpd, gpl); - gpencil_frame_delete_laststroke(gpl, gpf); - - scrarea_queue_winredraw(curarea); + gpencil_layer_setactive(gpd, gpl); + gpencil_frame_delete_laststroke(gpl, gpf); + + scrarea_queue_winredraw(curarea); + } } /* delete active frame of active layer */ diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index aa4372d164f..e112ca704bb 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -609,7 +609,7 @@ void uiItemEnumO_string(uiLayout *layout, char *name, int icon, char *opname, ch WM_operator_properties_create(&ptr, opname); /*RNA_enum_set(&ptr, propname, value);*/ - if(prop= RNA_struct_find_property(&ptr, propname)) { + if((prop= RNA_struct_find_property(&ptr, propname))) { RNA_property_enum_items(&ptr, prop, &item, &totitem); if(RNA_enum_value_from_id(item, value_str, &value)==0) { printf("uiItemEnumO_string: %s.%s, enum %s not found.\n", RNA_struct_identifier(ptr.type), propname, value_str); diff --git a/source/blender/editors/mesh/editdeform.c b/source/blender/editors/mesh/editdeform.c index 3019aabf371..3ccd4d56ece 100644 --- a/source/blender/editors/mesh/editdeform.c +++ b/source/blender/editors/mesh/editdeform.c @@ -223,11 +223,10 @@ void duplicate_defgroup ( Object *ob ) bDeformGroup *dg, *cdg; char name[32], s[32]; MDeformWeight *org, *cpy; - MDeformVert *dvert; - Mesh *me; - int i, idg, icdg; + MDeformVert *dvert, *dvert_array; + int i, idg, icdg, dvert_tot; - if (ob->type != OB_MESH) + if (ob->type != OB_MESH && ob->type != OB_LATTICE) return; dg = BLI_findlink (&ob->defbase, (ob->actdef-1)); @@ -258,16 +257,28 @@ void duplicate_defgroup ( Object *ob ) ob->actdef = BLI_countlist (&ob->defbase); icdg = (ob->actdef-1); - me = get_mesh (ob); - if (!me->dvert) + if(ob->type == OB_MESH) { + Mesh *me = get_mesh (ob); + dvert_array= me->dvert; + dvert_tot= me->totvert; + } + else if (ob->type == OB_LATTICE) { + Lattice *lt= (Lattice *)ob->data; + dvert_array= lt->dvert; + dvert_tot= lt->pntsu*lt->pntsv*lt->pntsw; + } + + if (!dvert_array) return; - for (i = 0; i < me->totvert; i++) { - dvert = me->dvert+i; + for (i = 0; i < dvert_tot; i++) { + dvert = dvert_array+i; org = get_defweight (dvert, idg); if (org) { + float weight = org->weight; + /* verify_defweight re-allocs org so need to store the weight first */ cpy = verify_defweight (dvert, icdg); - cpy->weight = org->weight; + cpy->weight = weight; } } } @@ -335,29 +346,39 @@ static void del_defgroup_update_users(Object *ob, int id) void del_defgroup_in_object_mode ( Object *ob ) { bDeformGroup *dg; - MDeformVert *dvert; - Mesh *me; - int i, e; + MDeformVert *dvert_array, *dvert; + + int i, e, dvert_tot; - if ((!ob) || (ob->type != OB_MESH)) + if ((!ob) || (ob->type != OB_MESH && ob->type != OB_LATTICE)) return; + if(ob->type == OB_MESH) { + Mesh *me = get_mesh (ob); + dvert_array= me->dvert; + dvert_tot= me->totvert; + } + else if (ob->type == OB_LATTICE) { + Lattice *lt= (Lattice *)ob->data; + dvert_array= lt->dvert; + dvert_tot= lt->pntsu*lt->pntsv*lt->pntsw; + } + dg = BLI_findlink (&ob->defbase, (ob->actdef-1)); if (!dg) return; - - me = get_mesh (ob); - if (me->dvert) { - for (i = 0; i < me->totvert; i++) { - dvert = me->dvert + i; + + if (dvert_array) { + for (i = 0; i < dvert_tot; i++) { + dvert = dvert_array + i; if (dvert) { if (get_defweight (dvert, (ob->actdef-1))) remove_vert_defgroup (ob, dg, i); } } - for (i = 0; i < me->totvert; i++) { - dvert = me->dvert+i; + for (i = 0; i < dvert_tot; i++) { + dvert = dvert_array+i; if (dvert) { for (e = 0; e < dvert->totweight; e++) { if (dvert->dw[e].def_nr > (ob->actdef-1)) diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index d835fdb8eed..f8f0030b258 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -615,9 +615,9 @@ static void mesh_octree_add_nodes(MocNode **basetable, float *co, float *offs, f float fx, fy, fz; int vx, vy, vz; - if (isnan(co[0]) || !finite(co[0]) || - isnan(co[1]) || !finite(co[1]) || - isnan(co[2]) || !finite(co[2]) + if (!finite(co[0]) || + !finite(co[1]) || + !finite(co[2]) ) { return; } @@ -834,9 +834,9 @@ EditVert *editmesh_get_x_mirror_vert(Object *ob, EditMesh *em, float *co) intptr_t poinval; /* ignore nan verts */ - if (isnan(co[0]) || !finite(co[0]) || - isnan(co[1]) || !finite(co[1]) || - isnan(co[2]) || !finite(co[2]) + if (!finite(co[0]) || + !finite(co[1]) || + !finite(co[2]) ) return NULL; diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 97835fba5af..4cf98f2c904 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -281,12 +281,12 @@ static Object *object_add_type(bContext *C, int type) ob= add_object(scene, type); /* editor level activate, notifiers */ ED_base_object_activate(C, BASACT); - + /* more editor stuff */ ED_object_base_init_from_view(C, BASACT); - + DAG_scene_sort(scene); - + return ob; } diff --git a/source/blender/editors/physics/editparticle.c b/source/blender/editors/physics/editparticle.c index f60d5493058..0947f540fc6 100644 --- a/source/blender/editors/physics/editparticle.c +++ b/source/blender/editors/physics/editparticle.c @@ -2455,13 +2455,16 @@ static void PE_mirror_x(Scene *scene, Object *ob, int tagged) new_pars= MEM_callocN(newtotpart*sizeof(ParticleData), "ParticleData new"); new_keys= MEM_callocN(newtotpart*sizeof(ParticleEditKey*), "ParticleEditKey new"); - memcpy(new_pars, psys->particles, totpart*sizeof(ParticleData)); - memcpy(new_keys, edit->keys, totpart*sizeof(ParticleEditKey*)); - - if(psys->particles) MEM_freeN(psys->particles); + if(psys->particles) { + memcpy(new_pars, psys->particles, totpart*sizeof(ParticleData)); + MEM_freeN(psys->particles); + } psys->particles= new_pars; - if(edit->keys) MEM_freeN(edit->keys); + if(edit->keys) { + memcpy(new_keys, edit->keys, totpart*sizeof(ParticleEditKey*)); + MEM_freeN(edit->keys); + } edit->keys= new_keys; if(edit->mirror_cache) { diff --git a/source/blender/editors/preview/previewrender.c b/source/blender/editors/preview/previewrender.c index b0d093dc10b..3ed4fa6bd0f 100644 --- a/source/blender/editors/preview/previewrender.c +++ b/source/blender/editors/preview/previewrender.c @@ -252,6 +252,12 @@ void BIF_preview_changed(short id_code) GPU_lamp_free(ob); } } + + for(ma=G.main->mat.first; ma; ma=ma->id.next) { + if(ma->gpumaterial.first) { + GPU_material_free(ma); + } + } } else if(OBACT) { Object *ob = OBACT; diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index 77cd06581fd..1effd8fd377 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -189,7 +189,7 @@ typedef struct ImagePaintPartialRedraw { // #define PROJ_BUCKET_CLONE_INIT 1<<1 /* used for testing doubles, if a point is on a line etc */ -#define PROJ_GEOM_TOLERANCE 0.0002f +#define PROJ_GEOM_TOLERANCE 0.00075f /* vert flags */ #define PROJ_VERT_CULL 1 @@ -238,8 +238,8 @@ typedef struct ProjPaintState { char *faceSeamFlags; /* store info about faces, if they are initialized etc*/ float (*faceSeamUVs)[4][2]; /* expanded UVs for faces to use as seams */ LinkNode **vertFaces; /* Only needed for when seam_bleed_px is enabled, use to find UV seams */ - char *vertFlags; /* store options per vert, now only store if the vert is pointing away from the view */ #endif + char *vertFlags; /* store options per vert, now only store if the vert is pointing away from the view */ int buckets_x; /* The size of the bucket grid, the grid span's screenMin/screenMax so you can paint outsize the screen or with 2 brushes at once */ int buckets_y; @@ -341,7 +341,7 @@ typedef struct UndoTile { typedef struct UndoElem { struct UndoElem *next, *prev; char name[MAXUNDONAME]; - unsigned long undosize; + uintptr_t undosize; ImBuf *ibuf; ListBase tiles; @@ -485,12 +485,12 @@ static void undo_imagepaint_push_begin(char *name) static void undo_imagepaint_push_end() { UndoElem *uel; - unsigned long totmem, maxmem; + uintptr_t totmem, maxmem; if(U.undomemory != 0) { /* limit to maximum memory (afterwards, we can't know in advance) */ totmem= 0; - maxmem= ((unsigned long)U.undomemory)*1024*1024; + maxmem= ((uintptr_t)U.undomemory)*1024*1024; uel= undobase.last; while(uel) { @@ -716,8 +716,8 @@ static int project_paint_PickFace(const ProjPaintState *ps, float pt[2], float w static void uvco_to_wrapped_pxco(float uv[2], int ibuf_x, int ibuf_y, float *x, float *y) { /* use */ - *x = (float)fmod(uv[0], 1.0f); - *y = (float)fmod(uv[1], 1.0f); + *x = (float)fmodf(uv[0], 1.0f); + *y = (float)fmodf(uv[1], 1.0f); if (*x < 0.0f) *x += 1.0f; if (*y < 0.0f) *y += 1.0f; @@ -751,7 +751,7 @@ static int project_paint_PickColor(const ProjPaintState *ps, float pt[2], float Vec2Weightf(uv, tf->uv[0], tf->uv[2], tf->uv[3], w); } - ibuf = BKE_image_get_ibuf((Image *)tf->tpage, NULL); /* TODO - this may be slow, the only way around it is to have an ibuf index per face */ + ibuf = tf->tpage->ibufs.first; /* we must have got the imbuf before getting here */ if (!ibuf) return 0; if (interp) { @@ -760,21 +760,21 @@ static int project_paint_PickColor(const ProjPaintState *ps, float pt[2], float if (ibuf->rect_float) { if (rgba_fp) { - bilinear_interpolation_color(ibuf, NULL, rgba_fp, x, y); + bilinear_interpolation_color_wrap(ibuf, NULL, rgba_fp, x, y); } else { float rgba_tmp_f[4]; - bilinear_interpolation_color(ibuf, NULL, rgba_tmp_f, x, y); + bilinear_interpolation_color_wrap(ibuf, NULL, rgba_tmp_f, x, y); IMAPAINT_FLOAT_RGBA_TO_CHAR(rgba, rgba_tmp_f); } } else { if (rgba) { - bilinear_interpolation_color(ibuf, rgba, NULL, x, y); + bilinear_interpolation_color_wrap(ibuf, rgba, NULL, x, y); } else { unsigned char rgba_tmp[4]; - bilinear_interpolation_color(ibuf, rgba_tmp, NULL, x, y); + bilinear_interpolation_color_wrap(ibuf, rgba_tmp, NULL, x, y); IMAPAINT_CHAR_RGBA_TO_FLOAT(rgba_fp, rgba_tmp); } } @@ -911,7 +911,7 @@ static int project_bucket_point_occluded(const ProjPaintState *ps, LinkNode *buc else isect_ret = project_paint_occlude_ptv(pixelScreenCo, ps->screenCoords[mf->v1], ps->screenCoords[mf->v3], ps->screenCoords[mf->v4], w, ps->is_ortho); } - if (isect_ret==1) { + if (isect_ret>=1) { /* TODO - we may want to cache the first hit, * it is not possible to swap the face order in the list anymore */ return 1; @@ -939,7 +939,7 @@ static int line_isect_y(const float p1[2], const float p2[2], const float y_leve return ISECT_TRUE_P2; } - y_diff= fabs(p1[1]-p2[1]); /* yuck, horizontal line, we cant do much here */ + y_diff= fabsf(p1[1]-p2[1]); /* yuck, horizontal line, we cant do much here */ if (y_diff < 0.000001f) { *x_isect = (p1[0]+p2[0]) * 0.5f; @@ -972,7 +972,7 @@ static int line_isect_x(const float p1[2], const float p2[2], const float x_leve return ISECT_TRUE_P2; } - x_diff= fabs(p1[0]-p2[0]); /* yuck, horizontal line, we cant do much here */ + x_diff= fabsf(p1[0]-p2[0]); /* yuck, horizontal line, we cant do much here */ if (x_diff < 0.000001) { /* yuck, vertical line, we cant do much here */ *y_isect = (p1[0]+p2[0]) * 0.5f; @@ -996,14 +996,15 @@ static int line_isect_x(const float p1[2], const float p2[2], const float x_leve * Its possible this gives incorrect results, when the UVs for 1 face go into the next * tile, but do not do this for the adjacent face, it could return a false positive. * This is so unlikely that Id not worry about it. */ +#ifndef PROJ_DEBUG_NOSEAMBLEED static int cmp_uv(const float vec2a[2], const float vec2b[2]) { /* if the UV's are not between 0.0 and 1.0 */ - float xa = (float)fmod(vec2a[0], 1.0f); - float ya = (float)fmod(vec2a[1], 1.0f); + float xa = (float)fmodf(vec2a[0], 1.0f); + float ya = (float)fmodf(vec2a[1], 1.0f); - float xb = (float)fmod(vec2b[0], 1.0f); - float yb = (float)fmod(vec2b[1], 1.0f); + float xb = (float)fmodf(vec2b[0], 1.0f); + float yb = (float)fmodf(vec2b[1], 1.0f); if (xa < 0.0f) xa += 1.0f; if (ya < 0.0f) ya += 1.0f; @@ -1011,12 +1012,13 @@ static int cmp_uv(const float vec2a[2], const float vec2b[2]) if (xb < 0.0f) xb += 1.0f; if (yb < 0.0f) yb += 1.0f; - return ((fabs(xa-xb) < PROJ_GEOM_TOLERANCE) && (fabs(ya-yb) < PROJ_GEOM_TOLERANCE)) ? 1:0; + return ((fabsf(xa-xb) < PROJ_GEOM_TOLERANCE) && (fabsf(ya-yb) < PROJ_GEOM_TOLERANCE)) ? 1:0; } - +#endif /* set min_px and max_px to the image space bounds of the UV coords * return zero if there is no area in the returned rectangle */ +#ifndef PROJ_DEBUG_NOSEAMBLEED static int pixel_bounds_uv( const float uv1[2], const float uv2[2], const float uv3[2], const float uv4[2], rcti *bounds_px, @@ -1044,6 +1046,7 @@ static int pixel_bounds_uv( /* face uses no UV area when quantized to pixels? */ return (bounds_px->xmin == bounds_px->xmax || bounds_px->ymin == bounds_px->ymax) ? 0 : 1; } +#endif static int pixel_bounds_array(float (* uv)[2], rcti *bounds_px, const int ibuf_x, const int ibuf_y, int tot) { @@ -1151,7 +1154,7 @@ static float angleToLength(float angle) return 1.0f; } else { - return fabs(1.0f / cos(angle * (M_PI/180.0f))); + return fabsf(1.0f / cosf(angle * (M_PI/180.0f))); } } @@ -1384,10 +1387,10 @@ static void project_face_pixel(const MTFace *tf_other, ImBuf *ibuf_other, const if (ibuf_other->rect_float) { /* from float to float */ - bilinear_interpolation_color(ibuf_other, NULL, rgba_f, x, y); + bilinear_interpolation_color_wrap(ibuf_other, NULL, rgba_f, x, y); } else { /* from char to float */ - bilinear_interpolation_color(ibuf_other, rgba_ub, NULL, x, y); + bilinear_interpolation_color_wrap(ibuf_other, rgba_ub, NULL, x, y); } } @@ -1407,7 +1410,7 @@ float project_paint_uvpixel_mask( ImBuf *ibuf_other; const MTFace *tf_other = ps->dm_mtface_mask + face_index; - if (tf_other->tpage && (ibuf_other = BKE_image_get_ibuf((Image *)tf_other->tpage, NULL))) { + if (tf_other->tpage && (ibuf_other = BKE_image_get_ibuf(tf_other->tpage, NULL))) { /* BKE_image_get_ibuf - TODO - this may be slow */ unsigned char rgba_ub[4]; float rgba_f[4]; @@ -1563,7 +1566,7 @@ static ProjPixel *project_paint_uvpixel_init( ImBuf *ibuf_other; const MTFace *tf_other = ps->dm_mtface_clone + face_index; - if (tf_other->tpage && (ibuf_other = BKE_image_get_ibuf((Image *)tf_other->tpage, NULL))) { + if (tf_other->tpage && (ibuf_other = BKE_image_get_ibuf(tf_other->tpage, NULL))) { /* BKE_image_get_ibuf - TODO - this may be slow */ if (ibuf->rect_float) { @@ -1632,7 +1635,7 @@ static int line_clip_rect2f( { /* first account for horizontal, then vertical lines */ /* horiz */ - if (fabs(l1[1]-l2[1]) < PROJ_GEOM_TOLERANCE) { + if (fabsf(l1[1]-l2[1]) < PROJ_GEOM_TOLERANCE) { /* is the line out of range on its Y axis? */ if (l1[1] < rect->ymin || l1[1] > rect->ymax) { return 0; @@ -1643,7 +1646,7 @@ static int line_clip_rect2f( } - if (fabs(l1[0]-l2[0]) < PROJ_GEOM_TOLERANCE) { /* this is a single point (or close to)*/ + if (fabsf(l1[0]-l2[0]) < PROJ_GEOM_TOLERANCE) { /* this is a single point (or close to)*/ if (BLI_in_rctf(rect, l1[0], l1[1])) { VECCOPY2D(l1_clip, l1); VECCOPY2D(l2_clip, l2); @@ -1660,7 +1663,7 @@ static int line_clip_rect2f( CLAMP(l2_clip[0], rect->xmin, rect->xmax); return 1; } - else if (fabs(l1[0]-l2[0]) < PROJ_GEOM_TOLERANCE) { + else if (fabsf(l1[0]-l2[0]) < PROJ_GEOM_TOLERANCE) { /* is the line out of range on its X axis? */ if (l1[0] < rect->xmin || l1[0] > rect->xmax) { return 0; @@ -1671,7 +1674,7 @@ static int line_clip_rect2f( return 0; } - if (fabs(l1[1]-l2[1]) < PROJ_GEOM_TOLERANCE) { /* this is a single point (or close to)*/ + if (fabsf(l1[1]-l2[1]) < PROJ_GEOM_TOLERANCE) { /* this is a single point (or close to)*/ if (BLI_in_rctf(rect, l1[0], l1[1])) { VECCOPY2D(l1_clip, l1); VECCOPY2D(l2_clip, l2); @@ -2015,7 +2018,6 @@ static void project_bucket_clip_face( const int flip = ((SIDE_OF_LINE(v1coSS, v2coSS, v3coSS) > 0.0f) != (SIDE_OF_LINE(uv1co, uv2co, uv3co) > 0.0f)); float bucket_bounds_ss[4][2]; - float w[3]; /* get the UV space bounding box */ inside_bucket_flag |= BLI_in_rctf(bucket_bounds, v1coSS[0], v1coSS[1]); @@ -2086,6 +2088,7 @@ static void project_bucket_clip_face( /* Maximum possible 6 intersections when using a rectangle and triangle */ float isectVCosSS[8][3]; /* The 3rd float is used to store angle for qsort(), NOT as a Z location */ float v1_clipSS[2], v2_clipSS[2]; + float w[3]; /* calc center*/ float cent[2] = {0.0f, 0.0f}; @@ -2128,6 +2131,7 @@ static void project_bucket_clip_face( if ((*tot) < 3) { /* no intersections to speak of */ *tot = 0; + return; } /* now we have all points we need, collect their angles and sort them clockwise */ @@ -2156,16 +2160,15 @@ static void project_bucket_clip_face( for(i=0; i<(*tot); i++) { v2_clipSS[0] = isectVCosSS[i][0] - cent[0]; v2_clipSS[1] = isectVCosSS[i][1] - cent[1]; - isectVCosSS[i][2] = atan2(v1_clipSS[0]*v2_clipSS[1] - v1_clipSS[1]*v2_clipSS[0], v1_clipSS[0]*v2_clipSS[0]+v1_clipSS[1]*v2_clipSS[1]); + isectVCosSS[i][2] = atan2f(v1_clipSS[0]*v2_clipSS[1] - v1_clipSS[1]*v2_clipSS[0], v1_clipSS[0]*v2_clipSS[0]+v1_clipSS[1]*v2_clipSS[1]); } if (flip) qsort(isectVCosSS, *tot, sizeof(float)*3, float_z_sort_flip); else qsort(isectVCosSS, *tot, sizeof(float)*3, float_z_sort); - /* remove doubles */ /* first/last check */ - if (fabs(isectVCosSS[0][0]-isectVCosSS[(*tot)-1][0]) < PROJ_GEOM_TOLERANCE && fabs(isectVCosSS[0][1]-isectVCosSS[(*tot)-1][1]) < PROJ_GEOM_TOLERANCE) { + if (fabsf(isectVCosSS[0][0]-isectVCosSS[(*tot)-1][0]) < PROJ_GEOM_TOLERANCE && fabsf(isectVCosSS[0][1]-isectVCosSS[(*tot)-1][1]) < PROJ_GEOM_TOLERANCE) { (*tot)--; } @@ -2180,8 +2183,8 @@ static void project_bucket_clip_face( while (doubles==TRUE) { doubles = FALSE; for(i=1; i<(*tot); i++) { - if (fabs(isectVCosSS[i-1][0]-isectVCosSS[i][0]) < PROJ_GEOM_TOLERANCE && - fabs(isectVCosSS[i-1][1]-isectVCosSS[i][1]) < PROJ_GEOM_TOLERANCE) + if (fabsf(isectVCosSS[i-1][0]-isectVCosSS[i][0]) < PROJ_GEOM_TOLERANCE && + fabsf(isectVCosSS[i-1][1]-isectVCosSS[i][1]) < PROJ_GEOM_TOLERANCE) { int j; for(j=i+1; j<(*tot); j++) { @@ -2309,6 +2312,19 @@ int IsectPoly2Df(const float pt[2], float uv[][2], const int tot) return 1; } +static int IsectPoly2Df_twoside(const float pt[2], float uv[][2], const int tot) +{ + int i; + int side = (SIDE_OF_LINE(uv[tot-1], uv[0], pt) > 0.0f); + + for (i=1; i<tot; i++) { + if ((SIDE_OF_LINE(uv[i-1], uv[i], pt) > 0.0f) != side) + return 0; + + } + + return 1; +} /* One of the most important function for projectiopn painting, since it selects the pixels to be added into each bucket. * initialize pixels from this face where it intersects with the bucket_index, optionally initialize pixels for removing seams */ @@ -2352,6 +2368,7 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i float uv_clip[8][2]; int uv_clip_tot; const short is_ortho = ps->is_ortho; + const short do_backfacecull = ps->do_backfacecull; vCo[0] = ps->dm_mvert[mf->v1].co; vCo[1] = ps->dm_mvert[mf->v2].co; @@ -2361,9 +2378,20 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i /* Use tf_uv_pxoffset instead of tf->uv so we can offset the UV half a pixel * this is done so we can avoid offseting all the pixels by 0.5 which causes * problems when wrapping negative coords */ - xhalfpx = 0.5f / ibuf_xf; - yhalfpx = 0.5f / ibuf_yf; - + xhalfpx = (0.5f+ (PROJ_GEOM_TOLERANCE/3.0f) ) / ibuf_xf; + yhalfpx = (0.5f+ (PROJ_GEOM_TOLERANCE/4.0f) ) / ibuf_yf; + + /* Note about (PROJ_GEOM_TOLERANCE/x) above... + Needed to add this offset since UV coords are often quads aligned to pixels. + In this case pixels can be exactly between 2 triangles causing nasty + artifacts. + + This workaround can be removed and painting will still work on most cases + but since the first thing most people try is painting onto a quad- better make it work. + */ + + + tf_uv_pxoffset[0][0] = tf->uv[0][0] - xhalfpx; tf_uv_pxoffset[0][1] = tf->uv[0][1] - yhalfpx; @@ -2399,8 +2427,7 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i v1coSS = ps->screenCoords[ (*(&mf->v1 + i1)) ]; v2coSS = ps->screenCoords[ (*(&mf->v1 + i2)) ]; v3coSS = ps->screenCoords[ (*(&mf->v1 + i3)) ]; - - + /* This funtion gives is a concave polyline in UV space from the clipped quad and tri*/ project_bucket_clip_face( is_ortho, bucket_bounds, @@ -2408,8 +2435,7 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i uv1co, uv2co, uv3co, uv_clip, &uv_clip_tot ); - - + /* sometimes this happens, better just allow for 8 intersectiosn even though there should be max 6 */ /* if (uv_clip_tot>6) { @@ -2431,7 +2457,10 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i //uv[0] = (((float)x) + 0.5f) / ibuf->x; uv[0] = (float)x / ibuf_xf; /* use pixel offset UV coords instead */ - if (IsectPoly2Df(uv, uv_clip, uv_clip_tot)) { + /* Note about IsectPoly2Df_twoside, checking the face or uv flipping doesnt work, + * could check the poly direction but better to do this */ + if( (do_backfacecull && IsectPoly2Df(uv, uv_clip, uv_clip_tot)) || + (do_backfacecull==0 && IsectPoly2Df_twoside(uv, uv_clip, uv_clip_tot))) { has_x_isect = has_isect = 1; @@ -2518,7 +2547,6 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i float (*outset_uv)[2] = ps->faceSeamUVs[face_index]; float insetCos[4][3]; /* inset face coords. NOTE!!! ScreenSace for ortho, Worldspace in prespective view */ - float *uv_seam_quad[4]; float fac; float *vCoSS[4]; /* vertex screenspace coords */ @@ -2574,16 +2602,11 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i fac1 = Vec2Lenf(vCoSS[fidx1], bucket_clip_edges[0]) / ftot; fac2 = Vec2Lenf(vCoSS[fidx1], bucket_clip_edges[1]) / ftot; - uv_seam_quad[0] = tf_uv_pxoffset[fidx1]; - uv_seam_quad[1] = tf_uv_pxoffset[fidx2]; - uv_seam_quad[2] = outset_uv[fidx2]; - uv_seam_quad[3] = outset_uv[fidx1]; - - Vec2Lerpf(seam_subsection[0], uv_seam_quad[0], uv_seam_quad[1], fac1); - Vec2Lerpf(seam_subsection[1], uv_seam_quad[0], uv_seam_quad[1], fac2); - - Vec2Lerpf(seam_subsection[2], uv_seam_quad[3], uv_seam_quad[2], fac2); - Vec2Lerpf(seam_subsection[3], uv_seam_quad[3], uv_seam_quad[2], fac1); + Vec2Lerpf(seam_subsection[0], tf_uv_pxoffset[fidx1], tf_uv_pxoffset[fidx2], fac1); + Vec2Lerpf(seam_subsection[1], tf_uv_pxoffset[fidx1], tf_uv_pxoffset[fidx2], fac2); + + Vec2Lerpf(seam_subsection[2], outset_uv[fidx1], outset_uv[fidx2], fac2); + Vec2Lerpf(seam_subsection[3], outset_uv[fidx1], outset_uv[fidx2], fac1); /* if the bucket_clip_edges values Z values was kept we could avoid this * Inset needs to be added so occlusion tests wont hit adjacent faces */ @@ -2636,14 +2659,28 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i /* Only bother calculating the weights if we intersect */ if (ps->do_mask_normal || ps->dm_mtface_clone) { - /* TODO, this is not QUITE correct since UV is not inside the UV's but good enough for seams */ +#if 0 + /* This is not QUITE correct since UV is not inside the UV's but good enough for seams */ if (side) { BarycentricWeights2f(uv, tf_uv_pxoffset[0], tf_uv_pxoffset[2], tf_uv_pxoffset[3], w); } else { BarycentricWeights2f(uv, tf_uv_pxoffset[0], tf_uv_pxoffset[1], tf_uv_pxoffset[2], w); } - +#endif +#if 1 + /* Cheat, we know where we are along the edge so work out the weights from that */ + fac = fac1 + (fac * (fac2-fac1)); + w[0]=w[1]=w[2]= 0.0; + if (side) { + w[fidx1?fidx1-1:0] = fac; + w[fidx2?fidx2-1:0] = 1.0-fac; + } + else { + w[fidx1] = fac; + w[fidx2] = 1.0-fac; + } +#endif } /* a pitty we need to get the worldspace pixel location here */ @@ -3076,7 +3113,7 @@ static void project_paint_begin(ProjPaintState *ps) ps->buckets_x = (int)(ps->screen_width / (((float)ps->brush->size) / PROJ_BUCKET_BRUSH_DIV)); ps->buckets_y = (int)(ps->screen_height / (((float)ps->brush->size) / PROJ_BUCKET_BRUSH_DIV)); - printf("\tscreenspace bucket division x:%d y:%d\n", ps->buckets_x, ps->buckets_y); + /* printf("\tscreenspace bucket division x:%d y:%d\n", ps->buckets_x, ps->buckets_y); */ /* really high values could cause problems since it has to allocate a few * (ps->buckets_x*ps->buckets_y) sized arrays */ @@ -3232,7 +3269,7 @@ static void project_paint_begin(ProjPaintState *ps) image_index = BLI_linklist_index(image_LinkList, tf->tpage); - if (image_index==-1 && BKE_image_get_ibuf((Image *)tf->tpage, NULL)) { /* MemArena dosnt have an append func */ + if (image_index==-1 && BKE_image_get_ibuf(tf->tpage, NULL)) { /* MemArena dosnt have an append func */ BLI_linklist_append(&image_LinkList, tf->tpage); image_index = ps->image_tot; ps->image_tot++; @@ -3254,10 +3291,10 @@ static void project_paint_begin(ProjPaintState *ps) for (node= image_LinkList, i=0; node; node= node->next, i++, projIma++) { projIma->ima = node->link; - // calloced - projIma->touch = 0; + projIma->touch = 0; projIma->ibuf = BKE_image_get_ibuf(projIma->ima, NULL); projIma->partRedrawRect = BLI_memarena_alloc(arena, sizeof(ImagePaintPartialRedraw) * PROJ_BOUNDBOX_SQUARED); - // calloced - memset(projIma->partRedrawRect, 0, sizeof(ImagePaintPartialRedraw) * PROJ_BOUNDBOX_SQUARED); + memset(projIma->partRedrawRect, 0, sizeof(ImagePaintPartialRedraw) * PROJ_BOUNDBOX_SQUARED); } /* we have built the array, discard the linked list */ @@ -3308,6 +3345,7 @@ static void project_paint_end(ProjPaintState *ps) int size = sizeof(UndoTile **) * IMAPAINT_TILE_NUMBER(last_projIma->ibuf->x) * IMAPAINT_TILE_NUMBER(last_projIma->ibuf->y); last_projIma->undoRect = (UndoTile **) BLI_memarena_alloc(arena, size); memset(last_projIma->undoRect, 0, size); + last_projIma->ibuf->userflags |= IB_BITMAPDIRTY; } for (bucket_index = 0; bucket_index < bucket_tot; bucket_index++) { @@ -3375,15 +3413,16 @@ static void project_paint_end(ProjPaintState *ps) MEM_freeN(ps->bucketFaces); MEM_freeN(ps->bucketFlags); +#ifndef PROJ_DEBUG_NOSEAMBLEED if (ps->seam_bleed_px > 0.0f) { MEM_freeN(ps->vertFaces); MEM_freeN(ps->faceSeamFlags); MEM_freeN(ps->faceSeamUVs); } +#endif if (ps->vertFlags) MEM_freeN(ps->vertFlags); - for (a=0; a<ps->thread_tot; a++) { BLI_memarena_free(ps->arena_mt[a]); } @@ -3411,7 +3450,7 @@ static void partial_redraw_array_init(ImagePaintPartialRedraw *pr) static int partial_redraw_array_merge(ImagePaintPartialRedraw *pr, ImagePaintPartialRedraw *pr_other, int tot) { - int touch; + int touch= 0; while (tot--) { pr->x1 = MIN2(pr->x1, pr_other->x1); pr->y1 = MIN2(pr->y1, pr_other->y1); @@ -3539,6 +3578,7 @@ static void blend_color_mix(unsigned char *cp, const unsigned char *cp1, const u cp[0]= (mfac*cp1[0]+fac*cp2[0])/255; cp[1]= (mfac*cp1[1]+fac*cp2[1])/255; cp[2]= (mfac*cp1[2]+fac*cp2[2])/255; + cp[3]= (mfac*cp1[3]+fac*cp2[3])/255; } static void blend_color_mix_float(float *cp, const float *cp1, const float *cp2, const float fac) @@ -3547,6 +3587,7 @@ static void blend_color_mix_float(float *cp, const float *cp1, const float *cp2, cp[0]= mfac*cp1[0] + fac*cp2[0]; cp[1]= mfac*cp1[1] + fac*cp2[1]; cp[2]= mfac*cp1[2] + fac*cp2[2]; + cp[3]= mfac*cp1[3] + fac*cp2[3]; } static void do_projectpaint_clone(ProjPaintState *ps, ProjPixel *projPixel, float *rgba, float alpha, float mask) @@ -3583,8 +3624,8 @@ static void do_projectpaint_smear(ProjPaintState *ps, ProjPixel *projPixel, floa if (project_paint_PickColor(ps, co, NULL, rgba_ub, 1)==0) return; - - ((ProjPixelClone *)projPixel)->clonepx.uint = IMB_blend_color(*projPixel->pixel.uint_pt, *((unsigned int *)rgba_ub), (int)(alpha*mask*255), ps->blend); + /* ((ProjPixelClone *)projPixel)->clonepx.uint = IMB_blend_color(*projPixel->pixel.uint_pt, *((unsigned int *)rgba_ub), (int)(alpha*mask*255), ps->blend); */ + blend_color_mix(((ProjPixelClone *)projPixel)->clonepx.ch, projPixel->pixel.ch_pt, rgba_ub, (int)(alpha*mask*255)); BLI_linklist_prepend_arena(smearPixels, (void *)projPixel, smearArena); } @@ -3597,7 +3638,8 @@ static void do_projectpaint_smear_f(ProjPaintState *ps, ProjPixel *projPixel, fl return; IMAPAINT_FLOAT_RGBA_TO_CHAR(rgba_smear, projPixel->pixel.f_pt); - ((ProjPixelClone *)projPixel)->clonepx.uint = IMB_blend_color(*((unsigned int *)rgba_smear), *((unsigned int *)rgba_ub), (int)(alpha*mask*255), ps->blend); + /* (ProjPixelClone *)projPixel)->clonepx.uint = IMB_blend_color(*((unsigned int *)rgba_smear), *((unsigned int *)rgba_ub), (int)(alpha*mask*255), ps->blend); */ + blend_color_mix(((ProjPixelClone *)projPixel)->clonepx.ch, rgba_smear, (rgba_ub), (int)(alpha*mask*255)); BLI_linklist_prepend_arena(smearPixels_f, (void *)projPixel, smearArena); } @@ -3708,12 +3750,12 @@ static void *do_projectpaint_thread(void *ph_v) projPixel = (ProjPixel *)node->link; - /*dist = Vec2Lenf(projPixel->projCoSS, pos);*/ /* correct but uses a sqrt */ + /*dist = Vec2Lenf(projPixel->projCoSS, pos);*/ /* correct but uses a sqrtf */ dist_nosqrt = Vec2Lenf_nosqrt(projPixel->projCoSS, pos); - /*if (dist < s->brush->size) {*/ /* correct but uses a sqrt */ + /*if (dist < s->brush->size) {*/ /* correct but uses a sqrtf */ if (dist_nosqrt < brush_size_sqared) { - falloff = brush_sample_falloff_noalpha(ps->brush, sqrt(dist_nosqrt)); + falloff = brush_sample_falloff_noalpha(ps->brush, sqrtf(dist_nosqrt)); if (falloff > 0.0f) { if (ps->is_texbrush) { brush_sample_tex(ps->brush, projPixel->projCoSS, rgba); @@ -3802,10 +3844,9 @@ static void *do_projectpaint_thread(void *ph_v) *projPixel->pixel.uint_pt = ((ProjPixelClone *)projPixel)->clonepx.uint; } - for (node= smearPixels_f; node; node= node->next) { /* this wont run for a float image */ + for (node= smearPixels_f; node; node= node->next) { projPixel = node->link; IMAPAINT_CHAR_RGBA_TO_FLOAT(projPixel->pixel.f_pt, ((ProjPixelClone *)projPixel)->clonepx.ch); - node = node->next; } BLI_memarena_free(smearArena); @@ -4261,7 +4302,7 @@ static int imapaint_paint_stroke(ViewContext *vc, ImagePaintState *s, BrushPaint ) { ImBuf *ibuf; - newimage = (Image*)((s->me->mtface+newfaceindex)->tpage); + newimage = (s->me->mtface+newfaceindex)->tpage; ibuf= BKE_image_get_ibuf(newimage, s->sima? &s->sima->iuser: NULL); if(ibuf && ibuf->rect) @@ -4399,6 +4440,7 @@ typedef struct PaintOperation { int first; int prevmouse[2]; + int brush_size_orig; double starttime; ViewContext vc; @@ -4485,6 +4527,8 @@ static int paint_init(bContext *C, wmOperator *op) pop->ps.brush = pop->s.brush; pop->ps.tool = pop->s.tool; pop->ps.blend = pop->s.blend; + + pop->brush_size_orig = pop->ps.brush->size; /* not nice hack because 1 size brushes always fail with projection paint */ } if(pop->mode != PAINT_MODE_2D) { @@ -4504,6 +4548,10 @@ static int paint_init(bContext *C, wmOperator *op) return 0; } + + /* Dont allow brush size below 2 */ + if (pop->ps.brush->size<=1) + pop->ps.brush->size = 2; } /* note, if we have no UVs on the derived mesh, then we must return here */ @@ -4602,8 +4650,10 @@ static void paint_exit(bContext *C, wmOperator *op) imapaint_canvas_free(&pop->s); brush_painter_free(pop->painter); - if(pop->mode == PAINT_MODE_3D_PROJECT) + if(pop->mode == PAINT_MODE_3D_PROJECT) { + pop->ps.brush->size = pop->brush_size_orig; project_paint_end(&pop->ps); + } paint_redraw(C, &pop->s, 1); undo_imagepaint_push_end(); @@ -5186,3 +5236,4 @@ void PAINT_OT_texture_paint_radial_control(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } + diff --git a/source/blender/editors/space_buttons/buttons_header.c b/source/blender/editors/space_buttons/buttons_header.c index 753095eeb53..79284ada483 100644 --- a/source/blender/editors/space_buttons/buttons_header.c +++ b/source/blender/editors/space_buttons/buttons_header.c @@ -172,7 +172,7 @@ void buttons_header_buttons(const bContext *C, ARegion *ar) if(sbuts->pathflag & (1<<BCONTEXT_OBJECT)) uiDefIconButS(block, ROW, B_CONTEXT_SWITCH, ICON_OBJECT_DATA, xco+=XIC, yco, XIC, YIC, &(sbuts->mainb), 0.0, (float)BCONTEXT_OBJECT, 0, 0, "Object"); if(sbuts->pathflag & (1<<BCONTEXT_CONSTRAINT)) - uiDefIconButS(block, ROW, B_CONTEXT_SWITCH, ICON_CONSTRAINT, xco+=XIC, yco, XIC, YIC, &(sbuts->mainb), 0.0, (float)BCONTEXT_CONSTRAINT, 0, 0, "Modifier"); + uiDefIconButS(block, ROW, B_CONTEXT_SWITCH, ICON_CONSTRAINT, xco+=XIC, yco, XIC, YIC, &(sbuts->mainb), 0.0, (float)BCONTEXT_CONSTRAINT, 0, 0, "Constraint"); if(sbuts->pathflag & (1<<BCONTEXT_MODIFIER)) uiDefIconButS(block, ROW, B_CONTEXT_SWITCH, ICON_MODIFIER, xco+=XIC, yco, XIC, YIC, &(sbuts->mainb), 0.0, (float)BCONTEXT_MODIFIER, 0, 0, "Modifier"); if(sbuts->pathflag & (1<<BCONTEXT_DATA)) diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index 01f94741f59..28121de1f1a 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -105,7 +105,7 @@ static void file_select(SpaceFile* sfile, ARegion* ar, const rcti* rect, short v int act_file; short selecting = (val == LEFTMOUSE); FileSelectParams *params = ED_fileselect_get_params(sfile); - FileLayout *layout = ED_fileselect_get_layout(sfile, ar); + // FileLayout *layout = ED_fileselect_get_layout(sfile, ar); int numfiles = filelist_numfiles(sfile->files); diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index f60b6f08348..766dec7c064 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -170,7 +170,7 @@ static int compare_name(const void *a1, const void *a2) if( strcmp(entry1->relname, "..")==0 ) return (-1); if( strcmp(entry2->relname, "..")==0 ) return (1); - return (BLI_strcasecmp(entry1->relname,entry2->relname)); + return (BLI_natstrcmp(entry1->relname,entry2->relname)); } static int compare_date(const void *a1, const void *a2) @@ -201,7 +201,7 @@ static int compare_date(const void *a1, const void *a2) if ( entry1->s.st_mtime < entry2->s.st_mtime) return 1; if ( entry1->s.st_mtime > entry2->s.st_mtime) return -1; - else return BLI_strcasecmp(entry1->relname,entry2->relname); + else return BLI_natstrcmp(entry1->relname,entry2->relname); } static int compare_size(const void *a1, const void *a2) @@ -231,7 +231,7 @@ static int compare_size(const void *a1, const void *a2) if ( entry1->s.st_size < entry2->s.st_size) return 1; if ( entry1->s.st_size > entry2->s.st_size) return -1; - else return BLI_strcasecmp(entry1->relname,entry2->relname); + else return BLI_natstrcmp(entry1->relname,entry2->relname); } static int compare_extension(const void *a1, const void *a2) { diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index 0cede662a9a..378d91c8e32 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -579,7 +579,7 @@ void IMAGE_OT_view_zoom_ratio(wmOperatorType *ot) static char *filesel_imagetype_string(Image *ima) { - char *strp, *str= MEM_callocN(14*32, "menu for filesel"); + char *strp, *str= MEM_callocN(15*32, "menu for filesel"); strp= str; str += sprintf(str, "Save Image as: %%t|"); @@ -588,6 +588,9 @@ static char *filesel_imagetype_string(Image *ima) str += sprintf(str, "PNG %%x%d|", R_PNG); str += sprintf(str, "BMP %%x%d|", R_BMP); str += sprintf(str, "Jpeg %%x%d|", R_JPEG90); +#ifdef WITH_OPENJPEG + str += sprintf(str, "Jpeg 2000 %%x%d|", R_JP2); +#endif str += sprintf(str, "Iris %%x%d|", R_IRIS); if(G.have_libtiff) str += sprintf(str, "Tiff %%x%d|", R_TIFF); diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index 6fe3aa734b4..f7f637670b5 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -35,6 +35,7 @@ #include "MEM_guardedalloc.h" #include "DNA_action_types.h" +#include "DNA_brush_types.h" #include "DNA_color_types.h" #include "DNA_image_types.h" #include "DNA_ipo_types.h" @@ -211,7 +212,7 @@ void snode_handle_recalc(bContext *C, SpaceNode *snode) else if(snode->treetype==NTREE_COMPOSIT) WM_event_add_notifier(C, NC_SCENE|ND_NODES, snode->id); else if(snode->treetype==NTREE_TEXTURE) { - // ntreeTexUpdatePreviews(snode->nodetree); + // ntreeTexUpdatePreviews(snode->nodetree); /* XXX texture nodes should follow shader node methods (ton) */ // XXX BIF_preview_changed(ID_TE); } } @@ -573,7 +574,7 @@ void node_texture_default(Tex *tx) nodeAddLink(tx->nodetree, in, fromsock, out, tosock); ntreeSolveOrder(tx->nodetree); /* needed for pointers */ - ntreeTexUpdatePreviews(tx->nodetree); + ntreeTexUpdatePreviews(tx->nodetree); /* XXX texture nodes should follow shader node methods (ton) */ } /* Here we set the active tree(s), even called for each redraw now, so keep it fast :) */ @@ -607,13 +608,42 @@ void snode_set_context(SpaceNode *snode, Scene *scene) snode->nodetree= scene->nodetree; } else if(snode->treetype==NTREE_TEXTURE) { - if(ob) { - Tex *tx= give_current_texture(ob, ob->actcol); - if(tx) { - snode->from= (ID*)ob; /* please check this; i have no idea what 'from' is. */ - snode->id= &tx->id; - snode->nodetree= tx->nodetree; + Tex *tx= NULL; + + if(snode->texfrom==SNODE_TEX_OBJECT) { + if(ob) { + tx= give_current_texture(ob, ob->actcol); + snode->from= (ID *)ob; + } + } + else if(snode->texfrom==SNODE_TEX_WORLD) { + tx= give_current_world_texture(scene); + snode->from= (ID *)scene->world; + } + else { + MTex *mtex= NULL; + + if(G.f & G_SCULPTMODE) { + Sculpt *sd= scene->toolsettings->sculpt; + if(sd && sd->brush) + if(sd->brush->texact != -1) + mtex= sd->brush->mtex[sd->brush->texact]; } + else { + Brush *br= scene->toolsettings->imapaint.brush; + if(br) + mtex= br->mtex[br->texact]; + } + + if(mtex) { + snode->from= (ID *)scene; + tx= mtex->tex; + } + } + + if(tx) { + snode->id= &tx->id; + snode->nodetree= tx->nodetree; } } @@ -1080,7 +1110,7 @@ static int node_resize_modal(bContext *C, wmOperator *op, wmEvent *event) } // XXX if(snode->nodetree->type == NTREE_TEXTURE) - ntreeTexUpdatePreviews(snode->nodetree); + ntreeTexUpdatePreviews(snode->nodetree); /* XXX texture nodes should follow shader node methods (ton) */ ED_region_tag_redraw(ar); @@ -1626,7 +1656,7 @@ bNode *node_add_node(SpaceNode *snode, Scene *scene, int type, float locx, float if(snode->nodetree->type==NTREE_TEXTURE) { ntreeTexCheckCyclics(snode->edittree); - ntreeTexUpdatePreviews(snode->edittree); + ntreeTexUpdatePreviews(snode->edittree); /* XXX texture nodes should follow shader node methods (ton) */ } return node; diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c index 8373f588fb2..f6cf6de4b00 100644 --- a/source/blender/editors/space_sequencer/sequencer_add.c +++ b/source/blender/editors/space_sequencer/sequencer_add.c @@ -338,6 +338,10 @@ static int sequencer_add_sound_strip_exec(bContext *C, wmOperator *op) RNA_string_get(op->ptr, "filename", filename); + /* XXX if(sfile->flag & FILE_STRINGCODE) { + BLI_makestringcode(G.sce, str); + }*/ + // XXX sound= sound_new_sound(filename); sound= NULL; diff --git a/source/blender/editors/space_sequencer/sequencer_buttons.c b/source/blender/editors/space_sequencer/sequencer_buttons.c index fb42d30e496..f127ab4b0cf 100644 --- a/source/blender/editors/space_sequencer/sequencer_buttons.c +++ b/source/blender/editors/space_sequencer/sequencer_buttons.c @@ -134,5 +134,3 @@ void SEQUENCER_OT_properties(wmOperatorType *ot) ot->flag= 0; } - - diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index 675602a23a0..bd31d8d86ff 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -741,12 +741,21 @@ static void draw_image_seq(Scene *scene, ARegion *ar, SpaceSeq *sseq) static int recursive= 0; float zoom; float zoomx, zoomy; + int render_size = 0; glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); - rectx= (scene->r.size*scene->r.xsch)/100; - recty= (scene->r.size*scene->r.ysch)/100; + render_size = sseq->render_size; + if (render_size == 0) { + render_size = scene->r.size; + } + if (render_size < 0) { + return; + } + + rectx= (render_size*scene->r.xsch)/100; + recty= (render_size*scene->r.ysch)/100; /* BIG PROBLEM: the give_ibuf_seq() can call a rendering, which in turn calls redraws... this shouldn't belong in a window drawing.... @@ -758,13 +767,13 @@ static void draw_image_seq(Scene *scene, ARegion *ar, SpaceSeq *sseq) else { recursive= 1; if (special_seq_update) { - ibuf= give_ibuf_seq_direct(scene, rectx, recty, (scene->r.cfra), special_seq_update); + ibuf= give_ibuf_seq_direct(scene, rectx, recty, (scene->r.cfra), render_size, special_seq_update); } else if (!U.prefetchframes) { // XXX || (G.f & G_PLAYANIM) == 0) { - ibuf= (ImBuf *)give_ibuf_seq(scene, rectx, recty, (scene->r.cfra), sseq->chanshown); + ibuf= (ImBuf *)give_ibuf_seq(scene, rectx, recty, (scene->r.cfra), sseq->chanshown, render_size); } else { - ibuf= (ImBuf *)give_ibuf_seq_threaded(scene, rectx, recty, (scene->r.cfra), sseq->chanshown); + ibuf= (ImBuf *)give_ibuf_seq_threaded(scene, rectx, recty, (scene->r.cfra), sseq->chanshown, render_size); } recursive= 0; @@ -815,6 +824,7 @@ static void draw_image_seq(Scene *scene, ARegion *ar, SpaceSeq *sseq) zoom= SEQ_ZOOM_FAC(sseq->zoom); if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) { + zoom /= render_size / 100.0; zoomx = zoom * ((float)scene->r.xasp / (float)scene->r.yasp); zoomy = zoom; } else { @@ -949,13 +959,21 @@ void seq_viewmove(Scene *scene, ARegion *ar, SpaceSeq *sseq) void drawprefetchseqspace(Scene *scene, ARegion *ar, SpaceSeq *sseq) { int rectx, recty; + int render_size = sseq->render_size; + if (render_size == 0) { + render_size = scene->r.size; + } + if (render_size < 0) { + return; + } - rectx= (scene->r.size*scene->r.xsch)/100; - recty= (scene->r.size*scene->r.ysch)/100; + rectx= (render_size*scene->r.xsch)/100; + recty= (render_size*scene->r.ysch)/100; if(sseq->mainb != SEQ_DRAW_SEQUENCE) { give_ibuf_prefetch_request( - rectx, recty, (scene->r.cfra), sseq->chanshown); + rectx, recty, (scene->r.cfra), sseq->chanshown, + render_size); } } diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 8c3ec96971b..9c3191c93d6 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -160,7 +160,7 @@ void set_last_seq(Scene *scene, Sequence *seq) ed->act_seq= seq; } -Sequence *get_forground_frame_seq(Scene *scene, int frame) +Sequence *get_foreground_frame_seq(Scene *scene, int frame) { Editing *ed= seq_give_editing(scene, FALSE); Sequence *seq, *best_seq=NULL; @@ -879,12 +879,33 @@ static void recurs_del_seq_flag(Scene *scene, ListBase *lb, short flag, short de static Sequence *dupli_seq(Sequence *seq) { Sequence *seqn = MEM_dupallocN(seq); + // XXX animato: ID *id; seq->tmp = seqn; seqn->strip= MEM_dupallocN(seq->strip); - if(seqn->ipo) seqn->ipo->id.us++; + // XXX animato +#if 0 + if (seqn->ipo) { + if (U.dupflag & USER_DUP_IPO) { + id= (ID *)seqn->ipo; + seqn->ipo= copy_ipo(seqn->ipo); + /* we don't need to decrease the number + * of the ipo because we never increase it, + * for example, adduplicate need decrease + * the number but only because copy_object + * call id_us_plus for the ipo block and + * single_ipo_users only work if id->us > 1. + * + * need call ipo_idnew here, for drivers ?? + * - Diego + */ + } + else + seqn->ipo->id.us++; + } +#endif seqn->strip->tstripdata = 0; seqn->strip->tstripdata_startstill = 0; diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index 57d459015dd..d7cb08db414 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -1576,7 +1576,7 @@ static void view3d_panel_bonesketch_spaces(const bContext *C, Panel *pa) uiBlockBeginAlign(block); /* use real flag instead of 1 */ - uiDefButBitC(block, TOG, BONE_SKETCHING, B_REDR, "Use Bone Sketching", 10, yco, 160, 20, &scene->toolsettings->bone_sketching, 0, 0, 0, 0, "Use sketching to create and edit bones"); + uiDefButBitC(block, TOG, BONE_SKETCHING, B_REDR, "Use Bone Sketching", 10, yco, 160, 20, &scene->toolsettings->bone_sketching, 0, 0, 0, 0, "Use sketching to create and edit bones, (Ctrl snaps to mesh volume)"); uiDefButBitC(block, TOG, BONE_SKETCHING_ADJUST, B_REDR, "A", 170, yco, 20, 20, &scene->toolsettings->bone_sketching, 0, 0, 0, 0, "Adjust strokes by drawing near them"); uiDefButBitC(block, TOG, BONE_SKETCHING_QUICK, B_REDR, "Q", 190, yco, 20, 20, &scene->toolsettings->bone_sketching, 0, 0, 0, 0, "Automatically convert and delete on stroke end"); yco -= 20; diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index bbf0279692a..54696fc4508 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -36,6 +36,7 @@ #include "DNA_customdata_types.h" #include "DNA_group_types.h" #include "DNA_key_types.h" +#include "DNA_lamp_types.h" #include "DNA_object_types.h" #include "DNA_space_types.h" #include "DNA_scene_types.h" @@ -1052,7 +1053,7 @@ void backdrawview3d(Scene *scene, ARegion *ar, View3D *v3d) int m; #endif - if(G.f & G_VERTEXPAINT || G.f & G_WEIGHTPAINT); + if(G.f & G_VERTEXPAINT || G.f & G_WEIGHTPAINT || (FACESEL_PAINT_TEST)); else if((G.f & G_TEXTUREPAINT) && scene->toolsettings && (scene->toolsettings->imapaint.flag & IMAGEPAINT_PROJECT_DISABLE)); else if((G.f & G_PARTICLEEDIT) && v3d->drawtype>OB_WIRE && (v3d->flag & V3D_ZBUF_SELECT)); else if(scene->obedit && v3d->drawtype>OB_WIRE && (v3d->flag & V3D_ZBUF_SELECT)); @@ -1727,12 +1728,14 @@ typedef struct View3DShadow { static void gpu_render_lamp_update(Scene *scene, View3D *v3d, Object *ob, Object *par, float obmat[][4], ListBase *shadows) { GPULamp *lamp; + Lamp *la = (Lamp*)ob->data; View3DShadow *shadow; lamp = GPU_lamp_from_blender(scene, ob, par); if(lamp) { GPU_lamp_update(lamp, ob->lay, obmat); + GPU_lamp_update_colors(lamp, la->r, la->g, la->b, la->energy); if((ob->lay & v3d->lay) && GPU_lamp_has_shadow_buffer(lamp)) { shadow= MEM_callocN(sizeof(View3DShadow), "View3DShadow"); diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c index 2d623c9c33d..de0680c6cc1 100644 --- a/source/blender/editors/space_view3d/view3d_header.c +++ b/source/blender/editors/space_view3d/view3d_header.c @@ -5465,7 +5465,7 @@ void view3d_header_buttons(const bContext *C, ARegion *ar) uiBlockBeginAlign(block); if (scene->snap_flag & SCE_SNAP) { - uiDefIconButBitS(block, TOG, SCE_SNAP, B_REDR, ICON_SNAP_GEO,xco,yco,XIC,YIC, &scene->snap_flag, 0, 0, 0, 0, "Use Snap or Grid (Shift Tab)"); + uiDefIconButBitS(block, TOG, SCE_SNAP, B_REDR, ICON_SNAP_GEO,xco,yco,XIC,YIC, &scene->snap_flag, 0, 0, 0, 0, "Snap while Ctrl is held during transform (Shift Tab)"); xco+= XIC; uiDefIconButBitS(block, TOG, SCE_SNAP_ROTATE, B_REDR, ICON_SNAP_NORMAL,xco,yco,XIC,YIC, &scene->snap_flag, 0, 0, 0, 0, "Align rotation with the snapping target"); xco+= XIC; diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.c b/source/blender/editors/uvedit/uvedit_parametrizer.c index 5cc471ebc22..20f74085e52 100644 --- a/source/blender/editors/uvedit/uvedit_parametrizer.c +++ b/source/blender/editors/uvedit/uvedit_parametrizer.c @@ -4374,11 +4374,11 @@ void param_pack(ParamHandle *handle, float margin) } box = boxarray+(i-unpacked); - trans[0] = margin * area; - trans[1] = margin * area; + trans[0] = margin; + trans[1] = margin; p_chart_uv_translate(chart, trans); - box->w += (margin * area) *2; - box->h += (margin * area) *2; + box->w += margin*2; + box->h += margin*2; } } diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index ccc687858f4..49c0dc166c1 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -159,6 +159,7 @@ void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[][4], int *winsize void GPU_lamp_shadow_buffer_unbind(GPULamp *lamp); void GPU_lamp_update(GPULamp *lamp, int lay, float obmat[][4]); +void GPU_lamp_update_colors(GPULamp *lamp, float r, float g, float b, float energy); int GPU_lamp_shadow_layer(GPULamp *lamp); #ifdef __cplusplus diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index 0e123d872fe..f8d0957f70d 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -79,29 +79,24 @@ void GPU_render_text(MTFace *tface, int mode, const char *textstr, int textlen, unsigned int *col, float *v1, float *v2, float *v3, float *v4, int glattrib) { - if (mode & TF_BMFONT) { - Image* ima; - int characters, index, character; + if ((mode & TF_BMFONT) && (textlen>0) && tface->tpage) { + Image* ima = (Image*)tface->tpage; + int index, character; float centerx, centery, sizex, sizey, transx, transy, movex, movey, advance; float advance_tab; - /* multiline */ - float line_start= 0.0f, line_height; + float line_start= 0.0f, line_height; + if (v4) line_height= MAX4(v1[1], v2[1], v3[1], v4[2]) - MIN4(v1[1], v2[1], v3[1], v4[2]); else line_height= MAX3(v1[1], v2[1], v3[1]) - MIN3(v1[1], v2[1], v3[1]); line_height *= 1.2; /* could be an option? */ /* end multiline */ - - characters = textlen; - ima = (Image*)tface->tpage; - if (ima == NULL) - characters = 0; - - // color has been set + + /* color has been set */ if (tface->mode & TF_OBCOL) col= NULL; else if (!col) @@ -116,7 +111,7 @@ void GPU_render_text(MTFace *tface, int mode, advance_tab= advance * 4; /* tab width could also be an option */ - for (index = 0; index < characters; index++) { + for (index = 0; index < textlen; index++) { float uv[4][2]; // lets calculate offset stuff diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index 87703bc73bf..818b67170c7 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -1306,6 +1306,16 @@ void GPU_lamp_update(GPULamp *lamp, int lay, float obmat[][4]) Mat4Invert(lamp->imat, mat); } +void GPU_lamp_update_colors(GPULamp *lamp, float r, float g, float b, float energy) +{ + lamp->energy = energy; + if(lamp->mode & LA_NEG) lamp->energy= -lamp->energy; + + lamp->col[0]= r* lamp->energy; + lamp->col[1]= g* lamp->energy; + lamp->col[2]= b* lamp->energy; +} + static void gpu_lamp_from_blender(Scene *scene, Object *ob, Object *par, Lamp *la, GPULamp *lamp) { float temp, angle, pixsize, wsize; diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h index 8bc1439fd09..1d8035a2358 100644 --- a/source/blender/imbuf/IMB_imbuf.h +++ b/source/blender/imbuf/IMB_imbuf.h @@ -410,6 +410,7 @@ void bilinear_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float void bicubic_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v); void neareast_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v); void bilinear_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v); +void bilinear_interpolation_color_wrap(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v); /** * Change the ordering of the color bytes pointed to by rect from diff --git a/source/blender/imbuf/intern/anim.c b/source/blender/imbuf/intern/anim.c index 30f24d9bbf3..a2dbdfbe483 100644 --- a/source/blender/imbuf/intern/anim.c +++ b/source/blender/imbuf/intern/anim.c @@ -1046,10 +1046,11 @@ struct ImBuf * IMB_anim_absolute(struct anim * anim, int position) { char head[256], tail[256]; unsigned short digits; int pic; - int filter_y = (anim->ib_flags & IB_animdeinterlace); - + int filter_y; if (anim == NULL) return(0); + filter_y = (anim->ib_flags & IB_animdeinterlace); + if (anim->curtype == 0) { ibuf = anim_getnew(anim); if (ibuf == NULL) { diff --git a/source/blender/imbuf/intern/imageprocess.c b/source/blender/imbuf/intern/imageprocess.c index fe7e26eac2b..e4977c77155 100644 --- a/source/blender/imbuf/intern/imageprocess.c +++ b/source/blender/imbuf/intern/imageprocess.c @@ -294,10 +294,79 @@ void bilinear_interpolation_color(struct ImBuf *in, unsigned char *outI, float * b= v-floor(v); a_b= a*b; ma_b= (1.0f-a)*b; a_mb= a*(1.0f-b); ma_mb= (1.0f-a)*(1.0f-b); - outI[0]= ma_mb*row1I[0] + a_mb*row3I[0] + ma_b*row2I[0]+ a_b*row4I[0]; - outI[1]= ma_mb*row1I[1] + a_mb*row3I[1] + ma_b*row2I[1]+ a_b*row4I[1]; - outI[2]= ma_mb*row1I[2] + a_mb*row3I[2] + ma_b*row2I[2]+ a_b*row4I[2]; - outI[3]= ma_mb*row1I[3] + a_mb*row3I[3] + ma_b*row2I[3]+ a_b*row4I[3]; + /* need to add 0.5 to avoid rounding down (causes darken with the smear brush) + * tested with white images and this should not wrap back to zero */ + outI[0]= (ma_mb*row1I[0] + a_mb*row3I[0] + ma_b*row2I[0]+ a_b*row4I[0]) + 0.5f; + outI[1]= (ma_mb*row1I[1] + a_mb*row3I[1] + ma_b*row2I[1]+ a_b*row4I[1]) + 0.5f; + outI[2]= (ma_mb*row1I[2] + a_mb*row3I[2] + ma_b*row2I[2]+ a_b*row4I[2]) + 0.5f; + outI[3]= (ma_mb*row1I[3] + a_mb*row3I[3] + ma_b*row2I[3]+ a_b*row4I[3]) + 0.5f; + } +} + +/* function assumes out to be zero'ed, only does RGBA */ +/* BILINEAR INTERPOLATION */ + +/* Note about wrapping, the u/v still needs to be within the image bounds, + * just the interpolation is wrapped. + * This the same as bilinear_interpolation_color except it wraps rather then using empty and emptyI */ +void bilinear_interpolation_color_wrap(struct ImBuf *in, unsigned char *outI, float *outF, float u, float v) +{ + float *row1, *row2, *row3, *row4, a, b; + unsigned char *row1I, *row2I, *row3I, *row4I; + float a_b, ma_b, a_mb, ma_mb; + int y1, y2, x1, x2; + + + /* ImBuf in must have a valid rect or rect_float, assume this is alredy checked */ + + x1= (int)floor(u); + x2= (int)ceil(u); + y1= (int)floor(v); + y2= (int)ceil(v); + + // sample area entirely outside image? + if (x2<0 || x1>in->x-1 || y2<0 || y1>in->y-1) return; + + /* wrap interpolation pixels - main difference from bilinear_interpolation_color */ + if(x1<0)x1= in->x+x1; + if(y1<0)y1= in->y+y1; + + if(x2>=in->x)x2= x2-in->x; + if(y2>=in->y)y2= y2-in->y; + + if (outF) { + // sample including outside of edges of image + row1= (float *)in->rect_float + in->x * y1 * 4 + 4*x1; + row2= (float *)in->rect_float + in->x * y2 * 4 + 4*x1; + row3= (float *)in->rect_float + in->x * y1 * 4 + 4*x2; + row4= (float *)in->rect_float + in->x * y2 * 4 + 4*x2; + + a= u-floor(u); + b= v-floor(v); + a_b= a*b; ma_b= (1.0f-a)*b; a_mb= a*(1.0f-b); ma_mb= (1.0f-a)*(1.0f-b); + + outF[0]= ma_mb*row1[0] + a_mb*row3[0] + ma_b*row2[0]+ a_b*row4[0]; + outF[1]= ma_mb*row1[1] + a_mb*row3[1] + ma_b*row2[1]+ a_b*row4[1]; + outF[2]= ma_mb*row1[2] + a_mb*row3[2] + ma_b*row2[2]+ a_b*row4[2]; + outF[3]= ma_mb*row1[3] + a_mb*row3[3] + ma_b*row2[3]+ a_b*row4[3]; + } + if (outI) { + // sample including outside of edges of image + row1I= (unsigned char *)in->rect + in->x * y1 * 4 + 4*x1; + row2I= (unsigned char *)in->rect + in->x * y2 * 4 + 4*x1; + row3I= (unsigned char *)in->rect + in->x * y1 * 4 + 4*x2; + row4I= (unsigned char *)in->rect + in->x * y2 * 4 + 4*x2; + + a= u-floor(u); + b= v-floor(v); + a_b= a*b; ma_b= (1.0f-a)*b; a_mb= a*(1.0f-b); ma_mb= (1.0f-a)*(1.0f-b); + + /* need to add 0.5 to avoid rounding down (causes darken with the smear brush) + * tested with white images and this should not wrap back to zero */ + outI[0]= (ma_mb*row1I[0] + a_mb*row3I[0] + ma_b*row2I[0]+ a_b*row4I[0]) + 0.5f; + outI[1]= (ma_mb*row1I[1] + a_mb*row3I[1] + ma_b*row2I[1]+ a_b*row4I[1]) + 0.5f; + outI[2]= (ma_mb*row1I[2] + a_mb*row3I[2] + ma_b*row2I[2]+ a_b*row4I[2]) + 0.5f; + outI[3]= (ma_mb*row1I[3] + a_mb*row3I[3] + ma_b*row2I[3]+ a_b*row4I[3]) + 0.5f; } } diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp index e723609f3ae..32d97d79bd7 100644 --- a/source/blender/imbuf/intern/openexr/openexr_api.cpp +++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp @@ -570,13 +570,17 @@ void IMB_exr_write_channels(void *handle) FrameBuffer frameBuffer; ExrChannel *echan; - for(echan= (ExrChannel *)data->channels.first; echan; echan= echan->next) - frameBuffer.insert (echan->name, Slice (FLOAT, (char *)echan->rect, - echan->xstride*sizeof(float), echan->ystride*sizeof(float))); - - data->ofile->setFrameBuffer (frameBuffer); - data->ofile->writePixels (data->height); - + if(data->channels.first) { + for(echan= (ExrChannel *)data->channels.first; echan; echan= echan->next) + frameBuffer.insert (echan->name, Slice (FLOAT, (char *)echan->rect, + echan->xstride*sizeof(float), echan->ystride*sizeof(float))); + + data->ofile->setFrameBuffer (frameBuffer); + data->ofile->writePixels (data->height); + } + else { + printf("Error: attempt to save MultiLayer without layers.\n"); + } } void IMB_exr_read_channels(void *handle) @@ -861,6 +865,7 @@ static const char *exr_rgba_channelname(InputFile *file, const char *chan) for (ChannelList::ConstIterator i = channels.begin(); i != channels.end(); ++i) { + /* const Channel &channel = i.channel(); */ /* Not used yet */ const char *str= i.name(); int len= strlen(str); if(len) { diff --git a/source/blender/imbuf/intern/rotate.c b/source/blender/imbuf/intern/rotate.c index c04987b3e71..732c06907df 100644 --- a/source/blender/imbuf/intern/rotate.c +++ b/source/blender/imbuf/intern/rotate.c @@ -30,6 +30,7 @@ */ #include "BLI_blenlib.h" +#include "BKE_utildefines.h" #include "imbuf.h" #include "imbuf_patch.h" @@ -94,7 +95,6 @@ void IMB_flipy(struct ImBuf * ibuf) void IMB_flipx(struct ImBuf * ibuf) { short x, y, xr, xl, yi; - unsigned int px; float px_f[4]; if (ibuf == NULL) return; @@ -105,9 +105,7 @@ void IMB_flipx(struct ImBuf * ibuf) if (ibuf->rect) { for(yi=y-1;yi>=0;yi--) { for(xr=x-1, xl=0; xr>=xl; xr--, xl++) { - px = ibuf->rect[(x*yi)+xr]; - ibuf->rect[(x*yi)+xr] = ibuf->rect[(x*yi)+xl]; - ibuf->rect[(x*yi)+xl] = px; + SWAP(unsigned int, ibuf->rect[(x*yi)+xr], ibuf->rect[(x*yi)+xl]); } } } diff --git a/source/blender/imbuf/intern/scaling.c b/source/blender/imbuf/intern/scaling.c index 807b0c84e90..1ccdad05deb 100644 --- a/source/blender/imbuf/intern/scaling.c +++ b/source/blender/imbuf/intern/scaling.c @@ -596,12 +596,12 @@ static void shrink_picture_byte( y_counter = 65536; for (y_src = 0; y_src < src_height; y_src++) { unsigned char* line = src + y_src * 4 * src_width; - uintptr_t weight1y = 65536 - (y_dst & 0xffff); - uintptr_t weight2y = 65536 - weight1y; + uintptr_t weight1y = 65535 - (y_dst & 0xffff); + uintptr_t weight2y = 65535 - weight1y; x_dst = 0; for (x_src = 0; x_src < src_width; x_src++) { - uintptr_t weight1x = 65536 - (x_dst & 0xffff); - uintptr_t weight2x = 65536 - weight1x; + uintptr_t weight1x = 65535 - (x_dst & 0xffff); + uintptr_t weight2x = 65535 - weight1x; uintptr_t x = x_dst >> 16; @@ -609,34 +609,35 @@ static void shrink_picture_byte( w = (weight1y * weight1x) >> 16; - dst_line1[x].r += (line[0] * w) >> 16; - dst_line1[x].g += (line[1] * w) >> 16; - dst_line1[x].b += (line[2] * w) >> 16; - dst_line1[x].a += (line[3] * w) >> 16; + /* ensure correct rounding, without this you get ugly banding, or too low color values (ton) */ + dst_line1[x].r += (line[0] * w + 32767) >> 16; + dst_line1[x].g += (line[1] * w + 32767) >> 16; + dst_line1[x].b += (line[2] * w + 32767) >> 16; + dst_line1[x].a += (line[3] * w + 32767) >> 16; dst_line1[x].weight += w; w = (weight2y * weight1x) >> 16; - dst_line2[x].r += (line[0] * w) >> 16; - dst_line2[x].g += (line[1] * w) >> 16; - dst_line2[x].b += (line[2] * w) >> 16; - dst_line2[x].a += (line[3] * w) >> 16; + dst_line2[x].r += (line[0] * w + 32767) >> 16; + dst_line2[x].g += (line[1] * w + 32767) >> 16; + dst_line2[x].b += (line[2] * w + 32767) >> 16; + dst_line2[x].a += (line[3] * w + 32767) >> 16; dst_line2[x].weight += w; w = (weight1y * weight2x) >> 16; - dst_line1[x+1].r += (line[0] * w) >> 16; - dst_line1[x+1].g += (line[1] * w) >> 16; - dst_line1[x+1].b += (line[2] * w) >> 16; - dst_line1[x+1].a += (line[3] * w) >> 16; + dst_line1[x+1].r += (line[0] * w + 32767) >> 16; + dst_line1[x+1].g += (line[1] * w + 32767) >> 16; + dst_line1[x+1].b += (line[2] * w + 32767) >> 16; + dst_line1[x+1].a += (line[3] * w + 32767) >> 16; dst_line1[x+1].weight += w; w = (weight2y * weight2x) >> 16; - dst_line2[x+1].r += (line[0] * w) >> 16; - dst_line2[x+1].g += (line[1] * w) >> 16; - dst_line2[x+1].b += (line[2] * w) >> 16; - dst_line2[x+1].a += (line[3] * w) >> 16; + dst_line2[x+1].r += (line[0] * w + 32767) >> 16; + dst_line2[x+1].g += (line[1] * w + 32767) >> 16; + dst_line2[x+1].b += (line[2] * w + 32767) >> 16; + dst_line2[x+1].a += (line[3] * w + 32767) >> 16; dst_line2[x+1].weight += w; x_dst += dx_dst; @@ -646,18 +647,18 @@ static void shrink_picture_byte( y_dst += dy_dst; y_counter -= dy_dst; if (y_counter < 0) { + int val; uintptr_t x; struct scale_outpix_byte * temp; y_counter += 65536; for (x=0; x < dst_width; x++) { - uintptr_t f = 0x80000000UL - / dst_line1[x].weight; - *dst++ = (dst_line1[x].r * f) >> 15; - *dst++ = (dst_line1[x].g * f) >> 15; - *dst++ = (dst_line1[x].b * f) >> 15; - *dst++ = (dst_line1[x].a * f) >> 15; + uintptr_t f = 0x80000000UL / dst_line1[x].weight; + *dst++ = (val= (dst_line1[x].r * f) >> 15) > 255 ? 255: val; + *dst++ = (val= (dst_line1[x].g * f) >> 15) > 255 ? 255: val; + *dst++ = (val= (dst_line1[x].b * f) >> 15) > 255 ? 255: val; + *dst++ = (val= (dst_line1[x].a * f) >> 15) > 255 ? 255: val; } memset(dst_line1, 0, dst_width * sizeof(struct scale_outpix_byte)); @@ -667,13 +668,14 @@ static void shrink_picture_byte( } } if (dst - dst_begin < dst_width * dst_height * 4) { + int val; uintptr_t x; for (x = 0; x < dst_width; x++) { uintptr_t f = 0x80000000UL / dst_line1[x].weight; - *dst++ = (dst_line1[x].r * f) >> 15; - *dst++ = (dst_line1[x].g * f) >> 15; - *dst++ = (dst_line1[x].b * f) >> 15; - *dst++ = (dst_line1[x].a * f) >> 15; + *dst++ = (val= (dst_line1[x].r * f) >> 15) > 255 ? 255: val; + *dst++ = (val= (dst_line1[x].g * f) >> 15) > 255 ? 255: val; + *dst++ = (val= (dst_line1[x].b * f) >> 15) > 255 ? 255: val; + *dst++ = (val= (dst_line1[x].a * f) >> 15) > 255 ? 255: val; } } MEM_freeN(dst_line1); @@ -911,6 +913,8 @@ static void q_scale_float(float* in, float* out, int in_width, Should be comparable in speed to the ImBuf ..._fast functions at least for byte-buffers. + NOTE: disabled, due to inacceptable inaccuracy and quality loss, see bug #18609 (ton) + */ static int q_scale_linear_interpolation( struct ImBuf *ibuf, int newx, int newy) @@ -1583,7 +1587,8 @@ struct ImBuf *IMB_scaleImBuf(struct ImBuf * ibuf, short newx, short newy) scalefast_Z_ImBuf(ibuf, newx, newy); /* try to scale common cases in a fast way */ - if (q_scale_linear_interpolation(ibuf, newx, newy)) { + /* disabled, quality loss is inacceptable, see report #18609 (ton) */ + if (0 && q_scale_linear_interpolation(ibuf, newx, newy)) { return ibuf; } diff --git a/source/blender/makesdna/CMakeLists.txt b/source/blender/makesdna/CMakeLists.txt index a1afa37e5e6..1f8ab831ba6 100644 --- a/source/blender/makesdna/CMakeLists.txt +++ b/source/blender/makesdna/CMakeLists.txt @@ -24,4 +24,4 @@ # # ***** END GPL LICENSE BLOCK ***** -SUBDIRS(intern) +ADD_SUBDIRECTORY(intern) diff --git a/source/blender/makesdna/DNA_actuator_types.h b/source/blender/makesdna/DNA_actuator_types.h index aeabae42adf..f713b4a8acc 100644 --- a/source/blender/makesdna/DNA_actuator_types.h +++ b/source/blender/makesdna/DNA_actuator_types.h @@ -107,6 +107,7 @@ typedef struct bObjectActuator { float loc[3], rot[3]; float dloc[3], drot[3]; float linearvelocity[3], angularvelocity[3]; + struct Object *reference; } bObjectActuator; typedef struct bIpoActuator { @@ -214,7 +215,8 @@ typedef struct bTwoDFilterActuator{ }bTwoDFilterActuator; typedef struct bParentActuator { - char pad[4]; + char pad[2]; + short flag; int type; struct Object *ob; } bParentActuator; @@ -482,6 +484,11 @@ typedef struct FreeCamera { /* parentactuator->type */ #define ACT_PARENT_SET 0 #define ACT_PARENT_REMOVE 1 + +/* parentactuator->flag */ +#define ACT_PARENT_COMPOUND 1 +#define ACT_PARENT_GHOST 2 + #endif diff --git a/source/blender/makesdna/DNA_controller_types.h b/source/blender/makesdna/DNA_controller_types.h index 376f95b0145..599bbf9653a 100644 --- a/source/blender/makesdna/DNA_controller_types.h +++ b/source/blender/makesdna/DNA_controller_types.h @@ -43,6 +43,9 @@ typedef struct bExpressionCont { typedef struct bPythonCont { struct Text *text; + char module[64]; + int mode; + int flag; /* only used for debug now */ } bPythonCont; typedef struct bController { @@ -76,6 +79,10 @@ typedef struct bController { #define CONT_DEL 2 #define CONT_NEW 4 #define CONT_MASK 8 +#define CONT_PRIO 16 + +/* pyctrl->flag */ +#define CONT_PY_DEBUG 1 #endif diff --git a/source/blender/makesdna/DNA_object_force.h b/source/blender/makesdna/DNA_object_force.h index 49435000820..718d1a17834 100644 --- a/source/blender/makesdna/DNA_object_force.h +++ b/source/blender/makesdna/DNA_object_force.h @@ -69,7 +69,7 @@ typedef struct PartDeflect { struct Tex *tex; /* Texture of the texture effector */ struct RNG *rng; /* random noise generator for e.g. wind */ float f_noise; /* noise of force (currently used for wind) */ - int pad; + int seed; /* wind noise random seed */ } PartDeflect; typedef struct PointCache { @@ -119,7 +119,8 @@ typedef struct BulletSoftBody { float kAHR; /* Anchors hardness [0,1] */ int collisionflags; /* Vertex/Face or Signed Distance Field(SDF) or Clusters, Soft versus Soft or Rigid */ int numclusteriterations; /* number of iterations to refine collision clusters*/ - + float welding; /* welding limit to remove duplicate/nearby vertices, 0.0..0.01 */ + float margin; /* margin specific to softbody */ } BulletSoftBody; /* BulletSoftBody.flag */ diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 60ca659c19c..febf2fe59cd 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -161,7 +161,7 @@ typedef struct Object { float margin; float max_vel; /* clamp the maximum velocity 0.0 is disabled */ float min_vel; /* clamp the maximum velocity 0.0 is disabled */ - float pad3; /* clamp the maximum velocity 0.0 is disabled */ + float m_contactProcessingThreshold; char dt, dtx; char totcol; /* copy of mesh or curve or meta */ @@ -427,6 +427,7 @@ extern Object workob; #define OB_COLLISION 65536 #define OB_SOFT_BODY 0x20000 #define OB_OCCLUDER 0x40000 +#define OB_SENSOR 0x80000 /* ob->gameflag2 */ #define OB_NEVER_DO_ACTIVITY_CULLING 1 @@ -446,6 +447,7 @@ extern Object workob; #define OB_BODY_TYPE_RIGID 3 #define OB_BODY_TYPE_SOFT 4 #define OB_BODY_TYPE_OCCLUDER 5 +#define OB_BODY_TYPE_SENSOR 6 /* ob->scavisflag */ #define OB_VIS_SENS 1 diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 6f88a98fee8..7391201776e 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -320,9 +320,9 @@ typedef struct RenderData { /* Dome variables */ short domeres, domemode; - short domeangle, pad9; - float domesize; + short domeangle, dometilt; float domeresbuf; + float pad2; struct Text *dometext; } RenderData; @@ -679,6 +679,7 @@ typedef struct Scene { #define R_STAMP_INFO 0x4000 #define R_FULL_SAMPLE 0x8000 #define R_COMP_RERENDER 0x10000 +#define R_RECURS_PROTECTION 0x20000 /* r->stamp */ #define R_STAMP_TIME 0x0001 @@ -762,7 +763,7 @@ typedef struct Scene { #define MAXFRAMEF 300000.0f #define MINFRAME 1 -#define MINFRAMEF 1.0 +#define MINFRAMEF 1.0f /* depricate this! */ #define TESTBASE(v3d, base) ( ((base)->flag & SELECT) && ((base)->lay & v3d->lay) && (((base)->object->restrictflag & OB_RESTRICT_VIEW)==0) ) @@ -835,6 +836,7 @@ typedef struct Scene { /* return flag next_object function */ +#define F_ERROR -1 #define F_START 0 #define F_SCENE 1 #define F_SET 2 diff --git a/source/blender/makesdna/DNA_sensor_types.h b/source/blender/makesdna/DNA_sensor_types.h index 7a358ad0694..8b29ce1338d 100644 --- a/source/blender/makesdna/DNA_sensor_types.h +++ b/source/blender/makesdna/DNA_sensor_types.h @@ -158,7 +158,8 @@ typedef struct bSensor { /* just add here, to avoid align errors... */ short invert; /* Whether or not to invert the output. */ short level; /* Whether the sensor is level base (edge by default) */ - int pad; + short tap; + short pad; } bSensor; typedef struct bJoystickSensor { diff --git a/source/blender/makesdna/DNA_sequence_types.h b/source/blender/makesdna/DNA_sequence_types.h index a5a25adf37b..7fa26aa7572 100644 --- a/source/blender/makesdna/DNA_sequence_types.h +++ b/source/blender/makesdna/DNA_sequence_types.h @@ -78,6 +78,8 @@ typedef struct StripColorBalance { typedef struct StripProxy { char dir[160]; + char file[80]; + struct anim *anim; } StripProxy; typedef struct Strip { @@ -262,6 +264,7 @@ typedef struct SpeedControlVars { #define SEQ_USE_CROP 131072 #define SEQ_USE_COLOR_BALANCE 262144 #define SEQ_USE_PROXY_CUSTOM_DIR 524288 +#define SEQ_USE_PROXY_CUSTOM_FILE 2097152 /* deprecated, dont use a flag anymore*/ /*#define SEQ_ACTIVE 1048576*/ diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 1b58bced0eb..3864bcd0a21 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -155,7 +155,8 @@ typedef struct SpaceSeq { View2D v2d; /* depricated, copied to region */ float xof, yof; /* offset for drawing the image preview */ - short mainb, pad; + short mainb; + short render_size; short chanshown; short zebra; int flag; @@ -344,7 +345,8 @@ typedef struct SpaceNode { float mx, my; /* mousepos for drawing socketless link */ struct bNodeTree *nodetree, *edittree; - int treetype, pad; /* treetype: as same nodetree->type */ + int treetype; /* treetype: as same nodetree->type */ + short texfrom, pad; /* texfrom object, world or brush */ struct bGPdata *gpd; /* grease-pencil data */ } SpaceNode; @@ -353,6 +355,11 @@ typedef struct SpaceNode { #define SNODE_BACKDRAW 2 #define SNODE_DISPGP 4 +/* snode->texfrom */ +#define SNODE_TEX_OBJECT 0 +#define SNODE_TEX_WORLD 1 +#define SNODE_TEX_BRUSH 2 + typedef struct SpaceImaSel { SpaceLink *next, *prev; ListBase regionbase; /* storage of regions for inactive spaces */ diff --git a/source/blender/makesdna/DNA_world_types.h b/source/blender/makesdna/DNA_world_types.h index 8216a0fb800..608a4ca982e 100644 --- a/source/blender/makesdna/DNA_world_types.h +++ b/source/blender/makesdna/DNA_world_types.h @@ -92,6 +92,7 @@ typedef struct World { short mode; short occlusionRes; /* resolution of occlusion Z buffer in pixel */ short physicsEngine; /* here it's aligned */ + short ticrate, maxlogicstep, physubstep, maxphystep; float misi, miststa, mistdist, misthi; diff --git a/source/blender/makesrna/CMakeLists.txt b/source/blender/makesrna/CMakeLists.txt index 879ebccc223..75f79fbdc3b 100644 --- a/source/blender/makesrna/CMakeLists.txt +++ b/source/blender/makesrna/CMakeLists.txt @@ -24,4 +24,4 @@ # # ***** END GPL LICENSE BLOCK ***** -SUBDIRS(intern) +ADD_SUBDIRECTORY(intern) diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 5145522a544..deda1a15b70 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -656,8 +656,8 @@ void RNA_enum_set(PointerRNA *ptr, const char *name, int value); int RNA_enum_is_equal(PointerRNA *ptr, const char *name, const char *enumname); /* lower level functions that donr use a PointerRNA */ -int RNA_enum_value_from_id(EnumPropertyItem *item, const char *identifier, int *value); -int RNA_enum_id_from_value(EnumPropertyItem *item, int value, const char **identifier); +int RNA_enum_value_from_id(const EnumPropertyItem *item, const char *identifier, int *value); +int RNA_enum_id_from_value(const EnumPropertyItem *item, int value, const char **identifier); void RNA_string_get(PointerRNA *ptr, const char *name, char *value); char *RNA_string_get_alloc(PointerRNA *ptr, const char *name, char *fixedbuf, int fixedlen); diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index c8037c1553a..870fa4d9aa3 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -2032,7 +2032,7 @@ int RNA_enum_is_equal(PointerRNA *ptr, const char *name, const char *enumname) } } -int RNA_enum_value_from_id(EnumPropertyItem *item, const char *identifier, int *value) +int RNA_enum_value_from_id(const EnumPropertyItem *item, const char *identifier, int *value) { for( ; item->identifier; item++) { if(strcmp(item->identifier, identifier)==0) { @@ -2044,7 +2044,7 @@ int RNA_enum_value_from_id(EnumPropertyItem *item, const char *identifier, int * return 0; } -int RNA_enum_id_from_value(EnumPropertyItem *item, int value, const char **identifier) +int RNA_enum_id_from_value(const EnumPropertyItem *item, int value, const char **identifier) { for( ; item->identifier; item++) { if(item->value==value) { diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c index d0730cd7bb0..a98bc41d129 100644 --- a/source/blender/makesrna/intern/rna_constraint.c +++ b/source/blender/makesrna/intern/rna_constraint.c @@ -904,8 +904,8 @@ static void rna_def_constraint_rigid_body_joint(BlenderRNA *brna) static EnumPropertyItem pivot_items[] = { {CONSTRAINT_RB_BALL, "BALL", "Ball", ""}, {CONSTRAINT_RB_HINGE, "HINGE", "Hinge", ""}, - {CONSTRAINT_RB_CONETWIST, "CONETWIST", "Cone Twist", ""}, - {CONSTRAINT_RB_GENERIC6DOF, "GENERIC", "Generic 6 DoF", ""}, + {CONSTRAINT_RB_CONETWIST, "CONE_TWIST", "Cone Twist", ""}, + {CONSTRAINT_RB_GENERIC6DOF, "GENERIC_6_DOF", "Generic 6 DoF", ""}, {0, NULL, NULL, NULL}}; srna= RNA_def_struct(brna, "RigidBodyJointConstraint", "Constraint"); diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index dcdd749be6e..08eca7b0528 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -976,12 +976,12 @@ static StructRNA *rna_def_object(BlenderRNA *brna) prop= RNA_def_property(srna, "time_offset", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "sf"); RNA_def_property_range(prop, -MAXFRAMEF, MAXFRAMEF); - RNA_def_property_ui_text(prop, "Time Offset", "Animation offset in frames for ipo's and dupligroup instances."); + RNA_def_property_ui_text(prop, "Time Offset", "Animation offset in frames for IPO's and dupligroup instances."); RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_update"); prop= RNA_def_property(srna, "time_offset_edit", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "ipoflag", OB_OFFS_OB); - RNA_def_property_ui_text(prop, "Time Offset Edit", "Use time offset when inserting keys and display time offset for ipo and action views."); + RNA_def_property_ui_text(prop, "Time Offset Edit", "Use time offset when inserting keys and display time offset for IPO and action views."); prop= RNA_def_property(srna, "time_offset_parent", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "ipoflag", OB_OFFS_PARENT); diff --git a/source/blender/makesrna/intern/rna_object_force.c b/source/blender/makesrna/intern/rna_object_force.c index afa45834eb0..4f4530e0424 100644 --- a/source/blender/makesrna/intern/rna_object_force.c +++ b/source/blender/makesrna/intern/rna_object_force.c @@ -233,6 +233,10 @@ static void rna_def_field(BlenderRNA *brna) RNA_def_property_range(prop, 0.0f, 10.0f); RNA_def_property_ui_text(prop, "Noise", "Noise of the wind force"); + prop= RNA_def_property(srna, "seed", PROP_INT, PROP_UNSIGNED); + RNA_def_property_range(prop, 1, 128); + RNA_def_property_ui_text(prop, "Seed", "Seed of the wind noise"); + /* Boolean */ prop= RNA_def_property(srna, "use_min_distance", PROP_BOOLEAN, PROP_NONE); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_normalize.c b/source/blender/nodes/intern/CMP_nodes/CMP_normalize.c index 846aec490c2..15f3148b54c 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_normalize.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_normalize.c @@ -55,6 +55,7 @@ static void do_normalize(bNode *node, float *out, float *src, float *min, float } } +/* The code below assumes all data is inside range +- this, and that input buffer is single channel */ #define BLENDER_ZMAX 10000.0f static void node_composit_exec_normalize(void *data, bNode *node, bNodeStack **in, bNodeStack **out) @@ -63,7 +64,7 @@ static void node_composit_exec_normalize(void *data, bNode *node, bNodeStack **i /* stack order out: valbuf */ if(out[0]->hasoutput==0) return; - /* input no image? then only value operation */ + /* Input has no image buffer? Then pass the value */ if(in[0]->data==NULL) { QUATCOPY(out[0]->vec, in[0]->vec); } @@ -78,18 +79,20 @@ static void node_composit_exec_normalize(void *data, bNode *node, bNodeStack **i CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1); /* allocs */ for (val = cbuf->rect; tot; tot--, val++) { - if ((*val > max) && (*val < BLENDER_ZMAX)) { + if ((*val > max) && (*val <= BLENDER_ZMAX)) { max = *val; } - if (*val < min) { + if ((*val < min) && (*val >= -BLENDER_ZMAX)) { min = *val; } } - mult = 1.0f/(max-min); - - printf("min %f max %f\n", min, max); - - composit3_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, NULL, &min, NULL, &mult, do_normalize, CB_VAL, CB_VAL, CB_VAL); + /* In the rare case of flat buffer, which would cause a divide by 0, just pass the input to the output */ + if ((max-min) != 0.0f) { + mult = 1.0f/(max-min); + composit3_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, NULL, &min, NULL, &mult, do_normalize, CB_VAL, CB_VAL, CB_VAL); + } else { + memcpy(stackbuf->rect, cbuf->rect, sizeof(float) * cbuf->x * cbuf->y); + } out[0]->data= stackbuf; } diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_scale.c b/source/blender/nodes/intern/CMP_nodes/CMP_scale.c index cc6f9249495..ee3607c11f6 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_scale.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_scale.c @@ -65,8 +65,8 @@ static void node_composit_exec_scale(void *data, bNode *node, bNodeStack **in, b newx = cbuf->x * (rd->size / 100.0f); newy = cbuf->y * (rd->size / 100.0f); } else { /* CMP_SCALE_ABSOLUTE */ - newx= (int)in[1]->vec[0]; - newy= (int)in[2]->vec[0]; + newx= MAX2((int)in[1]->vec[0], 1); + newy= MAX2((int)in[2]->vec[0], 1); } newx= MIN2(newx, CMP_SCALE_MAX); newy= MIN2(newy, CMP_SCALE_MAX); diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c b/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c index fedca8f9086..fbc56dfcc83 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c +++ b/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c @@ -33,6 +33,11 @@ #include <eval.h> #endif +/* TODO, support python3.x */ +#if PY_VERSION_HEX >= 0x03000000 +#define DISABLE_PYTHON 1 +#endif + #include "DNA_text_types.h" #include "BKE_text.h" #include "BKE_utildefines.h" @@ -56,13 +61,15 @@ static void node_dynamic_free_storage_cb(bNode *node); #ifndef DISABLE_PYTHON static PyObject *init_dynamicdict(void) { - PyObject *newscriptdict; + PyObject *newscriptdict, *item; PyGILState_STATE gilstate = PyGILState_Ensure(); newscriptdict= PyDict_New(); PyDict_SetItemString(newscriptdict, "__builtins__", PyEval_GetBuiltins()); - EXPP_dict_set_item_str(newscriptdict, "__name__", PyString_FromString("__main__")); + item= PyString_FromString("__main__"); + PyDict_SetItemString(newscriptdict, "__name__", item); + Py_DECREF(item); PyGILState_Release(gilstate); diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_material.c b/source/blender/nodes/intern/SHD_nodes/SHD_material.c index c0a2534ac4a..69c2c0a345c 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_material.c +++ b/source/blender/nodes/intern/SHD_nodes/SHD_material.c @@ -130,7 +130,9 @@ static void node_shader_exec_material(void *data, bNode *node, bNodeStack **in, nodestack_get_vec(&shi->translucency, SOCK_VALUE, in[MAT_IN_TRANSLUCENCY]); } + shi->nodes= 1; /* temp hack to prevent trashadow recursion */ node_shader_lamp_loop(shi, &shrnode); /* clears shrnode */ + shi->nodes= 0; /* write to outputs */ if(node->custom1 & SH_NODE_MAT_DIFF) { diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_math.c b/source/blender/nodes/intern/SHD_nodes/SHD_math.c index 050c2cdcc95..645f95686d7 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_math.c +++ b/source/blender/nodes/intern/SHD_nodes/SHD_math.c @@ -197,7 +197,7 @@ bNodeStack **out) static int gpu_shader_math(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *out) { static char *names[] = {"math_add", "math_subtract", "math_multiply", - "math_divide", "math_sine", "math_cosine", "math_tangnet", "math_asin", + "math_divide", "math_sine", "math_cosine", "math_tangent", "math_asin", "math_acos", "math_atan", "math_pow", "math_log", "math_min", "math_max", "math_round", "math_less_than", "math_greater_than"}; diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_vectMath.c b/source/blender/nodes/intern/SHD_nodes/SHD_vectMath.c index 96db8db18a6..8a73a318f70 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_vectMath.c +++ b/source/blender/nodes/intern/SHD_nodes/SHD_vectMath.c @@ -101,7 +101,7 @@ static void node_shader_exec_vect_math(void *data, bNode *node, bNodeStack **in, static int gpu_shader_vect_math(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *out) { - static char *names[] = {"vec_math_add", "vec_math_subtract", + static char *names[] = {"vec_math_add", "vec_math_sub", "vec_math_average", "vec_math_dot", "vec_math_cross", "vec_math_normalize"}; diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_bricks.c b/source/blender/nodes/intern/TEX_nodes/TEX_bricks.c index c9fa3528b02..80cbd6188ee 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_bricks.c +++ b/source/blender/nodes/intern/TEX_nodes/TEX_bricks.c @@ -49,12 +49,21 @@ static void init(bNode *node) { node->custom4 = 1.0; /* squash */ } +static float noise(int n) /* fast integer noise */ +{ + int nn; + n = (n >> 13) ^ n; + nn = (n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff; + return 0.5f * ((float)nn / 1073741824.0f); +} + static void colorfn(float *out, float *coord, bNode *node, bNodeStack **in, short thread) { float x = coord[0]; float y = coord[1]; - float bricknum, rownum, offset = 0; + int bricknum, rownum; + float offset = 0; float ins_x, ins_y; float tint; @@ -71,20 +80,19 @@ static void colorfn(float *out, float *coord, bNode *node, bNodeStack **in, shor tex_input_rgba(bricks2, in[1], coord, thread); tex_input_rgba(mortar, in[2], coord, thread); - rownum = floor(y / row_height); + rownum = (int)floor(y / row_height); if( node->custom1 && node->custom2 ) { brick_width *= ((int)(rownum) % node->custom2 ) ? 1.0f : node->custom4; /* squash */ offset = ((int)(rownum) % node->custom1 ) ? 0 : (brick_width*node->custom3); /* offset */ } - bricknum = floor((x+offset) / brick_width); + bricknum = (int)floor((x+offset) / brick_width); ins_x = (x+offset) - brick_width*bricknum; ins_y = y - row_height*rownum; - srand( (123456*rownum) + bricknum ); - tint = rand() / (float)RAND_MAX + bias; + tint = noise((rownum << 16) + (bricknum & 0xFFFF)) + bias; CLAMP(tint,0.0f,1.0f); if( ins_x < mortar_thickness || ins_y < mortar_thickness || diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_translate.c b/source/blender/nodes/intern/TEX_nodes/TEX_translate.c index 0e903301789..cadd27612f4 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_translate.c +++ b/source/blender/nodes/intern/TEX_nodes/TEX_translate.c @@ -31,7 +31,7 @@ static bNodeSocketType inputs[]= { { SOCK_RGBA, 1, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VECTOR, 1, "Offset", 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f }, + { SOCK_VECTOR, 1, "Offset", 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f }, { -1, 0, "" } }; diff --git a/source/blender/render/extern/include/RE_shader_ext.h b/source/blender/render/extern/include/RE_shader_ext.h index 2cee2673a26..0ad48fe97a9 100644 --- a/source/blender/render/extern/include/RE_shader_ext.h +++ b/source/blender/render/extern/include/RE_shader_ext.h @@ -171,6 +171,7 @@ typedef struct ShadeInput /* from initialize, part or renderlayer */ short do_preview; /* for nodes, in previewrender */ short thread, sample; /* sample: ShadeSample array index */ + short nodes; /* indicate node shading, temp hack to prevent recursion */ unsigned int lay; int layflag, passflag, combinedflag; diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 996bf2c3b19..199ff5dbb43 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -1760,7 +1760,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem if(parent->num < psmd->dm->getNumFaces(psmd->dm)) num = parent->num; - get_particle_uvco_mcol(part->from, psmd->dm, pa->fuv, num, &sd); + get_particle_uvco_mcol(part->from, psmd->dm, parent->fuv, num, &sd); } dosimplify = psys_render_simplify_params(psys, cpa, simplify); diff --git a/source/blender/render/intern/source/occlusion.c b/source/blender/render/intern/source/occlusion.c index c75de189b10..1cbf2523156 100644 --- a/source/blender/render/intern/source/occlusion.c +++ b/source/blender/render/intern/source/occlusion.c @@ -1633,7 +1633,7 @@ void sample_occ(Render *re, ShadeInput *shi) sample_occ_surface(shi); } /* try to get result from the cache if possible */ - else if(!sample_occ_cache(tree, shi->co, shi->vno, shi->xs, shi->ys, shi->thread, shi->ao)) { + else if(shi->depth!=0 || !sample_occ_cache(tree, shi->co, shi->vno, shi->xs, shi->ys, shi->thread, shi->ao)) { /* no luck, let's sample the occlusion */ exclude.obi= shi->obi - re->objectinstance; exclude.facenr= shi->vlr->index; diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index e464cbd1f43..07560edb76b 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -1667,6 +1667,42 @@ static void do_render_3d(Render *re) RE_Database_Free(re); } +/* called by blur loop, accumulate RGBA key alpha */ +static void addblur_rect_key(RenderResult *rr, float *rectf, float *rectf1, float blurfac) +{ + float mfac= 1.0f - blurfac; + int a, b, stride= 4*rr->rectx; + int len= stride*sizeof(float); + + for(a=0; a<rr->recty; a++) { + if(blurfac==1.0f) { + memcpy(rectf, rectf1, len); + } + else { + float *rf= rectf, *rf1= rectf1; + + for( b= rr->rectx; b>0; b--, rf+=4, rf1+=4) { + if(rf1[3]<0.01f) + rf[3]= mfac*rf[3]; + else if(rf[3]<0.01f) { + rf[0]= rf1[0]; + rf[1]= rf1[1]; + rf[2]= rf1[2]; + rf[3]= blurfac*rf1[3]; + } + else { + rf[0]= mfac*rf[0] + blurfac*rf1[0]; + rf[1]= mfac*rf[1] + blurfac*rf1[1]; + rf[2]= mfac*rf[2] + blurfac*rf1[2]; + rf[3]= mfac*rf[3] + blurfac*rf1[3]; + } + } + } + rectf+= stride; + rectf1+= stride; + } +} + /* called by blur loop, accumulate renderlayers */ static void addblur_rect(RenderResult *rr, float *rectf, float *rectf1, float blurfac, int channels) { @@ -1690,8 +1726,9 @@ static void addblur_rect(RenderResult *rr, float *rectf, float *rectf1, float bl } } + /* called by blur loop, accumulate renderlayers */ -static void merge_renderresult_blur(RenderResult *rr, RenderResult *brr, float blurfac) +static void merge_renderresult_blur(RenderResult *rr, RenderResult *brr, float blurfac, int key_alpha) { RenderLayer *rl, *rl1; RenderPass *rpass, *rpass1; @@ -1700,8 +1737,12 @@ static void merge_renderresult_blur(RenderResult *rr, RenderResult *brr, float b for(rl= rr->layers.first; rl && rl1; rl= rl->next, rl1= rl1->next) { /* combined */ - if(rl->rectf && rl1->rectf) - addblur_rect(rr, rl->rectf, rl1->rectf, blurfac, 4); + if(rl->rectf && rl1->rectf) { + if(key_alpha) + addblur_rect_key(rr, rl->rectf, rl1->rectf, blurfac); + else + addblur_rect(rr, rl->rectf, rl1->rectf, blurfac, 4); + } /* passes are allocated in sync */ rpass1= rl1->passes.first; @@ -1731,7 +1772,7 @@ static void do_render_blur_3d(Render *re) blurfac= 1.0f/(float)(re->r.osa-blur); - merge_renderresult_blur(rres, re->result, blurfac); + merge_renderresult_blur(rres, re->result, blurfac, re->r.alphamode & R_ALPHAKEY); if(re->test_break(re->tbh)) break; } diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index e89cf20e4b1..33b58cf9751 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -262,13 +262,15 @@ static void shade_ray(Isect *is, ShadeInput *shi, ShadeResult *shr) shade_input_set_shade_texco(shi); - if(is->mode==RE_RAY_SHADOW_TRA) - if(shi->mat->nodetree && shi->mat->use_nodes) { + if(is->mode==RE_RAY_SHADOW_TRA) { + /* temp hack to prevent recursion */ + if(shi->nodes==0 && shi->mat->nodetree && shi->mat->use_nodes) { ntreeShaderExecTree(shi->mat->nodetree, shi, shr); shi->mat= vlr->mat; /* shi->mat is being set in nodetree */ } else shade_color(shi, shr); + } else { if(shi->mat->nodetree && shi->mat->use_nodes) { ntreeShaderExecTree(shi->mat->nodetree, shi, shr); @@ -1273,7 +1275,7 @@ static void addAlphaLight(float *shadfac, float *col, float alpha, float filter) shadfac[3]= (1.0f-alpha)*shadfac[3]; } -static void ray_trace_shadow_tra(Isect *is, int depth, int traflag) +static void ray_trace_shadow_tra(Isect *is, ShadeInput *origshi, int depth, int traflag) { /* ray to lamp, find first face that intersects, check alpha properties, if it has col[3]>0.0f continue. so exit when alpha is full */ @@ -1290,16 +1292,15 @@ static void ray_trace_shadow_tra(Isect *is, int depth, int traflag) /* end warning! - Campbell */ shi.depth= 1; /* only used to indicate tracing */ - shi.mask= 1; - - /*shi.osatex= 0; - shi.thread= shi.sample= 0; - shi.lay= 0; - shi.passflag= 0; - shi.combinedflag= 0; - shi.do_preview= 0; - shi.light_override= NULL; - shi.mat_override= NULL;*/ + shi.mask= origshi->mask; + shi.thread= origshi->thread; + shi.passflag= SCE_PASS_COMBINED; + shi.combinedflag= 0xFFFFFF; /* ray trace does all options */ + + shi.xs= origshi->xs; + shi.ys= origshi->ys; + shi.lay= origshi->lay; + shi.nodes= origshi->nodes; shade_ray(is, &shi, &shr); if (traflag & RAY_TRA) @@ -1315,7 +1316,7 @@ static void ray_trace_shadow_tra(Isect *is, int depth, int traflag) is->oborig= RAY_OBJECT_SET(&R, shi.obi); is->faceorig= (RayFace*)shi.vlr; - ray_trace_shadow_tra(is, depth-1, traflag | RAY_TRA); + ray_trace_shadow_tra(is, origshi, depth-1, traflag | RAY_TRA); } } } @@ -1943,7 +1944,7 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float * isec->col[0]= isec->col[1]= isec->col[2]= 1.0f; isec->col[3]= 1.0f; - ray_trace_shadow_tra(isec, DEPTH_SHADOW_TRA, 0); + ray_trace_shadow_tra(isec, shi, DEPTH_SHADOW_TRA, 0); shadfac[0] += isec->col[0]; shadfac[1] += isec->col[1]; shadfac[2] += isec->col[2]; @@ -2041,7 +2042,7 @@ static void ray_shadow_jitter(ShadeInput *shi, LampRen *lar, float *lampco, floa isec->col[0]= isec->col[1]= isec->col[2]= 1.0f; isec->col[3]= 1.0f; - ray_trace_shadow_tra(isec, DEPTH_SHADOW_TRA, 0); + ray_trace_shadow_tra(isec, shi, DEPTH_SHADOW_TRA, 0); shadfac[0] += isec->col[0]; shadfac[1] += isec->col[1]; shadfac[2] += isec->col[2]; @@ -2122,7 +2123,7 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac) isec.col[0]= isec.col[1]= isec.col[2]= 1.0f; isec.col[3]= 1.0f; - ray_trace_shadow_tra(&isec, DEPTH_SHADOW_TRA, 0); + ray_trace_shadow_tra(&isec, shi, DEPTH_SHADOW_TRA, 0); QUATCOPY(shadfac, isec.col); } else if(RE_ray_tree_intersect(R.raytree, &isec)) shadfac[3]= 0.0f; diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index 27dd43a4ef9..165cb88de71 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -2542,8 +2542,12 @@ static void shade_tface(BakeShade *bs) /* get pixel level vertex coordinates */ for(a=0; a<4; a++) { - vec[a][0]= tface->uv[a][0]*(float)bs->rectx - 0.5f; - vec[a][1]= tface->uv[a][1]*(float)bs->recty - 0.5f; + /* Note, workaround for pixel aligned UVs which are common and can screw up our intersection tests + * where a pixel gets inbetween 2 faces or the middle of a quad, + * camera aligned quads also have this problem but they are less common. + * Add a small offset to the UVs, fixes bug #18685 - Campbell */ + vec[a][0]= tface->uv[a][0]*(float)bs->rectx - (0.5f + 0.001); + vec[a][1]= tface->uv[a][1]*(float)bs->recty - (0.5f + 0.002); } /* UV indices have to be corrected for possible quad->tria splits */ diff --git a/source/blender/render/intern/source/shadeoutput.c b/source/blender/render/intern/source/shadeoutput.c index 4c627056c1d..130cda9f107 100644 --- a/source/blender/render/intern/source/shadeoutput.c +++ b/source/blender/render/intern/source/shadeoutput.c @@ -1005,6 +1005,7 @@ static void do_specular_ramp(ShadeInput *shi, float is, float t, float *spec) } /* pure AO, check for raytrace and world should have been done */ +/* preprocess, textures were not done, don't use shi->amb for that reason */ void ambient_occlusion(ShadeInput *shi) { if((R.wrld.ao_gather_method == WO_AOGATHER_APPROX) && shi->mat->amb!=0.0f) @@ -1020,8 +1021,8 @@ void ambient_occlusion(ShadeInput *shi) void ambient_occlusion_to_diffuse(ShadeInput *shi, float *diff) { if((R.r.mode & R_RAYTRACE) || R.wrld.ao_gather_method == WO_AOGATHER_APPROX) { - if(shi->mat->amb!=0.0f) { - float f= R.wrld.aoenergy*shi->mat->amb; + if(shi->amb!=0.0f) { + float f= R.wrld.aoenergy*shi->amb; if (R.wrld.aomix==WO_AOADDSUB) { diff[0] = 2.0f*shi->ao[0]-1.0f; diff --git a/source/blender/render/intern/source/texture.c b/source/blender/render/intern/source/texture.c index afe732d885b..16f876fdd38 100644 --- a/source/blender/render/intern/source/texture.c +++ b/source/blender/render/intern/source/texture.c @@ -2029,6 +2029,10 @@ void do_material_tex(ShadeInput *shi) shi->amb= texture_value_blend(mtex->def_var, shi->amb, texres.tin, varfac, mtex->blendtype, flip); if(shi->amb<0.0) shi->amb= 0.0; else if(shi->amb>1.0) shi->amb= 1.0; + + shi->ambr= shi->amb*R.wrld.ambr; + shi->ambg= shi->amb*R.wrld.ambg; + shi->ambb= shi->amb*R.wrld.ambb; } } } diff --git a/source/blender/windowmanager/intern/wm_cursors.c b/source/blender/windowmanager/intern/wm_cursors.c index 2c7493a51ab..627aebbe875 100644 --- a/source/blender/windowmanager/intern/wm_cursors.c +++ b/source/blender/windowmanager/intern/wm_cursors.c @@ -55,7 +55,12 @@ static GHOST_TStandardCursor convert_cursor(int curs) case CURSOR_FACESEL: return GHOST_kStandardCursorRightArrow; case CURSOR_WAIT: return GHOST_kStandardCursorWait; case CURSOR_EDIT: return GHOST_kStandardCursorCrosshair; - case CURSOR_HELP: return GHOST_kStandardCursorHelp; + case CURSOR_HELP: +#ifdef __APPLE__ + return GHOST_kStandardCursorLeftRight; +#else + return GHOST_kStandardCursorHelp; +#endif case CURSOR_X_MOVE: return GHOST_kStandardCursorLeftRight; case CURSOR_Y_MOVE: return GHOST_kStandardCursorUpDown; case CURSOR_PENCIL: return GHOST_kStandardCursorPencil; |