* Assign weight from bones in weight paint mode now respects paint face
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Tue, 30 Mar 2010 12:01:17 +0000 (12:01 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Tue, 30 Mar 2010 12:01:17 +0000 (12:01 +0000)
  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
source/blender/blenkernel/intern/anim.c
source/blender/blenkernel/intern/customdata.c
source/blender/editors/armature/editarmature.c
source/blender/editors/armature/meshlaplacian.c
source/blender/makesrna/intern/rna_space.c
source/blender/render/extern/include/RE_raytrace.h
source/blender/render/intern/raytrace/rayobject.cpp
source/blender/render/intern/source/rayshade.c
source/blender/render/intern/source/rendercore.c
source/blender/render/intern/source/zbuf.c

index 4968c083685fcab9418795745a3acaa64c8c8a05..2f7a64790b43712bb7de52ea65b8e45b69688d58 100644 (file)
@@ -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:
index 1465f4550f5d4456af133557509911032074bcf4..e26072deb76fcddd84761ce810429139bd1dc796 100644 (file)
@@ -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);
 
index 447c1e2f035fd700ccf38684690b0bcb2bbc37da..0afb9a450dd05137b1e956fa904570c1de6f2906 100644 (file)
@@ -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);
 }
 
index 478a711aedd85679c7f2acf3aa602ac90302be64..5f0c2e3d4be27cf16afadb9a4c11596d97a290d6 100644 (file)
@@ -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);
index 136027b15049cdee196d18c16f64eb7bced71395..3190d8ad576bc0010360c2b32065238d039df362 100644 (file)
@@ -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; a<me->totface; 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; a<me->totvert; 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; a<me->totvert; 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; a<me->totvert; 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);
 
index d40c88bc431ec1a6feebf8d9fce5c4231522c4e2..3d2530d9fe0aec85dcffef55ba14e7d2df70d6bf 100644 (file)
@@ -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);
index 317de5b995486acc96c234bb508f115f31db6797..215dd816a4e806984322d08f50d98a007ecdf78d 100644 (file)
@@ -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
index 19e41b0f92acebeec8ae76e91d8c76db2815659b..024577e9f1f2ec57dc462443f43f1ca83cb3246b 100644 (file)
@@ -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)
index 9c589ee1b6491525adeceaa65466fa25a6575079..015922216f94ed42273bdd75facae06ea76fc82c 100644 (file)
@@ -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;
index 7375ea0f863bbf3718e546c45dcff53b20eee6ad..d9521bc892f502b638188a0d2b273ea8f4ebca51 100644 (file)
@@ -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)) {
index 2e6892cbc1c1fd2e9e903cdb43d68d8431d4b159..4f872a238cd6c3733f6f2bf112143c599eba9f5e 100644 (file)
@@ -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) {