svn merge -r 13095:13148 https://svn.blender.org/svnroot/bf-blender/trunk/blender
authorDaniel Genrich <daniel.genrich@gmx.net>
Mon, 7 Jan 2008 03:25:11 +0000 (03:25 +0000)
committerDaniel Genrich <daniel.genrich@gmx.net>
Mon, 7 Jan 2008 03:25:11 +0000 (03:25 +0000)
47 files changed:
intern/guardedalloc/MEM_guardedalloc.h
intern/guardedalloc/intern/mallocn.c
source/blender/blenkernel/BKE_anim.h
source/blender/blenkernel/BKE_constraint.h
source/blender/blenkernel/intern/anim.c
source/blender/blenkernel/intern/armature.c
source/blender/blenkernel/intern/constraint.c
source/blender/blenkernel/intern/curve.c
source/blender/blenkernel/intern/image.c
source/blender/blenkernel/intern/object.c
source/blender/blenkernel/intern/particle.c
source/blender/blenkernel/intern/particle_system.c
source/blender/blenlib/intern/BLI_kdtree.c
source/blender/blenloader/intern/readfile.c
source/blender/include/BIF_editconstraint.h
source/blender/include/BIF_gl.h
source/blender/makesdna/DNA_constraint_types.h
source/blender/python/api2_2x/Blender.c
source/blender/python/api2_2x/NLA.c
source/blender/python/api2_2x/doc/NLA.py
source/blender/render/intern/include/strand.h
source/blender/render/intern/source/convertblender.c
source/blender/render/intern/source/renderdatabase.c
source/blender/render/intern/source/strand.c
source/blender/src/buttons_editing.c
source/blender/src/buttons_object.c
source/blender/src/drawview.c
source/blender/src/editaction.c
source/blender/src/editconstraint.c
source/blender/src/editparticle.c
source/blender/src/editscreen.c
source/blender/src/editseq.c
source/blender/src/editview.c
source/blender/src/header_action.c
source/blender/src/header_nla.c
source/blender/src/header_view3d.c
source/blender/src/outliner.c
source/blender/src/poselib.c
source/blender/src/poseobject.c
source/blender/src/seqeffects.c
source/blender/src/sequence.c
source/blender/src/transform.c
source/blender/src/transform_conversions.c
source/creator/creator.c
source/nan_compile.mk
source/nan_definitions.mk
source/nan_link.mk

index 26a9258d03bb0b0f80730559f8e6a793cef53cd5..94276c0454aca442ab5ae7285d676f64dab28b25 100644 (file)
@@ -99,10 +99,14 @@ extern "C" {
                * */
        void *MEM_mapallocN(unsigned int len, const char * str);
 
+       /** Print a list of the names and sizes of all allocated memory
+        * blocks. as a python dict for easy investigation */ 
+       void MEM_printmemlist_pydict(void);
+
        /** Print a list of the names and sizes of all allocated memory
         * blocks. */ 
        void MEM_printmemlist(void);
-
+       
        /** Set the callback function for error output. */
        void MEM_set_error_callback(void (*func)(char *));
 
index 44909bbea548470c768f0c5fd95c612af7cca843..413f4d8051496ca7c8c6a0fcbc40245edb40245e 100644 (file)
@@ -334,7 +334,7 @@ void *MEM_mapallocN(unsigned int len, const char *str)
 
 
 /* Prints in python syntax for easy */
-void MEM_printmemlist()
+static void MEM_printmemlist_internal( int pydict )
 {
        MemHead *membl;
 
@@ -343,16 +343,23 @@ void MEM_printmemlist()
        membl = membase->first;
        if (membl) membl = MEMNEXT(membl);
        
-       print_error("# membase_debug.py\n");
-       print_error("membase = [\\\n");
+       if (pydict) {
+               print_error("# membase_debug.py\n");
+               print_error("membase = [\\\n");
+       }
        while(membl) {
-               fprintf(stderr, "{'len':%i, 'name':'''%s''', 'pointer':'%p'},\\\n", membl->len, membl->name, membl+1);
+               if (pydict) {
+                       fprintf(stderr, "{'len':%i, 'name':'''%s''', 'pointer':'%p'},\\\n", membl->len, membl->name, membl+1);
+               } else {
+                       print_error("%s len: %d %p\n",membl->name,membl->len, membl+1);
+               }
                if(membl->next)
                        membl= MEMNEXT(membl->next);
                else break;
        }
-       fprintf(stderr, "]\n\n");
-       fprintf(stderr,
+       if (pydict) {
+               fprintf(stderr, "]\n\n");
+               fprintf(stderr,
 "mb_userinfo = {}\n"
 "totmem = 0\n"
 "for mb_item in membase:\n"
@@ -367,11 +374,19 @@ void MEM_printmemlist()
 "\tmb_userinfo_sort.sort(key = sort_func)\n"
 "\tfor item in mb_userinfo_sort:\n"
 "\t\tprint 'name:%%s, users:%%i, len:%%i' %% (item[0], item[1][0], item[1][1])\n"
-       );
+               );
+       }
        
        mem_unlock_thread();
 }
 
+void MEM_printmemlist( void ) {
+       MEM_printmemlist_internal(0);
+}
+void MEM_printmemlist_pydict( void ) {
+       MEM_printmemlist_internal(1);
+}
+
 short MEM_freeN(void *vmemh)           /* anders compileertie niet meer */
 {
        short error = 0;
index c7808331d7e484e1cb3fd6ff2f92f71479769f07..c3e978a5a9a404fbc0aa01056415bbb9f6ea69e3 100644 (file)
@@ -44,7 +44,7 @@ typedef struct DupliObject {
        struct DupliObject *next, *prev;
        struct Object *ob;
        unsigned int origlay;
-       int index, no_draw;
+       int index, no_draw, type;
        float mat[4][4], omat[4][4];
 } DupliObject;
 
index aa8e9cf18f8b3b149fa937f1aa3ae6400ea391c6..5d145dc6dee908e506ed62edf5b6b57ace3889ce 100644 (file)
@@ -117,6 +117,9 @@ void copy_constraints(struct ListBase *dst, struct ListBase *src);
 void relink_constraints(struct ListBase *list);
 void free_constraint_data(struct bConstraint *con);
 
+/* Constraints + Proxies function prototypes */
+void extract_proxylocal_constraints(struct ListBase *dst, struct ListBase *src);
+short proxylocked_constraints_owner(struct Object *ob, struct bPoseChannel *pchan);
 
 /* Constraint Channel function prototypes */
 struct bConstraintChannel *get_constraint_channel(struct ListBase *list, const char *name);
@@ -126,6 +129,7 @@ void copy_constraint_channels(struct ListBase *dst, struct ListBase *src);
 void clone_constraint_channels(struct ListBase *dst, struct ListBase *src);
 void free_constraint_channels(struct ListBase *chanbase);
 
+
 /* Constraint Evaluation function prototypes */
 struct bConstraintOb *constraints_make_evalob(struct Object *ob, void *subdata, short datatype);
 void constraints_clear_evalob(struct bConstraintOb *cob);
index 0b733f9c0685331d4aade2ec73dfa3673a64967a..8651996515b310663220f880cd73e6a6d012faab 100644 (file)
@@ -284,7 +284,7 @@ int where_on_path(Object *ob, float ctime, float *vec, float *dir)  /* returns OK
 
 /* ****************** DUPLICATOR ************** */
 
-static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[][4], int lay, int index)
+static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[][4], int lay, int index, int type)
 {
        DupliObject *dob= MEM_callocN(sizeof(DupliObject), "dupliobject");
        
@@ -294,6 +294,7 @@ static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[][4], i
        Mat4CpyMat4(dob->omat, ob->obmat);
        dob->origlay= ob->lay;
        dob->index= index;
+       dob->type= type;
        ob->lay= lay;
        
        return dob;
@@ -321,7 +322,7 @@ static void group_duplilist(ListBase *lb, Object *ob, int level)
                if(go->ob!=ob) {
                        
                        Mat4MulMat4(mat, go->ob->obmat, ob->obmat);
-                       dob= new_dupli_object(lb, go->ob, mat, ob->lay, 0);
+                       dob= new_dupli_object(lb, go->ob, mat, ob->lay, 0, OB_DUPLIGROUP);
                        dob->no_draw= (dob->origlay & group->layer)==0;
                        
                        if(go->ob->transflag & OB_DUPLI) {
@@ -360,7 +361,7 @@ static void frames_duplilist(ListBase *lb, Object *ob, int level)
                if(ok) {
                        do_ob_ipo(ob);
                        where_is_object_time(ob, (float)G.scene->r.cfra);
-                       new_dupli_object(lb, ob, ob->obmat, ob->lay, G.scene->r.cfra);
+                       new_dupli_object(lb, ob, ob->obmat, ob->lay, G.scene->r.cfra, OB_DUPLIFRAMES);
                }
        }
 
@@ -405,7 +406,7 @@ static void vertex_dupli__mapFunc(void *userData, int index, float *co, float *n
                Mat4CpyMat4(tmat, obmat);
                Mat4MulMat43(obmat, tmat, mat);
        }
-       new_dupli_object(vdd->lb, vdd->ob, obmat, vdd->par->lay, index);
+       new_dupli_object(vdd->lb, vdd->ob, obmat, vdd->par->lay, index, OB_DUPLIVERTS);
        
        if(vdd->ob->transflag & OB_DUPLI) {
                float tmpmat[4][4];
@@ -631,7 +632,7 @@ static void face_duplilist(ListBase *lb, ID *id, Object *par, float (*par_space_
                                                Mat4CpyMat4(tmat, obmat);
                                                Mat4MulMat43(obmat, tmat, mat);
                                                
-                                               new_dupli_object(lb, ob, obmat, lay, a);
+                                               new_dupli_object(lb, ob, obmat, lay, a, OB_DUPLIFACES);
                                                
                                                if(ob->transflag & OB_DUPLI) {
                                                        float tmpmat[4][4];
@@ -772,7 +773,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, ParticleSy
 
                                                VECADD(tmat[3], go->ob->obmat[3], state.co);
 
-                                               new_dupli_object(lb, go->ob, tmat, par->lay, counter);
+                                               new_dupli_object(lb, go->ob, tmat, par->lay, counter, OB_DUPLIPARTS);
                                        }
                                }
                                else {
@@ -789,7 +790,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, ParticleSy
 
                                        VECCOPY(tmat[3], state.co);
 
-                                       new_dupli_object(lb, ob, tmat, par->lay, counter);
+                                       new_dupli_object(lb, ob, tmat, par->lay, counter, OB_DUPLIPARTS);
                                }
                        }
                }
@@ -867,7 +868,7 @@ static void font_duplilist(ListBase *lb, Object *par, int level)
                        Mat4CpyMat4(obmat, par->obmat);
                        VECCOPY(obmat[3], vec);
                        
-                       new_dupli_object(lb, ob, obmat, par->lay, a);
+                       new_dupli_object(lb, ob, obmat, par->lay, a, OB_DUPLIVERTS);
                }
                
        }
