From 253de0ed86f273d0032acbbd0b8237a358b35cbd Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 30 Mar 2010 12:01:17 +0000 Subject: [PATCH] * Assign weight from bones in weight paint mode now respects paint face mask, also avoid making vertex groups if they will not be filled. * Add back image pin option in image editor header. * Fix deep shadow not respecting Cast Buffer Shadows option. * Tangent space normal map baking should work again now. * Fix a problem with particle duplis, due to own bugfix for #20350, the problem for that seems to be in dupliverts, not particles. * Fix external multires data link getting lost on exiting editmode. (commits 27776,27777,27830,27840,27841,27862 by Brecht from render25 branch) --- release/scripts/ui/space_image.py | 1 + source/blender/blenkernel/intern/anim.c | 10 +++----- source/blender/blenkernel/intern/customdata.c | 11 +++++--- .../blender/editors/armature/editarmature.c | 17 +++++++------ .../blender/editors/armature/meshlaplacian.c | 25 +++++++++++++++++-- source/blender/makesrna/intern/rna_space.c | 1 + .../render/extern/include/RE_raytrace.h | 1 + .../render/intern/raytrace/rayobject.cpp | 16 ++++++++++-- .../blender/render/intern/source/rayshade.c | 2 +- .../blender/render/intern/source/rendercore.c | 22 +++------------- source/blender/render/intern/source/zbuf.c | 5 +++- 11 files changed, 69 insertions(+), 42 deletions(-) diff --git a/release/scripts/ui/space_image.py b/release/scripts/ui/space_image.py index 4968c083685..2f7a64790b4 100644 --- a/release/scripts/ui/space_image.py +++ b/release/scripts/ui/space_image.py @@ -276,6 +276,7 @@ class IMAGE_HT_header(bpy.types.Header): sub.menu("IMAGE_MT_uvs") layout.template_ID(sima, "image", new="image.new") + layout.prop(sima, "image_pin", text="") # uv editing if show_uvedit: diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index 1465f4550f5..e26072deb76 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -1073,7 +1073,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p ParticleCacheKey *cache; float ctime, pa_time, scale = 1.0f; float tmat[4][4], mat[4][4], pamat[4][4], vec[3], size=0.0; - float (*obmat)[4], (*oldobmat)[4], recurs_mat[4][4]; + float (*obmat)[4], (*oldobmat)[4]; int lay, a, b, counter, hair = 0; int totpart, totchild, totgroup=0, pa_num; @@ -1090,10 +1090,6 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p if(!psys_check_enabled(par, psys)) return; - /* particles are already in world space, don't want the object mat twice */ - if(par_space_mat) - mul_m4_m4m4(recurs_mat, psys->imat, par_space_mat); - ctime = bsystem_time(scene, par, (float)scene->r.cfra, 0.0); totpart = psys->totpart; @@ -1237,7 +1233,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p mul_m4_m4m4(tmat, oblist[b]->obmat, pamat); mul_mat3_m4_fl(tmat, size*scale); if(par_space_mat) - mul_m4_m4m4(mat, tmat, recurs_mat); + mul_m4_m4m4(mat, tmat, par_space_mat); else copy_m4_m4(mat, tmat); @@ -1263,7 +1259,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p VECADD(tmat[3], tmat[3], vec); if(par_space_mat) - mul_m4_m4m4(mat, tmat, recurs_mat); + mul_m4_m4m4(mat, tmat, par_space_mat); else copy_m4_m4(mat, tmat); diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index 447c1e2f035..0afb9a450dd 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -848,7 +848,7 @@ void CustomData_merge(const struct CustomData *source, struct CustomData *dest, { const LayerTypeInfo *typeInfo; CustomDataLayer *layer, *newlayer; - int i, type, number = 0, lasttype = -1, lastactive = 0, lastrender = 0, lastclone = 0, lastmask = 0; + int i, type, number = 0, lasttype = -1, lastactive = 0, lastrender = 0, lastclone = 0, lastmask = 0, lastflag = 0; for(i = 0; i < source->totlayer; ++i) { layer = &source->layers[i]; @@ -863,15 +863,16 @@ void CustomData_merge(const struct CustomData *source, struct CustomData *dest, lastclone = layer->active_clone; lastmask = layer->active_mask; lasttype = type; + lastflag = layer->flag; } else number++; - if(layer->flag & CD_FLAG_NOCOPY) continue; + if(lastflag & CD_FLAG_NOCOPY) 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)) + if((alloctype == CD_ASSIGN) && (lastflag & CD_FLAG_NOFREE)) newlayer = customData_add_layer__internal(dest, type, CD_REFERENCE, layer->data, totelem, layer->name); else @@ -883,6 +884,7 @@ void CustomData_merge(const struct CustomData *source, struct CustomData *dest, newlayer->active_rnd = lastrender; newlayer->active_clone = lastclone; newlayer->active_mask = lastmask; + newlayer->flag |= lastflag & (CD_FLAG_EXTERNAL|CD_FLAG_IN_MEMORY); } } } @@ -892,6 +894,9 @@ void CustomData_copy(const struct CustomData *source, struct CustomData *dest, { memset(dest, 0, sizeof(*dest)); + if(source->external) + dest->external= MEM_dupallocN(source->external); + CustomData_merge(source, dest, mask, alloctype, totelem); } diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index 478a711aedd..5f0c2e3d4be 100644 --- a/source/blender/editors/armature/editarmature.c +++ b/source/blender/editors/armature/editarmature.c @@ -4573,19 +4573,22 @@ static int dgroup_skinnable(Object *ob, Bone *bone, void *datap) * pointers to bDeformGroups, all with names * of skinnable bones. */ - bDeformGroup ***hgroup, *defgroup; + bDeformGroup ***hgroup, *defgroup= NULL; int a, segments; struct { Object *armob; void *list; int heat; } *data= datap; + int wpmode = (ob->mode & OB_MODE_WEIGHT_PAINT); + bArmature *arm= data->armob->data; - if (!(ob->mode & OB_MODE_WEIGHT_PAINT) || !(bone->flag & BONE_HIDDEN_P)) { + if (!wpmode || !(bone->flag & BONE_HIDDEN_P)) { if (!(bone->flag & BONE_NO_DEFORM)) { if (data->heat && data->armob->pose && get_pose_channel(data->armob->pose, bone->name)) segments = bone->segments; else segments = 1; - - if (!(defgroup = defgroup_find_name(ob, bone->name))) - defgroup = ED_vgroup_add_name(ob, bone->name); + + if(!wpmode || ((arm->layer & bone->layer) && (bone->flag & BONE_SELECTED))) + if (!(defgroup = defgroup_find_name(ob, bone->name))) + defgroup = ED_vgroup_add_name(ob, bone->name); if (data->list != NULL) { hgroup = (bDeformGroup ***) &data->list; @@ -4711,7 +4714,7 @@ void add_verts_to_dgroups(Scene *scene, Object *ob, Object *par, int heat, int m selected = MEM_callocN(numbones*sizeof(int), "selected"); for (j=0; j < numbones; ++j) { - bone = bonelist[j]; + bone = bonelist[j]; dgroup = dgrouplist[j]; /* handle bbone */ @@ -4759,7 +4762,7 @@ void add_verts_to_dgroups(Scene *scene, Object *ob, Object *par, int heat, int m selected[j] = 1; /* find flipped group */ - if (mirror) { + if (dgroup && mirror) { char name[32]; BLI_strncpy(name, dgroup->name, 32); diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c index 136027b1504..3190d8ad576 100644 --- a/source/blender/editors/armature/meshlaplacian.c +++ b/source/blender/editors/armature/meshlaplacian.c @@ -618,13 +618,24 @@ void heat_bone_weighting(Object *ob, Mesh *me, float (*verts)[3], int numsource, LaplacianSystem *sys; MFace *mface; float solution, weight; - int *vertsflipped = NULL; + int *vertsflipped = NULL, *mask= NULL; int a, totface, j, bbone, firstsegment, lastsegment, thrownerror = 0; - /* count triangles */ + /* count triangles and create mask */ + if(me->editflag & ME_EDIT_PAINT_MASK) + mask= MEM_callocN(sizeof(int)*me->totvert, "heat_bone_weighting mask"); + for(totface=0, a=0, mface=me->mface; atotface; a++, mface++) { totface++; if(mface->v4) totface++; + + if(mask && (mface->flag & ME_FACE_SEL)) { + mask[mface->v1]= 1; + mask[mface->v2]= 1; + mask[mface->v3]= 1; + if(mface->v4) + mask[mface->v4]= 1; + } } /* create laplacian */ @@ -661,6 +672,9 @@ void heat_bone_weighting(Object *ob, Mesh *me, float (*verts)[3], int numsource, /* clear weights */ if(bbone && firstsegment) { for(a=0; atotvert; a++) { + if(mask && !mask[a]) + continue; + ED_vgroup_vert_remove(ob, dgrouplist[j], a); if(vertsflipped && dgroupflip[j] && vertsflipped[a] >= 0) ED_vgroup_vert_remove(ob, dgroupflip[j], vertsflipped[a]); @@ -679,6 +693,9 @@ void heat_bone_weighting(Object *ob, Mesh *me, float (*verts)[3], int numsource, if(laplacian_system_solve(sys)) { /* load solution into vertex groups */ for(a=0; atotvert; a++) { + if(mask && !mask[a]) + continue; + solution= laplacian_system_get_solution(a); if(bbone) { @@ -723,6 +740,9 @@ void heat_bone_weighting(Object *ob, Mesh *me, float (*verts)[3], int numsource, /* remove too small vertex weights */ if(bbone && lastsegment) { for(a=0; atotvert; a++) { + if(mask && !mask[a]) + continue; + weight= ED_vgroup_vert_weight(ob, dgrouplist[j], a); weight= heat_limit_weight(weight); if(weight <= 0.0f) @@ -740,6 +760,7 @@ void heat_bone_weighting(Object *ob, Mesh *me, float (*verts)[3], int numsource, /* free */ if(vertsflipped) MEM_freeN(vertsflipped); + if(mask) MEM_freeN(mask); heat_system_free(sys); diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index d40c88bc431..3d2530d9fe0 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -1221,6 +1221,7 @@ static void rna_def_space_image(BlenderRNA *brna) prop= RNA_def_property(srna, "image_pin", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "pin", 0); RNA_def_property_ui_text(prop, "Image Pin", "Display current image regardless of object selection"); + RNA_def_property_ui_icon(prop, ICON_UNPINNED, 1); RNA_def_property_update(prop, NC_SPACE|ND_SPACE_IMAGE, NULL); prop= RNA_def_property(srna, "sample_histogram", PROP_POINTER, PROP_NONE); diff --git a/source/blender/render/extern/include/RE_raytrace.h b/source/blender/render/extern/include/RE_raytrace.h index 317de5b9954..215dd816a4e 100644 --- a/source/blender/render/extern/include/RE_raytrace.h +++ b/source/blender/render/extern/include/RE_raytrace.h @@ -201,6 +201,7 @@ struct Isect #define RE_SKIP_VLR_NEIGHBOUR (1 << 1) #define RE_SKIP_VLR_RENDER_CHECK (1 << 2) #define RE_SKIP_VLR_NON_SOLID_MATERIAL (1 << 3) +#define RE_SKIP_VLR_BAKE_CHECK (1 << 4) /* TODO use: FLT_MAX? */ #define RE_RAYTRACE_MAXDIST 1e33 diff --git a/source/blender/render/intern/raytrace/rayobject.cpp b/source/blender/render/intern/raytrace/rayobject.cpp index 19e41b0f92a..024577e9f1f 100644 --- a/source/blender/render/intern/raytrace/rayobject.cpp +++ b/source/blender/render/intern/raytrace/rayobject.cpp @@ -165,6 +165,11 @@ static inline int vlr_check_intersect_solid(Isect *is, ObjectInstanceRen* obi, V return 0; } +static inline int vlr_check_bake(Isect *is, ObjectInstanceRen* obi, VlakRen *vlr) +{ + return (obi->obr->ob != is->userdata); +} + static inline int rayface_check_cullface(RayFace *face, Isect *is) { float nor[3]; @@ -189,17 +194,24 @@ static int intersect_rayface(RayObject *hit_obj, RayFace *face, Isect *is) if(is->orig.ob == face->ob && is->orig.face == face->face) return 0; - + /* check if we should intersect this face */ if(is->skip & RE_SKIP_VLR_RENDER_CHECK) { if(vlr_check_intersect(is, (ObjectInstanceRen*)face->ob, (VlakRen*)face->face ) == 0) return 0; } - if(is->skip & RE_SKIP_VLR_NON_SOLID_MATERIAL) + else if(is->skip & RE_SKIP_VLR_NON_SOLID_MATERIAL) { + if(vlr_check_intersect(is, (ObjectInstanceRen*)face->ob, (VlakRen*)face->face ) == 0) + return 0; if(vlr_check_intersect_solid(is, (ObjectInstanceRen*)face->ob, (VlakRen*)face->face) == 0) return 0; } + else if(is->skip & RE_SKIP_VLR_BAKE_CHECK) { + if(vlr_check_bake(is, (ObjectInstanceRen*)face->ob, (VlakRen*)face->face ) == 0) + return 0; + } + if(is->skip & RE_SKIP_CULLFACE) { if(rayface_check_cullface(face, is) == 0) diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 9c589ee1b64..015922216f9 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -1856,7 +1856,7 @@ static void ray_ao_qmc(ShadeInput *shi, float *ao, float *env) RE_RC_INIT(isec, *shi); isec.orig.ob = shi->obi; isec.orig.face = shi->vlr; - isec.skip = RE_SKIP_VLR_NEIGHBOUR | RE_SKIP_VLR_RENDER_CHECK | RE_SKIP_VLR_NON_SOLID_MATERIAL; + isec.skip = RE_SKIP_VLR_NEIGHBOUR|RE_SKIP_VLR_NON_SOLID_MATERIAL; isec.hint = 0; isec.hit.ob = 0; diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index 7375ea0f863..d9521bc892f 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -2266,21 +2266,8 @@ static void bake_displacement(void *handle, ShadeInput *shi, float dist, int x, } } -#if 0 -static int bake_check_intersect(Isect *is, int ob, RayFace *face) -{ - BakeShade *bs = (BakeShade*)is->userdata; - - /* no direction checking for now, doesn't always improve the result - * (INPR(shi->facenor, bs->dir) > 0.0f); */ - - return (R.objectinstance[ob & ~RE_RAY_TRANSFORM_OFFS].obr->ob != bs->actob); -} -#endif - static int bake_intersect_tree(RayObject* raytree, Isect* isect, float *start, float *dir, float sign, float *hitco, float *dist) { - //TODO, validate against blender 2.4x, results may have changed. float maxdist; int hit; @@ -2288,7 +2275,7 @@ static int bake_intersect_tree(RayObject* raytree, Isect* isect, float *start, f if(R.r.bake_maxdist > 0.0f) maxdist= R.r.bake_maxdist; else - maxdist= FLT_MAX + R.r.bake_biasdist; + maxdist= RE_RAYTRACE_MAXDIST + R.r.bake_biasdist; /* 'dir' is always normalized */ VECADDFAC(isect->start, start, dir, -R.r.bake_biasdist); @@ -2299,10 +2286,6 @@ static int bake_intersect_tree(RayObject* raytree, Isect* isect, float *start, f isect->labda = maxdist; - /* TODO, 2.4x had this... - hit = RE_ray_tree_intersect_check(R.raytree, isect, bake_check_intersect); - ...the active object may NOT be ignored in some cases. - */ hit = RE_rayobject_raycast(raytree, isect); if(hit) { hitco[0] = isect->start[0] + isect->labda*isect->vec[0]; @@ -2432,7 +2415,8 @@ static void do_bake_shade(void *handle, int x, int y, float u, float v) isec.orig.ob = obi; isec.orig.face = vlr; - isec.userdata= bs; + isec.userdata= bs->actob; + isec.skip = RE_SKIP_VLR_NEIGHBOUR|RE_SKIP_VLR_BAKE_CHECK; if(bake_intersect_tree(R.raytree, &isec, shi->co, shi->vn, sign, co, &dist)) { if(!hit || len_v3v3(shi->co, co) < len_v3v3(shi->co, minco)) { diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c index 2e6892cbc1c..4f872a238cd 100644 --- a/source/blender/render/intern/source/zbuf.c +++ b/source/blender/render/intern/source/zbuf.c @@ -3312,7 +3312,10 @@ static int zbuffer_abuf(Render *re, RenderPart *pa, APixstr *APixbuf, ListBase * if(vlr->mat!=ma) { ma= vlr->mat; - dofill= shadow || (((ma->mode & MA_TRANSP) && (ma->mode & MA_ZTRANSP)) && !(ma->mode & MA_ONLYCAST)); + if(shadow) + dofill= (ma->mode & MA_SHADBUF); + else + dofill= (((ma->mode & MA_TRANSP) && (ma->mode & MA_ZTRANSP)) && !(ma->mode & MA_ONLYCAST)); } if(dofill) {