@@ -881,7 +882,7 @@ static void object_duplilist_recursive(ID *id, Object *ob, ListBase *duplilist,
        if((ob->transflag & OB_DUPLI)==0)
                return;
        
-       /* Should the dupli's be greated for this object? - Respect restrict flags */
+       /* Should the dupli's be generated for this object? - Respect restrict flags */
        if (G.rendering) {
                if (ob->restrictflag & OB_RESTRICT_RENDER) {
                        return;
@@ -922,7 +923,8 @@ static void object_duplilist_recursive(ID *id, Object *ob, ListBase *duplilist,
 
                if (level==0) {
                        for(dob= duplilist->first; dob; dob= dob->next)
-                               Mat4CpyMat4(dob->ob->obmat, dob->mat);
+                               if(dob->type == OB_DUPLIGROUP)
+                                       Mat4CpyMat4(dob->ob->obmat, dob->mat);
                }
        }
 }
index 6bdb663545c52b5e905074182245666ab93c0974..f4da821e3eae046d96f5516db763d5faf90f8252 100644 (file)
@@ -1317,6 +1317,7 @@ static void pose_proxy_synchronize(Object *ob, Object *from, int layer_protected
        pchan= pose->chanbase.first;
        for(; pchan; pchan= pchan->next) {
                if(pchan->bone->layer & layer_protected) {
+                       ListBase proxylocal_constraints = {NULL, NULL};
                        pchanp= get_pose_channel(frompose, pchan->name);
                        
                        /* copy posechannel to temp, but restore important pointers */
@@ -1327,9 +1328,16 @@ static void pose_proxy_synchronize(Object *ob, Object *from, int layer_protected
                        pchanw.child= pchan->child;
                        pchanw.path= NULL;
                        
-                       /* constraints, set target ob pointer to own object */
+                       /* constraints - proxy constraints are flushed... local ones are added after 
+                        *      1. extract constraints not from proxy (CONSTRAINT_PROXY_LOCAL) from pchan's constraints
+                        *      2. copy proxy-pchan's constraints on-to new
+                        *      3. add extracted local constraints back on top 
+                        */
+                       extract_proxylocal_constraints(&proxylocal_constraints, &pchan->constraints);
                        copy_constraints(&pchanw.constraints, &pchanp->constraints);
+                       addlisttolist(&pchanw.constraints, &proxylocal_constraints);
                        
+                       /* constraints - set target ob pointer to own object */
                        for (con= pchanw.constraints.first; con; con= con->next) {
                                bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
                                ListBase targets = {NULL, NULL};
index c87c75b0190ccbef294c9a3c5447610695e08cb5..295c52f141552a1c0d0050279cb4974041c4f2ac 100644 (file)
@@ -3246,6 +3246,46 @@ void copy_constraints (ListBase *dst, ListBase *src)
        }
 }
 
+/* -------- Constraints and Proxies ------- */
+
+/* Rescue all constraints tagged as being CONSTRAINT_PROXY_LOCAL (i.e. added to bone that's proxy-synced in this file) */
+void extract_proxylocal_constraints (ListBase *dst, ListBase *src)
+{
+       bConstraint *con, *next;
+       
+       /* for each tagged constraint, remove from src and move to dst */
+       for (con= src->first; con; con= next) {
+               next= con->next;
+               
+               /* check if tagged */
+               if (con->flag & CONSTRAINT_PROXY_LOCAL) {
+                       BLI_remlink(src, con);
+                       BLI_addtail(dst, con);
+               }
+       }
+}
+
+/* Returns if the owner of the constraint is proxy-protected */
+short proxylocked_constraints_owner (Object *ob, bPoseChannel *pchan)
+{
+       /* Currently, constraints can only be on object or bone level */
+       if (ob && ob->proxy) {
+               if (ob->pose && pchan) {
+                       bArmature *arm= ob->data;
+                       
+                       /* On bone-level, check if bone is on proxy-protected layer */
+                       if ((pchan->bone) && (pchan->bone->layer & arm->layer_protected))
+                               return 1;
+               }
+               else {
+                       /* FIXME: constraints on object-level are not handled well yet */
+                       return 1;
+               }       
+       }
+       
+       return 0;
+}
+
 /* -------- Target-Matrix Stuff ------- */
 
 /* This function is a relic from the prior implementations of the constraints system, when all
index fd22579ea67111897b68a03ba57c5303b1ac04ec..f7864761b1dc552c0d0874c964b96cc9fa899d28 100644 (file)
@@ -586,7 +586,7 @@ static void basisNurb(float t, short order, short pnts, float *knots, float *bas
 
        /* this is for float inaccuracy */
        if(t < knots[0]) t= knots[0];
-       else if(t > knots[opp2]) t= knots[opp2];
+       else if(t > knots[opp2]) t= knots[opp2]; /* Valgrind reports an error here, use a nurbs torus and change u/v res to reproduce a crash TODO*/
 
        /* this part is order '1' */
         o2 = order + 1;
index 3b40907244ae418454e9213f7e0d640cd83189bc..57370688e15ea83876c259ff96175461db8f4385 100644 (file)
@@ -400,8 +400,8 @@ static ImBuf *add_ibuf_size(int width, int height, char *name, int floatbuf, sho
 {
        ImBuf *ibuf;
        float h=0.0, hoffs=0.0, hue=0.0, s=0.9, v=0.9, r, g, b;
-       unsigned char *rect;
-       float *rect_float;
+       unsigned char *rect= NULL;
+       float *rect_float= NULL;
        int x, y;
        int checkerwidth=21, dark=1;
        
@@ -475,18 +475,20 @@ static ImBuf *add_ibuf_size(int width, int height, char *name, int floatbuf, sho
                                                        rect_float[1]= g;
                                                        rect_float[2]= b;
                                                        rect_float[3]= 1.0;
-                                                       rect_float+=4;
                                                }
                                                else {
                                                        rect[0]= (char)(r * 255.0);
                                                        rect[1]= (char)(g * 255.0);
                                                        rect[2]= (char)(b * 255.0);
                                                        rect[3]= 255;
-                                                       rect+=4;
                                                }
                                        }
                                }
-                               
+
+                               if (floatbuf)
+                                       rect_float+=4;
+                               else
+                                       rect+=4;
                        }
                }
        } else {        /* blank image */
@@ -1737,7 +1739,6 @@ ImBuf *BKE_image_get_ibuf(Image *ima, ImageUser *iuser)
 {
        ImBuf *ibuf= NULL;
        float color[] = {0, 0, 0, 1};
-       int floatbuf;
 
        /* quick reject tests */
        if(ima==NULL) 
@@ -1815,7 +1816,7 @@ ImBuf *BKE_image_get_ibuf(Image *ima, ImageUser *iuser)
                                /* UV testgrid or black or solid etc */
                                if(ima->gen_x==0) ima->gen_x= 256;
                                if(ima->gen_y==0) ima->gen_y= 256;
-                               ibuf= add_ibuf_size(ima->gen_x, ima->gen_y, ima->name, floatbuf, ima->gen_type, color);
+                               ibuf= add_ibuf_size(ima->gen_x, ima->gen_y, ima->name, 0, ima->gen_type, color);
                                image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0);
                                ima->ok= IMA_OK_LOADED;
                        }
index 54d090ddb225c4c46aefc74fe7727d00ba5b86a5..de2875c91f427436b27c8ea111cf6a55689e26fb 100644 (file)
@@ -2003,7 +2003,7 @@ BoundBox *unit_boundbox()
        BoundBox *bb;
        float min[3] = {-1,-1,-1}, max[3] = {-1,-1,-1};
 
-       bb= MEM_mallocN(sizeof(BoundBox), "bb");
+       bb= MEM_callocN(sizeof(BoundBox), "bb");
        boundbox_set_from_min_max(bb, min, max);
        
        return bb;
index 82b2d785c8ce0e246a767575e6c01e0d68cf9aec..54b8a5c47e64bb57b188370a1b1185be69bd3323 100644 (file)
@@ -367,7 +367,7 @@ void psys_free(Object *ob, ParticleSystem * psys)
  * removing the previous data. this should be solved properly once */
 
 typedef struct ParticleRenderElem {
-       int curchild, totchild;
+       int curchild, totchild, reduce;
        float lambda, t, scalemin, scalemax;
 } ParticleRenderElem;
 
@@ -396,7 +396,7 @@ static float psys_render_viewport_falloff(double rate, float dist, float width)
 static float psys_render_projected_area(ParticleSystem *psys, float *center, float area, double vprate, float *viewport)
 {
        ParticleRenderData *data= psys->renderdata;
-       float co[3], view[3], ortho1[3], ortho2[2], w, dx, dy, radius;
+       float co[4], view[3], ortho1[3], ortho2[3], w, dx, dy, radius;
        
        /* transform to view space */
        VECCOPY(co, center);
@@ -536,7 +536,7 @@ int psys_render_simplify_distribution(ParticleThreadContext *ctx, int tot)
        ParticleRenderData *data;
        ParticleRenderElem *elems, *elem;
        ParticleSettings *part= ctx->psys->part;
-       float *facearea, (*facecenter)[3], size[3], fac, powrate;
+       float *facearea, (*facecenter)[3], size[3], fac, powrate, scaleclamp;
        float co1[3], co2[3], co3[3], co4[3], lambda, arearatio, t, area, viewport;
        double vprate;
        int *origindex, *facetotvert;
@@ -562,6 +562,9 @@ int psys_render_simplify_distribution(ParticleThreadContext *ctx, int tot)
        elems= MEM_callocN(sizeof(ParticleRenderElem)*totorigface, "SimplifyFaceElem");
 
        data= ctx->psys->renderdata;
+       if(data->elems)
+               MEM_freeN(data->elems);
+
        data->dosimplify= 1;
        data->elems= elems;
        data->origindex= origindex;
@@ -619,19 +622,30 @@ int psys_render_simplify_distribution(ParticleThreadContext *ctx, int tot)
                area = psys_render_projected_area(ctx->psys, facecenter[a], facearea[a], vprate, &viewport);
                arearatio= fac*area/facearea[a];
 
-               if(arearatio < 1.0f || viewport < 1.0f) {
+               if((arearatio < 1.0f || viewport < 1.0f) && elem->totchild) {
                        /* lambda is percentage of elements to keep */
                        lambda= (arearatio < 1.0f)? pow(arearatio, powrate): 1.0f;
                        lambda *= viewport;
 
+                       lambda= MAX2(lambda, 1.0f/elem->totchild);
+
                        /* compute transition region */
                        t= part->simplify_transition;
                        elem->t= (lambda-t < 0.0f)? lambda: (lambda+t > 1.0f)? 1.0f-lambda: t;
+                       elem->reduce= 1;
 
                        /* scale at end and beginning of the transition region */
                        elem->scalemax= (lambda+t < 1.0f)? 1.0f/lambda: 1.0f/(1.0f - elem->t*elem->t/t);
                        elem->scalemin= (lambda+t < 1.0f)? 0.0f: elem->scalemax*(1.0f-elem->t/t);
 
+                       elem->scalemin= sqrt(elem->scalemin);
+                       elem->scalemax= sqrt(elem->scalemax);
+
+                       /* clamp scaling */
+                       scaleclamp= MIN2(elem->totchild, 10.0f);
+                       elem->scalemin= MIN2(scaleclamp, elem->scalemin);
+                       elem->scalemax= MIN2(scaleclamp, elem->scalemax);
+
                        /* extend lambda to include transition */
                        lambda= lambda + elem->t;
                        if(lambda > 1.0f)
@@ -642,6 +656,7 @@ int psys_render_simplify_distribution(ParticleThreadContext *ctx, int tot)
 
                        elem->scalemax= 1.0f; //sqrt(lambda);
                        elem->scalemin= 1.0f; //sqrt(lambda);
+                       elem->reduce= 0;
                }
 
                elem->lambda= lambda;
@@ -703,7 +718,7 @@ int psys_render_simplify_params(ParticleSystem *psys, ChildParticle *cpa, float
        scalemin= elem->scalemin;
        scalemax= elem->scalemax;
 
-       if(lambda >= 1.0f) {
+       if(!elem->reduce) {
                scale= scalemin;
                alpha= 1.0f;
        }
@@ -2157,6 +2172,7 @@ void psys_cache_child_paths(Object *ob, ParticleSystem *psys, float cfra, int ed
        ParticleCacheKey **cache, *tcache;
        ListBase threads;
        int i, totchild, totparent, totthread;
+       unsigned long totchildstep;
 
        pthreads= psys_threads_create(ob, psys, G.scene->r.threads);
 
@@ -2177,7 +2193,8 @@ void psys_cache_child_paths(Object *ob, ParticleSystem *psys, float cfra, int ed
                free_child_path_cache(psys);
 
                cache = psys->childcache = MEM_callocN(totchild*sizeof(void *), "Child path cache array");
-               tcache = MEM_callocN(totchild * (ctx->steps + 1) * sizeof(ParticleCacheKey), "Child path cache");
+               totchildstep= totchild*(ctx->steps + 1);
+               tcache = MEM_callocN(totchildstep*sizeof(ParticleCacheKey), "Child path cache");
                for(i=0; i<totchild; i++)
                        cache[i] = tcache + i * (ctx->steps + 1);
 
index ac06f75737ff714f014a3eab2968997272c22364..1235d9f539121a959db44e13e119f10ddd09dd69 100644 (file)
@@ -1333,7 +1333,7 @@ void psys_threads_free(ParticleThread *threads)
        if(ctx->vg_rough1)
                MEM_freeN(ctx->vg_rough1);
        if(ctx->vg_rough2)
-               MEM_freeN(ctx->vg_roughe);
+               MEM_freeN(ctx->vg_rough2);
        if(ctx->vg_roughe)
                MEM_freeN(ctx->vg_roughe);
 
@@ -4247,7 +4247,8 @@ static void psys_update_path_cache(Object *ob, ParticleSystemModifierData *psmd,
                /* for render, child particle paths are computed on the fly */
                if(part->childtype) {
                        if(((psys->totchild!=0)) || (psys_in_edit_mode(psys) && (pset->flag&PE_SHOW_CHILD)))
-                               psys_cache_child_paths(ob, psys, cfra, 0);
+                               if(!(psys->part->type == PART_HAIR) || (psys->flag & PSYS_HAIR_DONE))
+                                       psys_cache_child_paths(ob, psys, cfra, 0);
                }
        }
        else if(psys->pathcache)
@@ -4459,8 +4460,9 @@ static void system_step(Object *ob, ParticleSystem *psys, ParticleSystemModifier
 
                        distribute_particles(ob, psys, part->from);
 
-                       if(get_alloc_child_particles_tot(psys))
-                               distribute_particles(ob, psys, PART_FROM_CHILD);
+                       if(!(psys->part->type == PART_HAIR) || (psys->flag & PSYS_HAIR_DONE))
+                               if(get_alloc_child_particles_tot(psys))
+                                       distribute_particles(ob, psys, PART_FROM_CHILD);
                }
                initialize_all_particles(ob, psys, psmd);
 
index dbb9e95d379ea2ff3a4796d45b7db7f7b8b1c9cd..80e92cb88094862e2e2224bcfc832f75b0499e8a 100644 (file)
@@ -166,11 +166,18 @@ int       BLI_kdtree_find_nearest(KDTree *tree, float *co, float *nor, KDTreeNearest *
        min_node= root;
        min_dist= squared_distance(root->co,co,root->nor,nor);
 
-       if(root->left)
-               stack[cur++]=root->left;
-
-       if(root->right)
-               stack[cur++]=root->right;
+       if(co[root->d] < root->co[root->d]) {
+               if(root->right)
+                       stack[cur++]=root->right;
+               if(root->left)
+                       stack[cur++]=root->left;
+       }
+       else {
+               if(root->left)
+                       stack[cur++]=root->left;
+               if(root->right)
+                       stack[cur++]=root->right;
+       }
        
        while(cur--){
                node=stack[cur];
@@ -266,11 +273,18 @@ int       BLI_kdtree_find_n_nearest(KDTree *tree, int n, float *co, float *nor, KDTree
        cur_dist= squared_distance(root->co,co,root->nor,nor);
        add_nearest(nearest,&found,n,root->index,cur_dist,root->co);
        
-       if(root->left)
-               stack[cur++]=root->left;
-
-       if(root->right)
-               stack[cur++]=root->right;
+       if(co[root->d] < root->co[root->d]) {
+               if(root->right)
+                       stack[cur++]=root->right;
+               if(root->left)
+                       stack[cur++]=root->left;
+       }
+       else {
+               if(root->left)
+                       stack[cur++]=root->left;
+               if(root->right)
+                       stack[cur++]=root->right;
+       }
 
        while(cur--){
                node=stack[cur];
index 37d15b65de5c87dfe8ba11fba067bd99d3445e18..96b0c372835aacd8975be9c8105e69b192af816d 100644 (file)
@@ -7892,6 +7892,12 @@ static void expand_modifier(FileData *fd, Main *mainvar, ModifierData *md)
                        
                expand_doit(fd, mainvar, mmd->mirror_ob);
        }
+       else if (md->type==eModifierType_Displace) {
+               DisplaceModifierData *dmd = (DisplaceModifierData*) md;
+               
+               expand_doit(fd, mainvar, dmd->map_object);
+               expand_doit(fd, mainvar, dmd->texture);
+       }
 }
 
 static void expand_scriptlink(FileData *fd, Main *mainvar, ScriptLink *slink)
index b8977c00d89a8cafc6405891a5e92a6f3bf18755..81e2356e6cb3fabf1c74fb56760840876f3b4442 100644 (file)
@@ -41,23 +41,18 @@ struct bConstraintChannel;
 struct Text;
 
 /* generic constraint editing functions */
-
-struct bConstraint *add_new_constraint(short type);
-
-void add_constraint_to_object(struct bConstraint *con, struct Object *ob);
-
 struct ListBase *get_active_constraints(struct Object *ob);
 struct bConstraint *get_active_constraint(struct Object *ob);
 struct ListBase *get_active_constraint_channels (struct Object *ob, int forcevalid);
 struct bConstraintChannel *get_active_constraint_channel(struct Object *ob);
 
-void object_test_constraints(struct Object *owner);
-
-void add_constraint(int only_IK);
+void add_constraint_to_object(struct bConstraint *con, struct Object *ob);
+struct bConstraint *add_new_constraint(short type);
+void add_constraint(short only_IK);
 void ob_clear_constraints(void);
-
 void rename_constraint(struct Object *ob, struct bConstraint *con, char *newname);
 
+void object_test_constraints(struct Object *owner);
 
 /* a few special functions for PyConstraints */
 char *buildmenu_pyconstraints(struct Text *con_text, int *pyconindex);
index 215e88dc002528288bd2b93ca318800a36eb2468..67d51edc531e7a53723d6e1ba40f91fecb43cd5d 100644 (file)
 #endif
 
 #ifdef __APPLE__
-#include <OpenGL/gl.h>
-#include <OpenGL/glu.h>
+ #include <OpenGL/gl.h>
+ #include <OpenGL/glu.h>
 #else
-#include <GL/gl.h>
-#include <GL/glu.h>
+ #if defined (__sun) || defined (__sun__)
+  #include <GL/gl.h>
+  #include <mesa/glu.h>
+ #else
+  #include <GL/gl.h>
+  #include <GL/glu.h>
+ #endif
 #endif
        /*
         * these should be phased out. cpack should be replaced in
index 7f9fa49e7a95b1c0508be5415ece38fa0ad64295..4ae8d6b39e6a1944c766bd390a5267e79bba92ba 100644 (file)
@@ -352,7 +352,9 @@ typedef enum B_CONSTRAINT_FLAG {
                /* to indicate that the owner's space should only be changed into ownspace, but not out of it */
        CONSTRAINT_SPACEONCE =  (1<<6),
                /* influence ipo is on constraint itself, not in action channel */
-       CONSTRAINT_OWN_IPO      = (1<<7)
+       CONSTRAINT_OWN_IPO      = (1<<7),
+               /* indicates that constraint was added locally (i.e.  didn't come from the proxy-lib) */
+       CONSTRAINT_PROXY_LOCAL = (1<<8)
 } B_CONSTRAINT_FLAG;
 
 /* bConstraint->ownspace/tarspace */
index eb9856c72fcd2172016d458f77cc0759d8fb3d1e..db47d6550c28fa58dcf056a5284d68dac85526ee 100644 (file)
@@ -40,6 +40,7 @@ struct ID; /*keep me up here */
 #include "BDR_drawmesh.h"      /* set_mipmap() */
 #include "BIF_usiblender.h"
 #include "BLI_blenlib.h"
+#include "BLI_bpath.h"
 #include "BLO_writefile.h"
 #include "BKE_blender.h"
 #include "BKE_exotic.h"
@@ -112,7 +113,7 @@ static PyObject *Blender_UpdateMenus( PyObject * self);
 static PyObject *Blender_PackAll( PyObject * self);
 static PyObject *Blender_UnpackAll( PyObject * self, PyObject * value);
 static PyObject *Blender_CountPackedFiles( PyObject * self );
-
+static PyObject *Blender_GetPaths( PyObject * self, PyObject *args, PyObject *keywds );
 extern PyObject *Text3d_Init( void ); /* missing in some include */
 
 /*****************************************************************************/
@@ -196,6 +197,9 @@ All files will be unpacked using specified mode.\n\n\
 static char Blender_CountPackedFiles_doc[] =
 "() - Returns the number of packed files.";
 
+static char Blender_GetPaths_doc[] =
+"() - Returns a list of paths used in this blend file.";
+
 /*****************************************************************************/
 /* Python method structure definition.          */
 /*****************************************************************************/
@@ -209,6 +213,7 @@ static struct PyMethodDef Blender_methods[] = {
        {"Run", Blender_Run, METH_O, Blender_Run_doc},
        {"ShowHelp", Blender_ShowHelp, METH_O, Blender_ShowHelp_doc},
        {"CountPackedFiles", ( PyCFunction ) Blender_CountPackedFiles, METH_NOARGS, Blender_CountPackedFiles_doc},
+       {"GetPaths", ( PyCFunction ) Blender_GetPaths, METH_VARARGS|METH_KEYWORDS, Blender_GetPaths_doc},
        {"PackAll", ( PyCFunction ) Blender_PackAll, METH_NOARGS, Blender_PackAll_doc},
        {"UnpackAll", Blender_UnpackAll, METH_O, Blender_UnpackAll_doc},
        {"UpdateMenus", ( PyCFunction ) Blender_UpdateMenus, METH_NOARGS,
@@ -903,6 +908,47 @@ static PyObject *Blender_CountPackedFiles( PyObject * self )
        int nfiles = countPackedFiles();
        return PyInt_FromLong( nfiles );
 }
+
+/*****************************************************************************/
+/* Function:           Blender_GetPaths                 */
+/* Python equivalent:  Blender.GetPaths                         */
+/*****************************************************************************/
+static PyObject *Blender_GetPaths( PyObject * self, PyObject *args, PyObject *keywds )
+{
+       struct BPathIterator bpi;
+       PyObject *list = PyList_New(0), *st;
+       /* be sure there is low chance of the path being too short */
+       char filepath_expanded[FILE_MAXDIR*2]; 
+       
+       int absolute = 0;
+       static char *kwlist[] = {"absolute", NULL};
+
+       if (!PyArg_ParseTupleAndKeywords(args, keywds, "|i", kwlist, &absolute ) )
+               return EXPP_ReturnPyObjError( PyExc_AttributeError,
+                               "expected nothing or one bool (0 or 1) as argument" );
+       
+       BLI_bpathIterator_init(&bpi);
+       
+       while (!BLI_bpathIterator_isDone(&bpi)) {
+               
+               /* build the list */
+               if (absolute) {
+                       BLI_bpathIterator_copyPathExpanded( &bpi, filepath_expanded );
+                       st = PyString_FromString(filepath_expanded);
+               } else {
+                       st = PyString_FromString(BLI_bpathIterator_getPath(&bpi));
+               }
+               
+               PyList_Append(list, st);
+               Py_DECREF(st);
+               
+               BLI_bpathIterator_step(&bpi);
+       }
+       
+       return list;
+}
+
+
 static PyObject *Blender_UnpackModesDict( void )
 {
        PyObject *UnpackModes = PyConstant_New(  );
index 7d701382f7b90e3ff62894eddcd05931aad4669c..8fbb468de886dfe612ac9ea56247d1fbb82e0b04 100644 (file)
@@ -805,7 +805,8 @@ static int ActionStrip_setBlendMode( BPy_ActionStrip * self, PyObject * value )
  */
 
 #define ACTIONSTRIP_MASK (ACTSTRIP_SELECT | ACTSTRIP_USESTRIDE \
-               | ACTSTRIP_HOLDLASTFRAME | ACTSTRIP_ACTIVE | ACTSTRIP_LOCK_ACTION)
+               | ACTSTRIP_HOLDLASTFRAME | ACTSTRIP_ACTIVE | ACTSTRIP_LOCK_ACTION \
+               | ACTSTRIP_MUTE)
 
 static PyObject *ActionStrip_getFlag( BPy_ActionStrip * self )
 {
@@ -1181,6 +1182,8 @@ static PyObject *M_ActionStrip_FlagsDict( void )
                                PyInt_FromLong( ACTSTRIP_ACTIVE ) );
                PyConstant_Insert( d, "LOCK_ACTION",
                                PyInt_FromLong( ACTSTRIP_LOCK_ACTION ) );
+               PyConstant_Insert( d, "MUTE",
+                               PyInt_FromLong( ACTSTRIP_MUTE ) );
        }
        return S;
 }
index adfcf77d96568954d168ad422ec7accf76a0fab3..aeb5178f3d7a12ea32f703a9aa74fadde74dda1d 100644 (file)
@@ -18,6 +18,7 @@ It is a bitmask and settings are ORed together.
        - HOLD: continue displaying the last frame past the end of the strip
        - ACTIVE: action strip is active in NLA window
        - LOCK_ACTION: action start/end are automatically mapped to strip duration
+       - MUTE: action strip does not contribute to the NLA solution
 
 @type StrideAxes: readonly dictionary
 @var StrideAxes: Constant dict used by the L{ActionStrip.strideAxis} attribute.
index 34a147c193399fd07483c84514e883491b1666c3..f2f1c2763c0863bc58f313c0db55c128142d79db 100644 (file)
@@ -64,6 +64,7 @@ typedef struct StrandPoint {
        float co1[3], co2[3];
        float hoco1[4], hoco2[4];
        float zco1[3], zco2[3];
+       int clip1, clip2;
 
        /* screen space */
        float hoco[4];
index 68c32ee2d8bae3e8a0cff8d08f350b647f453031..c0ebab1390a3c6c8da8f57ef365d5e586b78ba3c 100644 (file)
@@ -1695,10 +1695,10 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
                        /* get orco */
                        if(tpsys && (part->from==PART_FROM_PARTICLE || part->phystype==PART_PHYS_NO)){
                                tpa=tpsys->particles+pa->num;
-                               psys_particle_on_emitter(ob, psmd,tpart->from,tpa->num, -1,tpa->fuv,tpa->foffset,co,nor,0,0,orco,0);
+                               psys_particle_on_emitter(ob, psmd,tpart->from,tpa->num,pa->num_dmcache,tpa->fuv,tpa->foffset,co,nor,0,0,orco,0);
                        }
                        else
-                               psys_particle_on_emitter(ob, psmd,part->from,pa->num,-1,pa->fuv,pa->foffset,co,nor,0,0,orco,0);
+                               psys_particle_on_emitter(ob, psmd,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,nor,0,0,orco,0);
 
                        if(uvco && ELEM(part->from,PART_FROM_FACE,PART_FROM_VOLUME)){
                                layer=psmd->dm->faceData.layers + CustomData_get_layer_index(&psmd->dm->faceData,CD_MFACE);
@@ -3502,16 +3502,22 @@ static GroupObject *add_render_lamp(Render *re, Object *ob)
                        
                        /* this is the way used all over to check for shadow */
                        if(lar->shb || (lar->mode & LA_SHAD_RAY)) {
+                               LampShadowSample *ls;
                                LampShadowSubSample *lss;
-                               int a, b, tot= re->r.threads*re->r.osa;
+                               int a, b;
                                
                                lar->shadsamp= MEM_mallocN(re->r.threads*sizeof(LampShadowSample), "lamp shadow sample");
-                               lss= lar->shadsamp[0].s;
+                               ls= lar->shadsamp;
+
                                /* shadfacs actually mean light, let's put them to 1 to prevent unitialized accidents */
-                               for(a=0; a<tot; a++, lss++) {
-                                       for(b=0; b<4; b++) {
+                               for(a=0; a<re->r.threads; a++, ls++) {
+                                       lss= ls->s;
+                                       for(b=0; b<re->r.osa; b++, lss++) {
                                                lss->samplenr= -1;      /* used to detect whether we store or read */
-                                               lss->shadfac[b]= 1.0f;
+                                               lss->shadfac[0]= 1.0f;
+                                               lss->shadfac[1]= 1.0f;
+                                               lss->shadfac[2]= 1.0f;
+                                               lss->shadfac[3]= 1.0f;
                                        }
                                }
                        }
@@ -4067,10 +4073,10 @@ static int allow_render_object(Object *ob, int nolamps, int onlyselected, Object
        return 1;
 }
 
-static int allow_render_dupli_instance(Render *re, Object *ob, Object *obd)
+static int allow_render_dupli_instance(Render *re, DupliObject *dob, Object *obd)
 {
        return (render_object_type(obd->type) &&
-               (!(ob->transflag & OB_DUPLIGROUP)) &&
+               (!(dob->type == OB_DUPLIGROUP)) &&
                !(re->r.mode & R_RADIO));
 }
 
@@ -4079,7 +4085,7 @@ static void database_init_objects(Render *re, unsigned int lay, int nolamps, int
        Base *base;
        Object *ob;
        Scene *sce;
-       float mat[4][4];
+       float mat[4][4], obmat[4][4];
 
        for(SETLOOPER(re->scene, base)) {
                ob= base->object;
@@ -4112,6 +4118,7 @@ static void database_init_objects(Render *re, unsigned int lay, int nolamps, int
                                for(dob= lb->first; dob; dob= dob->next) {
                                        Object *obd= dob->ob;
                                        
+                                       Mat4CpyMat4(obmat, obd->obmat);
                                        Mat4CpyMat4(obd->obmat, dob->mat);
 
                                        /* group duplis need to set ob matrices correct, for deform. so no_draw is part handled */
@@ -4127,14 +4134,14 @@ static void database_init_objects(Render *re, unsigned int lay, int nolamps, int
                                        if(!allow_render_object(obd, nolamps, onlyselected, actob))
                                                continue;
 
-                                       if(allow_render_dupli_instance(re, ob, obd)) {
+                                       if(allow_render_dupli_instance(re, dob, obd)) {
                                                ParticleSystem *psys;
                                                int psysindex;
                                                float imat[4][4], mat[4][4];
 
                                                /* compute difference between object matrix and
                                                 * object matrix with dupli transform, in viewspace */
-                                               Mat4Invert(imat, dob->omat);
+                                               Mat4Invert(imat, obmat);
                                                MTC_Mat4MulSerie(mat, re->viewmat, dob->mat, imat, re->viewinv, 0, 0, 0, 0);
 
                                                RE_addRenderInstance(re, NULL, obd, ob, dob->index, 0, mat);
@@ -4145,6 +4152,8 @@ static void database_init_objects(Render *re, unsigned int lay, int nolamps, int
                                                
                                                obd->flag |= OB_DONE;
                                                obd->transflag |= OB_RENDER_DUPLI;
+
+                                               Mat4CpyMat4(obd->obmat, obmat);
                                        }
                                        else
                                                init_render_object(re, obd, ob, dob->index, only_verts);
index 79c87252fc2354c861863684e8c0f1f74e3c16d8..059a72507c56128a3c075331dcaefebce502b07e 100644 (file)
@@ -822,14 +822,11 @@ void free_renderdata_tables(Render *re)
                re->totinstance= 0;
                re->instancetable.first= re->instancetable.last= NULL;
        }
-       else {
-               BLI_freelistN(&re->instancetable);
 
-               if(re->objecthash) {
-                       BLI_ghash_free(re->objecthash, NULL, NULL);
-                       re->objecthash= NULL;
-               }
-       }
+       if(re->objecthash) {
+               BLI_ghash_free(re->objecthash, NULL, NULL);
+               re->objecthash= NULL;
+       }
 
        if(re->sortedhalos) {
                MEM_freeN(re->sortedhalos);
@@ -843,6 +840,7 @@ void free_renderdata_tables(Render *re)
 
        BLI_freelistN(&re->customdata_names);
        BLI_freelistN(&re->objecttable);
+       BLI_freelistN(&re->instancetable);
 }
 
 /* ------------------------------------------------------------------------ */
index 4f0e9764a431c0e0e88f690aca1ce75f13452bc8..adaf2ae3259f3a00726d7ba9b8b1137c2ce9ba3b 100644 (file)
@@ -388,9 +388,9 @@ void strand_eval_point(StrandSegment *sseg, StrandPoint *spoint)
        Crossf(cross, spoint->co, spoint->tan);
 
        w= spoint->co[2]*strandbuf->winmat[2][3] + strandbuf->winmat[3][3];
-       dx= strandbuf->winx*cross[0]*strandbuf->winmat[0][0];
-       dy= strandbuf->winy*cross[1]*strandbuf->winmat[1][1];
-       w= sqrt(dx*dx + dy*dy)/w;
+       dx= strandbuf->winx*cross[0]*strandbuf->winmat[0][0]/w;
+       dy= strandbuf->winy*cross[1]*strandbuf->winmat[1][1]/w;
+       w= sqrt(dx*dx + dy*dy);
 
        if(w > 0.0f) {
                if(strandbuf->flag & R_STRAND_B_UNITS) {
@@ -777,7 +777,7 @@ static void strand_render(Render *re, float winmat[][4], StrandPart *spart, ZSpa
                projectvert(p2->co, winmat, hoco2);
 
                /* render both strand and single pixel wire to counter aliasing */
-               zbufclip4(zspan, 0, 0, p1->hoco2, p1->hoco1, p2->hoco1, p2->hoco2, 0, 0, 0, 0);
+               zbufclip4(zspan, 0, 0, p1->hoco2, p1->hoco1, p2->hoco1, p2->hoco2, p1->clip2, p1->clip1, p2->clip1, p2->clip2);
                zbufsinglewire(zspan, 0, 0, hoco1, hoco2);
        }
 }
@@ -817,6 +817,8 @@ static int strand_segment_recursive(Render *re, float winmat[][4], StrandPart *s
        else {
                projectvert(p.co1, winmat, p.hoco1);
                projectvert(p.co2, winmat, p.hoco2);
+               p.clip1= testclip(p.hoco1);
+               p.clip2= testclip(p.hoco2);
        }
 
        if(!strand_segment_recursive(re, winmat, spart, zspan, sseg, p1, &p, depth+1))
@@ -852,6 +854,10 @@ void render_strand_segment(Render *re, float winmat[][4], StrandPart *spart, ZSp
                projectvert(p1->co2, winmat, p1->hoco2);
                projectvert(p2->co1, winmat, p2->hoco1);
                projectvert(p2->co2, winmat, p2->hoco2);
+               p1->clip1= testclip(p1->hoco1);
+               p1->clip2= testclip(p1->hoco2);
+               p2->clip1= testclip(p2->hoco1);
+               p2->clip2= testclip(p2->hoco2);
        }
 
        if(!strand_segment_recursive(re, winmat, spart, zspan, sseg, p1, p2, 0))
index 7c3c8005e9f8061f8ace042587c55ae5a97ab2bc..57c9eab5d705dc22012b65e90c649e00333b1fbb 100644 (file)
@@ -5083,7 +5083,7 @@ static void editing_panel_links(Object *ob)
                        
                        xco= 143;
                        
-                       uiDefBut(block, LABEL,0, "Action (PoseLib):", xco, 154, 130,20, 0, 0, 0, 0, 0, "");
+                       uiDefBut(block, LABEL,0, "Pose Library (Action):", xco, 154, 200, 20, 0, 0, 0, 0, 0, "");
                        
                        /* PoseLib Action */
                        uiBlockSetCol(block, TH_BUT_SETTING2);
@@ -5100,12 +5100,12 @@ static void editing_panel_links(Object *ob)
                                
                                uiBlockBeginAlign(block);
                                        /* currently 'active' pose */
-                                       uiDefButI(block, MENU, B_POSELIB_APPLYP, menustr, xco, 85,18,20, &act->active_marker, 1, count, 0, 0, "Browses Poses in PoseLib. Applies chosen pose.");
+                                       uiDefButI(block, MENU, B_POSELIB_APPLYP, menustr, xco, 85,18,20, &act->active_marker, 1, count, 0, 0, "Browses Poses in Pose Library. Applies chosen pose.");
                                        MEM_freeN(menustr);
                                        
                                        if (act->active_marker) {
-                                               uiDefBut(block, TEX, REDRAWBUTSEDIT,"",         xco+18,85,160-18-20,20, marker->name, 0, 63, 0, 0, "Displays current PoseLib Pose name. Click to change.");
-                                               uiDefIconBut(block, BUT, B_POSELIB_REMOVEP, VICON_X, xco+160-20, 85, 20, 20, NULL, 0.0, 0.0, 0.0, 0.0, "Remove this PoseLib Pose from PoseLib");
+                                               uiDefBut(block, TEX, REDRAWBUTSEDIT,"",         xco+18,85,160-18-20,20, marker->name, 0, 63, 0, 0, "Displays current Pose Library Pose name. Click to change.");
+                                               uiDefIconBut(block, BUT, B_POSELIB_REMOVEP, VICON_X, xco+160-20, 85, 20, 20, NULL, 0.0, 0.0, 0.0, 0.0, "Remove this Pose Library Pose from Pose Library.");
                                        }
                                        
                                        /* add new poses */
index 662e0df093b0b1bab3b816b6e2650d35fd977d36..3883db39c74a3ead1618f0d1762e1440f83ad0e7 100644 (file)
@@ -192,15 +192,18 @@ static void constraint_active_func(void *ob_v, void *con_v)
 
 static void add_constraint_to_active(Object *ob, bConstraint *con)
 {
-       ListBase *list;
+       ListBase *list= get_active_constraints(ob);
+       bPoseChannel *pchan= get_active_posechannel(ob);
        
-       list = get_active_constraints(ob);
        if (list) {
                unique_constraint_name(con, list);
                BLI_addtail(list, con);
                
+               if (proxylocked_constraints_owner(ob, pchan))
+                       con->flag |= CONSTRAINT_PROXY_LOCAL;
+               
                con->flag |= CONSTRAINT_ACTIVE;
-               for(con= con->prev; con; con= con->prev)
+               for (con= con->prev; con; con= con->prev)
                        con->flag &= ~CONSTRAINT_ACTIVE;
        }
 }
@@ -211,8 +214,7 @@ static void get_constraint_ipo_context(void *ob_v, char *actname)
 {
        Object *ob= ob_v;
        
-       /* todo; check object if it has ob-level action ipo */
-       
+       /* todo: check object if it has ob-level action ipo */
        if (ob->flag & OB_POSEMODE) {
                bPoseChannel *pchan;
                
@@ -505,12 +507,15 @@ static void draw_constraint_spaceselect (uiBlock *block, bConstraint *con, short
 static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, short *xco, short *yco)
 {
        Object *ob= OBACT;
+       bPoseChannel *pchan= get_active_posechannel(ob);
        bConstraintTypeInfo *cti;
        uiBut *but;
        char typestr[32];
        short height, width = 265;
+       short proxy_protected;
        int rb_col;
 
+       /* get constraint typeinfo */
        cti= constraint_get_typeinfo(con);
        if (cti == NULL) {
                /* exception for 'Null' constraint - it doesn't have constraint typeinfo! */
@@ -522,6 +527,13 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
        else
                strcpy(typestr, cti->name);
                
+       /* determine whether constraint is proxy protected or not */
+       if (proxylocked_constraints_owner(ob, pchan)) {
+               proxy_protected= (con->flag & CONSTRAINT_PROXY_LOCAL) ? 0 : 1;
+       }
+       else
+               proxy_protected= 0;
+               
        /* unless button has own callback, it adds this callback to button */
        uiBlockSetFunc(block, constraint_active_func, ob, con);
 
@@ -536,17 +548,8 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
        /* open/close */
        uiDefIconButBitS(block, ICONTOG, CONSTRAINT_EXPAND, B_CONSTRAINT_TEST, ICON_DISCLOSURE_TRI_RIGHT, *xco-10, *yco, 20, 20, &con->flag, 0.0, 0.0, 0.0, 0.0, "Collapse/Expand Constraint");
        
-       /* up/down */
-       uiBlockBeginAlign(block);
-       uiBlockSetEmboss(block, UI_EMBOSS);
-       but = uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, VICON_MOVE_UP, *xco+width-50, *yco, 16, 18, NULL, 0.0, 0.0, 0.0, 0.0, "Move constraint up in constraint stack");
-       uiButSetFunc(but, constraint_moveUp, ob, con);
-       
-       but = uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, VICON_MOVE_DOWN, *xco+width-50+18, *yco, 16, 18, NULL, 0.0, 0.0, 0.0, 0.0, "Move constraint down in constraint stack");
-       uiButSetFunc(but, constraint_moveDown, ob, con);
-       uiBlockEndAlign(block);
-       
-       if (con->flag & CONSTRAINT_EXPAND) {
+       /* name */      
+       if ((con->flag & CONSTRAINT_EXPAND) && (proxy_protected==0)) {
                if (con->flag & CONSTRAINT_DISABLE)
                        uiBlockSetCol(block, TH_REDALERT);
                
@@ -570,14 +573,60 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
 
        uiBlockSetCol(block, TH_AUTO);  
        
-       uiBlockSetEmboss(block, UI_EMBOSSN);
+       /* proxy-protected constraints cannot be edited, so hide up/down + close buttons */
+       if (proxy_protected) {
+               uiBlockSetEmboss(block, UI_EMBOSSN);
+               
+               /* draw a ghost icon (for proxy) and also a lock beside it, to show that constraint is "proxy locked" */
+               uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, ICON_GHOST, *xco+244, *yco, 19, 19, NULL, 0.0, 0.0, 0.0, 0.0, "Proxy Protected");
+               uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, ICON_LOCKED, *xco+262, *yco, 19, 19, NULL, 0.0, 0.0, 0.0, 0.0, "Proxy Protected");
+               
+               uiBlockSetEmboss(block, UI_EMBOSS);
+       }
+       else {
+               short prev_proxylock;
+               
+               /* Up/Down buttons: 
+                *      Proxy-constraints are not allowed to occur after local (non-proxy) constraints
+                *      as that poses problems when restoring them, so disable the "up" button where
+                *      it may cause this situation.
+                */
+               if (proxylocked_constraints_owner(ob, pchan)) {
+                       if (con->prev) {
+                               prev_proxylock= (con->prev->flag & CONSTRAINT_PROXY_LOCAL) ? 0 : 1;
+                       }
+                       else
+                               prev_proxylock= 0;
+               }
+               else
+                       prev_proxylock= 0;
+                
+               uiBlockBeginAlign(block);
+                       uiBlockSetEmboss(block, UI_EMBOSS);
+                       
+                       if (prev_proxylock == 0) {
+                               but = uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, VICON_MOVE_UP, *xco+width-50, *yco, 16, 18, NULL, 0.0, 0.0, 0.0, 0.0, "Move constraint up in constraint stack");
+                               uiButSetFunc(but, constraint_moveUp, ob, con);
+                       }
+                       
+                       but = uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, VICON_MOVE_DOWN, *xco+width-50+18, *yco, 16, 18, NULL, 0.0, 0.0, 0.0, 0.0, "Move constraint down in constraint stack");
+                       uiButSetFunc(but, constraint_moveDown, ob, con);
+               uiBlockEndAlign(block);
+               
+               
+               /* Close 'button' - emboss calls here disable drawing of 'button' behind X */
+               uiBlockSetEmboss(block, UI_EMBOSSN);
+               
+                       but = uiDefIconBut(block, BUT, B_CONSTRAINT_CHANGETARGET, ICON_X, *xco+262, *yco, 19, 19, list, 0.0, 0.0, 0.0, 0.0, "Delete constraint");
+                       uiButSetFunc(but, del_constraint_func, ob, con);
+               
+               uiBlockSetEmboss(block, UI_EMBOSS);
+       }
+       
+       /* Set but-locks for protected settings (magic numbers are used here!) */
+       if (proxy_protected)
+               uiSetButLock(1, "Cannot edit Proxy-Protected Constraint");
        
-       but = uiDefIconBut(block, BUT, B_CONSTRAINT_CHANGETARGET, ICON_X, *xco+262, *yco, 19, 19, list, 0.0, 0.0, 0.0, 0.0, "Delete constraint");
-       uiButSetFunc(but, del_constraint_func, ob, con);
-
-       uiBlockSetEmboss(block, UI_EMBOSS);
-
-
        /* Draw constraint data */
        if ((con->flag & CONSTRAINT_EXPAND) == 0) {
                (*yco) -= 21;
@@ -616,7 +665,7 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
                                                
                                                /* target label */
                                                sprintf(tarstr, "Target %02d:", tarnum);
-                                               uiDefBut(block, LABEL, B_CONSTRAINT_TEST, tarstr, *xco+45, *yco-(48+yoffset), 60, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
+                                               uiDefBut(block, LABEL, B_CONSTRAINT_TEST, tarstr, *xco+45, *yco-(48+yoffset), 80, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
                                                
                                                /* target space-selector - per target */
                                                if (is_armature_target(ct->tar)) {
@@ -774,10 +823,10 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
                                /* Inverse options */
                                uiBlockBeginAlign(block);
                                        but=uiDefBut(block, BUT, B_CONSTRAINT_TEST, "Set Offset", *xco, *yco-151, (width/2),18, NULL, 0, 24, 0, 0, "Calculate current Parent-Inverse Matrix (i.e. restore offset from parent)");
-                                       uiButSetFunc(but, childof_const_setinv, data, NULL);
+                                       uiButSetFunc(but, childof_const_setinv, con, NULL);
                                        
                                        but=uiDefBut(block, BUT, B_CONSTRAINT_TEST, "Clear Offset", *xco+((width/2)+10), *yco-151, (width/2),18, NULL, 0, 24, 0, 0, "Clear Parent-Inverse Matrix (i.e. clear offset from parent)");
-                                       uiButSetFunc(but, childof_const_clearinv, data, NULL);
+                                       uiButSetFunc(but, childof_const_clearinv, con, NULL);
                                uiBlockEndAlign(block);
                        }
                        break;
@@ -1651,6 +1700,9 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
        else {
                (*yco)-=3;
        }
+       
+       /* clear any locks set up for proxies/lib-linking */
+       uiClearButLock();
 }
 
 static uiBlock *add_constraintmenu(void *arg_unused)
index 8fb5ba6cf2af6e06a51faa3b556c3e485cfaed09..1016de5c603509ae9881bdf5b754f3c32a2ab414 100644 (file)
@@ -2657,10 +2657,6 @@ static void draw_dupli_objects_color(View3D *v3d, Base *base, int color)
        
        if (base->object->restrictflag & OB_RESTRICT_VIEW) return;
        
-       /* test if we can do a displist */
-       if(base->object->transflag & OB_DUPLIGROUP)
-               use_displist= 0;
-       
        tbase.flag= OB_FROMDUPLI|base->flag;
        lb= object_duplilist(G.scene, base->object);
 
@@ -2689,7 +2685,7 @@ static void draw_dupli_objects_color(View3D *v3d, Base *base, int color)
                        if(use_displist == -1) {
                                
                                /* lamp drawing messes with matrices, could be handled smarter... but this works */
-                               if(dob->ob->type==OB_LAMP)
+                               if(dob->ob->type==OB_LAMP || dob->type==OB_DUPLIGROUP)
                                        use_displist= 0;
                                else {
                                        /* disable boundbox check for list creation */
@@ -3530,7 +3526,7 @@ int play_anim(int mode)
        ScrArea *sa, *oldsa;
        int cfraont;
        unsigned short event=0;
-       short val;
+       short val = 0; /* its possible qtest() wont run and val must be initialized */
 
        /* patch for very very old scenes */
        if(SFRA==0) SFRA= 1;
index c70f20aed896a0f6a9c0c3a0ccf8f2b4fa0d355f..3d8f70824aa2eb7fd61c49b3991e0b84d5e4890d 100644 (file)
@@ -1179,6 +1179,8 @@ void free_actcopybuf ()
                
                BLI_freelinkN(&actcopybuf, achan);
        }
+       
+       actcopybuf.first= actcopybuf.last= NULL;
 }
 
 /* This function adds data to the copy/paste buffer, freeing existing data first
@@ -1259,7 +1261,7 @@ void copy_actdata ()
        }
        
        /* check if anything ended up in the buffer */
-       if (actcopybuf.first==NULL || actcopybuf.last==NULL)
+       if (ELEM(NULL, actcopybuf.first, actcopybuf.last))
                error("Nothing copied to buffer");
        
        /* free temp memory */
@@ -1273,12 +1275,16 @@ void paste_actdata ()
        int filter;
        void *data;
        short datatype;
+       short no_name= 0;
        
        /* check if buffer is empty */
-       if (actcopybuf.first==NULL || actcopybuf.last==NULL) {
+       if (ELEM(NULL, actcopybuf.first, actcopybuf.last)) {
                error("No data in buffer to paste");
                return;
        }
+       /* check if single channel in buffer (disregard names if so)  */
+       if (actcopybuf.first == actcopybuf.last)
+               no_name= 1;
        
        /* get data */
        data= get_action_context(&datatype);
@@ -1305,7 +1311,7 @@ void paste_actdata ()
                                bActionChannel *achant= ale->owner;
                                
                                /* check if we have a corresponding action channel */
-                               if (strcmp(achan->name, achant->name)==0) {
+                               if ((no_name) || (strcmp(achan->name, achant->name)==0)) {
                                        /* check if this is a constraint channel */
                                        if (ale->type == ACTTYPE_CONCHAN) {
                                                bConstraintChannel *conchant= ale->data;
@@ -1327,13 +1333,17 @@ void paste_actdata ()
                        }
                        else if (ale->ownertype == ACTTYPE_SHAPEKEY) {
                                /* check if this action channel is "#ACP_ShapeKey" */
-                               if (strcmp(achan->name, "#ACP_ShapeKey")==0) {
+                               if ((no_name) || (strcmp(achan->name, "#ACP_ShapeKey")==0)) {
                                        ipo_src= achan->ipo;
                                        break;
                                }
                        }       
                }
                
+               /* this shouldn't happen, but it might */
+               if (ELEM(NULL, ipo_src, ipo_dst))
+                       continue;
+               
                /* loop over curves, pasting keyframes */
                for (icu= ipo_dst->curve.first; icu; icu= icu->next) {
                        for (ico= ipo_src->curve.first; ico; ico= ico->next) {
@@ -1550,7 +1560,7 @@ static void numbuts_action ()
        
        /* figure out what is under cursor */
        getmouseco_areawin(mval);
-       if (mval[0] < NAMEWIDTH) 
+       if (mval[0] > NAMEWIDTH) 
                return;
        act_channel= get_nearest_act_channel(mval, &chantype);
        
@@ -2943,10 +2953,10 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                case AKEY:
                        if (mval[0]<NAMEWIDTH) {
                                deselect_action_channels (1);
-                               allqueue (REDRAWVIEW3D, 0);
-                               allqueue (REDRAWACTION, 0);
+                               allqueue(REDRAWVIEW3D, 0);
+                               allqueue(REDRAWACTION, 0);
                                allqueue(REDRAWNLA, 0);
-                               allqueue (REDRAWIPO, 0);
+                               allqueue(REDRAWIPO, 0);
                        }
                        else if (mval[0]>ACTWIDTH) {
                                if (G.qual == LR_CTRLKEY) {
@@ -2959,9 +2969,9 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                                }
                                else {
                                        deselect_action_keys (1, 1);
-                                       allqueue (REDRAWACTION, 0);
+                                       allqueue(REDRAWACTION, 0);
                                        allqueue(REDRAWNLA, 0);
-                                       allqueue (REDRAWIPO, 0);
+                                       allqueue(REDRAWIPO, 0);
                                }
                        }
                        break;
@@ -3067,7 +3077,7 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                        break;
                        
                case NKEY:
-                       if(G.qual==0) {
+                       if (G.qual==0) {
                                numbuts_action();
                                
                                /* no panel (yet). current numbuts are not easy to put in panel... */
@@ -3272,8 +3282,7 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                }
        }
 
-       if(doredraw) addqueue(curarea->win, REDRAW, 1);
-       
+       if (doredraw) addqueue(curarea->win, REDRAW, 1);
 }
 
 /* **************************************************** */
index e0588b4c2a0493dff946dde585672bec75ccaa3c..ac5129dd02193a2732f32a2c0ff64cc0851a974c 100644 (file)
@@ -25,7 +25,7 @@
  *
  * The Original Code is: all of this file.
  *
- * Contributor(s): none yet.
+ * Contributor(s): Joshua Leung
  *
  * ***** END GPL/BL DUAL LICENSE BLOCK *****
  */
@@ -37,6 +37,7 @@
 
 #include "BLI_blenlib.h"
 #include "BLI_arithb.h"
+#include "BLI_dynstr.h"
 
 #include "DNA_action_types.h"
 #include "DNA_armature_types.h"
 #include "nla.h"
 #include "mydevice.h"
 
+/* -------------- Get Active Constraint Data ---------------------- */
 
 ListBase *get_active_constraint_channels (Object *ob, int forcevalid)
 {
        char ipstr[64];
        
-       if (!ob)
+       if (ob == NULL)
                return NULL;
        
        /* See if we are a bone constraint */
        if (ob->flag & OB_POSEMODE) {
                bActionChannel *achan;
                bPoseChannel *pchan;
-
+               
                pchan = get_active_posechannel(ob);
                if (pchan) {
-                       
                        /* Make sure we have an action */
-                       if (!ob->action){
-                               if (!forcevalid)
+                       if (ob->action == NULL) {
+                               if (forcevalid == 0)
                                        return NULL;
                                
-                               ob->action=add_empty_action("Action");
+                               ob->action= add_empty_action("Action");
                        }
                        
                        /* Make sure we have an actionchannel */
                        achan = get_action_channel(ob->action, pchan->name);
-                       if (!achan){
-                               if (!forcevalid)
+                       if (achan == NULL) {
+                               if (forcevalid == 0)
                                        return NULL;
                                
-                               achan = MEM_callocN (sizeof(bActionChannel), "actionChannel");
-
-                               strcpy (achan->name, pchan->name);
-                               sprintf (ipstr, "%s.%s", ob->action->id.name+2, achan->name);
+                               achan = MEM_callocN (sizeof(bActionChannel), "ActionChannel");
+                               
+                               strcpy(achan->name, pchan->name);
+                               sprintf(ipstr, "%s.%s", ob->action->id.name+2, achan->name);
                                ipstr[23]=0;
                                achan->ipo=     add_ipo(ipstr, ID_AC);  
                                
-                               BLI_addtail (&ob->action->chanbase, achan);
+                               BLI_addtail(&ob->action->chanbase, achan);
                        }
                        
                        return &achan->constraintChannels;
                }
-               else return NULL;
+               else 
+                       return NULL;
        }
        /* else we return object constraints */
        else {
-               if(ob->ipoflag & OB_ACTION_OB) {
+               if (ob->ipoflag & OB_ACTION_OB) {
                        bActionChannel *achan = get_action_channel(ob->action, "Object");
-                       if(achan)
+                       if (achan)
                                return &achan->constraintChannels;
                        else 
                                return NULL;
@@ -133,14 +135,14 @@ ListBase *get_active_constraint_channels (Object *ob, int forcevalid)
 
 
 /* if object in posemode, active bone constraints, else object constraints */
-ListBase *get_active_constraints(Object *ob)
+ListBase *get_active_constraints (Object *ob)
 {
-       if (!ob)
+       if (ob == NULL)
                return NULL;
 
        if (ob->flag & OB_POSEMODE) {
                bPoseChannel *pchan;
-
+               
                pchan = get_active_posechannel(ob);
                if (pchan)
                        return &pchan->constraints;
@@ -152,40 +154,46 @@ ListBase *get_active_constraints(Object *ob)
 }
 
 /* single constraint */
-bConstraint *get_active_constraint(Object *ob)
+bConstraint *get_active_constraint (Object *ob)
 {
        ListBase *lb= get_active_constraints(ob);
 
        if (lb) {
                bConstraint *con;
-               for (con= lb->first; con; con=con->next)
+               
+               for (con= lb->first; con; con=con->next) {
                        if (con->flag & CONSTRAINT_ACTIVE)
                                return con;
+               }
        }
+       
        return NULL;
 }
 
 /* single channel, for ipo */
-bConstraintChannel *get_active_constraint_channel(Object *ob)
+bConstraintChannel *get_active_constraint_channel (Object *ob)
 {
        bConstraint *con;
        bConstraintChannel *chan;
        
        if (ob->flag & OB_POSEMODE) {
-               if(ob->action) {
+               if (ob->action) {
                        bPoseChannel *pchan;
                        
                        pchan = get_active_posechannel(ob);
                        if (pchan) {
-                               for (con= pchan->constraints.first; con; con= con->next)
+                               for (con= pchan->constraints.first; con; con= con->next) {
                                        if (con->flag & CONSTRAINT_ACTIVE)
                                                break;
+                               }
+                               
                                if (con) {
                                        bActionChannel *achan = get_action_channel(ob->action, pchan->name);
                                        if (achan) {
-                                               for (chan= achan->constraintChannels.first; chan; chan= chan->next)
+                                               for (chan= achan->constraintChannels.first; chan; chan= chan->next) {
                                                        if (!strcmp(chan->name, con->name))
                                                                break;
+                                               }
                                                return chan;
                                        }
                                }
@@ -193,16 +201,20 @@ bConstraintChannel *get_active_constraint_channel(Object *ob)
                }
        }
        else {
-               for(con= ob->constraints.first; con; con= con->next)
-                       if(con->flag & CONSTRAINT_ACTIVE)
+               for (con= ob->constraints.first; con; con= con->next) {
+                       if (con->flag & CONSTRAINT_ACTIVE)
                                break;
-               if(con) {
+               }
+               
+               if (con) {
                        ListBase *lb= get_active_constraint_channels(ob, 0);
-
-                       if(lb) {
-                               for(chan= lb->first; chan; chan= chan->next)
-                                       if(!strcmp(chan->name, con->name))
+                       
+                       if (lb) {
+                               for (chan= lb->first; chan; chan= chan->next) {
+                                       if (!strcmp(chan->name, con->name))
                                                break;
+                               }
+                               
                                return chan;
                        }
                }
@@ -211,13 +223,15 @@ bConstraintChannel *get_active_constraint_channel(Object *ob)
        return NULL;
 }
 
+/* -------------- Constraint Management (Add New, Remove, Rename) -------------------- */
 
-bConstraint *add_new_constraint(short type)
+/* Creates a new constraint, initialises its data, and returns it */
+bConstraint *add_new_constraint (short type)
 {
        bConstraint *con;
        bConstraintTypeInfo *cti;
 
-       con = MEM_callocN(sizeof(bConstraint), "constraint");
+       con = MEM_callocN(sizeof(bConstraint), "Constraint");
        
        /* Set up a generic constraint datablock */
        con->type = type;
@@ -238,7 +252,8 @@ bConstraint *add_new_constraint(short type)
        return con;
 }
 
-void add_constraint_to_object(bConstraint *con, Object *ob)
+/* Adds the given constraint to the Object-level set of constraints for the given Object */
+void add_constraint_to_object (bConstraint *con, Object *ob)
 {
        ListBase *list;
        list = &ob->constraints;
@@ -247,370 +262,23 @@ void add_constraint_to_object(bConstraint *con, Object *ob)
                unique_constraint_name(con, list);
                BLI_addtail(list, con);
                
+               if (proxylocked_constraints_owner(ob, NULL))
+                       con->flag |= CONSTRAINT_PROXY_LOCAL;
+               
                con->flag |= CONSTRAINT_ACTIVE;
                for (con= con->prev; con; con= con->prev)
                        con->flag &= ~CONSTRAINT_ACTIVE;
        }
 }
 
-/* checks validity of object pointers, and NULLs,
- * if Bone doesnt exist it sets the CONSTRAINT_DISABLE flag 
- */
-static void test_constraints (Object *owner, const char substring[])
-{
-       
-       bConstraint *curcon;
-       ListBase *conlist= NULL;
-       int type;
-       
-       if (owner==NULL) return;
-       
-       /* Check parents */
-       /* Get the constraint list for this object */
-       
-       if (strlen (substring)) {
-               switch (owner->type) {
-                       case OB_ARMATURE:
-                               type = CONSTRAINT_OBTYPE_BONE;
-                               break;
-                       default:
-                               type = CONSTRAINT_OBTYPE_OBJECT;
-                               break;
-               }
-       }
-       else
-               type = CONSTRAINT_OBTYPE_OBJECT;
-       
-       
-       switch (type) {
-               case CONSTRAINT_OBTYPE_OBJECT:
-                       conlist = &owner->constraints;
-                       break;
-               case CONSTRAINT_OBTYPE_BONE:
-                       {
-                               Bone *bone;
-                               bPoseChannel *chan;
-                               
-                               bone = get_named_bone( ((bArmature *)owner->data ), substring );
-                               chan = get_pose_channel(owner->pose, substring);
-                               if (bone && chan) {
-                                       conlist = &chan->constraints;
-                               }
-                       }
-                       break;
-       }
-       
-       /* Check all constraints - is constraint valid? */
-       if (conlist) {
-               for (curcon = conlist->first; curcon; curcon=curcon->next) {
-                       curcon->flag &= ~CONSTRAINT_DISABLE;
-                       
-                       switch (curcon->type) {
-                               case CONSTRAINT_TYPE_PYTHON:
-                               {
-                                       bPythonConstraint *data = curcon->data;
-                                       
-                                       /* is there are valid script? */
-                                       if (!data->text) {
-                                               curcon->flag |= CONSTRAINT_DISABLE;
-                                               break;
-                                       }
-                                       else if (!BPY_is_pyconstraint(data->text)) {
-                                               curcon->flag |= CONSTRAINT_DISABLE;
-                                               break;
-                                       }
-                                       
-                                       /* does the constraint require target input... also validates targets */
-                                       BPY_pyconstraint_update(owner, curcon);
-                               }
-                                       break;
-                               case CONSTRAINT_TYPE_ACTION:
-                               {
-                                       bActionConstraint *data = curcon->data;
-                                       
-                                       if (!exist_object(data->tar)) {
-                                               data->tar = NULL;
-                                               curcon->flag |= CONSTRAINT_DISABLE;
-                                               break;
-                                       }
-                                       
-                                       if ( (data->tar == owner) &&
-                                                (!get_named_bone(get_armature(owner), 
-                                                                                 data->subtarget))) {
-                                               curcon->flag |= CONSTRAINT_DISABLE;
-                                               break;
-                                       }
-                               }
-                                       break;
-                               case CONSTRAINT_TYPE_LOCLIKE:
-                               {
-                                       bLocateLikeConstraint *data = curcon->data;
-                                       
-                                       if (!exist_object(data->tar)) {
-                                               data->tar = NULL;
-                                               curcon->flag |= CONSTRAINT_DISABLE;
-                                               break;
-                                       }
-                                       
-                                       if ( (data->tar == owner) &&
-                                                (!get_named_bone(get_armature(owner), 
-                                                                                 data->subtarget))) {
-                                               curcon->flag |= CONSTRAINT_DISABLE;
-                                               break;
-                                       }
-                               }
-                                       break;
-                               case CONSTRAINT_TYPE_MINMAX:
-                               {
-                                       bMinMaxConstraint *data = curcon->data;
-                                       
-                                       if (!exist_object(data->tar)) {
-                                               data->tar = NULL;
-                                               curcon->flag |= CONSTRAINT_DISABLE;
-                                               break;
-                                       }
-                                       
-                                       if ( (data->tar == owner) &&
-                                                (!get_named_bone(get_armature(owner), 
-                                                                                 data->subtarget))) {
-                                               curcon->flag |= CONSTRAINT_DISABLE;
-                                               break;
-                                       }
-                               }
-                                       break;
-                               case CONSTRAINT_TYPE_ROTLIKE:
-                               {
-                                       bRotateLikeConstraint *data = curcon->data;
-                                       
-                                       if (!exist_object(data->tar)) {
-                                               data->tar = NULL;
-                                               curcon->flag |= CONSTRAINT_DISABLE;
-                                               break;
-                                       }
-                                       
-                                       if ( (data->tar == owner) &&
-                                                (!get_named_bone(get_armature(owner), 
-                                                                                 data->subtarget))) {
-                                               curcon->flag |= CONSTRAINT_DISABLE;
-                                               break;
-                                       }
-                               }
-                                       break;
-                               case CONSTRAINT_TYPE_SIZELIKE:
-                               {
-                                       bSizeLikeConstraint *data = curcon->data;
-                               
-                                       if (!exist_object(data->tar)) {
-                                               data->tar = NULL;
-                                               curcon->flag |= CONSTRAINT_DISABLE;
-                                               break;
-                                       }
-                                       
-                                       if ( (data->tar == owner) &&
-                                                (!get_named_bone(get_armature(owner), 
-                                                                                 data->subtarget))) {
-                                               curcon->flag |= CONSTRAINT_DISABLE;
-                                               break;
-                                       }
-                               }
-                                       break;
-                               case CONSTRAINT_TYPE_KINEMATIC:
-                               {
-                                       bKinematicConstraint *data = curcon->data;
-
-                                       if (!exist_object(data->tar)) {
-                                               data->tar = NULL;
-                                               curcon->flag |= CONSTRAINT_DISABLE;
-                                       }
-                                       else if ( (data->tar == owner) &&
-                                                (!get_named_bone(get_armature(owner), 
-                                                                                 data->subtarget))) {
-                                               curcon->flag |= CONSTRAINT_DISABLE;
-                                       }
-
-                                       if (data->poletar && !exist_object(data->poletar)) {
-                                               data->poletar = NULL;
-                                       }
-                                       else if ( (data->poletar == owner) &&
-                                                (!get_named_bone(get_armature(owner), 
-                                                                                 data->polesubtarget))) {
-                                               curcon->flag |= CONSTRAINT_DISABLE;
-                                       }
-
-                               }
-                                       break;
-                               case CONSTRAINT_TYPE_TRACKTO:
-                               {
-                                       bTrackToConstraint *data = curcon->data;
-                                       if (!exist_object(data->tar)) {
-                                               data->tar = NULL;
-                                               curcon->flag |= CONSTRAINT_DISABLE;
-                                               break;
-                                       }
-                                       
-                                       if ( (data->tar == owner) &&
-                                                (!get_named_bone(get_armature(owner), 
-                                                                                 data->subtarget))) {
-                                               curcon->flag |= CONSTRAINT_DISABLE;
-                                               break;
-                                       }
-                                       if (data->reserved2==data->reserved1) {
-                                               curcon->flag |= CONSTRAINT_DISABLE;
-                                               break;
-                                       }
-                                       if (data->reserved2+3==data->reserved1) {
-                                               curcon->flag |= CONSTRAINT_DISABLE;
-                                               break;
-                                       }
-                               }
-                                       break;
-                               case CONSTRAINT_TYPE_LOCKTRACK:
-                               {
-                                       bLockTrackConstraint *data = curcon->data;
-                                       
-                                       if (!exist_object(data->tar)) {
-                                               data->tar = NULL;
-                                               curcon->flag |= CONSTRAINT_DISABLE;
-                                               break;
-                                       }
-                                       
-                                       if ( (data->tar == owner) &&
-                                                (!get_named_bone(get_armature(owner), 
-                                                                                 data->subtarget))) {
-                                               curcon->flag |= CONSTRAINT_DISABLE;
-                                               break;
-                                       }
-
-                                       if (data->lockflag==data->trackflag) {
-                                               curcon->flag |= CONSTRAINT_DISABLE;
-                                               break;
-                                       }
-                                       if (data->lockflag+3==data->trackflag) {
-                                               curcon->flag |= CONSTRAINT_DISABLE;
-                                               break;
-                                       }
-                               }
-                                       break;
-                               case CONSTRAINT_TYPE_STRETCHTO:
-                               {
-                                       bStretchToConstraint *data = curcon->data;
-                                       
-                                       if (!exist_object(data->tar)) {
-                                               data->tar = NULL;
-                                               curcon->flag |= CONSTRAINT_DISABLE;
-                                               break;
-                                       }
-                                       
-                                       if ( (data->tar == owner) &&
-                                                (!get_named_bone(get_armature(owner), 
-                                                                                 data->subtarget))) {
-                                               curcon->flag |= CONSTRAINT_DISABLE;
-                                               break;
-                                       }
-                               }
-                                       break;
-                               case CONSTRAINT_TYPE_FOLLOWPATH:
-                               {
-                                       bFollowPathConstraint *data = curcon->data;
-                                       
-                                       if (!exist_object(data->tar)) {
-                                               data->tar = NULL;
-                                               curcon->flag |= CONSTRAINT_DISABLE;
-                                               break;
-                                       }
-                                       if (data->tar->type != OB_CURVE) {
-                                               data->tar = NULL;
-                                               curcon->flag |= CONSTRAINT_DISABLE;
-                                               break;
-                                       }
-                                       if (data->upflag==data->trackflag) {
-                                               curcon->flag |= CONSTRAINT_DISABLE;
-                                               break;
-                                       }
-                                       if (data->upflag+3==data->trackflag) {
-                                               curcon->flag |= CONSTRAINT_DISABLE;
-                                               break;
-                                       }
-                               }
-                                       break;
-                               case CONSTRAINT_TYPE_CLAMPTO:
-                               {
-                                       bClampToConstraint *data = curcon->data;
-                                       
-                                       if (!exist_object(data->tar)) {
-                                               data->tar = NULL;
-                                               curcon->flag |= CONSTRAINT_DISABLE;
-                                               break;
-                                       }
-                                       
-                                       if (data->tar->type != OB_CURVE) {
-                                               data->tar = NULL;
-                                               curcon->flag |= CONSTRAINT_DISABLE;
-                                               break;
-                                       }
-                                       else {
-                                               Curve *cu= data->tar->data;
-                                               
-                                               /* auto-set 'Path' setting on curve so this works  */
-                                               cu->flag |= CU_PATH;
-                                       }                                       
-                               }
-                                       break;
-                               case CONSTRAINT_TYPE_TRANSFORM:
-                               {
-                                       bTransformConstraint *data = curcon->data;
-                                       
-                                       if (!exist_object(data->tar)) {
-                                               data->tar = NULL;
-                                               curcon->flag |= CONSTRAINT_DISABLE;
-                                               break;
-                                       }
-                                       
-                                       if ( (data->tar == owner) &&
-                                                (!get_named_bone(get_armature(owner), 
-                                                                                 data->subtarget))) {
-                                               curcon->flag |= CONSTRAINT_DISABLE;
-                                               break;
-                                       }
-                               }
-                                       break;
-                       }
-               }
-       }
-}
-
-static void test_bonelist_constraints (Object *owner, ListBase *list)
-{
-       Bone *bone;
-
-       for (bone = list->first; bone; bone=bone->next) {
-               
-               test_constraints(owner, bone->name);
-               test_bonelist_constraints (owner, &bone->childbase);
-       }
-}
-
-void object_test_constraints (Object *owner)
-{
-       test_constraints(owner, "");
-
-       if(owner->type==OB_ARMATURE) {
-               bArmature *arm;
-               arm = get_armature(owner);
-               if (arm)
-                       test_bonelist_constraints (owner, &arm->bonebase);
-       }
-
-}
-
 /* helper function for add_constriant - sets the last target for the active constraint */
-static void set_constraint_nth_target(bConstraint *con, Object *target, char subtarget[], int index)
+static void set_constraint_nth_target (bConstraint *con, Object *target, char subtarget[], int index)
 {
        bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
        ListBase targets = {NULL, NULL};
        bConstraintTarget *ct;
        int num_targets, i;
-               
+       
        if (cti && cti->get_constraint_targets) {
                cti->get_constraint_targets(con, &targets);
                num_targets= BLI_countlist(&targets);
@@ -639,7 +307,7 @@ static void set_constraint_nth_target(bConstraint *con, Object *target, char sub
 }
 
 /* context: active object in posemode, active channel, optional selected channel */
-void add_constraint(int only_IK)
+void add_constraint (short only_IK)
 {
        Object *ob= OBACT, *obsel=NULL;
        bPoseChannel *pchanact=NULL, *pchansel=NULL;
@@ -648,95 +316,94 @@ void add_constraint(int only_IK)
        short nr;
        
        /* paranoia checks */
-       if(ob==NULL || ob==G.obedit) return;
+       if ((ob==NULL) || (ob==G.obedit)) 
+               return;
 
-       if(ob->pose && (ob->flag & OB_POSEMODE)) {
+       if ((ob->pose) && (ob->flag & OB_POSEMODE)) {
                bArmature *arm= ob->data;
                
                /* find active channel */
                pchanact= get_active_posechannel(ob);
-               if(pchanact==NULL) return;
-       
-               /* check protection */
-               if(ob->proxy && (pchanact->bone->layer & arm->layer_protected)) {
-                       error("Bone is Proxy protected");
+               if (pchanact==NULL) 
                        return;
-               }
                
                /* find selected bone */
-               for(pchansel= ob->pose->chanbase.first; pchansel; pchansel= pchansel->next) {
-                       if(pchansel!=pchanact)
-                               if(pchansel->bone->flag & BONE_SELECTED) 
-                                       if(pchansel->bone->layer & arm->layer)
+               for (pchansel=ob->pose->chanbase.first; pchansel; pchansel=pchansel->next) {
+                       if (pchansel != pchanact) {
+                               if (pchansel->bone->flag & BONE_SELECTED)  {
+                                       if (pchansel->bone->layer & arm->layer)
                                                break;
+                               }
+                       }
                }
        }
        
        /* find selected object */
-       for(base= FIRSTBASE; base; base= base->next)
-               if( TESTBASE(base) && base->object!=ob 
+       for (base= FIRSTBASE; base; base= base->next) {
+               if ((TESTBASE(base)) && (base->object!=ob)
                        obsel= base->object;
+       }
        
        /* the only_IK caller has checked for posemode! */
-       if(only_IK) {
-               for(con= pchanact->constraints.first; con; con= con->next) {
-                       if(con->type==CONSTRAINT_TYPE_KINEMATIC) break;
+       if (only_IK) {
+               for (con= pchanact->constraints.first; con; con= con->next) {
+                       if (con->type==CONSTRAINT_TYPE_KINEMATIC) break;
                }
-               if(con) {
+               if (con) {
                        error("Pose Channel already has IK");
                        return;
                }
                
-               if(pchansel)
+               if (pchansel)
                        nr= pupmenu("Add IK Constraint%t|To Active Bone%x10");
-               else if(obsel)
+               else if (obsel)
                        nr= pupmenu("Add IK Constraint%t|To Active Object%x10");
                else 
                        nr= pupmenu("Add IK Constraint%t|To New Empty Object%x10|Without Target%x11");
        }
        else {
-               if(pchanact) {
-                       if(pchansel)
+               if (pchanact) {
+                       if (pchansel)
                                nr= pupmenu("Add Constraint to Active Bone%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7|%l|Action%x16|Script%x18");
-                       else if(obsel && obsel->type==OB_CURVE)
+                       else if ((obsel) && (obsel->type==OB_CURVE))
                                nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|Follow Path%x6|Clamp To%x17|Stretch To%x7|%l|Action%x16|Script%x18");
-                       else if(obsel)
+                       else if (obsel)
                                nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7|%l|Action%x16|Script%x18");
                        else
                                nr= pupmenu("Add Constraint to New Empty Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7|%l|Action%x16|Script%x18");
                }
                else {
-                       if(obsel && obsel->type==OB_CURVE)
+                       if ((obsel) && (obsel->type==OB_CURVE))
                                nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|Follow Path%x6|Clamp To%x17|%l|Action%x16|Script%x18");
-                       else if(obsel)
+                       else if (obsel)
                                nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|%l|Action%x16|Script%x18");
                        else
                                nr= pupmenu("Add Constraint to New Empty Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|%l|Action%x16|Script%x18");
                }
        }
        
-       if(nr<1) return;
+       if (nr < 1) return;
        
        /* handle IK separate */
-       if(nr==10 || nr==11) {
-               
-               /* prevent weird chains... */
-               if(pchansel) {
+       if (nr==10 || nr==11) {
+               /* ik - prevent weird chains... */
+               if (pchansel) {
                        bPoseChannel *pchan= pchanact;
-                       while(pchan) {
-                               if(pchan==pchansel) break;
+                       while (pchan) {
+                               if (pchan==pchansel) break;
                                pchan= pchan->parent;
                        }
-                       if(pchan) {
+                       if (pchan) {
                                error("IK root cannot be linked to IK tip");
                                return;
                        }
+                       
                        pchan= pchansel;
-                       while(pchan) {
-                               if(pchan==pchanact) break;
+                       while (pchan) {
+                               if (pchan==pchanact) break;
                                pchan= pchan->parent;
                        }
-                       if(pchan) {
+                       if (pchan) {
                                error("IK tip cannot be linked to IK root");
                                return;
                        }               
@@ -745,11 +412,14 @@ void add_constraint(int only_IK)
                con = add_new_constraint(CONSTRAINT_TYPE_KINEMATIC);
                BLI_addtail(&pchanact->constraints, con);
                unique_constraint_name(con, &pchanact->constraints);
-               pchanact->constflag |= PCHAN_HAS_IK;    // for draw, but also for detecting while pose solving
-               if(nr==11) pchanact->constflag |= PCHAN_HAS_TARGET;
+               pchanact->constflag |= PCHAN_HAS_IK;    /* for draw, but also for detecting while pose solving */
+               if (nr==11) 
+                       pchanact->constflag |= PCHAN_HAS_TARGET;
+               if (proxylocked_constraints_owner(ob, pchanact))
+                       con->flag |= CONSTRAINT_PROXY_LOCAL;
        }
        else {
-               
+               /* normal constraints - add data */
                if (nr==1) con = add_new_constraint(CONSTRAINT_TYPE_LOCLIKE);
                else if (nr==2) con = add_new_constraint(CONSTRAINT_TYPE_ROTLIKE);
                else if (nr==3) con = add_new_constraint(CONSTRAINT_TYPE_TRACKTO);
@@ -812,10 +482,14 @@ void add_constraint(int only_IK)
                        BLI_addtail(&pchanact->constraints, con);
                        unique_constraint_name(con, &pchanact->constraints);
                        pchanact->constflag |= PCHAN_HAS_CONST; /* for draw */
+                       if (proxylocked_constraints_owner(ob, pchanact))
+                               con->flag |= CONSTRAINT_PROXY_LOCAL;
                }
                else {
                        BLI_addtail(&ob->constraints, con);
                        unique_constraint_name(con, &ob->constraints);
+                       if (proxylocked_constraints_owner(ob, NULL))
+                               con->flag |= CONSTRAINT_PROXY_LOCAL;
                }
        }
        
@@ -823,7 +497,7 @@ void add_constraint(int only_IK)
        if (pchansel) {
                set_constraint_nth_target(con, ob, pchansel->name, 0);
        }
-       else if(obsel) {
+       else if (obsel) {
                set_constraint_nth_target(con, obsel, "", 0);
        }
        else if (ELEM4(nr, 11, 13, 14, 15)==0) {        /* add new empty as target */
@@ -838,7 +512,7 @@ void add_constraint(int only_IK)
                
                /* transform cent to global coords for loc */
                if (pchanact) {
-                       if(only_IK)
+                       if (only_IK)
                                VecMat4MulVecfl(obt->loc, ob->obmat, pchanact->pose_tail);
                        else
                                VecMat4MulVecfl(obt->loc, ob->obmat, pchanact->pose_head);
@@ -855,7 +529,7 @@ void add_constraint(int only_IK)
        
        /* active flag */
        con->flag |= CONSTRAINT_ACTIVE;
-       for(con= con->prev; con; con= con->prev)
+       for (con= con->prev; con; con= con->prev)
                con->flag &= ~CONSTRAINT_ACTIVE;
 
        DAG_scene_sort(G.scene);                // sort order of objects
@@ -867,9 +541,9 @@ void add_constraint(int only_IK)
        else
                DAG_object_flush_update(G.scene, ob, OB_RECALC_OB);     // and all its relations
 
-       allqueue (REDRAWVIEW3D, 0);
-       allqueue (REDRAWBUTSOBJECT, 0);
-       allqueue (REDRAWOOPS, 0);
+       allqueue(REDRAWVIEW3D, 0);
+       allqueue(REDRAWBUTSOBJECT, 0);
+       allqueue(REDRAWOOPS, 0);
        
        if (only_IK)
                BIF_undo_push("Add IK Constraint");
@@ -878,30 +552,36 @@ void add_constraint(int only_IK)
 
 }
 
-void ob_clear_constraints(void)
+/* Remove all constraints from the active object */
+void ob_clear_constraints (void)
 {
        Object *ob= OBACT;
        
        /* paranoia checks */
-       if(!ob) return;
-       if(ob==G.obedit || (ob->flag & OB_POSEMODE)) return;
+       if ((ob==NULL) || (ob==G.obedit) || (ob->flag & OB_POSEMODE)) 
+               return;
        
-       if(okee("Clear Constraints")==0) return;
+       /* get user permission */
+       if (okee("Clear Constraints")==0) 
+               return;
        
+       /* do freeing */
        free_constraints(&ob->constraints);
        
+       /* do updates */
        DAG_object_flush_update(G.scene, ob, OB_RECALC_OB);
        
-       allqueue (REDRAWVIEW3D, 0);
-       allqueue (REDRAWBUTSOBJECT, 0);
-       allqueue (REDRAWOOPS, 0);
+       allqueue(REDRAWVIEW3D, 0);
+       allqueue(REDRAWBUTSOBJECT, 0);
+       allqueue(REDRAWOOPS, 0);
        
        BIF_undo_push("Clear Constraint(s)");
-       
 }
 
-/* con already has the new name */
-void rename_constraint(Object *ob, bConstraint *con, char *oldname)
+/* Rename the given constraint 
+ *     - con already has the new name 
+ */
+void rename_constraint (Object *ob, bConstraint *con, char *oldname)
 {
        bConstraint *tcon;
        bConstraintChannel *conchan;
@@ -910,33 +590,35 @@ void rename_constraint(Object *ob, bConstraint *con, char *oldname)
        char *channame="";
        
        /* get context by searching for con (primitive...) */
-       for(tcon= ob->constraints.first; tcon; tcon= tcon->next)
-               if(tcon==con)
+       for (tcon= ob->constraints.first; tcon; tcon= tcon->next) {
+               if (tcon==con)
                        break;
+       }
        
-       if(tcon) {
+       if (tcon) {
                conlist= &ob->constraints;
                channame= "Object";
                from_object= 1;
        }
-       else if(ob->pose) {
+       else if (ob->pose) {
                bPoseChannel *pchan;
                
-               for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
-                       for(tcon= pchan->constraints.first; tcon; tcon= tcon->next) {
-                               if(tcon==con)
+               for (pchan=ob->pose->chanbase.first; pchan; pchan=pchan->next) {
+                       for (tcon= pchan->constraints.first; tcon; tcon= tcon->next) {
+                               if (tcon==con)
                                        break;
                        }
-                       if(tcon)
+                       if (tcon) 
                                break;
                }
-               if(tcon) {
+               
+               if (tcon) {
                        conlist= &pchan->constraints;
                        channame= pchan->name;
                }
        }
        
-       if(conlist==NULL) {
+       if (conlist==NULL) {
                printf("rename constraint failed\n");   /* should not happen in UI */
                return;
        }
@@ -945,29 +627,235 @@ void rename_constraint(Object *ob, bConstraint *con, char *oldname)
        unique_constraint_name (con, conlist);
 
        /* own channels */
-       if(from_object) {
-               for(conchan= ob->constraintChannels.first; conchan; conchan= conchan->next) {
-                       if( strcmp(oldname, conchan->name)==0 )
+       if (from_object) {
+               for (conchan= ob->constraintChannels.first; conchan; conchan= conchan->next) {
+                       if ( strcmp(oldname, conchan->name)==0 )
                                BLI_strncpy(conchan->name, con->name, sizeof(conchan->name));
                }
        }
+       
        /* own action */
-       if(ob->action) {
+       if (ob->action) {
                bActionChannel *achan= get_action_channel(ob->action, channame);
-               if(achan) {
+               if (achan) {
                        conchan= get_constraint_channel(&achan->constraintChannels, oldname);
-                       if(conchan)
+                       if (conchan)
                                BLI_strncpy(conchan->name, con->name, sizeof(conchan->name));
                }
        }
+}
+
+
+/* ------------- Constraint Sanity Testing ------------------- */
+
+/* checks validity of object pointers, and NULLs,
+ * if Bone doesnt exist it sets the CONSTRAINT_DISABLE flag 
+ */
+static void test_constraints (Object *owner, const char substring[])
+{
+       bConstraint *curcon;
+       ListBase *conlist= NULL;
+       int type;
        
+       if (owner==NULL) return;
+       
+       /* Check parents */
+       if (strlen (substring)) {
+               switch (owner->type) {
+                       case OB_ARMATURE:
+                               type = CONSTRAINT_OBTYPE_BONE;
+                               break;
+                       default:
+                               type = CONSTRAINT_OBTYPE_OBJECT;
+                               break;
+               }
+       }
+       else
+               type = CONSTRAINT_OBTYPE_OBJECT;
+       
+       /* Get the constraint list for this object */
+       switch (type) {
+               case CONSTRAINT_OBTYPE_OBJECT:
+                       conlist = &owner->constraints;
+                       break;
+               case CONSTRAINT_OBTYPE_BONE:
+                       {
+                               Bone *bone;
+                               bPoseChannel *chan;
+                               
+                               bone = get_named_bone( ((bArmature *)owner->data ), substring );
+                               chan = get_pose_channel(owner->pose, substring);
+                               if (bone && chan) {
+                                       conlist = &chan->constraints;
+                               }
+                       }
+                       break;
+       }
+       
+       /* Check all constraints - is constraint valid? */
+       if (conlist) {
+               for (curcon = conlist->first; curcon; curcon=curcon->next) {
+                       bConstraintTypeInfo *cti= constraint_get_typeinfo(curcon);
+                       ListBase targets = {NULL, NULL};
+                       bConstraintTarget *ct;
+                       
+                       /* clear disabled-flag first */
+                       curcon->flag &= ~CONSTRAINT_DISABLE;
+                       
+                       /* Check specialised data (settings) for constraints that need this */
+                       if (curcon->type == CONSTRAINT_TYPE_PYTHON) {
+                               bPythonConstraint *data = curcon->data;
+                               
+                               /* is there are valid script? */
+                               if (data->text == NULL) {
+                                       curcon->flag |= CONSTRAINT_DISABLE;
+                               }
+                               else if (BPY_is_pyconstraint(data->text)==0) {
+                                       curcon->flag |= CONSTRAINT_DISABLE;
+                               }
+                               else {  
+                                       /* does the constraint require target input... also validates targets */
+                                       BPY_pyconstraint_update(owner, curcon);
+                               }
+                               
+                               /* targets have already been checked for this */
+                               continue;
+                       }
+                       else if (curcon->type == CONSTRAINT_TYPE_KINEMATIC) {
+                               bKinematicConstraint *data = curcon->data;
+                               
+                               /* bad: we need a separate set of checks here as poletarget is 
+                                *              optional... otherwise poletarget must exist too or else
+                                *              the constraint is deemed invalid
+                                */
+                               if (exist_object(data->tar) == 0) {
+                                       data->tar = NULL;
+                                       curcon->flag |= CONSTRAINT_DISABLE;
+                               }
+                               else if (data->tar == owner) {
+                                       if (!get_named_bone(get_armature(owner), data->subtarget)) {
+                                               curcon->flag |= CONSTRAINT_DISABLE;
+                                       }
+                               }
+                               
+                               if (data->poletar) {
+                                       if (exist_object(data->poletar) == 0) {
+                                               data->poletar = NULL;
+                                               curcon->flag |= CONSTRAINT_DISABLE;
+                                       }
+                                       else if (data->poletar == owner) {
+                                               if (!get_named_bone(get_armature(owner), data->polesubtarget)) {
+                                                       curcon->flag |= CONSTRAINT_DISABLE;
+                                               }
+                                       }
+                               }
+                               
+                               /* targets have already been checked for this */
+                               continue;
+                       }
+                       else if (curcon->type == CONSTRAINT_TYPE_ACTION) {
+                               bActionConstraint *data = curcon->data;
+                               
+                               /* validate action */
+                               if (data->act == NULL) 
+                                       curcon->flag |= CONSTRAINT_DISABLE;
+                       }
+                       else if (curcon->type == CONSTRAINT_TYPE_FOLLOWPATH) {
+                               bFollowPathConstraint *data = curcon->data;
+                               
+                               /* don't allow track/up axes to be the same */
+                               if (data->upflag==data->trackflag)
+                                       curcon->flag |= CONSTRAINT_DISABLE;
+                               if (data->upflag+3==data->trackflag)
+                                       curcon->flag |= CONSTRAINT_DISABLE;
+                       }
+                       else if (curcon->type == CONSTRAINT_TYPE_TRACKTO) {
+                               bTrackToConstraint *data = curcon->data;
+                               
+                               /* don't allow track/up axes to be the same */
+                               if (data->reserved2==data->reserved1)
+                                       curcon->flag |= CONSTRAINT_DISABLE;
+                               if (data->reserved2+3==data->reserved1)
+                                       curcon->flag |= CONSTRAINT_DISABLE;
+                       }
+                       else if (curcon->type == CONSTRAINT_TYPE_LOCKTRACK) {
+                               bLockTrackConstraint *data = curcon->data;
+                               
+                               if (data->lockflag==data->trackflag)
+                                       curcon->flag |= CONSTRAINT_DISABLE;
+                               if (data->lockflag+3==data->trackflag)
+                                       curcon->flag |= CONSTRAINT_DISABLE;
+                       }
+                       
+                       /* Check targets for constraints */
+                       if (cti && cti->get_constraint_targets) {
+                               cti->get_constraint_targets(curcon, &targets);
+                               
+                               /* disable and clear constraints targets that are incorrect */
+                               for (ct= targets.first; ct; ct= ct->next) {
+                                       /* general validity checks (for those constraints that need this) */
+                                       if (exist_object(ct->tar) == 0) {
+                                               ct->tar = NULL;
+                                               curcon->flag |= CONSTRAINT_DISABLE;
+                                       }
+                                       else if (ct->tar == owner) {
+                                               if (!get_named_bone(get_armature(owner), ct->subtarget)) {
+                                                       curcon->flag |= CONSTRAINT_DISABLE;
+                                               }
+                                       }
+                                       
+                                       /* target checks for specific constraints */
+                                       if (ELEM(curcon->type, CONSTRAINT_TYPE_FOLLOWPATH, CONSTRAINT_TYPE_CLAMPTO)) {
+                                               if (ct->tar) {
+                                                       if (ct->tar->type != OB_CURVE) {
+                                                               ct->tar= NULL;
+                                                               curcon->flag |= CONSTRAINT_DISABLE;
+                                                       }
+                                                       else {
+                                                               Curve *cu= ct->tar->data;
+                                                               
+                                                               /* auto-set 'Path' setting on curve so this works  */
+                                                               cu->flag |= CU_PATH;
+                                                       }
+                                               }                                               
+                                       }
+                               }       
+                               
+                               /* free any temporary targets */
+                               if (cti->flush_constraint_targets)
+                                       cti->flush_constraint_targets(curcon, &targets, 0);
+                       }
+               }
+       }
+}
+
+static void test_bonelist_constraints (Object *owner, ListBase *list)
+{
+       Bone *bone;
+
+       for (bone = list->first; bone; bone=bone->next) {
+               test_constraints(owner, bone->name);
+               test_bonelist_constraints (owner, &bone->childbase);
+       }
+}
+
+void object_test_constraints (Object *owner)
+{
+       test_constraints(owner, "");
+
+       if (owner->type==OB_ARMATURE) {
+               bArmature *arm= get_armature(owner);
+               
+               if (arm)
+                       test_bonelist_constraints (owner, &arm->bonebase);
+       }
 }
 
 /* ********************** CONSTRAINT-SPECIFIC STUFF ********************* */
 /* ------------- PyConstraints ------------------ */
 
 /* this callback sets the text-file to be used for selected menu item */
-void validate_pyconstraint_cb(void *arg1, void *arg2)
+void validate_pyconstraint_cb (void *arg1, void *arg2)
 {
        bPythonConstraint *data = arg1;
        Text *text;
@@ -980,42 +868,44 @@ void validate_pyconstraint_cb(void *arg1, void *arg2)
 }
 
 /* this returns a string for the list of usable pyconstraint script names */
-char *buildmenu_pyconstraints(Text *con_text, int *pyconindex)
+char *buildmenu_pyconstraints (Text *con_text, int *pyconindex)
 {
+       DynStr *pupds= BLI_dynstr_new();
        Text *text;
-       char *menustr = MEM_callocN(128, "menustr pyconstraints");
-       char *name, stmp[128];
-       int buf = 128;
-       int used = strlen("Scripts: %t") + 1;
+       char *str;
+       char buf[64];
        int i;
-               
-       sprintf(menustr, "%s", "Scripts: %t");
        
+       /* add title first */
+       sprintf(buf, "Scripts: %%t|");
+       BLI_dynstr_append(pupds, buf);
+       
+       /* loop through markers, adding them */
        for (text=G.main->text.first, i=1; text; i++, text=text->id.next) {
                /* this is important to ensure that right script is shown as active */
                if (text == con_text) *pyconindex = i;
                
-               /* menu entry is length of name + 3(len(|%X)) + 6 characters for the int.*/
+               /* only include valid pyconstraint scripts */
                if (BPY_is_pyconstraint(text)) {
-                       name= text->id.name;
-                       if (strlen(name)+used+10 >= buf) {
-                               char *newbuf = MEM_callocN(buf+128, "menustr pyconstraints 2");
-                               memcpy(newbuf, menustr, used);
-                               MEM_freeN(menustr);
-                               menustr = newbuf;
-                               buf += 128;
-                       }
-                       sprintf(stmp, "|%s%%x%d", name, i);
-                       strcat(menustr, stmp);
-                       used += strlen(name)+10;
+                       BLI_dynstr_append(pupds, text->id.name+2);
+                       
+                       sprintf(buf, "%%x%d", i);
+                       BLI_dynstr_append(pupds, buf);
+                       
+                       if (text->id.next)
+                               BLI_dynstr_append(pupds, "|");
                }
        }
        
-       return menustr;
+       /* convert to normal MEM_malloc'd string */
+       str= BLI_dynstr_get_cstring(pupds);
+       BLI_dynstr_free(pupds);
+       
+       return str;
 }
 
 /* this callback gets called when the 'refresh' button of a pyconstraint gets pressed */
-void update_pyconstraint_cb(void *arg1, void *arg2)
+void update_pyconstraint_cb (void *arg1, void *arg2)
 {
        Object *owner= (Object *)arg1;
        bConstraint *con= (bConstraint *)arg2;
@@ -1029,7 +919,8 @@ void update_pyconstraint_cb(void *arg1, void *arg2)
 /* ChildOf Constraint - set inverse callback */
 void childof_const_setinv (void *conv, void *unused)
 {
-       bChildOfConstraint *data= (bChildOfConstraint *)conv;
+       bConstraint *con= (bConstraint *)conv;
+       bChildOfConstraint *data= (bChildOfConstraint *)con->data;
        Object *ob= OBACT;
        bPoseChannel *pchan= NULL;
 
@@ -1039,48 +930,30 @@ void childof_const_setinv (void *conv, void *unused)
        
        /* calculate/set inverse matrix */
        if (pchan) {
-               bConstraintOb *cob;
-               float ctime= bsystem_time(ob, (float)G.scene->r.cfra, 0.0);     /* not accurate... */
-               float pmat[4][4], chmat[4][4], cimat[4][4];
-               float vec0[3]={0,0,0}, vec1[3]={1,1,1};
+               float pmat[4][4], cinf;
+               float imat[4][4], tmat[4][4];
                
-               /* make copies of pchan's original matrices (to be restored later) */
+               /* make copy of pchan's original pose-mat (for use later) */
                Mat4CpyMat4(pmat, pchan->pose_mat);
-               Mat4CpyMat4(chmat, pchan->chan_mat);
-               Mat4CpyMat4(cimat, pchan->constinv);
-               
-               
-               /* clear pchan's transform (for constraint solving) */
-               LocEulSizeToMat4(pchan->chan_mat, vec0, vec0, vec1);
-               Mat4MulMat4(pchan->pose_mat, pmat, cimat);
-               Mat4One(pchan->constinv);
-               Mat4One(data->invmat);
-               
                
-               /* do constraint solving on pose-matrix containing no transforms
-                *       N.B. code is copied from armature.c (where_is_pose_bone) 
-                */
-               cob= constraints_make_evalob(ob, pchan, CONSTRAINT_OBTYPE_BONE);
-               solve_constraints(&pchan->constraints, cob, ctime);
-               constraints_clear_evalob(cob);
+               /* disable constraint for pose to be solved without it */
+               cinf= con->enforce;
+               con->enforce= 0.0f;
                
+               /* solve pose without constraint */
+               where_is_pose(ob);
                
-               /* parent-inverse matrix for this constraint is given by taking the 
-                * local-space (i.e. without any standard parents + restpose) pose_matrix
-                * (that was calulated with no transforms applied), and inverting it.
+               /* determine effect of constraint by removing the newly calculated 
+                * pchan->pose_mat from the original pchan->pose_mat, thus determining 
+                * the effect of the constraint
                 */
-               Mat4CpyMat4(pchan->constinv, pchan->pose_mat);
-               
-               constraint_mat_convertspace(ob, pchan, pchan->constinv, 
-                               CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL);
-                               
-               Mat4Invert(data->invmat, pchan->constinv);
-               
+               Mat4Invert(imat, pchan->pose_mat);
+               Mat4MulMat4(tmat, imat, pmat);
+               Mat4Invert(data->invmat, tmat);
                
-               /* restore original matrices of pchan */
-               Mat4CpyMat4(pchan->pose_mat, pmat);
-               Mat4CpyMat4(pchan->chan_mat, chmat);
-               Mat4CpyMat4(pchan->constinv, cimat);
+               /* recalculate pose with new inv-mat */
+               con->enforce= cinf;
+               where_is_pose(ob);
        }
        else if (ob) {
                /* use what_does_parent to find inverse - just like for normal parenting.
@@ -1096,7 +969,8 @@ void childof_const_setinv (void *conv, void *unused)
 /* ChildOf Constraint - clear inverse callback */
 void childof_const_clearinv (void *conv, void *unused)
 {
-       bChildOfConstraint *data= (bChildOfConstraint *)conv;
+       bConstraint *con= (bConstraint *)conv;
+       bChildOfConstraint *data= (bChildOfConstraint *)con->data;
        
        /* simply clear the matrix */
        Mat4One(data->invmat);
index 2c05daa189564e601a8e37a59d5bc9f56468bbe5..2274cc63980e790186408eb74ff879c4e9187f05 100644 (file)
@@ -244,6 +244,10 @@ static int key_inside_circle(short mco[2], float rad, float co[3], float *distan
        short vertco[2];
 
        project_short(co,vertco);
+       
+       if (vertco[0]==IS_CLIPPED)
+               return 0;
+       
        dx=(float)(mco[0]-vertco[0]);
        dy=(float)(mco[1]-vertco[1]);
        dist=(float)sqrt((double)(dx*dx + dy*dy));
@@ -261,6 +265,9 @@ static int key_inside_rect(rcti *rect, float co[3])
 
        project_short(co,vertco);
 
+       if (vertco[0]==IS_CLIPPED)
+               return 0;
+       
        if(vertco[0] > rect->xmin && vertco[0] < rect->xmax &&
                        vertco[1] > rect->ymin && vertco[1] < rect->ymax)
                return 1;
@@ -278,7 +285,10 @@ static int test_key_depth(float *co, bglMats *mats){
                        (GLint *)mats->viewport, &ux, &uy, &uz );
 
        project_short(co,wco);
-
+       
+       if (wco[0]==IS_CLIPPED)
+               return 0;
+       
        x=wco[0];
        y=wco[1];
 
@@ -1453,7 +1463,7 @@ void PE_do_lasso_select(short mcords[][2], short moves, short select)
                                VECCOPY(co, key->co);
                                Mat4MulVecfl(mat, co);
                                project_short(co,vertco);
-                               if(lasso_inside(mcords,moves,vertco[0],vertco[1])){
+                               if((vertco[0] != IS_CLIPPED) && lasso_inside(mcords,moves,vertco[0],vertco[1])){
                                        if(select && !(key->flag & PEK_SELECT)) {
                                                key->flag|=PEK_SELECT;
                                                pa->flag |= PARS_EDIT_RECALC;
@@ -1471,7 +1481,7 @@ void PE_do_lasso_select(short mcords[][2], short moves, short select)
                        VECCOPY(co, key->co);
                        Mat4MulVecfl(mat, co);
                        project_short(co,vertco);
-                       if(lasso_inside(mcords,moves,vertco[0],vertco[1])){
+                       if((vertco[0] != IS_CLIPPED) && lasso_inside(mcords,moves,vertco[0],vertco[1])){
                                if(select && !(key->flag & PEK_SELECT)) {
                                        key->flag|=PEK_SELECT;
                                        pa->flag |= PARS_EDIT_RECALC;
@@ -2018,7 +2028,7 @@ static void brush_cut(ParticleSystem *psys, int index, void *userData)
 
        cut=0;
 
-       project_short(key->co, vertco);
+       project_short_noclip(key->co, vertco);
        x0 = (float)vertco[0];
        x1 = (float)vertco[1];
 
@@ -2036,7 +2046,7 @@ static void brush_cut(ParticleSystem *psys, int index, void *userData)
        else {
                /* calculate path time closest to root that was inside the circle */
                for(k=1, key++; k<=keys; k++, key++){
-                       project_short(key->co, vertco);
+                       project_short_noclip(key->co, vertco);
 
                        v0 = (float)vertco[0] - x0;
                        v1 = (float)vertco[1] - x1;
index 43d163bff09a5178d1bead8d9cb14759c7a847c9..2d6cc99b1cea4af1d89435701f4130670d94aa1c 100644 (file)
@@ -1399,7 +1399,7 @@ void screenmain(void)
                else if (event==QKEY) {
                        /* Temp place to print mem debugging info ctrl+alt+shift + qkey */
                        if ( G.qual == (LR_SHIFTKEY | LR_ALTKEY | LR_CTRLKEY) ) {
-                               MEM_printmemlist();
+                               MEM_printmemlist_pydict();
                        }
                        
                        else if((G.obedit && G.obedit->type==OB_FONT && g_activearea->spacetype==SPACE_VIEW3D)||g_activearea->spacetype==SPACE_TEXT||g_activearea->spacetype==SPACE_SCRIPT);
index dd31ebaad5df7c4930ab8e5b234a744c0b657745..a85f4cb587440deb96ad016ea2b8b897c13438fa 100644 (file)
@@ -2255,6 +2255,18 @@ static Sequence *dupli_seq(Sequence *seq) {
                                "handled in duplicate!\nExpect a crash"
                                                " now...\n");
        }
+
+       if (seq->strip->crop) {
+               seqn->strip->crop = MEM_dupallocN(seq->strip->crop);
+       }
+
+       if (seq->strip->transform) {
+               seqn->strip->transform = MEM_dupallocN(seq->strip->transform);
+       }
+
+       if (seq->strip->proxy) {
+               seqn->strip->proxy = MEM_dupallocN(seq->strip->proxy);
+       }
        
        return seqn;
 }
index b3252487fa66f76873a4125b5294135a13e1737d..df3d74aa345233ead3b286fe6089388bfffdddc8 100644 (file)
@@ -2730,7 +2730,7 @@ void view3d_edit_clipping(View3D *v3d)
                if(val==0) return;
                
                v3d->flag |= V3D_CLIPPING;
-               v3d->clipbb= MEM_mallocN(sizeof(BoundBox), "clipbb");
+               v3d->clipbb= MEM_callocN(sizeof(BoundBox), "clipbb");
                
                /* convert border to 3d coordinates */
                
index a5e2f8b11a3a6c35b20c0ee044acfc6d69a3b839..1707dc828700d8e26360512f11e5282dbe7962c3 100644 (file)
@@ -1280,13 +1280,13 @@ void action_buttons(void)
        /* draw AUTOSNAP */
        if (G.saction->flag & SACTION_DRAWTIME) {
                uiDefButS(block, MENU, B_REDR,
-                               "Auto-Snap Keyframes %t|No Snap %x0|Second Step Snap %x1|Nearest Second Snap %x2|Nearest Marker Snap%x3", 
+                               "Auto-Snap Keyframes %t|No Snap %x0|Second Step %x1|Nearest Second %x2|Nearest Marker %x3", 
                                xco,0,70,YIC, &(G.saction->autosnap), 0, 1, 0, 0, 
                                "Auto-snapping mode for keyframes when transforming");
        }
        else {
                uiDefButS(block, MENU, B_REDR, 
-                               "Auto-Snap Keyframes %t|No Snap %x0|Frame Step Snap %x1|Nearest Frame Snap %x2|Nearest Marker Snap %x3", 
+                               "Auto-Snap Keyframes %t|No Snap %x0|Frame Step %x1|Nearest Frame %x2|Nearest Marker %x3", 
                                xco,0,70,YIC, &(G.saction->autosnap), 0, 1, 0, 0, 
                                "Auto-snapping mode for keyframes when transforming");
        }
index 3b614ebfb7cb36ae803d2e8693d1cf582f3721b0..05f809a46ae4e9aa636e85187d3b8496ddc1b6ed 100644 (file)
@@ -517,47 +517,19 @@ void nla_buttons(void)
        
        if (G.snla->flag & SNLA_DRAWTIME) {
                uiDefButS(block, MENU, B_REDR,
-                               "Auto-Snap Strips/Keyframes %t|Off %x0|Second Step %x1|Nearest Second %x2|Nearest Marker %x3", 
+                               "Auto-Snap Strips/Keyframes %t|No Snap %x0|Second Step %x1|Nearest Second %x2|Nearest Marker %x3", 
                                xco,0,70,YIC, &(G.snla->autosnap), 0, 1, 0, 0, 
                                "Auto-snapping mode for strips and keyframes when transforming");
        }
        else {
                uiDefButS(block, MENU, B_REDR, 
-                               "Auto-Snap Strips/Keyframes %t|Off %x0|Frame Step %x1|Nearest Frame %x2|Nearest Marker %x3", 
+                               "Auto-Snap Strips/Keyframes %t|No Snap %x0|Frame Step %x1|Nearest Frame %x2|Nearest Marker %x3", 
                                xco,0,70,YIC, &(G.snla->autosnap), 0, 1, 0, 0, 
                                "Auto-snapping mode for strips and keyframes when transforming");
        }
        
        xco += (70 + 8);
        
-       /* FULL WINDOW */
-       
-       
-//     xco = 8;
-       
-//     uiDefIconTextButC(block, ICONTEXTROW,B_NEWSPACE, ICON_VIEW3D, windowtype_pup(), xco,0,XIC+10,YIC, &(curarea->butspacetype), 1.0, SPACEICONMAX, 0, 0, "Displays Current Window Type. Click for menu of available types.");
-
-//     xco+= XIC+22;
-       
-       /* FULL WINDOW */
-//     if(curarea->full) uiDefIconBut(block, BUT,B_FULL, ICON_SPLITSCREEN,     xco,0,XIC,YIC, 0, 0, 0, 0, 0, "Returns to multiple views window (CTRL+Up arrow)");
-//     else uiDefIconBut(block, BUT,B_FULL, ICON_FULLSCREEN,   xco,0,XIC,YIC, 0, 0, 0, 0, 0, "Makes current window full screen (CTRL+Down arrow)");
-       
-       /* HOME */
-//     uiDefIconBut(block, BUT, B_NLAHOME, ICON_HOME,  xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Zooms window to home view showing all items (HOMEKEY)");    
-//     xco+= XIC;
-       
-       /* IMAGE */
-//     uiDefIconButS(block, TOG, B_REDR, ICON_IMAGE_COL,       xco+=XIC,0,XIC,YIC, &sseq->mainb, 0, 0, 0, 0, "Toggles image display");
-
-       /* ZOOM en BORDER */
-//     xco+= XIC;
-//     uiDefIconButI(block, TOG, B_VIEW2DZOOM, ICON_VIEWZOOM,  xco+=XIC,0,XIC,YIC, &viewmovetemp, 0, 0, 0, 0, "Zoom view (CTRL+MiddleMouse)");
-//     uiDefIconBut(block, BUT, B_NLABORDER, ICON_BORDERMOVE,  xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Zoom view to area");
-
-       /* draw LOCK */
-//     xco+= XIC/2;
-
        xco += 8;
 
        uiDefIconButS(block, ICONTOG, 1, ICON_UNLOCKED, xco,0,XIC,YIC, &(snla->lock), 0, 0, 0, 0, "Toggles forced redraw of other windows to reflect changes in real time");
index 89f21301213e4eb4e7b867bc74ccd7eb68c4e291..e34890c4313eedc47ef2654508a2497d6848b919 100644 (file)
@@ -4083,7 +4083,7 @@ static uiBlock *view3d_pose_armature_poselibmenu(void *arg_unused)
        block= uiNewBlock(&curarea->uiblocks, "view3d_pose_armature_poselibmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
        uiBlockSetButmFunc(block, do_view3d_pose_armature_poselibmenu, NULL);
        
-       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Apply Pose|Ctrl L",                      0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Browse Poses|Ctrl L",                    0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
        
        uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
        
@@ -4174,7 +4174,7 @@ static uiBlock *view3d_pose_armaturemenu(void *arg_unused)
        
        uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
        
-       uiDefIconTextBlockBut(block, view3d_pose_armature_poselibmenu, NULL, ICON_RIGHTARROW_THIN, "PoseLib", 0, yco-=20, 120, 19, "");
+       uiDefIconTextBlockBut(block, view3d_pose_armature_poselibmenu, NULL, ICON_RIGHTARROW_THIN, "Pose Library", 0, yco-=20, 120, 19, "");
        uiDefIconTextBlockBut(block, view3d_pose_armature_motionpathsmenu, NULL, ICON_RIGHTARROW_THIN, "Motion Paths", 0, yco-=20, 120, 19, "");
        uiDefIconTextBlockBut(block, view3d_pose_armature_ikmenu, NULL, ICON_RIGHTARROW_THIN, "Inverse Kinematics", 0, yco-=20, 120, 19, "");
        uiDefIconTextBlockBut(block, view3d_pose_armature_constraintsmenu, NULL, ICON_RIGHTARROW_THIN, "Constraints", 0, yco-=20, 120, 19, "");
index 3b957b5f1423096389234f9a2baacb6fc50237f3..f0d23f9988a7bf96b01242f55e3df77917227a96 100644 (file)
@@ -229,6 +229,7 @@ static void check_persistant(SpaceOops *soops, TreeElement *te, ID *id, short ty
        if(type) tselem->nr= nr; // we're picky! :)
        else tselem->nr= 0;
        tselem->id= id;
+       tselem->used = 0;
        tselem->flag= TSE_CLOSED;
        te->store_index= ts->usedelem;
        
index 2d11f149ed774abc3cef09b698228ed2a4d72e46..c87531ec8bd02e1ff1120ace87f1cbd66e6f67c0 100644 (file)
@@ -515,6 +515,49 @@ void poselib_rename_pose (Object *ob)
 
 /* ************************************************************* */
 
+/* Simple struct for storing settings/data for use during PoseLib preview */
+typedef struct tPoseLib_PreviewData {
+       ListBase backups;               /* tPoseLib_Backup structs for restoring poses */
+       ListBase searchp;               /* LinkData structs storing list of poses which match the current search-string */
+       
+       Object *ob;                             /* object to work on */
+       bArmature *arm;                 /* object's armature data */
+       bPose *pose;                    /* object's pose */
+       bAction *act;                   /* poselib to use */
+       TimeMarker *marker;             /* 'active' pose */
+       
+       short state;                    /* state of main loop */
+       short redraw;                   /* redraw/update settings during main loop */
+       short firsttime;                /* first loop... (no restore) */
+       
+       int selcount;                   /* number of selected elements to work on */
+       int totcount;                   /* total number of elements to work on */
+       
+       char headerstr[200];    /* Info-text to print in header */
+       
+       char searchstr[64];             /* (Part of) Name to search for to filter poses that get shown */
+       char searchold[64];             /* Previously set searchstr (from last loop run), so that we can detected when to rebuild searchp */
+       short search_cursor;    /* position of cursor in searchstr (cursor occurs before the item at the nominated index) */
+} tPoseLib_PreviewData;
+
+/* defines for tPoseLib_PreviewData->state values */
+enum {
+       PL_PREVIEW_ERROR = -1,
+       PL_PREVIEW_RUNNING,
+       PL_PREVIEW_CONFIRM,
+       PL_PREVIEW_CANCEL,
+       PL_PREVIEW_RUNONCE 
+};
+
+/* defines for tPoseLib_PreviewData->redraw values */
+enum {
+       PL_PREVIEW_NOREDRAW = 0,
+       PL_PREVIEW_REDRAWALL,
+       PL_PREVIEW_REDRAWHEADER,
+};
+
+/* ---------------------------- */
+
 /* simple struct for storing backup info */
 typedef struct tPoseLib_Backup {
        struct tPoseLib_Backup *next, *prev;
@@ -524,41 +567,46 @@ typedef struct tPoseLib_Backup {
 } tPoseLib_Backup;
 
 /* Makes a copy of the current pose for restoration purposes - doesn't do constraints currently */
-static void poselib_backup_posecopy (ListBase *backups, bPose *pose, bAction *act)
+static void poselib_backup_posecopy (tPoseLib_PreviewData *pld)
 {
        bActionChannel *achan;
        bPoseChannel *pchan;
        
        /* for each posechannel that has an actionchannel in */
-       for (achan= act->chanbase.first; achan; achan= achan->next) {
+       for (achan= pld->act->chanbase.first; achan; achan= achan->next) {
                /* try to find posechannel */
-               pchan= get_pose_channel(pose, achan->name);
+               pchan= get_pose_channel(pld->pose, achan->name);
                
                /* backup data if available */
                if (pchan) {
                        tPoseLib_Backup *plb;
                        
+                       /* store backup */
                        plb= MEM_callocN(sizeof(tPoseLib_Backup), "tPoseLib_Backup");
                        
                        plb->pchan= pchan;
                        memcpy(&plb->olddata, plb->pchan, sizeof(bPoseChannel));
                        
-                       BLI_addtail(backups, plb);
+                       BLI_addtail(&pld->backups, plb);
+                       
+                       /* mark as being affected */
+                       if ((pchan->bone) && (pchan->bone->flag & BONE_SELECTED))
+                               pld->selcount++;
+                       pld->totcount++;
                }
        }
 }
 
 /* Restores original pose - doesn't do constraints currently */
-static void poselib_backup_restore (ListBase *backups)
+static void poselib_backup_restore (tPoseLib_PreviewData *pld)
 {
        tPoseLib_Backup *plb;
        
-       for (plb= backups->first; plb; plb= plb->next) {
+       for (plb= pld->backups.first; plb; plb= plb->next) {
                memcpy(plb->pchan, &plb->olddata, sizeof(bPoseChannel));
        }
 }
 
-
 /* ---------------------------- */
 
 /* Applies the appropriate stored pose from the pose-library to the current pose
@@ -566,14 +614,19 @@ static void poselib_backup_restore (ListBase *backups)
  *     - gets the string to print in the header
  *     - this code is based on the code for extract_pose_from_action in blenkernel/action.c
  */
-static void poselib_apply_pose (Object *ob, TimeMarker *marker, char headerstr[])
+static void poselib_apply_pose (tPoseLib_PreviewData *pld)
 {
-       bPose *pose= ob->pose;
+       bPose *pose= pld->pose;
        bPoseChannel *pchan;
-       bAction *act= ob->poselib;
+       bAction *act= pld->act;
        bActionChannel *achan;
        IpoCurve *icu;
-       int frame= marker->frame;
+       int frame;
+       
+       if (pld->marker)
+               frame= pld->marker->frame;
+       else
+               return; 
        
        /* start applying - only those channels which have a key at this point in time! */
        for (achan= act->chanbase.first; achan; achan= achan->next) {
@@ -600,13 +653,18 @@ static void poselib_apply_pose (Object *ob, TimeMarker *marker, char headerstr[]
                        if (found) {
                                pchan= get_pose_channel(pose, achan->name);
                                
-                               if ( (pchan) && (pchan->bone) && 
-                                        (pchan->bone->flag & (BONE_SELECTED|BONE_ACTIVE)) ) 
-                               {
-                                       /* Evaluates and sets the internal ipo values   */
-                                       calc_ipo(achan->ipo, frame);
-                                       /* This call also sets the pchan flags */
-                                       execute_action_ipo(achan, pchan);
+                               if (pchan) {    
+                                       short ok;
+                                       
+                                       ok= (pchan->bone) ? (pchan->bone->flag & (BONE_SELECTED|BONE_ACTIVE)) : 0;
+                                       ok= (ok || pld->selcount) ? 1 : 0; 
+                                       
+                                       if (ok) {
+                                               /* Evaluates and sets the internal ipo values   */
+                                               calc_ipo(achan->ipo, frame);
+                                               /* This call also sets the pchan flags */
+                                               execute_action_ipo(achan, pchan);
+                                       }
                                }
                        }
                }
@@ -620,21 +678,22 @@ static void poselib_apply_pose (Object *ob, TimeMarker *marker, char headerstr[]
 }
 
 /* Auto-keys/tags bones affected by the pose used from the poselib */
-static void poselib_keytag_pose (Object *ob)
+static void poselib_keytag_pose (tPoseLib_PreviewData *pld)
 {
+       bPose *pose= pld->pose;
        bPoseChannel *pchan;
-       bAction *act= ob->poselib;
+       bAction *act= pld->act;
        bActionChannel *achan;
        
        /* start tagging/keying */
        for (achan= act->chanbase.first; achan; achan= achan->next) {
                /* only for selected action channels */
                if (achan->flag & ACHAN_SELECTED) {
-                       pchan= get_pose_channel(ob->pose, achan->name);
+                       pchan= get_pose_channel(pose, achan->name);
                        
                        if (pchan) {
                                if (G.flags & G_RECORDKEYS) {
-                                       ID *id= &ob->id;
+                                       ID *id= &pld->ob->id;
                                        
                                        /* Set keys on pose */
                                        if (pchan->flag & POSE_ROT) {
@@ -673,216 +732,361 @@ static void poselib_keytag_pose (Object *ob)
 /* This helper function is called during poselib_preview_poses to find the 
  * pose to preview next (after a change event)
  */
-static TimeMarker *poselib_preview_get_next (bAction *act, TimeMarker *current, int step)
+static void poselib_preview_get_next (tPoseLib_PreviewData *pld, int step)
 {
-       if (step) {
-               TimeMarker *marker, *next;
-               
-               /* Loop through the markers in a cyclic fashion, incrementing/decrementing step as appropriate 
-                * until step == 0. At this point, marker should be the correct marker.
-                */
-               if (step > 0) {
-                       for (marker=current; marker && step; marker=next, step--)
-                               next= (marker->next) ? marker->next : act->markers.first;
+       if ((pld->marker) && (step)) {
+               /* search-string dictates a special approach */
+               if (pld->searchstr[0]) {
+                       TimeMarker *marker;
+                       LinkData *ld, *ldn, *ldc;
+                       
+                       /* free and rebuild if needed (i.e. if search-str changed) */
+                       if (strcmp(pld->searchstr, pld->searchold)) {
+                               /* free list of temporary search matches */
+                               BLI_freelistN(&pld->searchp);
+                               
+                               /* generate a new list of search matches */
+                               for (marker= pld->act->markers.first; marker; marker= marker->next) {
+                                       /* does the name partially match? 
+                                        *      - don't worry about case, to make it easier for users to quickly input a name (or 
+                                        *        part of one), which is the whole point of this feature
+                                        */
+                                       if (BLI_strcasestr(marker->name, pld->searchstr)) {
+                                               /* make link-data to store reference to it */
+                                               ld= MEM_callocN(sizeof(LinkData), "PoseMatch");
+                                               ld->data= marker;
+                                               BLI_addtail(&pld->searchp, ld);
+                                       }
+                               }
+                               
+                               /* set current marker to NULL (so that we start from first) */
+                               pld->marker= NULL;
+                       }
+                       
+                       /* check if any matches */
+                       if (pld->searchp.first == NULL) { 
+                               pld->marker= NULL;
+                               return;
+                       }
+                       
+                       /* find first match */
+                       for (ldc= pld->searchp.first; ldc; ldc= ldc->next) {
+                               if (ldc->data == pld->marker)
+                                       break;
+                       }
+                       if (ldc == NULL)
+                               ldc= pld->searchp.first;
+                               
+                       /* Loop through the matches in a cyclic fashion, incrementing/decrementing step as appropriate 
+                        * until step == 0. At this point, marker should be the correct marker.
+                        */
+                       if (step > 0) {
+                               for (ld=ldc; ld && step; ld=ldn, step--)
+                                       ldn= (ld->next) ? ld->next : pld->searchp.first;
+                       }
+                       else {
+                               for (ld=ldc; ld && step; ld=ldn, step++)
+                                       ldn= (ld->prev) ? ld->prev : pld->searchp.last;
+                       }
+                       
+                       /* set marker */
+                       if (ld)
+                               pld->marker= ld->data;
                }
                else {
-                       for (marker=current; marker && step; marker=next, step++)
-                               next= (marker->prev) ? marker->prev : act->markers.last;
+                       TimeMarker *marker, *next;
+                       
+                       /* Loop through the markers in a cyclic fashion, incrementing/decrementing step as appropriate 
+                        * until step == 0. At this point, marker should be the correct marker.
+                        */
+                       if (step > 0) {
+                               for (marker=pld->marker; marker && step; marker=next, step--)
+                                       next= (marker->next) ? marker->next : pld->act->markers.first;
+                       }
+                       else {
+                               for (marker=pld->marker; marker && step; marker=next, step++)
+                                       next= (marker->prev) ? marker->prev : pld->act->markers.last;
+                       }
+                       
+                       /* it should be fairly impossible for marker to be NULL */
+                       if (marker)
+                               pld->marker= marker;
                }
-               
-               /* don't go anywhere if for some reason an error occurred */
-               return (marker) ? marker : current;
        }
-       else
-               return current;
 }
 
-/* ---------------------------- */
+/* specially handle events for searching */
+static void poselib_preview_handle_search (tPoseLib_PreviewData *pld, unsigned short event, char ascii)
+{
+       if (ascii) {
+               /* character to add to the string */
+               short index= pld->search_cursor;
+               short len= (pld->searchstr[0]) ? strlen(pld->searchstr) : 0;
+               short i;
+               
+               if (len) {
+                       for (i = len; i > index; i--)  
+                               pld->searchstr[i]= pld->searchstr[i-1];
+               }
+               else
+                       pld->searchstr[1]= 0;
+                       
+               pld->searchstr[index]= ascii;
+               pld->search_cursor++;
+               
+               poselib_preview_get_next(pld, 1);
+               pld->redraw = PL_PREVIEW_REDRAWALL;
+       }
+       else {
+               /* some form of string manipulation */
+               switch (event) {
+                       case BACKSPACEKEY:
+                               if (pld->searchstr[0] && pld->search_cursor) {
+                                       short len= strlen(pld->searchstr);
+                                       short index= pld->search_cursor;
+                                       short i;
+                                       
+                                       for (i = index; i <= len; i++) 
+                                               pld->searchstr[i-1] = pld->searchstr[i];
+                                       
+                                       pld->search_cursor--;
+                                       
+                                       poselib_preview_get_next(pld, 1);
+                                       pld->redraw = PL_PREVIEW_REDRAWALL;
+                               }       
+                               break;
+                               
+                       case DELKEY:
+                               if (pld->searchstr[0] && pld->searchstr[1]) {
+                                       short len= strlen(pld->searchstr);
+                                       short index= pld->search_cursor;
+                                       int i;
+                                       
+                                       if (index < len) {
+                                               for (i = index; i < len; i++) 
+                                                       pld->searchstr[i] = pld->searchstr[i+1];
+                                                       
+                                               poselib_preview_get_next(pld, 1);
+                                               pld->redraw = PL_PREVIEW_REDRAWALL;
+                                       }
+                               }
+                               break;
+               }
+       }
+}
 
-/* defines for poselib_preview_poses --> ret_val values */
-enum {
-       PL_PREVIEW_RUNNING = 0,
-       PL_PREVIEW_CONFIRM,
-       PL_PREVIEW_CANCEL,
-       PL_PREVIEW_RUNONCE 
-};
+/* handle events for poselib_preview_poses */
+static void poselib_preview_handle_event (tPoseLib_PreviewData *pld, unsigned short event, char ascii)
+{
+       /* backup stuff that needs to occur before every operation
+        *      - make a copy of searchstr, so that we know if cache needs to be rebuilt
+        */
+       strcpy(pld->searchold, pld->searchstr);
+       
+       /* searching takes priority over normal activity */
+       switch (event) {
+               /* exit - cancel */
+               case ESCKEY:
+               case RIGHTMOUSE:
+                       pld->state= PL_PREVIEW_CANCEL;
+                       break;
+                       
+               /* exit - confirm */
+               case LEFTMOUSE:
+               case RETKEY:
+               case PADENTER:
+               case SPACEKEY:
+                       pld->state= PL_PREVIEW_CONFIRM;
+                       break;
+               
+               /* change to previous pose (cyclic) */
+               case PAGEUPKEY:
+               case WHEELUPMOUSE:
+                       poselib_preview_get_next(pld, -1);
+                       pld->redraw= PL_PREVIEW_REDRAWALL;
+                       break;
+               
+               /* change to next pose (cyclic) */
+               case PAGEDOWNKEY:
+               case WHEELDOWNMOUSE:
+                       poselib_preview_get_next(pld, 1);
+                       pld->redraw= PL_PREVIEW_REDRAWALL;
+                       break;
+               
+               /* jump 5 poses (cyclic, back) */
+               case DOWNARROWKEY:
+                       poselib_preview_get_next(pld, -5);
+                       pld->redraw= PL_PREVIEW_REDRAWALL;
+                       break;
+               
+               /* jump 5 poses (cyclic, forward) */
+               case UPARROWKEY:
+                       poselib_preview_get_next(pld, 5);
+                       pld->redraw= PL_PREVIEW_REDRAWALL;
+                       break;
+               
+               /* change to previous pose or searching cursor control */
+               case RIGHTARROWKEY:
+                       if (pld->searchstr[0]) {
+                               /* move text-cursor to the right */
+                               if (pld->search_cursor < strlen(pld->searchstr))
+                                       pld->search_cursor++;
+                               pld->redraw= PL_PREVIEW_REDRAWHEADER;
+                       }
+                       else {
+                               /* change to previous pose (cyclic) */
+                               poselib_preview_get_next(pld, -1);
+                               pld->redraw= PL_PREVIEW_REDRAWALL;
+                       }
+                       break;
+                       
+               /* change to next pose or searching cursor control */
+               case LEFTARROWKEY:
+                       if (pld->searchstr[0]) {
+                               /* move text-cursor to the left */
+                               if (pld->search_cursor)
+                                       pld->search_cursor--;
+                               pld->redraw= PL_PREVIEW_REDRAWHEADER;
+                       }
+                       else {
+                               /* change to next pose (cyclic) */
+                               poselib_preview_get_next(pld, 1);
+                               pld->redraw= PL_PREVIEW_REDRAWALL;
+                       }
+                       break;
+                       
+               /* change to first pose or start of searching string */
+               case HOMEKEY:
+                       if (pld->searchstr[0]) {
+                               pld->search_cursor= 0;
+                               pld->redraw= PL_PREVIEW_REDRAWHEADER;
+                       }
+                       else {
+                               /* change to first pose */
+                               pld->marker= pld->act->markers.first;
+                               pld->act->active_marker= 1;
+                               
+                               pld->redraw= PL_PREVIEW_REDRAWALL;
+                       }
+                       break;
+                       
+               /* change to last pose or start of searching string */
+               case ENDKEY:
+                       if (pld->searchstr[0]) {
+                               pld->search_cursor= strlen(pld->searchstr);
+                               pld->redraw= PL_PREVIEW_REDRAWHEADER;
+                       }
+                       else {
+                               /* change to last pose */
+                               pld->marker= pld->act->markers.last;
+                               pld->act->active_marker= BLI_countlist(&pld->act->markers);
+                               
+                               pld->redraw= PL_PREVIEW_REDRAWALL;
+                       }
+                       break;
+                       
+               /* view manipulation */
+               case MIDDLEMOUSE:
+                       // there's a little bug here that causes the normal header to get drawn while view is manipulated 
+                       handle_view_middlemouse();
+                       pld->redraw= PL_PREVIEW_REDRAWHEADER;
+                       break;
+                       
+               /* view manipulation, or searching */
+               case PAD0: case PAD1: case PAD2: case PAD3: case PAD4:
+               case PAD5: case PAD6: case PAD7: case PAD8: case PAD9:
+               case PADPLUSKEY: case PADMINUS:
+                       if (pld->searchstr[0]) {
+                               poselib_preview_handle_search(pld, event, ascii);
+                       }
+                       else {
+                               persptoetsen(event);
+                               pld->redraw= PL_PREVIEW_REDRAWHEADER;
+                       }
+                       break;
+                       
+               /* otherwise, assume that searching might be able to handle it */
+               default:
+                       poselib_preview_handle_search(pld, event, ascii);
+                       break;
+       }
+}
 
-/* defines for poselib_preview_poses --> redraw values */
-enum {
-       PL_PREVIEW_NOREDRAW = 0,
-       PL_PREVIEW_REDRAWALL,
-       PL_PREVIEW_REDRAWHEADER,
-};
+/* ---------------------------- */
 
-/* This tool allows users to preview the pose from the pose-lib using the mouse-scrollwheel/pageupdown
- * It is also used to apply the active poselib pose only
- */
-void poselib_preview_poses (Object *ob, short apply_active)
+/* Init PoseLib Previewing data */
+static void poselib_preview_init_data (tPoseLib_PreviewData *pld, Object *ob, short apply_active)
 {
-       ListBase backups = {NULL, NULL};
+       /* clear pld first as it resides on the stack */
+       memset(pld, 0, sizeof(tPoseLib_PreviewData));
        
-       bPose *pose= (ob) ? (ob->pose) : NULL;
-       bArmature *arm= (ob) ? (ob->data) : NULL;
-       bAction *act= (ob) ? (ob->poselib) : NULL; 
-       TimeMarker *marker= poselib_get_active_pose(act);
-       Base *base;
-       
-       short ret_val= (apply_active) ? PL_PREVIEW_RUNONCE : PL_PREVIEW_RUNNING;
-       short val=0, redraw=1, firsttime=1;
-       unsigned short event;
-       char headerstr[200];
+       /* get basic data */
+       pld->ob= ob;
+       pld->arm= (ob) ? (ob->data) : NULL;
+       pld->pose= (ob) ? (ob->pose) : NULL;
+       pld->act= (ob) ? (ob->poselib) : NULL;
+       pld->marker= poselib_get_active_pose(pld->act);
        
        /* check if valid poselib */
-       if (ELEM3(NULL, ob, pose, arm)) {
+       if (ELEM3(NULL, pld->ob, pld->pose, pld->arm)) {
                error("PoseLib is only for Armatures in PoseMode");
+               pld->state= PL_PREVIEW_ERROR;
                return;
        }
-       if (act == NULL) {
+       if (pld->act == NULL) {
                error("Object doesn't have a valid PoseLib");
+               pld->state= PL_PREVIEW_ERROR;
                return;
        }
-       if (marker == NULL) {
-               error("PoseLib has no poses to preview/apply");
-               return;
+       if (pld->marker == NULL) {
+               if ((apply_active==0) || (pld->act->markers.first)) {
+                       /* just use first one then... */
+                       pld->marker= pld->act->markers.first;
+                       printf("PoseLib had no active pose\n");
+               }
+               else {
+                       error("PoseLib has no poses to preview/apply");
+                       pld->state= PL_PREVIEW_ERROR;
+                       return;
+               }
        }
        
-       /* make backup of current pose for restoring pose */
-       poselib_backup_posecopy(&backups, pose, act);
+       /* make backups for restoring pose */
+       poselib_backup_posecopy(pld);
+       
+       /* set flags for running */
+       pld->state= (apply_active) ? PL_PREVIEW_RUNONCE : PL_PREVIEW_RUNNING;
+       pld->redraw= PL_PREVIEW_REDRAWALL;
+       pld->firsttime= 1;
        
        /* set depsgraph flags */
                /* make sure the lock is set OK, unlock can be accidentally saved? */
-       pose->flag |= POSE_LOCKED;
-       pose->flag &= ~POSE_DO_UNLOCK;
-
+       pld->pose->flag |= POSE_LOCKED;
+       pld->pose->flag &= ~POSE_DO_UNLOCK;
        
-       /* start preview loop */
-       while (ELEM(ret_val, PL_PREVIEW_RUNNING, PL_PREVIEW_RUNONCE)) {
-               /* preview a pose */
-               if (redraw) {
-                       /* only recalc pose (and its dependencies) if pose has changed */
-                       if (redraw == PL_PREVIEW_REDRAWALL) {
-                               /* don't clear pose if firsttime */
-                               if (firsttime == 0)
-                                       poselib_backup_restore(&backups);
-                               else
-                                       firsttime = 0;
-                                       
-                               /* pose should be the right one to draw */
-                               poselib_apply_pose(ob, marker, headerstr);
-                               
-                               /* old optimize trick... this enforces to bypass the depgraph 
-                                *      - note: code copied from transform_generics.c -> recalcData()
-                                */
-                               if ((arm->flag & ARM_DELAYDEFORM)==0) {
-                                       DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);  /* sets recalc flags */
-                                       
-                                       /* bah, softbody exception... recalcdata doesnt reset */
-                                       for (base= FIRSTBASE; base; base= base->next) {
-                                               if (base->object->recalc & OB_RECALC_DATA)
-                                                       if (modifiers_isSoftbodyEnabled(base->object)) {
-                                                               base->object->softflag |= OB_SB_REDO;
-                                               }
-                                       }
-                               }
-                               else
-                                       where_is_pose(ob);
-                       }
-                       
-                       /* do header print - if interactively previewing */
-                       if (ret_val == PL_PREVIEW_RUNNING) {
-                               sprintf(headerstr, "PoseLib Previewing Pose: \"%s\"  | Use ScrollWheel or PageUp/Down to change", marker->name);
-                               headerprint(headerstr);
-                       }
-                       
-                       /* force drawing of view + clear redraw flag */
-                       force_draw(0);
-                       redraw= PL_PREVIEW_NOREDRAW;
-               }
-               
-               /* stop now if only running once */
-               if (ret_val == PL_PREVIEW_RUNONCE) {
-                       ret_val = PL_PREVIEW_CONFIRM;
-                       break;
-               }
-               
-               /* essential for idling subloop */
-               if (qtest() == 0) 
-                       PIL_sleep_ms(2);
-               
-               /* emptying queue and reading events */
-               while ( qtest() ) {
-                       event= extern_qread(&val);
-                       
-                       /* event processing */
-                       if (val) {
-                               switch (event) {
-                                       /* exit - cancel */
-                                       case ESCKEY:
-                                       case RIGHTMOUSE:
-                                               ret_val= PL_PREVIEW_CANCEL;
-                                               break;
-                                               
-                                       /* exit - confirm */
-                                       case LEFTMOUSE:
-                                       case RETKEY:
-                                       case SPACEKEY:
-                                               ret_val= PL_PREVIEW_CONFIRM;
-                                               break;
-                                       
-                                       /* change to previous pose (cyclic) */
-                                       case PAGEUPKEY:
-                                       case WHEELUPMOUSE:
-                                       case RIGHTARROWKEY:
-                                               marker= poselib_preview_get_next(act, marker, -1);
-                                               redraw= PL_PREVIEW_REDRAWALL;
-                                               break;
-                                               
-                                       /* change to next pose (cyclic) */
-                                       case PAGEDOWNKEY:
-                                       case WHEELDOWNMOUSE:
-                                       case LEFTARROWKEY:
-                                               marker= poselib_preview_get_next(act, marker, 1);
-                                               redraw= PL_PREVIEW_REDRAWALL;
-                                               break;
-                                       
-                                       /* jump 5 poses (cyclic, back) */
-                                       case DOWNARROWKEY:
-                                               marker= poselib_preview_get_next(act, marker, -5);
-                                               redraw= PL_PREVIEW_REDRAWALL;
-                                               break;
-                                       
-                                       /* jump 5 poses (cyclic, forward) */
-                                       case UPARROWKEY:
-                                               marker= poselib_preview_get_next(act, marker, 5);
-                                               redraw= PL_PREVIEW_REDRAWALL;
-                                               break;
-                                               
-                                       /* view manipulation */
-                                       case MIDDLEMOUSE:
-                                               // there's a little bug here that causes the normal header to get drawn while view is manipulated 
-                                               handle_view_middlemouse();
-                                               redraw= PL_PREVIEW_REDRAWHEADER;
-                                               break;
-                                               
-                                       case PAD0: case PAD1: case PAD2: case PAD3: case PAD4:
-                                       case PAD5: case PAD6: case PAD7: case PAD8: case PAD9:
-                                       case PADPLUSKEY:
-                                       case PADMINUS:
-                                       case PADENTER:
-                                               persptoetsen(event);
-                                               redraw= PL_PREVIEW_REDRAWHEADER;
-                                               break;
-                               }
-                       }
-               }
-       }
+       /* clear strings + search */
+       strcpy(pld->headerstr, "");
+       strcpy(pld->searchstr, "");
+       strcpy(pld->searchold, "");
+       pld->search_cursor= 0;
+}
+
+/* After previewing poses */
+static void poselib_preview_cleanup (tPoseLib_PreviewData *pld)
+{
+       Base *base;
+       Object *ob= pld->ob;
+       bPose *pose= pld->pose;
+       bArmature *arm= pld->arm;
+       bAction *act= pld->act;
+       TimeMarker *marker= pld->marker;
        
        /* this signal does one recalc on pose, then unlocks, so ESC or edit will work */
        pose->flag |= POSE_DO_UNLOCK;
        
        /* clear pose if cancelled */
-       if (ret_val == PL_PREVIEW_CANCEL) {
-               poselib_backup_restore(&backups);
+       if (pld->state == PL_PREVIEW_CANCEL) {
+               poselib_backup_restore(pld);
                
                /* old optimize trick... this enforces to bypass the depgraph 
                 *      - note: code copied from transform_generics.c -> recalcData()
@@ -902,13 +1106,15 @@ void poselib_preview_poses (Object *ob, short apply_active)
                        where_is_pose(ob);
                
                allqueue(REDRAWVIEW3D, 0);
+               allqueue(REDRAWBUTSEDIT, 0);
        }
-       else if (ret_val == PL_PREVIEW_CONFIRM) {
+       else if (pld->state == PL_PREVIEW_CONFIRM) {
                /* tag poses as appropriate */
-               poselib_keytag_pose(ob);
+               poselib_keytag_pose(pld);
                
                /* change active pose setting */
                act->active_marker= BLI_findindex(&act->markers, marker) + 1;
+               action_set_activemarker(act, marker, 0);
                
                /* Update event for pose and deformation children */
                DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
@@ -932,8 +1138,121 @@ void poselib_preview_poses (Object *ob, short apply_active)
                        allqueue(REDRAWBUTSEDIT, 0);
                }
        }
+       
        /* free memory used for backups */
-       BLI_freelistN(&backups);
+       BLI_freelistN(&pld->backups);
+       BLI_freelistN(&pld->searchp);
+}
+
+
+
+/* This tool allows users to preview the pose from the pose-lib using the mouse-scrollwheel/pageupdown
+ * It is also used to apply the active poselib pose only
+ */
+void poselib_preview_poses (Object *ob, short apply_active)
+{
+       tPoseLib_PreviewData pld;
+       Base *base;
+       
+       unsigned short event;
+       short val=0;
+       char ascii;
+       
+       /* check if valid poselib */
+       poselib_preview_init_data(&pld, ob, apply_active);
+       if (pld.state == PL_PREVIEW_ERROR)
+               return;
+               
+       /* start preview loop */
+       while (ELEM(pld.state, PL_PREVIEW_RUNNING, PL_PREVIEW_RUNONCE)) {
+               /* preview a pose */
+               if (pld.redraw) {
+                       /* only recalc pose (and its dependencies) if pose has changed */
+                       if (pld.redraw == PL_PREVIEW_REDRAWALL) {
+                               /* don't clear pose if firsttime */
+                               if (pld.firsttime == 0)
+                                       poselib_backup_restore(&pld);
+                               else
+                                       pld.firsttime = 0;
+                                       
+                               /* pose should be the right one to draw */
+                               poselib_apply_pose(&pld);
+                               
+                               /* old optimize trick... this enforces to bypass the depgraph 
+                                *      - note: code copied from transform_generics.c -> recalcData()
+                                */
+                               if ((pld.arm->flag & ARM_DELAYDEFORM)==0) {
+                                       DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);  /* sets recalc flags */
+                                       
+                                       /* bah, softbody exception... recalcdata doesnt reset */
+                                       for (base= FIRSTBASE; base; base= base->next) {
+                                               if (base->object->recalc & OB_RECALC_DATA)
+                                                       if (modifiers_isSoftbodyEnabled(base->object)) {
+                                                               base->object->softflag |= OB_SB_REDO;
+                                               }
+                                       }
+                               }
+                               else
+                                       where_is_pose(ob);
+                       }
+                       
+                       /* do header print - if interactively previewing */
+                       if (pld.state == PL_PREVIEW_RUNNING) {
+                               if (pld.searchstr[0]) {
+                                       char tempstr[65];
+                                       char markern[64];
+                                       short index;
+                                       
+                                       /* get search-string */
+                                       index= pld.search_cursor;
+                                       
+                                       memcpy(&tempstr[0], &pld.searchstr[0], index);
+                                       tempstr[index]= '|';
+                                       memcpy(&tempstr[index+1], &pld.searchstr[index], 64-index);
+                                       
+                                       /* get marker name */
+                                       if (pld.marker)
+                                               strcpy(markern, pld.marker->name);
+                                       else
+                                               strcpy(markern, "No Matches");
+                                       
+                                       sprintf(pld.headerstr, "PoseLib Previewing Pose: Filter - [%s] | Current Pose - \"%s\"  | Use ScrollWheel or PageUp/Down to change", tempstr, markern);
+                                       headerprint(pld.headerstr);
+                               }
+                               else {
+                                       sprintf(pld.headerstr, "PoseLib Previewing Pose: \"%s\"  | Use ScrollWheel or PageUp/Down to change", pld.marker->name);
+                                       headerprint(pld.headerstr);
+                               }
+                       }
+                       
+                       /* force drawing of view + clear redraw flag */
+                       force_draw(0);
+                       pld.redraw= PL_PREVIEW_NOREDRAW;
+               }
+               
+               /* stop now if only running once */
+               if (pld.state == PL_PREVIEW_RUNONCE) {
+                       pld.state = PL_PREVIEW_CONFIRM;
+                       break;
+               }
+               
+               /* essential for idling subloop */
+               if (qtest() == 0) 
+                       PIL_sleep_ms(2);
+               
+               /* emptying queue and reading events */
+               while ( qtest() ) {
+                       event= extern_qread_ext(&val, &ascii);
+                       
+                       /* event processing */
+                       if (val) {
+                               poselib_preview_handle_event(&pld, event, ascii);
+                       }
+               }
+       }
+       
+       /* finish up */
+       poselib_preview_cleanup(&pld);
        
        BIF_undo_push("PoseLib Apply Pose");
 }
index 585ff320b71682eb06aad08f48cbbceb91c741d4..e1854c0043e5d9dfe9d61cf51c9d69c79c112d17 100644 (file)
@@ -165,6 +165,9 @@ bPoseChannel *get_active_posechannel (Object *ob)
        bArmature *arm= ob->data;
        bPoseChannel *pchan;
        
+       if ELEM(NULL, ob, ob->pose)
+               return NULL;
+       
        /* find active */
        for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
                if(pchan->bone && (pchan->bone->flag & BONE_ACTIVE) && (pchan->bone->layer & arm->layer))
index 0099e5b9860296220c7ebc5bb3eeeb7dd0406d28..8c98fd47e09051c30e863a3bbecad5c816652793 100644 (file)
@@ -786,9 +786,9 @@ static void do_cross_effect(Sequence * seq,int cfra,
    ********************************************************************** */
 
 /* copied code from initrender.c */
-static unsigned short *gamtab = 0;
-static unsigned short *igamtab1 = 0;
-static int gamma_tabs_refcount = 0;
+static unsigned short gamtab[65536];
+static unsigned short igamtab1[256];
+static int gamma_tabs_init = FALSE;
 
 #define RE_GAMMA_TABLE_SIZE 400
 
@@ -882,9 +882,6 @@ static void gamtabs(float gamma)
        float val, igamma= 1.0f/gamma;
        int a;
        
-       gamtab= MEM_mallocN(65536*sizeof(short), "initGaus2");
-       igamtab1= MEM_mallocN(256*sizeof(short), "initGaus2");
-
        /* gamtab: in short, out short */
        for(a=0; a<65536; a++) {
                val= a;
@@ -907,36 +904,25 @@ static void gamtabs(float gamma)
 
 }
 
-static void alloc_or_ref_gammatabs()
+static void build_gammatabs()
 {
-       if (gamma_tabs_refcount == 0) {
+       if (gamma_tabs_init == FALSE) {
                gamtabs(2.0f);
                makeGammaTables(2.0f);
+               gamma_tabs_init = TRUE;
        }
-       gamma_tabs_refcount++;
 }
 
 static void init_gammacross(Sequence * seq)
 {
-       alloc_or_ref_gammatabs();
 }
 
 static void load_gammacross(Sequence * seq)
 {
-       alloc_or_ref_gammatabs();
 }
 
 static void free_gammacross(Sequence * seq)
 {
-       if (--gamma_tabs_refcount == 0) {
-               MEM_freeN(gamtab);
-               MEM_freeN(igamtab1);
-               gamtab = 0;
-               igamtab1 = 0;
-       }
-       if (gamma_tabs_refcount < 0) {
-               fprintf(stderr, "seqeffects: free_gammacross double free!\n");
-       }
 }
 
 static void do_gammacross_effect_byte(float facf0, float facf1, 
@@ -1043,6 +1029,8 @@ static void do_gammacross_effect(Sequence * seq,int cfra,
                                 struct ImBuf *ibuf1, struct ImBuf *ibuf2, 
                                 struct ImBuf *ibuf3, struct ImBuf *out)
 {
+       build_gammatabs();
+
        if (out->rect_float) {
                do_gammacross_effect_float(
                        facf0, facf1, x, y,
index 88766089317d1e52ca5add8dcd00876e3043ee07..a12501b6735d0e864f3849189ef844c55af70edc 100644 (file)
@@ -1498,7 +1498,7 @@ static TStripElem* do_build_seq_array_recursively(
                        break;
                }
 
-               sh = get_sequence_blend(seq_arr[i]);
+               sh = get_sequence_blend(seq);
 
                seq->facf0 = seq->facf1 = 1.0;
 
@@ -1543,9 +1543,13 @@ static TStripElem* do_build_seq_array_recursively(
                                        (short)seqrectx, (short)seqrecty, 
                                        32, IB_rect, 0);
                        }
+                       if (i == 0) {
+                               se->ibuf_comp = se->ibuf;
+                               IMB_refImBuf(se->ibuf_comp);
+                       }
                        break;
                }
-               
+       
                if (se->ibuf_comp) {
                        break;
                }
@@ -1564,6 +1568,7 @@ static TStripElem* do_build_seq_array_recursively(
                case 0: {
                        int x= se2->ibuf->x;
                        int y= se2->ibuf->y;
+                       int swap_input = FALSE;
 
                        if (se1->ibuf_comp->rect_float ||
                            se2->ibuf->rect_float) {
@@ -1588,16 +1593,33 @@ static TStripElem* do_build_seq_array_recursively(
 
                        if (!se1->ibuf_comp->rect && 
                            !se2->ibuf_comp->rect_float) {
-                               IMB_rect_from_float(se1->ibuf);
+                               IMB_rect_from_float(se1->ibuf_comp);
                        }
                        if (!se2->ibuf->rect && 
                            !se2->ibuf_comp->rect_float) {
                                IMB_rect_from_float(se2->ibuf);
                        }
 
-                       sh.execute(seq, cfra, seq->facf0, seq->facf1, x, y, 
-                                  se1->ibuf_comp, se2->ibuf, 0,
-                                  se2->ibuf_comp);
+                       /* bad hack, to fix crazy input ordering of 
+                          those two effects */
+
+                       if (seq->blend_mode == SEQ_ALPHAOVER ||
+                           seq->blend_mode == SEQ_ALPHAUNDER ||
+                           seq->blend_mode == SEQ_OVERDROP) {
+                               swap_input = TRUE;
+                       }
+
+                       if (swap_input) {
+                               sh.execute(seq, cfra, 
+                                          seq->facf0, seq->facf1, x, y, 
+                                          se2->ibuf, se1->ibuf_comp, 0,
+                                          se2->ibuf_comp);
+                       } else {
+                               sh.execute(seq, cfra, 
+                                          seq->facf0, seq->facf1, x, y, 
+                                          se1->ibuf_comp, se2->ibuf, 0,
+                                          se2->ibuf_comp);
+                       }
                        
                        IMB_cache_limiter_insert(se2->ibuf_comp);
                        IMB_cache_limiter_ref(se2->ibuf_comp);
index 82e7a446de590082bc45789f87d5930dd00adde4..1b9f87521030bc22bed3ccc93373092321155d21 100644 (file)
@@ -2310,7 +2310,7 @@ int Rotation(TransInfo *t, short mval[2])
        dphi = saacos((float)deler);
        if( (dx1*dy2-dx2*dy1)>0.0 ) dphi= -dphi;
 
-       if(G.qual & LR_SHIFTKEY) t->fac += dphi/30.0f;
+       if(t->flag & T_SHIFT_MOD) t->fac += dphi/30.0f;
        else t->fac += dphi;
 
        /*
@@ -2453,10 +2453,7 @@ int Trackball(TransInfo *t, short mval[2])
        /* factore has to become setting or so */
        phi[0]= 0.01f*(float)( t->imval[1] - mval[1] );
        phi[1]= 0.01f*(float)( mval[0] - t->imval[0] );
-       
-       //if(G.qual & LR_SHIFTKEY) t->fac += dphi/30.0f;
-       //else t->fac += dphi;
-       
+               
        snapGrid(t, phi);
        
        if (hasNumInput(&t->num)) {
@@ -2473,8 +2470,13 @@ int Trackball(TransInfo *t, short mval[2])
        }
        else {
                sprintf(str, "Trackball: %.2f %.2f %s", 180.0*phi[0]/M_PI, 180.0*phi[1]/M_PI, t->proptext);
-       }
        
+               if(t->flag & T_SHIFT_MOD) {
+                       if(phi[0] != 0.0) phi[0]/= 5.0f;
+                       if(phi[1] != 0.0) phi[1]/= 5.0f;
+               }
+       }
+
        VecRotToMat3(axis1, phi[0], smat);
        VecRotToMat3(axis2, phi[1], totmat);
        
index 83bac0e257ccbfd33d83b2b517ddbb1db2f57fc0..6e5f808c4904d39fecaf137f18f7b6db5ded1d78 100644 (file)
@@ -788,10 +788,11 @@ static short pose_grab_with_ik_add(bPoseChannel *pchan)
        if (pchan == NULL) 
                return 0;
        
-       /* rule: not if there's already an IK on this channel */
-       for (con= pchan->constraints.first; con; con= con->next)
+       /* Rule: not if there's already an IK on this channel */
+       for (con= pchan->constraints.first; con; con= con->next) {
                if (con->type==CONSTRAINT_TYPE_KINEMATIC)
                        break;
+       }
        
        if (con) {
                /* but, if this is a targetless IK, we make it auto anyway (for the children loop) */
@@ -827,7 +828,7 @@ static short pose_grab_with_ik_add(bPoseChannel *pchan)
        return 1;
 }
 
-/* bone is a canditate to get IK, but we don't do it if it has children connected */
+/* bone is a candidate to get IK, but we don't do it if it has children connected */
 static short pose_grab_with_ik_children(bPose *pose, Bone *bone)
 {
        Bone *bonec;
@@ -853,43 +854,47 @@ static short pose_grab_with_ik_children(bPose *pose, Bone *bone)
 static short pose_grab_with_ik(Object *ob)
 {
        bArmature *arm;
-       bPoseChannel *pchan, *pchansel= NULL;
+       bPoseChannel *pchan, *parent;
        Bone *bonec;
+       short tot_ik= 0;
        
-       if (ob==NULL || ob->pose==NULL || (ob->flag & OB_POSEMODE)==0)
+       if ((ob==NULL) || (ob->pose==NULL) || (ob->flag & OB_POSEMODE)==0)
                return 0;
                
        arm = ob->data;
        
-       /* rule: only one Bone */
+       /* Rule: allow multiple Bones (but they must be selected, and only one ik-solver per chain should get added) */
        for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
                if (pchan->bone->layer & arm->layer) {
                        if (pchan->bone->flag & BONE_SELECTED) {
-                               if (pchansel)
-                                       break;
-                               pchansel= pchan;
+                               /* Rule: no IK for solitatry (unconnected) bones */
+                               for (bonec=pchan->bone->childbase.first; bonec; bonec=bonec->next) {
+                                       if (bonec->flag & BONE_CONNECTED) {
+                                               break;
+                                       }
+                               }
+                               if ((pchan->bone->flag & BONE_CONNECTED)==0 && (bonec == NULL))
+                                       continue;
+                               
+                               /* rule: if selected Bone is not a root bone, it gets a temporal IK */
+                               if (pchan->parent) {
+                                       /* only adds if there's no IK yet (and no parent bone was selected) */
+                                       for (parent= pchan->parent; parent; parent= parent->parent) {
+                                               if (parent->bone->flag & BONE_SELECTED)
+                                                       break;
+                                       }
+                                       if (parent == NULL)
+                                               tot_ik += pose_grab_with_ik_add(pchan);
+                               }
+                               else {
+                                       /* rule: go over the children and add IK to the tips */
+                                       tot_ik += pose_grab_with_ik_children(ob->pose, pchan->bone);
+                               }
                        }
                }
        }
-       if (pchan || pchansel==NULL) return 0;
-
-       /* rule: no IK for solitary (unconnected) bone */
-       for (bonec=pchansel->bone->childbase.first; bonec; bonec=bonec->next) {
-               if (bonec->flag & BONE_CONNECTED) {
-                       break;
-               }
-       }
-       if ((pchansel->bone->flag & BONE_CONNECTED)==0 && (bonec == NULL)) return 0;
        
-       /* rule: if selected Bone is not a root bone, it gets a temporal IK */
-       if (pchansel->parent) {
-               /* only adds if there's no IK yet */
-               return pose_grab_with_ik_add(pchansel);
-       }
-       else {
-               /* rule: go over the children and add IK to the tips */
-               return pose_grab_with_ik_children(ob->pose, pchansel->bone);
-       }
+       return (tot_ik) ? 1 : 0;
 }      
 
 
index e5abe425468f6e61c7adf087eeae4b3d97449558..9b5a151b56bd42660680f9e7ec12638d827c518d 100644 (file)
@@ -171,9 +171,15 @@ static void print_help(void)
 {
        printf ("Blender %d.%02d (sub %d) Build\n", G.version/100, G.version%100, BLENDER_SUBVERSION);
        printf ("Usage: blender [options ...] [file]\n");
-       
+       printf ("Note: Arguments are executed in the order they are given. eg.\n");
+       printf ("    blender -b test.blend -f 1 -o /tmp\n");
+       printf ("  ...may not render to /tmp because '-f 1' renders before the output path is set\n");
+       printf ("    blender -b -o /tmp test.blend -f 1\n");
+       printf ("  ...may not render to /tmp because loading the blend file overwrites the output path that was set\n");
+       printf ("    \"blender -b test.blend -o /tmp -f 1\" works as expected.\n");
        printf ("\nRender options:\n");
        printf ("  -b <file>\tRender <file> in background\n");
+       printf ("    -a render frames from start to end (inclusive), only works when used after -b\n");
        printf ("    -S <name>\tSet scene <name>\n");
        printf ("    -f <frame>\tRender frame <frame> and save it\n");                          
        printf ("    -s <frame>\tSet start to frame <frame> (use with -a)\n");
@@ -182,16 +188,25 @@ static void print_help(void)
        printf ("      Use // at the start of the path to\n");
        printf ("        render relative to the blend file.\n");
        printf ("      The frame number will be added at the end of the filename.\n");
-       printf ("      eg: blender -b foobar.blend -o //render_ -F PNG -x 1\n");
-       printf ("    -F <format>\tSet the render format, Valid options are..\n");
-       printf ("    \tTGA IRIS HAMX FTYPE JPEG MOVIE IRIZ RAWTGA\n");
+       printf ("      eg: blender -b foobar.blend -o //render_ -F PNG -x 1 -a\n");
+       printf ("\nFormat options:\n");
+       printf ("    -F <format>\tSet the render format, Valid options are...\n");
+       printf ("    \tTGA IRIS HAMX JPEG MOVIE IRIZ RAWTGA\n");
        printf ("    \tAVIRAW AVIJPEG PNG BMP FRAMESERVER\n");
        printf ("    (formats that can be compiled into blender, not available on all systems)\n");
-       printf ("    \tHDR TIFF EXR MPEG AVICODEC QUICKTIME CINEON DPX\n");
+       printf ("    \tHDR TIFF EXR MPEG AVICODEC QUICKTIME CINEON DPX DDS\n");
        printf ("    -x <bool>\tSet option to add the file extension to the end of the file.\n");
        printf ("    -t <threads>\tUse amount of <threads> for rendering\n");
-       printf ("\nAnimation options:\n");
-       printf ("  -a <file(s)>\tPlayback <file(s)>\n");
+       /*Add these later - Campbell*/
+       /*
+       printf ("    -colorchannel <type>\tColors to save, valid types are: BW RGB RGBA \n");
+       printf ("    -compression <type>\t Use with EXR format, valid types are..\n");
+       printf ("    \tZIP Pxr24 PIZ RLE\n");
+       printf ("    -zbuf <bool>\tUse with EXR format, set the zbuf save option\n");
+       printf ("    -halffloat <bool>\tUse with EXR format, set the half float option\n");
+       printf ("    -preview <bool>\tUse with EXR format, save a jpeg for viewing as well as the EXR\n");*/
+       printf ("\nAnimation playback options:\n");
+       printf ("  -a <file(s)>\tPlayback <file(s)>, only operates this way when -b is not used.\n");
        printf ("    -p <sx> <sy>\tOpen with lower left corner at <sx>, <sy>\n");
        printf ("    -m\t\tRead from disk (Don't buffer)\n");
        printf ("    -f <fps> <fps-base>\t\tSpecify FPS to start with\n");
@@ -333,7 +348,7 @@ int main(int argc, char **argv)
                /* Handle -* switches */
                else if(argv[a][0] == '-') {
                        switch(argv[a][1]) {
-                       case 'a':
+                       case 'a': /* -b was not given, play an animation */
                                playanim(argc-1, argv+1);
                                exit(0);
                                break;
@@ -636,7 +651,9 @@ int main(int argc, char **argv)
                                                if      (!strcmp(argv[a],"TGA")) G.scene->r.imtype = R_TARGA;
                                                else if (!strcmp(argv[a],"IRIS")) G.scene->r.imtype = R_IRIS;
                                                else if (!strcmp(argv[a],"HAMX")) G.scene->r.imtype = R_HAMX;
-                                               else if (!strcmp(argv[a],"FTYPE")) G.scene->r.imtype = R_FTYPE;
+#ifdef WITH_DDS
+                                               else if (!strcmp(argv[a],"DDS")) G.scene->r.imtype = R_DDS;
+#endif
                                                else if (!strcmp(argv[a],"JPEG")) G.scene->r.imtype = R_JPEG90;
                                                else if (!strcmp(argv[a],"MOVIE")) G.scene->r.imtype = R_MOVIE;
                                                else if (!strcmp(argv[a],"IRIZ")) G.scene->r.imtype = R_IRIZ;
@@ -649,12 +666,14 @@ int main(int argc, char **argv)
                                                else if (!strcmp(argv[a],"BMP")) G.scene->r.imtype = R_BMP;
                                                else if (!strcmp(argv[a],"HDR")) G.scene->r.imtype = R_RADHDR;
                                                else if (!strcmp(argv[a],"TIFF")) G.scene->r.imtype = R_IRIS;
+#ifdef WITH_OPENEXR
                                                else if (!strcmp(argv[a],"EXR")) G.scene->r.imtype = R_OPENEXR;
+#endif
                                                else if (!strcmp(argv[a],"MPEG")) G.scene->r.imtype = R_FFMPEG;
                                                else if (!strcmp(argv[a],"FRAMESERVER")) G.scene->r.imtype = R_FRAMESERVER;
                                                else if (!strcmp(argv[a],"CINEON")) G.scene->r.imtype = R_CINEON;
                                                else if (!strcmp(argv[a],"DPX")) G.scene->r.imtype = R_DPX;
-                                               else printf("\nError: Format from '-F ' not known.\n");
+                                               else printf("\nError: Format from '-F' not known or not compiled in this release.\n");
                                        }
                                } else {
                                        printf("\nError: no blend loaded. cannot use '-x'.\n");
index a5f0dccce3557b0af1355f6e53dbf6d68b8616e9..0c52a3e6014e3aa6ddd32803a228c46efd7afbe9 100644 (file)
@@ -171,10 +171,17 @@ ifeq ($(OS),openbsd)
 endif
 
 ifeq ($(OS),solaris)
-    CC = gcc
-    CCC = g++
-#    CC        = cc
-#    CCC = CC
+    # Adding gcc flag to $CC is not good, however if its not there makesdna wont build - Campbell
+    ifeq (x86_64, $(findstring x86_64, $(CPU)))
+        CC  = gcc -m64
+        CCC = g++ -m64
+    else
+        CC  = gcc
+        CCC = g++
+        #CC  = cc
+        #CCC = CC
+    endif
+    
     JAVAC = javac
     JAVAH = javah
     CFLAGS     += -pipe -fPIC -funsigned-char -fno-strict-aliasing
@@ -182,6 +189,7 @@ ifeq ($(OS),solaris)
 #    CFLAGS    += "-fast -xdepend -xarch=v8plus -xO3 -xlibmil -KPIC -DPIC -xchar=unsigned"
 #    CCFLAGS   += "-fast -xdepend -xarch=v8plus -xO3 -xlibmil -xlibmopt -features=tmplife -norunpath -KPIC -DPIC -xchar=unsigned"
 
+    # Note, you might still want to compile a 32 bit binary if you have a 64bit system. if so remove the following lines
 #    ifeq ($(findstring 64,$(CPU)), 64)
 #        CFLAGS        += -m64
 #        CCFLAGS       += -m64
@@ -198,7 +206,8 @@ ifeq ($(OS),solaris)
         JAVA_HEADERS = /usr/java/include
         JAVA_SYSTEM_HEADERS = /usr/java/include/solaris
     else
-        OPENGL_HEADERS = $(LCGDIR)/mesa/include
+        # OPENGL_HEADERS = /usr/X11/include/mesa
+       OPENGL_HEADERS = /usr/X11/include/
     endif
     AR = ar
     ARFLAGS = ruv
index 5fda29b800243f4f85d3cb5e5bf94f2cbcdfe221..246be668f5bb775dfbea2e38bdfe17930732e382 100644 (file)
@@ -482,7 +482,7 @@ endif
     export NAN_TIFF ?= /usr
     export NAN_ODE ?= $(LCGDIR)/ode
     export NAN_TERRAPLAY ?=
-    export NAN_MESA ?= $(LCGDIR)/mesa
+    export NAN_MESA ?= /usr/X11
     export NAN_ZLIB ?= $(LCGDIR)/zlib
     export NAN_NSPR ?= $(LCGDIR)/nspr
     export NAN_FREETYPE ?= $(LCGDIR)/freetype
index 00d233962a9265951856f8730333099770e31754..e0745e9c1d43035e3ae53be21357243540396bb5 100644 (file)
@@ -119,8 +119,12 @@ endif
 ifeq ($(OS),solaris)
     ifeq (x86_64, $(findstring x86_64, $(CPU)))
         LLIBS = -lrt
+        LLIBS += -L$(NAN_MESA)/lib/amd64
+    else
+        LLIBS += -L$(NAN_MESA)/lib
     endif
-    LLIBS += -L$(NAN_MESA)/lib -lGLU -lGL -lXmu -lXext -lXi -lX11 -lc -lm -ldl -lsocket -lnsl 
+    
+    LLIBS += -lGLU -lGL -lXmu -lXext -lXi -lX11 -lc -lm -ldl -lsocket -lnsl 
     DYNLDFLAGS = -shared $(LDFLAGS)
 endif