svn merge -r 13357:13382 https://svn.blender.org/svnroot/bf-blender/trunk/blender
authorDaniel Genrich <daniel.genrich@gmx.net>
Thu, 24 Jan 2008 10:53:16 +0000 (10:53 +0000)
committerDaniel Genrich <daniel.genrich@gmx.net>
Thu, 24 Jan 2008 10:53:16 +0000 (10:53 +0000)
32 files changed:
SConstruct
source/blender/blenkernel/intern/constraint.c
source/blender/blenkernel/intern/modifier.c
source/blender/blenkernel/intern/particle.c
source/blender/blenkernel/intern/particle_system.c
source/blender/makesdna/DNA_userdef_types.h
source/blender/python/api2_2x/IDProp.c
source/blender/python/api2_2x/doc/Scene.py
source/blender/python/api2_2x/sceneRender.c
source/blender/radiosity/intern/source/radrender.c
source/blender/render/intern/include/render_types.h
source/blender/render/intern/include/rendercore.h
source/blender/render/intern/include/renderdatabase.h
source/blender/render/intern/include/zbuf.h
source/blender/render/intern/source/convertblender.c
source/blender/render/intern/source/envmap.c
source/blender/render/intern/source/rayshade.c
source/blender/render/intern/source/rendercore.c
source/blender/render/intern/source/renderdatabase.c
source/blender/render/intern/source/shadbuf.c
source/blender/render/intern/source/shadeoutput.c
source/blender/render/intern/source/strand.c
source/blender/render/intern/source/zbuf.c
source/blender/src/buttons_editing.c
source/blender/src/buttons_object.c
source/blender/src/drawarmature.c
source/blender/src/drawview.c
source/blender/src/editaction.c
source/blender/src/editipo.c
source/blender/src/resources.c
source/blender/src/space.c
source/blender/src/transform_conversions.c

index adecfcb5dcf15056e285a3c8ac6c448de519359c..1886b6486b8ebc90eb5804bf05813fb8cefe5596 100644 (file)
@@ -413,7 +413,7 @@ if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw'):
                         '${LCGDIR}/zlib/lib/zlib.dll',
                         '${LCGDIR}/tiff/lib/libtiff.dll']
     if env['BF_DEBUG']:
-        dllsources.append('${LCGDIR}/python/lib/${BF_PYTHON_LIB}.dll')
+        dllsources.append('${LCGDIR}/python/lib/${BF_PYTHON_LIB}_d.dll')
     else:
         dllsources.append('${LCGDIR}/python/lib/${BF_PYTHON_LIB}.dll')
     if env['OURPLATFORM'] == 'win32-mingw':
index 6300d88287998084c9153d62e9badf6f28425d98..7d7180da27103650bb43116d1c1e2a0659826956 100644 (file)
@@ -295,7 +295,7 @@ void constraints_clear_evalob (bConstraintOb *cob)
        
        /* calculate delta of constraints evaluation */
        Mat4Invert(imat, cob->startmat);
-       Mat4MulMat4(delta, cob->matrix, imat);
+       Mat4MulMat4(delta, imat, cob->matrix);
        
        /* copy matrices back to source */
        switch (cob->type) {
index 428c136a7fe7bad1350af77fc54fd2e499e1e248..d18d5ae3fd082f65aefa62cfbedc3e69f107c09f 100644 (file)
@@ -5513,7 +5513,7 @@ static DerivedMesh * particleInstanceModifier_applyModifier(
        MVert *mvert, *orig_mvert;
        int i,totvert, totpart=0, totface, maxvert, maxface, first_particle=0;
        short track=ob->trackflag%3, trackneg;
-       float max_co=0.0, min_co=0.0, temp_co[3];
+       float max_co=0.0, min_co=0.0, temp_co[3], cross[3];
 
        trackneg=((ob->trackflag>2)?1:0);
 
@@ -5592,15 +5592,29 @@ static DerivedMesh * particleInstanceModifier_applyModifier(
                        if(trackneg)
                                state.time=1.0f-state.time;
                        psys_get_particle_on_path(pimd->ob,psys,first_particle + i/totvert,&state,1);
+
+                       mv->co[0] = 0.0;
+
+                       Normalize(state.vel);
+                       
+                       if(state.vel[0] < -0.9999 || state.vel[0] > 0.9999) {
+                               state.rot[0] = 1.0;
+                               state.rot[1] = state.rot[2] = state.rot[3] = 0.0f;
+                       }
+                       else {
+                               /* a cross product of state.vel and a unit vector in x-direction */
+                               cross[0] = 0.0f;
+                               cross[1] = -state.vel[2];
+                               cross[2] = state.vel[1];
+
+                               /* state.vel[0] is the only component surviving from a dot product with a vector in x-direction*/
+                               VecRotToQuat(cross,saacos(state.vel[0]),state.rot);
+                       }
                }
                else{
                        state.time=-1.0;
                        psys_get_particle_state(pimd->ob,psys,i/totvert,&state,1);
-               }
-
-               /*displace vertice to path location*/
-               if(pimd->flag & eParticleInstanceFlag_Path)
-                       mv->co[0]=0.0;
+               }       
 
                QuatMulVecf(state.rot,mv->co);
                VECADD(mv->co,mv->co,state.co);
index 9cfc7e9dafe97044253add78190a753e3db28e50..5b92eb12d4fb664112ff39f9b39488c549b2d659 100644 (file)
@@ -776,7 +776,7 @@ static void weighted_particle_vector(float *v1, float *v2, float *v3, float *v4,
        vec[1]= weights[0]*v1[1] + weights[1]*v2[1] + weights[2]*v3[1] + weights[3]*v4[1];
        vec[2]= weights[0]*v1[2] + weights[1]*v2[2] + weights[2]*v3[2] + weights[3]*v4[2];
 }
-static void interpolate_particle(short type, ParticleKey keys[4], float dt, ParticleKey *result)
+static void interpolate_particle(short type, ParticleKey keys[4], float dt, ParticleKey *result, int velocity)
 {
        float t[4];
 
@@ -788,18 +788,20 @@ static void interpolate_particle(short type, ParticleKey keys[4], float dt, Part
 
                weighted_particle_vector(keys[0].co, keys[1].co, keys[2].co, keys[3].co, t, result->co);
 
-               //if(ve){
-               //      if(dt>0.999f){
-               //              set_four_ipo(dt+0.001f,t,ipo_type);
-               //              weighted_particle_vector(key0->co,key1->co,key2->co,key3->co,t,temp);
-               //              VECSUB(ve,temp,co);
-               //      }
-               //      else{
-               //              set_four_ipo(dt-0.001f,t,ipo_type);
-               //              weighted_particle_vector(key0->co,key1->co,key2->co,key3->co,t,temp);
-               //              VECSUB(ve,co,temp);
-               //      }
-               //}
+               if(velocity){
+                       float temp[3];
+
+                       if(dt>0.999f){
+                               set_four_ipo(dt-0.001f, t, type);
+                               weighted_particle_vector(keys[0].co, keys[1].co, keys[2].co, keys[3].co, t, temp);
+                               VECSUB(result->vel, result->co, temp);
+                       }
+                       else{
+                               set_four_ipo(dt+0.001f, t, type);
+                               weighted_particle_vector(keys[0].co, keys[1].co, keys[2].co, keys[3].co, t, temp);
+                               VECSUB(result->vel, temp, result->co);
+                       }
+               }
        }
 }
 
@@ -2426,7 +2428,7 @@ void psys_cache_paths(Object *ob, ParticleSystem *psys, float cfra, int editupda
                        /* now we should have in chronologiacl order k1<=k2<=t<=k3<=k4 with keytime between [0,1]->[k2,k3] (k1 & k4 used for cardinal & bspline interpolation)*/
                        interpolate_particle((psys->flag & PSYS_KEYED) ? -1 /* signal for cubic interpolation */
                                : ((psys->part->flag & PART_HAIR_BSPLINE) ? KEY_BSPLINE : KEY_CARDINAL)
-                               ,keys, keytime, &result);
+                               ,keys, keytime, &result, 0);
 
                        /* the velocity needs to be converted back from cubic interpolation */
                        if(psys->flag & PSYS_KEYED){
@@ -3371,7 +3373,7 @@ void psys_get_particle_on_path(Object *ob, ParticleSystem *psys, int p, Particle
 
                interpolate_particle((psys->flag & PSYS_KEYED) ? -1 /* signal for cubic interpolation */
                        : ((psys->part->flag & PART_HAIR_BSPLINE) ? KEY_BSPLINE : KEY_CARDINAL)
-                       ,keys, keytime, state);
+                       ,keys, keytime, state, 1);
 
                /* the velocity needs to be converted back from cubic interpolation */
                if(psys->flag & PSYS_KEYED){
@@ -3381,6 +3383,7 @@ void psys_get_particle_on_path(Object *ob, ParticleSystem *psys, int p, Particle
                        if((pa->flag & PARS_REKEY)==0) {
                                psys_mat_hair_to_global(ob, psmd->dm, part->from, pa, hairmat);
                                Mat4MulVecfl(hairmat, state->co);
+                               Mat4Mul3Vecfl(hairmat, state->vel);
 
                                if(psys->effectors.first && (part->flag & PART_CHILD_GUIDE)==0) {
                                        do_guide(state, p, state->time, &psys->effectors);
index 5f481f94b61d25ac36ab72fe0a9153abb7f58f26..e71c4f90d483a4473d3ad3fc336fa02b41877934 100644 (file)
@@ -2058,45 +2058,33 @@ static int get_particles_from_cache(Object *ob, ParticleSystem *psys, int cfra)
 /************************************************/
 /*                     Effectors                                                       */
 /************************************************/
-static float particle_falloff(PartDeflect *pd, float fac)
+static float falloff_func(float fac, int usemin, float mindist, int usemax, float maxdist, float power)
 {
-       float mindist= (pd->flag & PFIELD_USEMIN)? pd->mindist: 0.0f;
-
-#if 0
-       if(distance<=mindist) fallof= 1.0f;
-       else if(pd->flag & PFIELD_USEMAX) {
-               if(distance>pd->maxdist || mindist>=pd->maxdist) fallof= 0.0f;
-               else {
-                       fallof= 1.0f - (distance-mindist)/(pd->maxdist - mindist);
-                       if(ffall_val!=0.0f)
-                               fallof = (float)pow(fallof, ffall_val+1.0);
-               }
-       }
-       else {
-               fallof= 1.0f/(1.0f + distance-mindist);
-               if(ffall_val!=0.0f)
-                       fallof = (float)pow(fallof, ffall_val+1.0);
-       }
-
-       fac=VecLength(vec_to_part);
-#endif
+       if(!usemin)
+               mindist= 0.0f;
 
        if(fac < mindist) {
                return 1.0f;
        }
-       else if(pd->flag & PFIELD_USEMAX) {
-               if(fac>pd->maxdist || (pd->maxdist-mindist)<=0.0f)
+       else if(usemax) {
+               if(fac>maxdist || (maxdist-mindist)<=0.0f)
                        return 0.0f;
 
-               fac= 1.0f - (fac-mindist)/(pd->maxdist-mindist);
-               printf("fac %f^%f\n", fac, pd->f_power);
-               return (float)pow((double)fac, (double)pd->f_power);
+               fac= (fac-mindist)/(maxdist-mindist);
+               return 1.0f - (float)pow((double)fac, (double)power);
        }
-       else {
-               fac+=1.0f-pd->mindist;
+       else
+               return pow((double)1.0f+fac-mindist, (double)-power);
+}
 
-               return (float)pow((double)fac,(double)-pd->f_power);
-       }
+static float falloff_func_dist(PartDeflect *pd, float fac)
+{
+       return falloff_func(fac, pd->flag&PFIELD_USEMIN, pd->mindist, pd->flag&PFIELD_USEMAX, pd->maxdist, pd->f_power);
+}
+
+static float falloff_func_rad(PartDeflect *pd, float fac)
+{
+       return falloff_func(fac, pd->flag&PFIELD_USEMINR, pd->minrad, pd->flag&PFIELD_USEMAXR, pd->maxrad, pd->f_power_r);
 }
 
 static float effector_falloff(PartDeflect *pd, float *eff_velocity, float *vec_to_part)
@@ -2112,95 +2100,27 @@ static float effector_falloff(PartDeflect *pd, float *eff_velocity, float *vec_t
        else switch(pd->falloff){
                case PFIELD_FALL_SPHERE:
                        fac=VecLength(vec_to_part);
-                       falloff= particle_falloff(pd, fac);
-#if 0
-                       if(pd->flag&PFIELD_USEMAX && fac>pd->maxdist){
-                               falloff=0.0f;
-                               break;
-                       }
-
-                       if(pd->flag & PFIELD_USEMIN){
-                               if(fac>pd->mindist)
-                                       fac+=1.0f-pd->mindist;
-                               else
-                                       fac=1.0f;
-                       }
-                       else if(fac<0.001)
-                               fac=0.001f;
-
-                       falloff=1.0f/(float)pow((double)fac,(double)pd->f_power);
-#endif
+                       falloff= falloff_func_dist(pd, fac);
                        break;
 
                case PFIELD_FALL_TUBE:
                        fac=Inpf(vec_to_part,eff_dir);
-                       if(pd->flag&PFIELD_USEMAX && ABS(fac)>pd->maxdist){
-                               falloff=0.0f;
+                       falloff= falloff_func_dist(pd, ABS(fac));
+                       if(falloff == 0.0f)
                                break;
-                       }
 
                        VECADDFAC(temp,vec_to_part,eff_dir,-fac);
                        r_fac=VecLength(temp);
-                       if(pd->flag&PFIELD_USEMAXR && r_fac>pd->maxrad){
-                               falloff=0.0f;
-                               break;
-                       }
-
-                       fac=ABS(fac);
-
-
-                       if(pd->flag & PFIELD_USEMIN){
-                               if(fac>pd->mindist)
-                                       fac+=1.0f-pd->mindist;
-                               else
-                                       fac=1.0f;
-                       }
-                       else if(fac<0.001)
-                               fac=0.001f;
-
-                       if(pd->flag & PFIELD_USEMINR){
-                               if(r_fac>pd->minrad)
-                                       r_fac+=1.0f-pd->minrad;
-                               else
-                                       r_fac=1.0f;
-                       }
-                       else if(r_fac<0.001)
-                               r_fac=0.001f;
-
-                       falloff=1.0f/((float)pow((double)fac,(double)pd->f_power)*(float)pow((double)r_fac,(double)pd->f_power_r));
-
+                       falloff*= falloff_func_rad(pd, r_fac);
                        break;
                case PFIELD_FALL_CONE:
                        fac=Inpf(vec_to_part,eff_dir);
-                       if(pd->flag&PFIELD_USEMAX && ABS(fac)>pd->maxdist){
-                               falloff=0.0f;
+                       falloff= falloff_func_dist(pd, ABS(fac));
+                       if(falloff == 0.0f)
                                break;
-                       }
-                       r_fac=saacos(fac/VecLength(vec_to_part))*180.0f/(float)M_PI;
-                       if(pd->flag&PFIELD_USEMAXR && r_fac>pd->maxrad){
-                               falloff=0.0f;
-                               break;
-                       }
 
-                       if(pd->flag & PFIELD_USEMIN){
-                               if(fac>pd->mindist)
-                                       fac+=1.0f-pd->mindist;
-                               else
-                                       fac=1.0f;
-                       }
-                       else if(fac<0.001)
-                               fac=0.001f;
-
-                       if(pd->flag & PFIELD_USEMINR){
-                               if(r_fac>pd->minrad)
-                                       r_fac+=1.0f-pd->minrad;
-                               else
-                                       r_fac=1.0f;
-                       }
-                       else if(r_fac<0.001)
-                               r_fac=0.001f;
-
-                       falloff=1.0f/((float)pow((double)fac,(double)pd->f_power)*(float)pow((double)r_fac,(double)pd->f_power_r));
+                       r_fac=saacos(fac/VecLength(vec_to_part))*180.0f/(float)M_PI;
+                       falloff*= falloff_func_rad(pd, r_fac);
 
                        break;
 //             case PFIELD_FALL_INSIDE:
index 14002daded534cb3514f38bd6ee2a3b58d0d6ab5..6238b878c74118e8f934fb4f99a8af5155eff3a5 100644 (file)
@@ -64,7 +64,6 @@ typedef struct ThemeUI {
        char but_drawtype;
        char pad[3];
        char iconfile[80];      // FILE_MAXFILE length
-
 } ThemeUI;
 
 /* try to put them all in one, if needed a special struct can be created as well
@@ -107,14 +106,20 @@ typedef struct ThemeSpace {
        char editmesh_active[4]; 
 } ThemeSpace;
 
+
 /* set of colors for use as a custom color set for Objects/Bones wire drawing */
 typedef struct ThemeWireColor {
-       char    unselected[3];
-       char    selected[3];
-       char    active[3];
-       char    pad[7];
+       char    solid[4];
+       char    select[4];
+       char    active[4];
+       
+       short   flag;
+       short   pad;
 } ThemeWireColor; 
 
+/* flags for ThemeWireColor */
+#define TH_WIRECOLOR_CONSTCOLS (1<<0)
+
 /* A theme */
 typedef struct bTheme {
        struct bTheme *next, *prev;
index 4f2fa82b21e66841d4c0f24b1d11f624fa37f930..cf5cf42de5d0895a869c69d08a7c705d3e65d7cf 100644 (file)
@@ -392,7 +392,7 @@ PyObject *BPy_IDGroup_Pop(BPy_IDProperty *self, PyObject *value)
        
        if (!name) {
                return EXPP_ReturnPyObjError( PyExc_TypeError,
-                  "pop expected at least 1 arguments, got 0" );
+                  "pop expected at least 1 argument, got 0" );
        }
        
        for (loop=self->prop->data.group.first; loop; loop=loop->next) {
index 77e33e143f5b3084b3bebbbd64de3a13b78185fb..caa5b56e8d56282577ec27af345c2174631ea7a4 100644 (file)
@@ -117,6 +117,16 @@ class Scene:
        @ivar render: The scenes L{render<Render.RenderData>} settings. (read only)
        @type radiosity: RenderData
        @ivar radiosity: The scenes L{radiosity<Radio>} settings. (read only)
+       @type halfFloat: OpenEXR's half float option
+       @ivar halfFloat: boolean
+       @type zbuf: OpenEXR's save zbuf option
+       @ivar zbuf: boolean
+       @type preview: OpenEXR's save preview option
+       @ivar preview: boolean
+       @type touch: enable creating empty image files while they are rendered.
+       @ivar touch: boolean
+       @type noOverwrite: Skip rendering existing image files
+       @ivar noOverwrite: boolean
        """
 
        def getName():
index 5f71cfc4bd192e13e2104e001a6566515696bb36..ec160ddf4cee6d5fbf32552d31202a310d22a80d 100644 (file)
@@ -1948,6 +1948,18 @@ static int RenderData_setIValueAttrClamp( BPy_RenderData *self, PyObject *value,
 /* handlers for other getting/setting attributes                           */
 /***************************************************************************/
 
+static PyObject *RenderData_getSubImTypeBits( BPy_RenderData *self, void* type )
+{
+       return EXPP_getBitfield( &self->renderContext->subimtype, (int)type, 'h' );
+}
+
+static int RenderData_setSubImTypeBits( BPy_RenderData* self, PyObject *value,
+               void* type )
+{
+       return EXPP_setBitfield( value, &self->renderContext->subimtype,
+                       (int)type, 'h' );
+}
+
 static PyObject *RenderData_getModeBit( BPy_RenderData *self, void* type )
 {
        return EXPP_getBitfield( &self->renderContext->mode,
@@ -2419,6 +2431,16 @@ static PyGetSetDef BPy_RenderData_getseters[] = {
         (getter)RenderData_getModeBit, (setter)RenderData_setModeBit,
         "Ray tracing enabled",
         (void *)R_RAYTRACE},
+         
+       {"touch",
+        (getter)RenderData_getModeBit, (setter)RenderData_setModeBit,
+        "Create an empry file with the frame name before rendering",
+        (void *)R_TOUCH},
+       {"noOverwrite",
+        (getter)RenderData_getModeBit, (setter)RenderData_setModeBit,
+        "Skip rendering existing image files",
+        (void *)R_NO_OVERWRITE},
+         
 /* R_GAUSS unused */
 /* R_FBUF unused */
 /* R_THREADS unused */
@@ -2601,6 +2623,19 @@ static PyGetSetDef BPy_RenderData_getseters[] = {
         "Active rendering layer",
         NULL},
 
+       {"halfFloat",
+     (getter)RenderData_getSubImTypeBits, (setter)RenderData_setSubImTypeBits,
+     "'Half' openexr option enabled",
+     (void *)R_OPENEXR_HALF},
+       {"zbuf",
+     (getter)RenderData_getSubImTypeBits, (setter)RenderData_setSubImTypeBits,
+     "'ZBuf' openexr option enabled",
+     (void *)R_OPENEXR_ZBUF},
+       {"preview",
+     (getter)RenderData_getSubImTypeBits, (setter)RenderData_setSubImTypeBits,
+     "'preview' openexr option enabled",
+     (void *)R_PREVIEW_JPG},
+
        {"yafrayGIMethod",
         (getter)RenderData_getYafrayGIMethod, (setter)RenderData_setYafrayGIMethod,
         "Global illumination method",
index ee52956bbd2510bc2e4f65054177cbe1fac0ce73..52e2b46d506341f6805772d2b941d498e36b4edf 100644 (file)
@@ -84,22 +84,23 @@ static float maxenergy;
 
 /* find the face with maximum energy to become shooter */
 /* nb: _rr means rad-render version of existing radio call */
-static VlakRen *findshoot_rr(Render *re)
+static void findshoot_rr(Render *re, VlakRen **shoot_p, RadFace **shootrf_p)
 {
-       RadFace *rf;
+       RadFace *rf, *shootrf, **radface;
        ObjectRen *obr;
        VlakRen *vlr=NULL, *shoot;
        float energy;
        int a;
        
        shoot= NULL;
+       shootrf= NULL;
        maxenergy= 0.0;
        
        for(obr=re->objecttable.first; obr; obr=obr->next) {
                for(a=0; a<obr->totvlak; a++) {
                        if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++;
-                       if(vlr->radface) {
-                               rf= vlr->radface;
+                       if((radface=RE_vlakren_get_radface(obr, vlr, 0))) {
+                               rf= *radface;
                                rf->flag &= ~RAD_SHOOT;
                                
                                energy= rf->unshot[0]*rf->area;
@@ -108,26 +109,31 @@ static VlakRen *findshoot_rr(Render *re)
 
                                if(energy>maxenergy) {
                                        shoot= vlr;
+                                       shootrf= rf;
                                        maxenergy= energy;
                                }
                        }
                }
        }
 
-       if(shoot) {
+       if(shootrf) {
                maxenergy/= RG.totenergy;
-               if(maxenergy<RG.convergence) return NULL;
-               shoot->radface->flag |= RAD_SHOOT;
+               if(maxenergy<RG.convergence) {
+                       *shoot_p= NULL;
+                       *shootrf_p= NULL;
+               }
+               shootrf->flag |= RAD_SHOOT;
        }
 
-       return shoot;
+       *shoot_p= shoot;
+       *shootrf_p= shootrf;
 }
 
-static void backface_test_rr(Render *re, VlakRen *shoot)
+static void backface_test_rr(Render *re, VlakRen *shoot, RadFace *shootrf)
 {
        ObjectRen *obr;
        VlakRen *vlr=NULL;
-       RadFace *rf;
+       RadFace *rf, **radface;
        float tvec[3];
        int a;
        
@@ -135,9 +141,9 @@ static void backface_test_rr(Render *re, VlakRen *shoot)
        for(obr=re->objecttable.first; obr; obr=obr->next) {
                for(a=0; a<obr->totvlak; a++) {
                        if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++;
-                       if(vlr->radface && vlr!=shoot) {
-                               rf= vlr->radface;
-                               VecSubf(tvec, shoot->radface->cent, rf->cent);
+                       if(vlr != shoot && (radface=RE_vlakren_get_radface(obr, vlr, 0))) {
+                               rf= *radface;
+                               VecSubf(tvec, shootrf->cent, rf->cent);
                                
                                if(tvec[0]*rf->norm[0]+ tvec[1]*rf->norm[1]+ tvec[2]*rf->norm[2] < 0.0)
                                        rf->flag |= RAD_BACKFACE;
@@ -150,7 +156,7 @@ static void clear_backface_test_rr(Render *re)
 {
        ObjectRen *obr;
        VlakRen *vlr=NULL;
-       RadFace *rf;
+       RadFace *rf, **radface;
        int a;
        
        /* backface flag clear */
@@ -158,8 +164,8 @@ static void clear_backface_test_rr(Render *re)
                for(a=0; a<obr->totvlak; a++) {
                        if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++;
                        
-                       if(vlr->radface) {
-                               rf= vlr->radface;
+                       if((radface=RE_vlakren_get_radface(obr, vlr, 0))) {
+                               rf= *radface;
                                rf->flag &= ~RAD_BACKFACE;
                        }
                }
@@ -169,11 +175,11 @@ static void clear_backface_test_rr(Render *re)
 extern RadView hemitop, hemiside; // radfactors.c
 
 /* hemi-zbuffering, delivers formfactors array */
-static void makeformfactors_rr(Render *re, VlakRen *shoot)
+static void makeformfactors_rr(Render *re, VlakRen *shoot, RadFace *shootrf)
 {
        ObjectRen *obr;
        VlakRen *vlr=NULL;
-       RadFace *rf;
+       RadFace *rf, **radface;
        float len, vec[3], up[3], side[3], tar[5][3], *fp;
        int a;
 
@@ -182,25 +188,25 @@ static void makeformfactors_rr(Render *re, VlakRen *shoot)
        /* set up hemiview */
        /* first: upvector for hemitop, we use diagonal hemicubes to prevent aliasing */
        
-       VecSubf(vec, shoot->v1->co, shoot->radface->cent);
-       Crossf(up, shoot->radface->norm, vec);
+       VecSubf(vec, shoot->v1->co, shootrf->cent);
+       Crossf(up, shootrf->norm, vec);
        len= Normalize(up);
        
        VECCOPY(hemitop.up, up);
-       VECCOPY(hemiside.up, shoot->radface->norm);
+       VECCOPY(hemiside.up, shootrf->norm);
 
-       Crossf(side, shoot->radface->norm, up);
+       Crossf(side, shootrf->norm, up);
 
        /* five targets */
-       VecAddf(tar[0], shoot->radface->cent, shoot->radface->norm);
-       VecAddf(tar[1], shoot->radface->cent, up);
-       VecSubf(tar[2], shoot->radface->cent, up);
-       VecAddf(tar[3], shoot->radface->cent, side);
-       VecSubf(tar[4], shoot->radface->cent, side);
+       VecAddf(tar[0], shootrf->cent, shootrf->norm);
+       VecAddf(tar[1], shootrf->cent, up);
+       VecSubf(tar[2], shootrf->cent, up);
+       VecAddf(tar[3], shootrf->cent, side);
+       VecSubf(tar[4], shootrf->cent, side);
 
        /* camera */
-       VECCOPY(hemiside.cam, shoot->radface->cent);
-       VECCOPY(hemitop.cam, shoot->radface->cent);
+       VECCOPY(hemiside.cam, shootrf->cent);
+       VECCOPY(hemitop.cam, shootrf->cent);
 
        /* do it! */
        VECCOPY(hemitop.tar, tar[0]);
@@ -218,10 +224,10 @@ static void makeformfactors_rr(Render *re, VlakRen *shoot)
                for(a=0; a<obr->totvlak; a++) {
                        if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++;
                        
-                       if(vlr->radface) {
-                               rf= vlr->radface;
+                       if((radface=RE_vlakren_get_radface(obr, vlr, 0))) {
+                               rf= *radface;
                                if(*fp!=0.0 && rf->area!=0.0) {
-                                       *fp *= shoot->radface->area/rf->area;
+                                       *fp *= shootrf->area/rf->area;
                                        if(*fp>1.0) *fp= 1.0001;
                                }
                                fp++;
@@ -231,17 +237,17 @@ static void makeformfactors_rr(Render *re, VlakRen *shoot)
 }
 
 /* based at RG.formfactors array, distribute shoot energy over other faces */
-static void applyformfactors_rr(Render *re, VlakRen *shoot)
+static void applyformfactors_rr(Render *re, VlakRen *shoot, RadFace *shootrf)
 {
        ObjectRen *obr;
        VlakRen *vlr=NULL;
-       RadFace *rf;
+       RadFace *rf, **radface;
        float *fp, *ref, unr, ung, unb, r, g, b;
        int a;
 
-       unr= shoot->radface->unshot[0];
-       ung= shoot->radface->unshot[1];
-       unb= shoot->radface->unshot[2];
+       unr= shootrf->unshot[0];
+       ung= shootrf->unshot[1];
+       unb= shootrf->unshot[2];
 
        fp= RG.formfactors;
        
@@ -249,8 +255,8 @@ static void applyformfactors_rr(Render *re, VlakRen *shoot)
                for(a=0; a<obr->totvlak; a++) {
                        if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++;
                        
-                       if(vlr->radface) {
-                               rf= vlr->radface;
+                       if((radface=RE_vlakren_get_radface(obr, vlr, 0))) {
+                               rf= *radface;
                                if(*fp!= 0.0) {
                                        
                                        ref= &(vlr->mat->r);
@@ -274,7 +280,7 @@ static void applyformfactors_rr(Render *re, VlakRen *shoot)
                }
        }
        /* shoot energy has been shot */
-       shoot->radface->unshot[0]= shoot->radface->unshot[1]= shoot->radface->unshot[2]= 0.0;
+       shootrf->unshot[0]= shootrf->unshot[1]= shootrf->unshot[2]= 0.0;
 }
 
 
@@ -282,29 +288,30 @@ static void applyformfactors_rr(Render *re, VlakRen *shoot)
 static void progressiverad_rr(Render *re)
 {
        VlakRen *shoot;
+       RadFace *shootrf;
        float unshot[3];
        int it= 0;
        
-       shoot= findshoot_rr(re);
+       findshoot_rr(re, &shoot, &shootrf);
        while( shoot ) {
                
                /* backfaces receive no energy, but are zbuffered... */
-               backface_test_rr(re, shoot);
+               backface_test_rr(re, shoot, shootrf);
                
                /* ...unless it's two sided */
-               if(shoot->radface->flag & RAD_TWOSIDED) {
-                       VECCOPY(unshot, shoot->radface->unshot);
-                       VecMulf(shoot->radface->norm, -1.0);
-                       makeformfactors_rr(re, shoot);
-                       applyformfactors_rr(re, shoot);
-                       VecMulf(shoot->radface->norm, -1.0);
-                       VECCOPY(shoot->radface->unshot, unshot);
+               if(shootrf->flag & RAD_TWOSIDED) {
+                       VECCOPY(unshot, shootrf->unshot);
+                       VecMulf(shootrf->norm, -1.0);
+                       makeformfactors_rr(re, shoot, shootrf);
+                       applyformfactors_rr(re, shoot, shootrf);
+                       VecMulf(shootrf->norm, -1.0);
+                       VECCOPY(shootrf->unshot, unshot);
                }
 
                /* hemi-zbuffers */
-               makeformfactors_rr(re, shoot);
+               makeformfactors_rr(re, shoot, shootrf);
                /* based at RG.formfactors array, distribute shoot energy over other faces */
-               applyformfactors_rr(re, shoot);
+               applyformfactors_rr(re, shoot, shootrf);
                
                it++;
                re->timecursor(it);
@@ -314,7 +321,7 @@ static void progressiverad_rr(Render *re)
                if(re->test_break()) break;
                if(RG.maxiter && RG.maxiter<=it) break;
                
-               shoot= findshoot_rr(re);
+               findshoot_rr(re, &shoot, &shootrf);
        }
        printf(" Unshot energy:%f\n", 1000.0*maxenergy);
        
@@ -327,7 +334,7 @@ static void initradfaces(Render *re)
 {
        ObjectRen *obr;
        VlakRen *vlr= NULL;
-       RadFace *rf;
+       RadFace *rf, **radface;
        int a, b;
        
        /* globals */
@@ -393,7 +400,8 @@ printf(" Rad elems: %d emittors %d\n", RG.totelem, RG.totpatch);
        // uncommented; this isnt satisfying, but i leave it in the code for now (ton)                  
        //                      if(vlr->mat->translucency!=0.0) rf->flag |= RAD_TWOSIDED;
                                
-                               vlr->radface= rf++;
+                               radface=RE_vlakren_get_radface(obr, vlr, 1);
+                               *radface= rf++;
                        }
                }
        }
@@ -428,7 +436,7 @@ static void make_vertex_rad_values(Render *re)
        ObjectRen *obr;
        VertRen *v1=NULL;
        VlakRen *vlr=NULL;
-       RadFace *rf;
+       RadFace *rf, **radface;
        float *col;
        int a;
 
@@ -440,8 +448,8 @@ static void make_vertex_rad_values(Render *re)
                for(a=0; a<obr->totvlak; a++) {
                        if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++;
                        
-                       if(vlr->radface) {
-                               rf= vlr->radface;
+                       if((radface=RE_vlakren_get_radface(obr, vlr, 0))) {
+                               rf= *radface;
                                
                                /* apply correction */
                                rf->totrad[0]= RG.radfactor*pow( rf->totrad[0], RG.igamma);
index 05d8324dfc6e8a54c47de2d09aa2563c1a545dd2..46b5face22a7962be7b1089ad82184b571fdb12f 100644 (file)
@@ -244,7 +244,7 @@ typedef struct ObjectRen {
        struct ObjectRen *next, *prev;
        struct Object *ob, *par;
        struct Scene *sce;
-       int index, psysindex, flag;
+       int index, psysindex, flag, lay;
 
        int totvert, totvlak, totstrand, tothalo;
        int vertnodeslen, vlaknodeslen, strandnodeslen, blohalen;
@@ -309,12 +309,10 @@ typedef struct RadFace {
 
 typedef struct VlakRen {
        struct VertRen *v1, *v2, *v3, *v4;      /* keep in order for ** addressing */
-       unsigned int lay;
        float n[3];
        struct Material *mat;
        char puno;
        char flag, ec;
-       RadFace *radface;
        int index;
 } VlakRen;
 
index 600ece8ad50923a7971b3880985e68144e2782e5..f2fae7cca84b7c222ca59a67cedfd08278343221 100644 (file)
@@ -50,6 +50,7 @@ struct World;
 struct RenderPart;
 struct RenderLayer;
 struct ObjectRen;
+struct ListBase;
 
 /* ------------------------------------------------------------------------- */
 
@@ -90,6 +91,8 @@ void zbufshadeDA_tile(struct RenderPart *pa);
 
 void zbufshade_sss_tile(struct RenderPart *pa);
 
+void addps(struct ListBase *lb, long *rd, int obi, int facenr, int z, unsigned short mask);
+
 /* -------- ray.c ------- */
 
 extern void freeraytree(Render *re);
index a74579acc4af1aa6ccb53fe036e27cf7e36ae86c..cfcbb4e777560bcf7ae6aac641ff429095e58ead 100644 (file)
@@ -42,6 +42,7 @@ struct CustomData;
 struct StrandBuffer;
 struct StrandRen;
 struct ObjectInstanceRen;
+struct RadFace;
 
 #define RE_QUAD_MASK   0x7FFFFFF
 #define RE_QUAD_OFFS   0x8000000
@@ -63,6 +64,7 @@ typedef struct VlakTableNode {
        struct MCol *mcol;
        int totmtface, totmcol;
        float *surfnor;
+       struct RadFace **radface;
 } VlakTableNode;
 
 typedef struct StrandTableNode {
@@ -94,7 +96,7 @@ struct HaloRen *RE_inithalo(struct Render *re, struct ObjectRen *obr, struct Mat
 struct HaloRen *RE_inithalo_particle(struct Render *re, struct ObjectRen *obr, struct DerivedMesh *dm, struct Material *ma,   float *vec,   float *vec1, float *orco, float *uvco, float hasize, float vectsize, int seed);
 struct StrandBuffer *RE_addStrandBuffer(struct ObjectRen *obr, int totvert);
 
-struct ObjectRen *RE_addRenderObject(struct Render *re, struct Object *ob, struct Object *par, int index, int psysindex);
+struct ObjectRen *RE_addRenderObject(struct Render *re, struct Object *ob, struct Object *par, int index, int psysindex, int lay);
 struct ObjectInstanceRen *RE_addRenderInstance(struct Render *re, struct ObjectRen *obr, struct Object *ob, struct Object *par, int index, int psysindex, float mat[][4]);
 void RE_makeRenderInstances(struct Render *re);
 void RE_instanceTransformNormal(struct ObjectInstanceRen *obi, float *nor, float *tnor);
@@ -109,6 +111,7 @@ float *RE_vertren_get_winspeed(struct ObjectInstanceRen *obi, struct VertRen *ve
 struct MTFace *RE_vlakren_get_tface(struct ObjectRen *obr, VlakRen *ren, int n, char **name, int verify);
 struct MCol *RE_vlakren_get_mcol(struct ObjectRen *obr, VlakRen *ren, int n, char **name, int verify);
 float *RE_vlakren_get_surfnor(struct ObjectRen *obr, VlakRen *ren, int verify);
+RadFace **RE_vlakren_get_radface(struct ObjectRen *obr, VlakRen *ren, int verify);
 int RE_vlakren_get_normal(struct Render *re, struct ObjectInstanceRen *obi, struct VlakRen *vlr, float *nor);
 
 float *RE_strandren_get_surfnor(struct ObjectRen *obr, struct StrandRen *strand, int verify);
index 4d30c1e0dfb87f34a989232e3c26007ccee660f8..1d202fa45fa5eb224bf246c36a8680070cfeb39d 100644 (file)
@@ -50,7 +50,7 @@ int testclip(float *v);
 void zbuffer_shadow(struct Render *re, float winmat[][4], struct LampRen *lar, int *rectz, int size, float jitx, float jity);
 void zbuffer_solid(struct RenderPart *pa, unsigned int layer, short layflag, void (*fillfunc)(struct RenderPart*, struct ZSpan*, int, void*), void *data);
 
-unsigned short *zbuffer_transp_shade(struct RenderPart *pa, struct RenderLayer *rl, float *pass);
+unsigned short *zbuffer_transp_shade(struct RenderPart *pa, struct RenderLayer *rl, float *pass, struct ListBase *psmlist);
 unsigned short *zbuffer_strands_shade(struct Render *re, struct RenderPart *pa, struct RenderLayer *rl, float *pass);
 void convert_zbuf_to_distbuf(struct RenderPart *pa, struct RenderLayer *rl);
 void zbuffer_sss(RenderPart *pa, unsigned int lay, void *handle, void (*func)(void*, int, int, int, int, int));
index 3faaec4c00cdccee1bfde8b0ccda8d9add21dbcf..69ae280dc4c73dabd0001145d8b7a4aebf54e195 100644 (file)
@@ -230,7 +230,7 @@ void RE_make_stars(Render *re, void (*initfunc)(void),
        }
 
        if(re) /* add render object for stars */
-               obr= RE_addRenderObject(re, NULL, NULL, 0, 0);
+               obr= RE_addRenderObject(re, NULL, NULL, 0, 0, 0);
        
        for (x = sx, fx = sx * stargrid; x <= ex; x++, fx += stargrid) {
                for (y = sy, fy = sy * stargrid; y <= ey ; y++, fy += stargrid) {
@@ -1075,7 +1075,6 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, flo
                
                vlr->mat= ma;
                vlr->ec= ME_V2V3;
-               vlr->lay= obr->ob->lay;
 
                if(surfnor) {
                        float *snor= RE_vlakren_get_surfnor(obr, vlr, 1);
@@ -1192,7 +1191,6 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, flo
                
                vlr->mat= ma;
                vlr->ec= ME_V2V3;
-               vlr->lay= obr->ob->lay;
 
                if(surfnor) {
                        float *snor= RE_vlakren_get_surfnor(obr, vlr, 1);
@@ -1244,7 +1242,6 @@ static void static_particle_wire(ObjectRen *obr, Material *ma, float *vec, float
                
                vlr->mat= ma;
                vlr->ec= ME_V1V2;
-               vlr->lay= obr->ob->lay;
 
        }
        else if(first) {
@@ -1267,7 +1264,6 @@ static void static_particle_wire(ObjectRen *obr, Material *ma, float *vec, float
                
                vlr->mat= ma;
                vlr->ec= ME_V1V2;
-               vlr->lay= obr->ob->lay;
        }
 
 }
@@ -1366,7 +1362,6 @@ static void particle_billboard(Render *re, ObjectRen *obr, Material *ma, Object
        
        vlr->mat= ma;
        vlr->ec= ME_V2V3;
-       vlr->lay= obr->ob->lay;
 
        if(uv_split>1){
                uvdx=uvdy=1.0f/(float)uv_split;
@@ -2304,7 +2299,6 @@ static void init_render_mball(Render *re, ObjectRen *obr)
                vlr->mat= ma;
                vlr->flag= ME_SMOOTH+R_NOPUNOFLIP;
                vlr->ec= 0;
-               vlr->lay= ob->lay;
 
                /* mball -too bad- always has triangles, because quads can be non-planar */
                if(index[3] && index[3]!=index[2]) {
@@ -2418,7 +2412,6 @@ static int dl_surf_to_renderdata(ObjectRen *obr, DispList *dl, Material **matar,
                        flen= CalcNormFloat4(vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co, n1);
                        VECCOPY(vlr->n, n1);
                        
-                       vlr->lay= ob->lay;
                        vlr->mat= matar[ dl->col];
                        vlr->ec= ME_V1V2+ME_V2V3;
                        vlr->flag= dl->rt;
@@ -2652,7 +2645,6 @@ static void init_render_curve(Render *re, ObjectRen *obr, int only_verts)
                                                vlr->flag |= R_NOPUNOFLIP;
                                        }
                                        vlr->ec= 0;
-                                       vlr->lay= ob->lay;
                                }
                        }
                }
@@ -2705,7 +2697,6 @@ static void init_render_curve(Render *re, ObjectRen *obr, int only_verts)
                                                        if(a==0) vlr->ec+= ME_V1V2;
 
                                                        vlr->flag= dl->rt;
-                                                       vlr->lay= ob->lay;
 
                                                        /* this is not really scientific: the vertices
                                                                * 2, 3 en 4 seem to give better vertexnormals than 1 2 3:
@@ -3105,7 +3096,6 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int only_verts)
                                                                vlr->flag |= R_NOPUNOFLIP;
                                                        }
                                                        vlr->ec= 0; /* mesh edges rendered separately */
-                                                       vlr->lay= ob->lay;
 
                                                        if(len==0) obr->totvlak--;
                                                        else {
@@ -3176,7 +3166,6 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int only_verts)
                                                vlr->mat= ma;
                                                vlr->flag= 0;
                                                vlr->ec= ME_V1V2;
-                                               vlr->lay= ob->lay;
                                        }
                                }
                                if(edgetable)
@@ -4006,7 +3995,7 @@ static void add_render_object(Render *re, Object *ob, Object *par, int index, in
 
        /* one render object for the data itself */
        if(allow_render) {
-               obr= RE_addRenderObject(re, ob, par, index, 0);
+               obr= RE_addRenderObject(re, ob, par, index, 0, ob->lay);
                if(instanceable) {
                        obr->flag |= R_INSTANCEABLE;
                        Mat4CpyMat4(obr->obmat, ob->obmat);
@@ -4024,7 +4013,7 @@ static void add_render_object(Render *re, Object *ob, Object *par, int index, in
        if(ob->particlesystem.first) {
                psysindex= 1;
                for(psys=ob->particlesystem.first; psys; psys=psys->next, psysindex++) {
-                       obr= RE_addRenderObject(re, ob, par, index, psysindex);
+                       obr= RE_addRenderObject(re, ob, par, index, psysindex, ob->lay);
                        if(instanceable) {
                                obr->flag |= R_INSTANCEABLE;
                                Mat4CpyMat4(obr->obmat, ob->obmat);
@@ -4298,8 +4287,11 @@ static void database_init_objects(Render *re, unsigned int lay, int nolamps, int
                                                                obi->dupliuv[0]= dob->uv[0];
                                                                obi->dupliuv[1]= dob->uv[1];
                                                        }
-                                                       else
+                                                       else {
                                                                assign_dupligroup_dupli(re, obi, obr);
+                                                               if(obd->transflag & OB_RENDER_DUPLI)
+                                                                       find_dupli_instances(re, obr);
+                                                       }
                                                }
                                                else
                                                        init_render_object(re, obd, ob, dob->index, only_verts, !dob->animated);
@@ -4313,8 +4305,11 @@ static void database_init_objects(Render *re, unsigned int lay, int nolamps, int
                                                                        obi->dupliuv[0]= dob->uv[0];
                                                                        obi->dupliuv[1]= dob->uv[1];
                                                                }
-                                                               else
+                                                               else {
                                                                        assign_dupligroup_dupli(re, obi, obr);
+                                                                       if(obd->transflag & OB_RENDER_DUPLI)
+                                                                               find_dupli_instances(re, obr);
+                                                               }
                                                        }
                                                }
                                                
index b1b907aebb62b3ec371746955b43cb8aeaf06ef4..6d93d91ae971fdaefb234eb340638a8d0573177e 100644 (file)
@@ -313,12 +313,13 @@ static void env_layerflags(Render *re, unsigned int notlay)
        notlay= ~notlay;
        
        for(obr=re->objecttable.first; obr; obr=obr->next) {
-               for(a=0; a<obr->totvlak; a++) {
-                       if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak;
-                       else vlr++;
+               if((obr->lay & notlay)==0) {
+                       for(a=0; a<obr->totvlak; a++) {
+                               if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak;
+                               else vlr++;
 
-                       if((vlr->lay & notlay)==0)
                                vlr->flag |= R_HIDDEN;
+                       }
                }
        }
 }
index e67cf6de6a1e3f7d022a499e9935d83061bc785a..218f5fe931ed27a609c74e20d0cbae40bd6b85ed 100644 (file)
@@ -79,13 +79,14 @@ static void vlr_face_coords(RayFace *face, float **v1, float **v2, float **v3, f
 
 static int vlr_check_intersect(Isect *is, int ob, RayFace *face)
 {
+       ObjectInstanceRen *obi= RAY_OBJECT_GET((Render*)is->userdata, ob);
        VlakRen *vlr = (VlakRen*)face;
 
        /* I know... cpu cycle waste, might do smarter once */
        if(is->mode==RE_RAY_MIRROR)
                return !(vlr->mat->mode & MA_ONLYCAST);
        else
-               return (is->lay & vlr->lay);
+               return (is->lay & obi->obr->lay);
 }
 
 static float *vlr_get_transform(void *userdata, int i)
@@ -878,11 +879,13 @@ void init_render_hammersley(Render *re)
 void free_lamp_qmcsampler(LampRen *lar)
 {
        QMC_freeSampler(lar->qsa);
+       lar->qsa = NULL;
 }
 
 void free_render_qmcsampler(Render *re)
 {
        QMC_freeSampler(re->qsa);
+       re->qsa = NULL;
 }
 
 static int adaptive_sample_variance(int samples, float *col, float *colsq, float thresh)
index 46f94c81c63e06603892aa0fc612bbd36cbb6058..50f3142f95afd557c8e0237ceec6737ebf4f3d67 100644 (file)
@@ -631,7 +631,7 @@ static void freeps(ListBase *lb)
        lb->first= lb->last= NULL;
 }
 
-static void addps(ListBase *lb, long *rd, int obi, int facenr, int z, unsigned short mask)
+void addps(ListBase *lb, long *rd, int obi, int facenr, int z, unsigned short mask)
 {
        PixStrMain *psm;
        PixStr *ps, *last= NULL;
@@ -925,7 +925,7 @@ void zbufshadeDA_tile(RenderPart *pa)
                                
                                /* swap for live updates, and it is used in zbuf.c!!! */
                                SWAP(float *, rl->acolrect, rl->rectf);
-                               ztramask= zbuffer_transp_shade(pa, rl, rl->rectf);
+                               ztramask= zbuffer_transp_shade(pa, rl, rl->rectf, &psmlist);
                                SWAP(float *, rl->acolrect, rl->rectf);
                                
                                /* zbuffer transp only returns ztramask if there's solid rendered */
@@ -1147,7 +1147,7 @@ void zbufshade_tile(RenderPart *pa)
                                
                                /* swap for live updates */
                                SWAP(float *, rl->acolrect, rl->rectf);
-                               zbuffer_transp_shade(pa, rl, rl->rectf);
+                               zbuffer_transp_shade(pa, rl, rl->rectf, NULL);
                                SWAP(float *, rl->acolrect, rl->rectf);
                                
                                fcol= rl->rectf; acol= rl->acolrect;
@@ -1722,6 +1722,8 @@ void add_halo_flare(Render *re)
 void RE_shade_external(Render *re, ShadeInput *shi, ShadeResult *shr)
 {
        static VlakRen vlr;
+       static ObjectRen obr;
+       static ObjectInstanceRen obi;
        
        /* init */
        if(re) {
@@ -1729,11 +1731,16 @@ void RE_shade_external(Render *re, ShadeInput *shi, ShadeResult *shr)
                
                /* fake render face */
                memset(&vlr, 0, sizeof(VlakRen));
-               vlr.lay= -1;
+               memset(&obr, 0, sizeof(ObjectRen));
+               memset(&obi, 0, sizeof(ObjectInstanceRen));
+               obr.lay= -1;
+               obi.obr= &obr;
                
                return;
        }
        shi->vlr= &vlr;
+       shi->obr= &obr;
+       shi->obi= &obi;
        
        if(shi->mat->nodetree && shi->mat->use_nodes)
                ntreeShaderExecTree(shi->mat->nodetree, shi, shr);
index 8aaf29b65c4f9a135907187abf1b52de33cfcedb..27daad9dc266b6c7fab217a7daec4312fedc8112 100644 (file)
 #define RE_MCOL_ELEMS          4
 #define RE_UV_ELEMS                    2
 #define RE_SURFNOR_ELEMS       3
+#define RE_RADFACE_ELEMS       1
 #define RE_SIMPLIFY_ELEMS      2
 #define RE_FACE_ELEMS  1
 
@@ -363,12 +364,28 @@ float *RE_vlakren_get_surfnor(ObjectRen *obr, VlakRen *vlak, int verify)
        return surfnor + (vlak->index & 255)*RE_SURFNOR_ELEMS;
 }
 
+RadFace **RE_vlakren_get_radface(ObjectRen *obr, VlakRen *vlak, int verify)
+{
+       RadFace **radface;
+       int nr= vlak->index>>8;
+       
+       radface= obr->vlaknodes[nr].radface;
+       if(radface==NULL) {
+               if(verify) 
+                       radface= obr->vlaknodes[nr].radface= MEM_callocN(256*RE_RADFACE_ELEMS*sizeof(void*), "radface table");
+               else
+                       return NULL;
+       }
+       return radface + (vlak->index & 255)*RE_RADFACE_ELEMS;
+}
+
 VlakRen *RE_vlakren_copy(ObjectRen *obr, VlakRen *vlr)
 {
        VlakRen *vlr1 = RE_findOrAddVlak(obr, obr->totvlak++);
        MTFace *mtface, *mtface1;
        MCol *mcol, *mcol1;
        float *surfnor, *surfnor1;
+       RadFace **radface, **radface1;
        int i, index = vlr1->index;
        char *name;
 
@@ -391,6 +408,12 @@ VlakRen *RE_vlakren_copy(ObjectRen *obr, VlakRen *vlr)
                VECCOPY(surfnor1, surfnor);
        }
 
+       radface= RE_vlakren_get_radface(obr, vlr, 0);
+       if(radface) {
+               radface1= RE_vlakren_get_radface(obr, vlr1, 1);
+               *radface1= *radface;
+       }
+
        return vlr1;
 }
 
@@ -695,7 +718,7 @@ StrandBuffer *RE_addStrandBuffer(ObjectRen *obr, int totvert)
 
 /* ------------------------------------------------------------------------ */
 
-ObjectRen *RE_addRenderObject(Render *re, Object *ob, Object *par, int index, int psysindex)
+ObjectRen *RE_addRenderObject(Render *re, Object *ob, Object *par, int index, int psysindex, int lay)
 {
        ObjectRen *obr= MEM_callocN(sizeof(ObjectRen), "object render struct");
        
@@ -704,6 +727,7 @@ ObjectRen *RE_addRenderObject(Render *re, Object *ob, Object *par, int index, in
        obr->par= par;
        obr->index= index;
        obr->psysindex= psysindex;
+       obr->lay= lay;
 
        return obr;
 }
@@ -749,6 +773,8 @@ void free_renderdata_vlaknodes(VlakTableNode *vlaknodes)
                        MEM_freeN(vlaknodes[a].mcol);
                if(vlaknodes[a].surfnor)
                        MEM_freeN(vlaknodes[a].surfnor);
+               if(vlaknodes[a].radface)
+                       MEM_freeN(vlaknodes[a].radface);
        }
        
        MEM_freeN(vlaknodes);
index 42086d078f67c7e04943f6d0bf1456bbd885bd0f..fcd9220df0ea636fcf58803d8e4e6810fda873c8 100644 (file)
@@ -325,7 +325,7 @@ static void shadowbuf_autoclip(Render *re, LampRen *lar)
                                if((ma->mode & MA_SHADBUF)==0) ok= 0;
                        }
                        
-                       if(ok && (vlr->lay & lay)) {
+                       if(ok && (obr->lay & lay)) {
                                clipflag[vlr->v1->index]= 1;
                                clipflag[vlr->v2->index]= 1;
                                clipflag[vlr->v3->index]= 1;
@@ -1558,7 +1558,7 @@ static void isb_bsp_fillfaces(Render *re, LampRen *lar, ISBBranch *root)
                                zspanstrand.shad_alpha= zspan.shad_alpha= ma->shad_alpha;
                        }
                        
-                       if(ok && (vlr->lay & lay)) {
+                       if(ok && (obr->lay & lay)) {
                                float hoco[4][4];
                                int c1, c2, c3, c4=0;
                                int d1, d2, d3, d4=0;
index 1498683baab82d96349a2f269cdc0799500d5f45..8af98158981956c75cd7686f7d3fe8cb441937dd 100644 (file)
@@ -355,7 +355,7 @@ void renderspothalo(ShadeInput *shi, float *col, float alpha)
                if(lar->type==LA_SPOT && (lar->mode & LA_HALO) && lar->haint>0) {
                        
                        if(lar->mode & LA_LAYER) 
-                               if(shi->vlr && (lar->lay & shi->vlr->lay)==0) 
+                               if(shi->vlr && (lar->lay & shi->obr->lay)==0) 
                                        continue;
                        if((lar->lay & shi->lay)==0) 
                                continue;
@@ -1460,7 +1460,7 @@ static void shade_lamp_loop_only_shadow(ShadeInput *shi, ShadeResult *shr)
                        /* yafray: ignore shading by photonlights, not used in Blender */
                        if (lar->type==LA_YF_PHOTON) continue;
                        
-                       if(lar->mode & LA_LAYER) if((lar->lay & shi->vlr->lay)==0) continue;
+                       if(lar->mode & LA_LAYER) if((lar->lay & shi->obr->lay)==0) continue;
                        if((lar->lay & shi->lay)==0) continue;
                        
                        if(lar->shb || (lar->mode & LA_SHAD_RAY)) {
@@ -1520,7 +1520,6 @@ static void wrld_exposure_correct(float *diff)
 void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
 {
        Material *ma= shi->mat;
-       VlakRen *vlr= shi->vlr;
        int passflag= shi->passflag;
        
        memset(shr, 0, sizeof(ShadeResult));
@@ -1597,7 +1596,7 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
                        if (lar->type==LA_YF_PHOTON) continue;
                        
                        /* test for lamp layer */
-                       if(lar->mode & LA_LAYER) if((lar->lay & vlr->lay)==0) continue;
+                       if(lar->mode & LA_LAYER) if((lar->lay & shi->obr->lay)==0) continue;
                        if((lar->lay & shi->lay)==0) continue;
                        
                        /* accumulates in shr->diff and shr->spec and shr->shad (diffuse with shadow!) */
index 3a4f44b11d3eec4c50bbe0f905b9755d772783fe..3a1d98572ca11efd045b82afec771e0694933cb9 100644 (file)
@@ -428,6 +428,7 @@ typedef struct StrandPart {
        ShadeResult *result;
        float *pass;
        int *rectz, *outrectz;
+       long *rectdaps;
        unsigned short *mask;
        int rectx, recty;
        int addpassflag, addzbuf, sample;
@@ -607,13 +608,33 @@ static void do_strand_blend(void *handle, int x, int y, float u, float v, float
        StrandBuffer *buffer= spart->segment->buffer;
        ShadeResult *shr;
        float /**pass,*/ t, s;
-       int offset, zverg;
+       int offset, zverg, bufferz;
 
        /* check again solid z-buffer */
        offset = y*spart->rectx + x;
        zverg= (int)z;
 
-       if(zverg < spart->rectz[offset]) {
+       if(spart->rectdaps) {
+               /* find the z of the sample */
+               PixStr *ps;
+               long *rd= spart->rectdaps + offset;
+               int sample= (1<<spart->sample);
+               
+               bufferz= 0x7FFFFFFF;
+               
+               if(*rd) {       
+                       for(ps= (PixStr *)(*rd); ps; ps= ps->next) {
+                               if(sample & ps->mask) {
+                                       bufferz= ps->z;
+                                       break;
+                               }
+                       }
+               }
+       }
+       else
+               bufferz= spart->rectz[offset];
+
+       if(zverg < bufferz) {
                /* fill in output z-buffer if needed */
                if(spart->addzbuf)
                        if(zverg < spart->outrectz[offset])
@@ -686,7 +707,6 @@ static void strand_shade_point(Render *re, ShadeSample *ssamp, StrandSegment *ss
 
        memset(&vlr, 0, sizeof(vlr));
        vlr.flag= R_SMOOTH;
-       vlr.lay= sseg->strand->buffer->lay;
        if(sseg->buffer->ma->mode & MA_TANGENT_STR)
                vlr.flag |= R_TANGENT;
 
@@ -891,11 +911,12 @@ static void zbuffer_strands_filter(Render *re, RenderPart *pa, RenderLayer *rl,
 {
        RenderResult *rr= pa->result;
        ShadeResult *shr, *shrrect= spart->result;
-       float *passrect= pass;
+       float *passrect= pass, alpha, sampalpha;
        long *rdrect;
        int osa, x, y, a, crop= 0, offs=0, od;
 
        osa= (re->osa? re->osa: 1);
+       sampalpha= 1.0f/osa;
 
        /* filtered render, for now we assume only 1 filter size */
        if(pa->crop) {
@@ -929,21 +950,28 @@ static void zbuffer_strands_filter(Render *re, RenderPart *pa, RenderLayer *rl,
                                        add_transp_speed(rl, od, NULL, 0.0f, rdrect);
                        }
                        else {
+                               alpha= 0.0f;
+
                                if(re->osa == 0) {
                                        addAlphaUnderFloat(pass, shr->combined);
                                }
                                else {
-                                       for(a=0; a<re->osa; a++)
+                                       /* note; cannot use pass[3] for alpha due to filtermask */
+                                       for(a=0; a<re->osa; a++) {
                                                add_filt_fmask(1<<a, shr[a].combined, pass, rr->rectx);
+                                               alpha += shr[a].combined[3];
+                                       }
                                }
 
                                if(spart->addpassflag) {
+                                       alpha *= sampalpha;
+
                                        /* merge all in one, and then add */
                                        merge_transp_passes(rl, shr);
-                                       add_transp_passes(rl, od, shr, pass[3]);
+                                       add_transp_passes(rl, od, shr, alpha);
 
                                        if(spart->addpassflag & SCE_PASS_VECTOR)
-                                               add_transp_speed(rl, od, shr->winspeed, pass[3], rdrect);
+                                               add_transp_speed(rl, od, shr->winspeed, alpha, rdrect);
                                }
                        }
                }
@@ -987,6 +1015,7 @@ unsigned short *zbuffer_strands_shade(Render *re, RenderPart *pa, RenderLayer *r
        spart.rectx= pa->rectx;
        spart.recty= pa->recty;
        spart.rectz= pa->rectz;
+       spart.rectdaps= pa->rectdaps;
        spart.addpassflag= rl->passflag & ~(SCE_PASS_Z|SCE_PASS_COMBINED);
        spart.addzbuf= rl->passflag & SCE_PASS_Z;
 
index 2ad1f6bac5328af5840fcf18adf09e6a18e91fa7..a8b6dfec667d5fb1abeef16a4dba114ec05d5cb2 100644 (file)
@@ -2003,7 +2003,7 @@ void zbuffer_solid(RenderPart *pa, unsigned int lay, short layflag, void(*fillfu
                        else vlr++;
 
                        /* three cases, visible for render, only z values and nothing */
-                       if(vlr->lay & lay) {
+                       if(obr->lay & lay) {
                                if(vlr->mat!=ma) {
                                        ma= vlr->mat;
                                        nofill= ma->mode & (MA_ZTRA|MA_ONLYCAST);
@@ -2191,7 +2191,7 @@ void RE_zbufferall_radio(struct RadView *vw, RNode **rg_elem, int rg_totelem, Re
        else {  /* radio render */
                ObjectRen *obr;
                VlakRen *vlr=NULL;
-               RadFace *rf;
+               RadFace **radface, *rf;
                int totface=0;
                
                /* note: radio render doesn't support duplis */
@@ -2201,8 +2201,8 @@ void RE_zbufferall_radio(struct RadView *vw, RNode **rg_elem, int rg_totelem, Re
                        for(a=0; a<obr->totvlak; a++) {
                                if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++;
                        
-                               if(vlr->radface) {
-                                       rf= vlr->radface;
+                               if((radface=RE_vlakren_get_radface(obr, vlr, 0))) {
+                                       rf= *radface;
                                        if( (rf->flag & RAD_SHOOT)==0 ) {    /* no shootelement */
                                                
                                                if( rf->flag & RAD_TWOSIDED) zvlnr= totface;
@@ -2293,7 +2293,7 @@ void zbuffer_shadow(Render *re, float winmat[][4], LampRen *lar, int *rectz, int
                                if((ma->mode & MA_SHADBUF)==0) ok= 0;
                        }
 
-                       if(ok && (vlr->lay & lay) && !(vlr->flag & R_HIDDEN)) {
+                       if(ok && (obr->lay & lay) && !(vlr->flag & R_HIDDEN)) {
                                c1= zbuf_shadow_project(cache, vlr->v1->index, obwinmat, vlr->v1->co, ho1);
                                c2= zbuf_shadow_project(cache, vlr->v2->index, obwinmat, vlr->v2->co, ho2);
                                c3= zbuf_shadow_project(cache, vlr->v3->index, obwinmat, vlr->v3->co, ho3);
@@ -2508,7 +2508,7 @@ void zbuffer_sss(RenderPart *pa, unsigned int lay, void *handle, void (*func)(vo
                        
                        if(material_in_material(vlr->mat, sss_ma)) {
                                /* three cases, visible for render, only z values and nothing */
-                               if(vlr->lay & lay) {
+                               if(obr->lay & lay) {
                                        if(vlr->mat!=ma) {
                                                ma= vlr->mat;
                                                nofill= ma->mode & MA_ONLYCAST;
@@ -3214,7 +3214,7 @@ static int zbuffer_abuf(RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, un
                        }
                        
                        if(dofill) {
-                               if(!(vlr->flag & R_HIDDEN) && (vlr->lay & lay)) {
+                               if(!(vlr->flag & R_HIDDEN) && (obr->lay & lay)) {
                                        unsigned short partclip;
                                        
                                        v1= vlr->v1;
@@ -3693,7 +3693,7 @@ void reset_sky_speedvectors(RenderPart *pa, RenderLayer *rl, float *rectf)
 
 /* main render call to fill in pass the full transparent layer */
 /* returns a mask, only if a) transp rendered and b) solid was rendered */
-unsigned short *zbuffer_transp_shade(RenderPart *pa, RenderLayer *rl, float *pass)
+unsigned short *zbuffer_transp_shade(RenderPart *pa, RenderLayer *rl, float *pass, ListBase *psmlist)
 {
        RenderResult *rr= pa->result;
        ShadeSample ssamp;
@@ -3859,6 +3859,9 @@ unsigned short *zbuffer_transp_shade(RenderPart *pa, RenderLayer *rl, float *pas
                                                                *sp |= zrow[totface].mask;
                                                        if(filled==0)
                                                                break;
+
+                                                       if(R.totstrand)
+                                                               addps(psmlist, pa->rectdaps+od, zrow[totface].obi, zrow[totface].p, zrow[totface].z, zrow[totface].mask);
                                                }
                                        }
                                        
index ddecbac1b8d3be0e8bea0dfb5706ff9c739d90fe..d3a474a57a5cb1e6a18f179c65bb68bf5c60a845 100644 (file)
@@ -4086,9 +4086,10 @@ static void editing_panel_armature_type(Object *ob, bArmature *arm)
        uiDefButI(block, ROW, REDRAWVIEW3D, "B-Bone",   155, 87,70,20, &arm->drawtype, 0, ARM_B_BONE, 0, 0, "Draw bones as boxes, showing subdivision and b-splines");
        uiDefButI(block, ROW, REDRAWVIEW3D, "Envelope", 225, 87,85,20, &arm->drawtype, 0, ARM_ENVELOPE, 0, 0, "Draw bones as extruded spheres, showing deformation influence volume");
 
-       uiDefButBitI(block, TOG, ARM_DRAWAXES, REDRAWVIEW3D, "Draw Axes", 10, 67,100,20, &arm->flag, 0, 0, 0, 0, "Draw bone axes");
-       uiDefButBitI(block, TOG, ARM_DRAWNAMES, REDRAWVIEW3D, "Draw Names", 110,67,100,20, &arm->flag, 0, 0, 0, 0, "Draw bone names");
-       uiDefButBitI(block, TOGN, ARM_NO_CUSTOM, REDRAWVIEW3D, "Draw Shapes", 210,67,100,20, &arm->flag, 0, 0, 0, 0, "Draw custom bone shapes");
+       uiDefButBitI(block, TOG, ARM_DRAWAXES, REDRAWVIEW3D, "Axes", 10, 67,75,20, &arm->flag, 0, 0, 0, 0, "Draw bone axes");
+       uiDefButBitI(block, TOG, ARM_DRAWNAMES, REDRAWVIEW3D, "Names", 85,67,75,20, &arm->flag, 0, 0, 0, 0, "Draw bone names");
+       uiDefButBitI(block, TOGN, ARM_NO_CUSTOM, REDRAWVIEW3D, "Shapes", 160,67,75,20, &arm->flag, 0, 0, 0, 0, "Draw custom bone shapes");
+       uiDefButBitI(block, TOG, ARM_COL_CUSTOM, REDRAWVIEW3D, "Colors", 235,67,75,20, &arm->flag, 0, 0, 0, 0, "Draw custom bone colors (colors are set per Bone Group)");
        
        uiBlockEndAlign(block);
        
@@ -5182,7 +5183,19 @@ static void editing_panel_links(Object *ob)
                                                uiDefIconBut(block, BUT, B_POSEGRP_REMOVE, VICON_X, xco+140-20, 85, 20, 20, NULL, 0.0, 0.0, 0.0, 0.0, "Remove this Pose Group");
                                                
                                                /* set custom color set */
-                                               uiDefButI(block, MENU,B_POSEGRP_RECALC, "Custom Color Set%t|GrpCol: [None]%x0", xco,65,140,19, &grp->customCol, 0.0, 0.0, 0.0, 0.0, "Set of Custom Colors to shade Group's bones with. (NOT YET FUNCTIONAL)");
+                                               uiDefButI(block, NUM,B_POSEGRP_RECALC, "GroupColor: ", xco,65,110,19, &grp->customCol, 0, 20, 0.0, 0.0, "Index of set of Custom Colors to shade Group's bones with. 0 = Use Default Color Scheme");                                             
+                                               if (grp->customCol) {
+                                                       bTheme *btheme= U.themes.first;
+                                                       ThemeWireColor *col_set= &btheme->tarm[(grp->customCol - 1)];
+                                                       
+                                                       uiSetButLock(1, "To change these colors, see Themes -> Bone Color Sets");
+                                                       
+                                                       uiDefButC(block, COL, B_POSEGRP_RECALC, "",             xco+110, 65, 10, 19, col_set->solid, 0, 0, 0, 0, "Color to use for surface of bones. See current theme in Info Window.");
+                                                       uiDefButC(block, COL, B_POSEGRP_RECALC, "",             xco+120, 65, 10, 19, col_set->select, 0, 0, 0, 0, "Color to use for 'selected' bones. See current theme in Info Window.");
+                                                       uiDefButC(block, COL, B_POSEGRP_RECALC, "",             xco+130, 65, 10, 19, col_set->active, 0, 0, 0, 0, "Color to use for 'active' bones. See current theme in Info Window.");
+                                                       
+                                                       uiClearButLock();
+                                               }
                                        }
                                uiBlockEndAlign(block);
                        }
index a064e266d6d8c15aa2394f5e9ee80f9f91983ab5..0b30f0b3cbaa846acf8600ad6126faa12a21d3a6 100644 (file)
@@ -604,13 +604,27 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
                uiBlockBeginAlign(block);
                        uiBlockSetEmboss(block, UI_EMBOSS);
                        
-                       if (prev_proxylock == 0) {
+                       if ((prev_proxylock) || (con->prev==NULL)) {
+                               /* don't draw 'button' behind arrow if disabled (and button doesn't do anything anyways) */
+                               uiBlockSetEmboss(block, UI_EMBOSSN);
+                               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");
+                               uiBlockSetEmboss(block, UI_EMBOSS);
+                       }
+                       else {
                                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);
+                       if (con->next) {
+                               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);
+                       }
+                       else {
+                               /* don't draw 'button' behind arrow if no next constraint (it doesn't do anything anyways) */
+                               uiBlockSetEmboss(block, UI_EMBOSSN);
+                               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");
+                               uiBlockSetEmboss(block, UI_EMBOSS);
+                       }
                uiBlockEndAlign(block);
                
                
@@ -3472,7 +3486,7 @@ static char sbsolvers[] = "SIF  semi implicit euler with fixed step size (worth
 static char sbsolvers[] = "SOFT  step size controlled midpoint(1rst choice for real softbodies)%x0";
 #endif
 
-static void object_softbodies_II(Object *ob)
+static void object_softbodies_collision(Object *ob)
 {
        SoftBody *sb=ob->soft;
        uiBlock *block;
@@ -3487,9 +3501,9 @@ static void object_softbodies_II(Object *ob)
                ob->pd->pdef_sbift  = 0.2f;
                ob->pd->pdef_sboft  = 0.02f;
        }
-       block= uiNewBlock(&curarea->uiblocks, "object_softbodies_II", UI_EMBOSS, UI_HELV, curarea->win);
-       uiNewPanelTabbed("Soft Body", "Physics");
-       if(uiNewPanel(curarea, block, "Soft Body Col&Solv", "Physics", 651, 0, 318, 204)==0) return;
+       block= uiNewBlock(&curarea->uiblocks, "object_softbodies_collision", UI_EMBOSS, UI_HELV, curarea->win);
+       // uiNewPanelTabbed("Soft Body", "Physics"); /*don't really want it tabbed first */
+       if(uiNewPanel(curarea, block, "Soft Body Collision", "Physics", 651, 0, 318, 204)==0) return;
 
        uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
 
@@ -3562,9 +3576,10 @@ static void object_softbodies_II(Object *ob)
                        uiBlockEndAlign(block);
                        /*SOLVER SETTINGS*/
                        uiBlockBeginAlign(block);
+                       /* done in another panel now*/
+                       /*
                        uiDefButS(block, MENU, B_SOFTBODY_CHANGE, sbsolvers,10,100,50,20, &sb->solver_ID, 14.0, 0.0, 0, 0, "Select Solver");
-                       /*some have adapive step size - some not*/
-                       sb->solver_ID = 0; /* ugly hack to prepare peach freeze */
+                       sb->solver_ID = 0; 
                        switch (sb->solver_ID) {
                        case 0:
                        case 1:
@@ -3593,6 +3608,7 @@ static void object_softbodies_II(Object *ob)
                                uiDefButS(block, NUM, B_DIFF, "Steps:", 10,80,100,20, &sb->minloops,  1.00,  30000.0, 10, 0, "Solver steps/frame ");
                                uiDefButS(block, NUM, B_DIFF, "Choke:", 210,80,100,20, &sb->choke, 0.00,  100.0, 10, 0, "'Viscosity' inside collision target ");
                        }
+                       */
 
 
                }
@@ -3610,6 +3626,103 @@ static void object_softbodies_II(Object *ob)
        }
        uiBlockEndAlign(block);
 }
+static void object_softbodies_solver(Object *ob)
+{
+       SoftBody *sb=ob->soft;
+       uiBlock *block;
+       static int val;
+       short *softflag=&ob->softflag, psys_cur=0, adaptive_mode=0;
+       int ob_has_hair=psys_ob_has_hair(ob);
+    if(!_can_softbodies_at_all(ob)) return;
+       block= uiNewBlock(&curarea->uiblocks, "object_softbodies_solver", UI_EMBOSS, UI_HELV, curarea->win);
+       if(uiNewPanel(curarea, block, "Soft Body Solver", "Physics", 651, 0, 318, 204)==0) return;
+
+       uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
+    /* doubt that is really needed here but for now */ 
+       if(ob_has_hair) {
+               if(PE_get_current_num(ob) >= 0) {
+                       ParticleSystem *psys = PE_get_current(ob);
+                       if(psys) {
+                               sb = psys->soft;
+                               softflag = &psys->softflag;
+                               psys_cur = 1;
+                       }
+               }
+       }
+
+       if(psys_cur) {
+               if(*softflag & OB_SB_ENABLE)
+                       val = 1;
+               else
+                       val = 0;
+       }
+       else
+               val = modifiers_isSoftbodyEnabled(ob);
+
+       if(!val) { 
+               uiDefBut(block, LABEL, 0, "",10,10,1,2, NULL, 0.0, 0, 0, 0, ""); /* tell UI we go to 10,10*/
+               if(psys_cur){
+                       uiDefBut(block, LABEL, 0, "Hair is not a softbody",10,190,300,20, NULL, 0.0, 0, 0, 0, ""); 
+               }
+               else {
+                       uiDefBut(block, LABEL, 0, "Object is not a softbody",10,190,300,20, NULL, 0.0, 0, 0, 0, ""); 
+               }
+       }
+       else{ 
+               if ((ob->type==OB_MESH)||(ob->type==OB_CURVE) ) {
+                       /*SOLVER SETTINGS*/
+                       uiBlockBeginAlign(block);
+                       uiDefBut(block, LABEL, 0, "Solver select",10,200,300,20, NULL, 0.0, 0, 0, 0, ""); 
+                       uiDefButS(block, MENU, B_SOFTBODY_CHANGE, sbsolvers,10,180,300,20, &sb->solver_ID, 14.0, 0.0, 0, 0, "Select Solver (choose 1 of 1 i was working on some other but failed *sigh* BM) ");
+                       uiBlockEndAlign(block);
+                       
+                       /*some have adapive step size - some not*/
+                       sb->solver_ID = 0; /* ugly hack to prepare peach freeze */
+                       switch (sb->solver_ID) {
+                       case 0:
+                       case 1:
+                               {adaptive_mode = 1; break;}
+                       case 3:
+                               {adaptive_mode = 0; break;}
+                       default: printf("SB_solver?\n"); // should never happen
+                       }
+                       if(adaptive_mode){
+                               uiBlockBeginAlign(block);
+                           uiDefBut(block, LABEL, 0, "Step size controls",10,160,300,20, NULL, 0.0, 0, 0, 0, "");
+                               uiDefButF(block, NUM, B_DIFF, "Error Lim:",     10,140,280,20, &sb->rklimit , 0.001, 10.0, 10, 0, "The Runge-Kutta ODE solver error limit, low value gives more precision, high values speed");
+                               uiDefButBitS(block, TOG, SBSO_OLDERR, B_DIFF,"V", 290,140,20,20, &sb->solverflags,  0,  0, 0, 0, "Use velocities for automagic step sizes");
+                               uiDefButS(block, NUM, B_DIFF, "MinS:", 10,120,150,20, &sb->minloops,  0.00,  30000.0, 10, 0, "Minimal # solver steps/frame ");
+                               uiDefButS(block, NUM, B_DIFF, "MaxS:", 160,120,150,20, &sb->maxloops,  0.00,  30000.0, 10, 0, "Maximal # solver steps/frame ");
+                               uiBlockEndAlign(block);
+
+                               uiBlockBeginAlign(block);
+                       uiDefBut(block, LABEL, 0, "Collision helpers",10,100,300,20, NULL, 0.0, 0, 0, 0, "");
+                               uiDefButS(block, NUM, B_DIFF, "Choke:", 10,80,150,20, &sb->choke, 0.00,  100.0, 10, 0, "'Viscosity' inside collision target ");
+                               uiDefButS(block, NUM, B_DIFF, "Fuzzy:", 160,80,150,20, &sb->fuzzyness,  1.00,  100.0, 10, 0, "Fuzzyness while on collision, high values make collsion handling faster but less stable");
+                               uiBlockEndAlign(block);
+                               
+                               uiBlockBeginAlign(block);
+                               uiDefBut(block, LABEL, 0, "Diagnosis stuff",10,60,300,20, NULL, 0.0, 0, 0, 0, "");
+                               uiDefButBitS(block, TOG, SBSO_MONITOR, B_DIFF,"Print Performance to Console", 10,40,300,20, &sb->solverflags,  0,  0, 0, 0, "Turn on SB diagnose console prints");                              
+                               uiBlockEndAlign(block);
+                       } 
+                       else{
+                               uiBlockEndAlign(block);
+                               uiBlockBeginAlign(block);
+                               uiDefButS(block, NUM, B_DIFF, "Fuzzy:", 210,100,90,20, &sb->fuzzyness,  1.00,  100.0, 10, 0, "Fuzzyness while on collision, high values make collsion handling faster but less stable");
+                               uiDefButBitS(block, TOG, SBSO_MONITOR, B_DIFF,"M", 290,100,20,20, &sb->solverflags,  0,  0, 0, 0, "Turn on SB diagnose console prints");
+                               uiBlockEndAlign(block);
+                               uiDefButS(block, NUM, B_DIFF, "Steps:", 10,80,100,20, &sb->minloops,  1.00,  30000.0, 10, 0, "Solver steps/frame ");
+                               uiDefButS(block, NUM, B_DIFF, "Choke:", 210,80,100,20, &sb->choke, 0.00,  100.0, 10, 0, "'Viscosity' inside collision target ");
+                       }
+
+       uiBlockEndAlign(block);
+
+               }
+               //uiDefBut(block, LABEL, 0, "",10,10,1,2, NULL, 0.0, 0, 0, 0, ""); /* tell UI we go to 10,10*/
+       }
+       uiBlockEndAlign(block);
+}
 
 static void sb_clear_cache(void *ob_v, void *actsoft_v)
 {
@@ -5149,7 +5262,8 @@ void physics_panels()
                        object_panel_deflection(ob);
                object_panel_fields(ob);
                object_softbodies(ob);
-               object_softbodies_II(ob);
+               object_softbodies_collision(ob);
+               object_softbodies_solver(ob);
                object_panel_cloth(ob);
                object_panel_cloth_II(ob);
                object_panel_fluidsim(ob);
index 3e08910abfea804a1e074c80ae9585f6a51d23e3..abe22a1804df89898ff8f2875cb8e7f278e45944 100644 (file)
@@ -49,6 +49,7 @@
 #include "DNA_screen_types.h"
 #include "DNA_space_types.h"
 #include "DNA_view3d_types.h"
+#include "DNA_userdef_types.h"
 
 #include "BLI_blenlib.h"
 #include "BLI_arithb.h"
 #include "blendef.h"
 #include "nla.h"
 
+
+/* *************** Armature Drawing - Coloring API ***************************** */
+
+/* global here is reset before drawing each bone */
+static ThemeWireColor *bcolor= NULL;
+
+/* values of colCode for set_pchan_glcolor */
+enum {
+       PCHAN_COLOR_NORMAL      = 0,            /* normal drawing */
+       PCHAN_COLOR_SOLID,                              /* specific case where "solid" colour is needed */
+       PCHAN_COLOR_CONSTS,                             /* "constraint" colors (which may/may-not be suppressed) */
+       
+       PCHAN_COLOR_SPHEREBONE_BASE,    /* for the 'stick' of sphere (envelope) bones */
+       PCHAN_COLOR_SPHEREBONE_END,             /* for the ends of sphere (envelope) bones */
+       PCHAN_COLOR_LINEBONE                    /* for the middle of line-bones */
+};     
+
+/* This function sets the color-set for coloring a certain bone */
+static void set_pchan_colorset (Object *ob, bPoseChannel *pchan)
+{
+       bPose *pose= (ob) ? ob->pose : NULL;
+       bArmature *arm= (ob) ? ob->data : NULL;
+       short color_index= 0;
+       
+       /* sanity check */
+       if (ELEM4(NULL, ob, arm, pose, pchan)) {
+               bcolor= NULL;
+               return;
+       }
+       
+       /* only try to set custom color if enabled for armature */
+       if (arm->flag & ARM_COL_CUSTOM) {       
+               /* currently, a bone can only use a custom color set if it's group (if it has one),
+                * has been set to use one
+                */
+               if (pchan->agrp_index) {
+                       bActionGroup *grp= (bActionGroup *)BLI_findlink(&pose->agroups, (pchan->agrp_index - 1));
+                       if (grp)
+                               color_index= grp->customCol;
+               }
+       }
+       
+       /* bcolor is a pointer to the color set to use. If NULL, then the default
+        * color set (based on the theme colors for 3d-view) is used. 
+        */
+       if (color_index) {
+               bTheme *btheme= U.themes.first;
+               bcolor= &btheme->tarm[(color_index - 1)];
+       }
+       else 
+               bcolor= NULL;
+}
+
+/* This function is for brightening/darkening a given color (like BIF_ThemeColorShade()) */
+static void cp_shade_color3ub (char cp[], int offset)
+{
+       int r, g, b;
+       
+       r= offset + (int) cp[0];
+       CLAMP(r, 0, 255);
+       g= offset + (int) cp[1];
+       CLAMP(g, 0, 255);
+       b= offset + (int) cp[2];
+       CLAMP(b, 0, 255);
+       
+       cp[0]= r;
+       cp[1]= g;
+       cp[2]= b;
+}
+
+/* This function sets the gl-color for coloring a certain bone (based on bcolor) */
+static short set_pchan_glColor (short colCode, int armflag, int boneflag, int constflag)
+{
+       switch (colCode) {
+       case PCHAN_COLOR_NORMAL:
+       {
+               if (bcolor) {
+                       char cp[3];
+                       
+                       if (boneflag & BONE_ACTIVE) {
+                               VECCOPY(cp, bcolor->active);
+                       }
+                       else if (boneflag & BONE_SELECTED) {
+                               VECCOPY(cp, bcolor->select);
+                       }
+                       else {
+                               /* a bit darker than solid */
+                               VECCOPY(cp, bcolor->solid);
+                               cp_shade_color3ub(cp, -50);
+                       }
+                       
+                       glColor3ub(cp[0], cp[1], cp[2]);
+               }
+               else {
+                       if (boneflag & BONE_ACTIVE) BIF_ThemeColorShade(TH_BONE_POSE, 40);
+                       else if (boneflag & BONE_SELECTED) BIF_ThemeColor(TH_BONE_POSE);
+                       else BIF_ThemeColor(TH_WIRE);
+               }
+               
+               return 1;
+       }
+               break;
+       
+       case PCHAN_COLOR_SOLID:
+       {
+               if (bcolor) {
+                       char *cp= bcolor->solid;
+                       glColor3ub(cp[0], cp[1], cp[2]);
+               }
+               else 
+                       BIF_ThemeColor(TH_BONE_SOLID);
+                       
+               return 1;
+       }
+               break;
+               
+       case PCHAN_COLOR_CONSTS:
+       {
+               if ( (bcolor == NULL) || (bcolor->flag & TH_WIRECOLOR_CONSTCOLS) ) {
+                       if (constflag & PCHAN_HAS_STRIDE) glColor4ub(0, 0, 200, 80);
+                       else if (constflag & PCHAN_HAS_TARGET) glColor4ub(255, 150, 0, 80);
+                       else if (constflag & PCHAN_HAS_IK) glColor4ub(255, 255, 0, 80);
+                       else if (constflag & PCHAN_HAS_CONST) glColor4ub(0, 255, 120, 80);
+                       else if (constflag) BIF_ThemeColor4(TH_BONE_POSE);      // PCHAN_HAS_ACTION 
+                       
+                       return 1;
+               }
+               else 
+                       return 0;
+       }
+               break;
+               
+       case PCHAN_COLOR_SPHEREBONE_BASE:
+       {
+               if (bcolor) {
+                       char cp[3];
+                       
+                       if (boneflag & BONE_ACTIVE) {
+                               VECCOPY(cp, bcolor->active);
+                       }
+                       else if (boneflag & BONE_SELECTED) {
+                               VECCOPY(cp, bcolor->select);
+                       }
+                       else {
+                               VECCOPY(cp, bcolor->solid);
+                       }
+                       
+                       glColor3ub(cp[0], cp[1], cp[2]);
+               }
+               else {
+                       if (boneflag & BONE_ACTIVE) BIF_ThemeColorShade(TH_BONE_POSE, 40);
+                       else if (boneflag & BONE_SELECTED) BIF_ThemeColor(TH_BONE_POSE);
+                       else BIF_ThemeColor(TH_BONE_SOLID);
+               }
+               
+               return 1;
+       }
+               break;
+       case PCHAN_COLOR_SPHEREBONE_END:
+       {
+               if (bcolor) {
+                       char cp[3];
+                       
+                       if (boneflag & BONE_ACTIVE) {
+                               VECCOPY(cp, bcolor->active);
+                               cp_shade_color3ub(cp, 10);
+                       }
+                       else if (boneflag & BONE_SELECTED) {
+                               VECCOPY(cp, bcolor->select);
+                               cp_shade_color3ub(cp, -30);
+                       }
+                       else {
+                               VECCOPY(cp, bcolor->solid);
+                               cp_shade_color3ub(cp, -30);
+                       }
+                       
+                       glColor3ub(cp[0], cp[1], cp[2]);
+               }
+               else {
+                       if (boneflag & BONE_ACTIVE) BIF_ThemeColorShade(TH_BONE_POSE, 10);
+                       else if (boneflag & BONE_SELECTED) BIF_ThemeColorShade(TH_BONE_POSE, -30);
+                       else BIF_ThemeColorShade(TH_BONE_SOLID, -30);
+               }
+       }
+               break;
+               
+       case PCHAN_COLOR_LINEBONE:
+       {
+               /* inner part in background color or constraint */
+               if ((bcolor == NULL) || (bcolor->flag & TH_WIRECOLOR_CONSTCOLS)) {
+                       if (constflag & PCHAN_HAS_STRIDE) glColor3ub(0, 0, 200);
+                       else if (constflag & PCHAN_HAS_TARGET) glColor3ub(255, 150, 0);
+                       else if (constflag & PCHAN_HAS_IK) glColor3ub(255, 255, 0);
+                       else if (constflag & PCHAN_HAS_CONST) glColor3ub(0, 255, 120);
+                       else if (constflag) BIF_ThemeColor(TH_BONE_POSE);       /* PCHAN_HAS_ACTION */ 
+               }
+               else {
+                       if (bcolor) {
+                               char *cp= bcolor->solid;
+                               glColor4ub(cp[0], cp[1], cp[2], 0.8);   
+                       }
+                       else
+                               BIF_ThemeColorShade(TH_BACK, -30);
+               }
+               
+               return 1;
+       }
+               break;
+       }
+       
+       return 0;
+}
+
+
+/* *************** Armature drawing, helper calls for parts ******************* */
+
 /* half the cube, in Y */
 static float cube[8][3] = {
 {-1.0,  0.0, -1.0},
@@ -98,9 +315,6 @@ static float cube[8][3] = {
 { 1.0,  1.0, -1.0},
 };
 
-
-/* *************** Armature drawing, helper calls for parts ******************* */
-
 static void drawsolidcube_size(float xsize, float ysize, float zsize)
 {
        static GLuint displist=0;
@@ -152,10 +366,10 @@ static void drawcube_size(float xsize, float ysize, float zsize)
        
        glScalef(xsize, ysize, zsize);
        
-       if(displist==0) {
+       if(displist == 0) {
                displist= glGenLists(1);
                glNewList(displist, GL_COMPILE_AND_EXECUTE);
-
+               
                glBegin(GL_LINE_STRIP);
                glVertex3fv(cube[0]); glVertex3fv(cube[1]);glVertex3fv(cube[2]); glVertex3fv(cube[3]);
                glVertex3fv(cube[0]); glVertex3fv(cube[4]);glVertex3fv(cube[5]); glVertex3fv(cube[6]);
@@ -167,7 +381,7 @@ static void drawcube_size(float xsize, float ysize, float zsize)
                glVertex3fv(cube[2]); glVertex3fv(cube[6]);
                glVertex3fv(cube[3]); glVertex3fv(cube[7]);
                glEnd();
-
+               
                glEndList();
        }
        else glCallList(displist);
@@ -179,37 +393,38 @@ static void draw_bonevert(void)
 {
        static GLuint displist=0;
        
-       if(displist==0) {
+       if (displist == 0) {
                GLUquadricObj   *qobj;
                
                displist= glGenLists(1);
                glNewList(displist, GL_COMPILE_AND_EXECUTE);
-                               
+                       
                glPushMatrix();
                
                qobj    = gluNewQuadric(); 
                gluQuadricDrawStyle(qobj, GLU_SILHOUETTE); 
-               gluDisk( qobj, 0.0,  0.05, 16, 1);
+               gluDisk(qobj, 0.0,  0.05, 16, 1);
                
-               glRotatef (90, 0, 1, 0);
-               gluDisk( qobj, 0.0,  0.05, 16, 1);
+               glRotatef(90, 0, 1, 0);
+               gluDisk(qobj, 0.0,  0.05, 16, 1);
                
-               glRotatef (90, 1, 0, 0);
-               gluDisk( qobj, 0.0,  0.05, 16, 1);
+               glRotatef(90, 1, 0, 0);
+               gluDisk(qobj, 0.0,  0.05, 16, 1);
                
                gluDeleteQuadric(qobj);  
                
                glPopMatrix();
                glEndList();
        }
-       else glCallList(displist);
+       else 
+               glCallList(displist);
 }
 
 static void draw_bonevert_solid(void)
 {
        static GLuint displist=0;
        
-       if(displist==0) {
+       if (displist == 0) {
                GLUquadricObj   *qobj;
                
                displist= glGenLists(1);
@@ -224,19 +439,20 @@ static void draw_bonevert_solid(void)
                
                glEndList();
        }
-       else glCallList(displist);
+       else 
+               glCallList(displist);
 }
 
 static void draw_bone_octahedral()
 {
        static GLuint displist=0;
        
-       if(displist==0) {
+       if (displist == 0) {
                float vec[6][3];        
                
                displist= glGenLists(1);
                glNewList(displist, GL_COMPILE_AND_EXECUTE);
-
+               
                vec[0][0]= vec[0][1]= vec[0][2]= 0.0;
                vec[5][0]= vec[5][2]= 0.0; vec[5][1]= 1.0;
                
@@ -267,14 +483,15 @@ static void draw_bone_octahedral()
                
                glEndList();
        }
-       else glCallList(displist);
+       else 
+               glCallList(displist);
 }      
 
 static void draw_bone_solid_octahedral(void)
 {
        static GLuint displist=0;
        
-       if(displist==0) {
+       if (displist == 0) {
                float vec[6][3], nor[3];        
                
                displist= glGenLists(1);
@@ -328,7 +545,8 @@ static void draw_bone_solid_octahedral(void)
                
                glEndList();
        }
-       else glCallList(displist);
+       else 
+               glCallList(displist);
 }      
 
 /* *************** Armature drawing, bones ******************* */
@@ -337,40 +555,51 @@ static void draw_bone_solid_octahedral(void)
 static void draw_bone_points(int dt, int armflag, unsigned int boneflag, int id)
 {
        /*      Draw root point if we are not connected */
-       if (!(boneflag & BONE_CONNECTED)){
+       if ((boneflag & BONE_CONNECTED)==0) {
                if (id != -1)
-                       glLoadName (id | BONESEL_ROOT);
+                       glLoadName(id | BONESEL_ROOT);
                
-               if(dt<=OB_WIRE) {
-                       if(armflag & ARM_EDITMODE) {
+               if(dt <= OB_WIRE) {
+                       if (armflag & ARM_EDITMODE) {
                                if (boneflag & BONE_ROOTSEL) BIF_ThemeColor(TH_VERTEX_SELECT);
                                else BIF_ThemeColor(TH_VERTEX);
                        }
                }
-               else 
-                       BIF_ThemeColor(TH_BONE_SOLID);
+               else {
+                       if (armflag & ARM_POSEMODE) 
+                               set_pchan_glColor(PCHAN_COLOR_SOLID, armflag, boneflag, 0);
+                       else
+                               BIF_ThemeColor(TH_BONE_SOLID);
+               }
                
-               if(dt>OB_WIRE) draw_bonevert_solid();
-               else draw_bonevert();
+               if (dt > OB_WIRE) 
+                       draw_bonevert_solid();
+               else 
+                       draw_bonevert();
        }
        
        /*      Draw tip point */
        if (id != -1)
-               glLoadName (id | BONESEL_TIP);
+               glLoadName(id | BONESEL_TIP);
        
-       if(dt<=OB_WIRE) {
-               if(armflag & ARM_EDITMODE) {
+       if (dt <= OB_WIRE) {
+               if (armflag & ARM_EDITMODE) {
                        if (boneflag & BONE_TIPSEL) BIF_ThemeColor(TH_VERTEX_SELECT);
                        else BIF_ThemeColor(TH_VERTEX);
                }
        }
        else {
-               BIF_ThemeColor(TH_BONE_SOLID);
+               if (armflag & ARM_POSEMODE) 
+                       set_pchan_glColor(PCHAN_COLOR_SOLID, armflag, boneflag, 0);
+               else
+                       BIF_ThemeColor(TH_BONE_SOLID);
        }
        
        glTranslatef(0.0, 1.0, 0.0);
-       if(dt>OB_WIRE) draw_bonevert_solid();
-       else draw_bonevert();
+       if (dt > OB_WIRE) 
+               draw_bonevert_solid();
+       else 
+               draw_bonevert();
        glTranslatef(0.0, -1.0, 0.0);
        
 }
@@ -409,7 +638,7 @@ static void draw_sphere_bone_dist(float smat[][4], float imat[][4], int boneflag
        float *headvec, *tailvec, dirvec[3];
        
        /* figure out the sizes of spheres */
-       if(ebone) {
+       if (ebone) {
                /* this routine doesn't call set_matrix_editbone() that calculates it */
                ebone->length = VecLenf(ebone->head, ebone->tail);
                
@@ -445,7 +674,7 @@ static void draw_sphere_bone_dist(float smat[][4], float imat[][4], int boneflag
        /* move vector back */
        Mat4Mul3Vecfl(imat, dirvec);
        
-       if(0.0f != Normalize(dirvec)) {
+       if (0.0f != Normalize(dirvec)) {
                float norvec[3], vec1[3], vec2[3], vec[3];
                int a;
                
@@ -453,8 +682,8 @@ static void draw_sphere_bone_dist(float smat[][4], float imat[][4], int boneflag
                Crossf(norvec, dirvec, imat[2]);
                
                glBegin(GL_QUAD_STRIP);
-
-               for(a=0; a<16; a++) {
+               
+               for (a=0; a<16; a++) {
                        vec[0]= - *(si+a) * dirvec[0] + *(co+a) * norvec[0];
                        vec[1]= - *(si+a) * dirvec[1] + *(co+a) * norvec[1];
                        vec[2]= - *(si+a) * dirvec[2] + *(co+a) * norvec[2];
@@ -472,7 +701,7 @@ static void draw_sphere_bone_dist(float smat[][4], float imat[][4], int boneflag
                        glVertex3fv(vec2);
                }
                
-               for(a=15; a>=0; a--) {
+               for (a=15; a>=0; a--) {
                        vec[0]= *(si+a) * dirvec[0] + *(co+a) * norvec[0];
                        vec[1]= *(si+a) * dirvec[1] + *(co+a) * norvec[1];
                        vec[2]= *(si+a) * dirvec[2] + *(co+a) * norvec[2];
@@ -519,10 +748,10 @@ static void draw_sphere_bone_wire(float smat[][4], float imat[][4], int armflag,
        float *headvec, *tailvec, dirvec[3];
        
        /* figure out the sizes of spheres */
-       if(ebone) {
+       if (ebone) {
                /* this routine doesn't call set_matrix_editbone() that calculates it */
                ebone->length = VecLenf(ebone->head, ebone->tail);
-
+               
                length= ebone->length;
                tail= ebone->rad_tail;
                if (ebone->parent && (boneflag & BONE_CONNECTED))
@@ -535,7 +764,7 @@ static void draw_sphere_bone_wire(float smat[][4], float imat[][4], int armflag,
        else {
                length= pchan->bone->length;
                tail= pchan->bone->rad_tail;
-               if (pchan->parent && (boneflag & BONE_CONNECTED))
+               if ((pchan->parent) && (boneflag & BONE_CONNECTED))
                        head= pchan->parent->bone->rad_tail;
                else
                        head= pchan->bone->rad_head;
@@ -544,38 +773,34 @@ static void draw_sphere_bone_wire(float smat[][4], float imat[][4], int armflag,
        }
        
        /* sphere root color */
-       if(armflag & ARM_EDITMODE) {
+       if (armflag & ARM_EDITMODE) {
                if (boneflag & BONE_ROOTSEL) BIF_ThemeColor(TH_VERTEX_SELECT);
                else BIF_ThemeColor(TH_VERTEX);
        }
-       else if(armflag & ARM_POSEMODE) {
-               /* in black or selection color */
-               if (boneflag & BONE_ACTIVE) BIF_ThemeColorShade(TH_BONE_POSE, 40);
-               else if (boneflag & BONE_SELECTED) BIF_ThemeColor(TH_BONE_POSE);
-               else BIF_ThemeColor(TH_WIRE);
-       }
+       else if (armflag & ARM_POSEMODE)
+               set_pchan_glColor(PCHAN_COLOR_NORMAL, armflag, boneflag, constflag);
        
        /*      Draw root point if we are not connected */
-       if (!(boneflag & BONE_CONNECTED)){
+       if ((boneflag & BONE_CONNECTED)==0) {
                if (id != -1)
-                       glLoadName (id | BONESEL_ROOT);
+                       glLoadName(id | BONESEL_ROOT);
                
                drawcircball(GL_LINE_LOOP, headvec, head, imat);
        }
        
        /*      Draw tip point */
-       if(armflag & ARM_EDITMODE) {
+       if (armflag & ARM_EDITMODE) {
                if (boneflag & BONE_TIPSEL) BIF_ThemeColor(TH_VERTEX_SELECT);
                else BIF_ThemeColor(TH_VERTEX);
        }
        
        if (id != -1)
-               glLoadName (id | BONESEL_TIP);
+               glLoadName(id | BONESEL_TIP);
        
        drawcircball(GL_LINE_LOOP, tailvec, tail, imat);
        
        /* base */
-       if(armflag & ARM_EDITMODE) {
+       if (armflag & ARM_EDITMODE) {
                if (boneflag & BONE_SELECTED) BIF_ThemeColor(TH_SELECT);
                else BIF_ThemeColor(TH_WIRE);
        }
@@ -589,7 +814,7 @@ static void draw_sphere_bone_wire(float smat[][4], float imat[][4], int armflag,
        /* move vector back */
        Mat4Mul3Vecfl(imat, dirvec);
        
-       if(0.0f != Normalize(dirvec)) {
+       if (0.0f != Normalize(dirvec)) {
                float norvech[3], norvect[3], vec[3];
                
                VECCOPY(vec, dirvec);
@@ -601,8 +826,8 @@ static void draw_sphere_bone_wire(float smat[][4], float imat[][4], int armflag,
                Crossf(norvect, vec, imat[2]);
                
                if (id != -1)
-                       glLoadName (id | BONESEL_BONE);
-
+                       glLoadName(id | BONESEL_BONE);
+               
                glBegin(GL_LINES);
                vec[0]= headvec[0] + norvech[0];
                vec[1]= headvec[1] + norvech[1];
@@ -636,7 +861,7 @@ static void draw_sphere_bone(int dt, int armflag, int boneflag, int constflag, u
        qobj    = gluNewQuadric();
 
        /* figure out the sizes of spheres */
-       if(ebone) {
+       if (ebone) {
                length= ebone->length;
                tail= ebone->rad_tail;
                if (ebone->parent && (boneflag & BONE_CONNECTED))
@@ -654,9 +879,9 @@ static void draw_sphere_bone(int dt, int armflag, int boneflag, int constflag, u
        }
        
        /* move to z-axis space */
-       glRotatef (-90.0f, 1.0f, 0.0f, 0.0f);
+       glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
 
-       if(dt==OB_SOLID) {
+       if (dt==OB_SOLID) {
                /* set up solid drawing */
                glEnable(GL_COLOR_MATERIAL);
                glEnable(GL_LIGHTING);
@@ -669,57 +894,49 @@ static void draw_sphere_bone(int dt, int armflag, int boneflag, int constflag, u
        }
        
        /* sphere root color */
-       if(armflag & ARM_EDITMODE) {
+       if (armflag & ARM_EDITMODE) {
                if (boneflag & BONE_ROOTSEL) BIF_ThemeColor(TH_VERTEX_SELECT);
                else BIF_ThemeColorShade(TH_BONE_SOLID, -30);
        }
-       else if(armflag & ARM_POSEMODE) {
-               if (boneflag & BONE_ACTIVE) BIF_ThemeColorShade(TH_BONE_POSE, 10);
-               else if (boneflag & BONE_SELECTED) BIF_ThemeColorShade(TH_BONE_POSE, -30);
-               else BIF_ThemeColorShade(TH_BONE_SOLID, -30);
-               
-       }
-       else if(dt==OB_SOLID) 
+       else if (armflag & ARM_POSEMODE)
+               set_pchan_glColor(PCHAN_COLOR_SPHEREBONE_END, armflag, boneflag, constflag);
+       else if (dt==OB_SOLID) 
                BIF_ThemeColorShade(TH_BONE_SOLID, -30);
        
        /*      Draw root point if we are not connected */
-       if (!(boneflag & BONE_CONNECTED)){
+       if ((boneflag & BONE_CONNECTED)==0) {
                if (id != -1)
-                       glLoadName (id | BONESEL_ROOT);
-               gluSphere( qobj, head, 16, 10);
+                       glLoadName(id | BONESEL_ROOT);
+               gluSphere(qobj, head, 16, 10);
        }
        
        /*      Draw tip point */
-       if(armflag & ARM_EDITMODE) {
+       if (armflag & ARM_EDITMODE) {
                if (boneflag & BONE_TIPSEL) BIF_ThemeColor(TH_VERTEX_SELECT);
                else BIF_ThemeColorShade(TH_BONE_SOLID, -30);
        }
 
        if (id != -1)
-               glLoadName (id | BONESEL_TIP);
+               glLoadName(id | BONESEL_TIP);
        
        glTranslatef(0.0, 0.0, length);
-       gluSphere( qobj, tail, 16, 10);
+       gluSphere(qobj, tail, 16, 10);
        glTranslatef(0.0, 0.0, -length);
        
        /* base */
-       if(armflag & ARM_EDITMODE) {
+       if (armflag & ARM_EDITMODE) {
                if (boneflag & BONE_SELECTED) BIF_ThemeColor(TH_SELECT);
                else BIF_ThemeColor(TH_BONE_SOLID);
        }
-       else if(armflag & ARM_POSEMODE) {
-               if (boneflag & BONE_ACTIVE) BIF_ThemeColorShade(TH_BONE_POSE, 40);
-               else if (boneflag & BONE_SELECTED) BIF_ThemeColor(TH_BONE_POSE);
-               else BIF_ThemeColor(TH_BONE_SOLID);
-               
-       }
-       else if(dt==OB_SOLID)
+       else if (armflag & ARM_POSEMODE)
+               set_pchan_glColor(PCHAN_COLOR_SPHEREBONE_BASE, armflag, boneflag, constflag);
+       else if (dt == OB_SOLID)
                BIF_ThemeColor(TH_BONE_SOLID);
        
        fac1= (length-head)/length;
        fac2= (length-tail)/length;
        
-       if(length > head+tail) {
+       if (length > (head+tail)) {
                if (id != -1)
                        glLoadName (id | BONESEL_BONE);
                
@@ -729,25 +946,25 @@ static void draw_sphere_bone(int dt, int armflag, int boneflag, int constflag, u
                glTranslatef(0.0f, 0.0f, head);
                gluCylinder(qobj, fac1*head + (1.0f-fac1)*tail, fac2*tail + (1.0f-fac2)*head, length-head-tail, 16, 1);
                glTranslatef(0.0f, 0.0f, -head);
-
+               
                glDisable(GL_POLYGON_OFFSET_FILL);
                
                /* draw sphere on extrema */
                glTranslatef(0.0f, 0.0f, length-tail);
-               gluSphere( qobj, fac2*tail + (1.0f-fac2)*head, 16, 10);
+               gluSphere(qobj, fac2*tail + (1.0f-fac2)*head, 16, 10);
                glTranslatef(0.0f, 0.0f, -length+tail);
-
+               
                glTranslatef(0.0f, 0.0f, head);
-               gluSphere( qobj, fac1*head + (1.0f-fac1)*tail, 16, 10);
+               gluSphere(qobj, fac1*head + (1.0f-fac1)*tail, 16, 10);
        }
        else {          
                /* 1 sphere in center */
                glTranslatef(0.0f, 0.0f, (head + length-tail)/2.0);
-               gluSphere( qobj, fac1*head + (1.0f-fac1)*tail, 16, 10);
+               gluSphere(qobj, fac1*head + (1.0f-fac1)*tail, 16, 10);
        }
        
        /* restore */
-       if(dt==OB_SOLID) {
+       if (dt==OB_SOLID) {
                glShadeModel(GL_FLAT);
                glDisable(GL_LIGHTING);
                glDisable(GL_COLOR_MATERIAL);
@@ -770,7 +987,7 @@ static void draw_line_bone(int armflag, int boneflag, int constflag, unsigned in
        
        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
        
-       if(pchan) 
+       if (pchan) 
                length= pchan->bone->length;
        else 
                length= ebone->length;
@@ -779,20 +996,16 @@ static void draw_line_bone(int armflag, int boneflag, int constflag, unsigned in
        glScalef(length, length, length);
        
        /* this chunk not in object mode */
-       if(armflag & (ARM_EDITMODE|ARM_POSEMODE)) {
+       if (armflag & (ARM_EDITMODE|ARM_POSEMODE)) {
                glLineWidth(4.0);
-               if(armflag & ARM_POSEMODE) {
-                       /* outline in black or selection color */
-                       if (boneflag & BONE_ACTIVE) BIF_ThemeColorShade(TH_BONE_POSE, 40);
-                       else if (boneflag & BONE_SELECTED) BIF_ThemeColor(TH_BONE_POSE);
-                       else BIF_ThemeColor(TH_WIRE);
-               }
+               if (armflag & ARM_POSEMODE)
+                       set_pchan_glColor(PCHAN_COLOR_NORMAL, armflag, boneflag, constflag);
                else if (armflag & ARM_EDITMODE) {
                        BIF_ThemeColor(TH_WIRE);
                }
                
                /*      Draw root point if we are not connected */
-               if (!(boneflag & BONE_CONNECTED)){
+               if ((boneflag & BONE_CONNECTED)==0) {
                        if (G.f & G_PICKSEL) {  // no bitmap in selection mode, crashes 3d cards...
                                glLoadName (id | BONESEL_ROOT);
                                glBegin(GL_POINTS);
@@ -806,7 +1019,7 @@ static void draw_line_bone(int armflag, int boneflag, int constflag, unsigned in
                }
                
                if (id != -1)
-                       glLoadName ((GLuint) id|BONESEL_BONE);
+                       glLoadName((GLuint) id|BONESEL_BONE);
                
                glBegin(GL_LINES);
                glVertex3f(0.0f, 0.0f, 0.0f);
@@ -814,8 +1027,9 @@ static void draw_line_bone(int armflag, int boneflag, int constflag, unsigned in
                glEnd();
                
                /* tip */
-               if (G.f & G_PICKSEL) {  // no bitmap in selection mode, crashes 3d cards...
-                       glLoadName (id | BONESEL_TIP);
+               if (G.f & G_PICKSEL) {  
+                       /* no bitmap in selection mode, crashes 3d cards... */
+                       glLoadName(id | BONESEL_TIP);
                        glBegin(GL_POINTS);
                        glVertex3f(0.0f, 1.0f, 0.0f);
                        glEnd();
@@ -827,27 +1041,19 @@ static void draw_line_bone(int armflag, int boneflag, int constflag, unsigned in
                
                /* further we send no names */
                if (id != -1)
-                       glLoadName (id & 0xFFFF);       // object tag, for bordersel optim
-               
-               if(armflag & ARM_POSEMODE) {
-                       /* inner part in background color or constraint */
-                       if(constflag) {
-                               if(constflag & PCHAN_HAS_STRIDE) glColor3ub(0, 0, 200);
-                               else if(constflag & PCHAN_HAS_TARGET) glColor3ub(255, 150, 0);
-                               else if(constflag & PCHAN_HAS_IK) glColor3ub(255, 255, 0);
-                               else if(constflag & PCHAN_HAS_CONST) glColor3ub(0, 255, 120);
-                               else BIF_ThemeColor(TH_BONE_POSE);      // PCHAN_HAS_ACTION 
-                       }
-                       else BIF_ThemeColorShade(TH_BACK, -30);
-               }
+                       glLoadName(id & 0xFFFF);        /* object tag, for bordersel optim */
+               
+               if (armflag & ARM_POSEMODE)
+                       set_pchan_glColor(PCHAN_COLOR_LINEBONE, armflag, boneflag, constflag);
        }
        
        glLineWidth(2.0);
        
-       /*      Draw root point if we are not connected */
-       if (!(boneflag & BONE_CONNECTED)){
-               if ((G.f & G_PICKSEL)==0) {     // no bitmap in selection mode, crashes 3d cards...
-                       if(armflag & ARM_EDITMODE) {
+       /*Draw root point if we are not connected */
+       if ((boneflag & BONE_CONNECTED)==0) {
+               if ((G.f & G_PICKSEL)==0) {     
+                       /* no bitmap in selection mode, crashes 3d cards... */
+                       if (armflag & ARM_EDITMODE) {
                                if (boneflag & BONE_ROOTSEL) BIF_ThemeColor(TH_VERTEX_SELECT);
                                else BIF_ThemeColor(TH_VERTEX);
                        }
@@ -856,18 +1062,19 @@ static void draw_line_bone(int armflag, int boneflag, int constflag, unsigned in
                }
        }
        
-   if(armflag & ARM_EDITMODE) {
-          if (boneflag & BONE_SELECTED) BIF_ThemeColor(TH_EDGE_SELECT);
-          else BIF_ThemeColorShade(TH_BACK, -30);
-   }
+       if (armflag & ARM_EDITMODE) {
+               if (boneflag & BONE_SELECTED) BIF_ThemeColor(TH_EDGE_SELECT);
+               else BIF_ThemeColorShade(TH_BACK, -30);
+       }
        glBegin(GL_LINES);
        glVertex3f(0.0f, 0.0f, 0.0f);
        glVertex3f(0.0f, 1.0f, 0.0f);
        glEnd();
        
        /* tip */
-       if ((G.f & G_PICKSEL)==0) {     // no bitmap in selection mode, crashes 3d cards...
-               if(armflag & ARM_EDITMODE) {
+       if ((G.f & G_PICKSEL)==0) {     
+               /* no bitmap in selection mode, crashes 3d cards... */
+               if (armflag & ARM_EDITMODE) {
                        if (boneflag & BONE_TIPSEL) BIF_ThemeColor(TH_VERTEX_SELECT);
                        else BIF_ThemeColor(TH_VERTEX);
                }
@@ -884,24 +1091,25 @@ static void draw_b_bone_boxes(int dt, bPoseChannel *pchan, float xwidth, float l
 {
        int segments= 0;
        
-       if(pchan) segments= pchan->bone->segments;
+       if (pchan) 
+               segments= pchan->bone->segments;
        
-       if(segments>1 && pchan) {
+       if ((segments > 1) && (pchan)) {
                float dlen= length/(float)segments;
                Mat4 *bbone= b_bone_spline_setup(pchan, 0);
                int a;
                
-               for(a=0; a<segments; a++, bbone++) {
+               for (a=0; a<segments; a++, bbone++) {
                        glPushMatrix();
                        glMultMatrixf(bbone->mat);
-                       if(dt==OB_SOLID) drawsolidcube_size(xwidth, dlen, zwidth);
+                       if (dt==OB_SOLID) drawsolidcube_size(xwidth, dlen, zwidth);
                        else drawcube_size(xwidth, dlen, zwidth);
                        glPopMatrix();
                }
        }
        else {
                glPushMatrix();
-               if(dt==OB_SOLID) drawsolidcube_size(xwidth, length, zwidth);
+               if (dt==OB_SOLID) drawsolidcube_size(xwidth, length, zwidth);
                else drawcube_size(xwidth, length, zwidth);
                glPopMatrix();
        }
@@ -911,7 +1119,7 @@ static void draw_b_bone(int dt, int armflag, int boneflag, int constflag, unsign
 {
        float xwidth, length, zwidth;
        
-       if(pchan) {
+       if (pchan) {
                xwidth= pchan->bone->xwidth;
                length= pchan->bone->length;
                zwidth= pchan->bone->zwidth;
@@ -923,7 +1131,7 @@ static void draw_b_bone(int dt, int armflag, int boneflag, int constflag, unsign
        }
        
        /* draw points only if... */
-       if(armflag & ARM_EDITMODE) {
+       if (armflag & ARM_EDITMODE) {
                /* move to unitspace */
                glPushMatrix();
                glScalef(length, length, length);
@@ -934,16 +1142,13 @@ static void draw_b_bone(int dt, int armflag, int boneflag, int constflag, unsign
 
        /* colors for modes */
        if (armflag & ARM_POSEMODE) {
-               if(dt==OB_WIRE) {
-                       if (boneflag & BONE_ACTIVE) BIF_ThemeColorShade(TH_BONE_POSE, 40);
-                       else if (boneflag & BONE_SELECTED) BIF_ThemeColor(TH_BONE_POSE);
-                       else BIF_ThemeColor(TH_WIRE);
-               }
+               if (dt <= OB_WIRE)
+                       set_pchan_glColor(PCHAN_COLOR_NORMAL, armflag, boneflag, constflag);
                else 
-                       BIF_ThemeColor(TH_BONE_SOLID);
+                       set_pchan_glColor(PCHAN_COLOR_SOLID, armflag, boneflag, constflag);
        }
        else if (armflag & ARM_EDITMODE) {
-               if(dt==OB_WIRE) {
+               if (dt==OB_WIRE) {
                        if (boneflag & BONE_ACTIVE) BIF_ThemeColor(TH_EDGE_SELECT);
                        else if (boneflag & BONE_SELECTED) BIF_ThemeColorShade(TH_EDGE_SELECT, -20);
                        else BIF_ThemeColor(TH_WIRE);
@@ -957,10 +1162,14 @@ static void draw_b_bone(int dt, int armflag, int boneflag, int constflag, unsign
        }
        
        /* set up solid drawing */
-       if(dt > OB_WIRE) {
+       if (dt > OB_WIRE) {
                glEnable(GL_COLOR_MATERIAL);
                glEnable(GL_LIGHTING);
-               BIF_ThemeColor(TH_BONE_SOLID);
+               
+               if (armflag & ARM_POSEMODE)
+                       set_pchan_glColor(PCHAN_COLOR_SOLID, armflag, boneflag, constflag);
+               else
+                       BIF_ThemeColor(TH_BONE_SOLID);
                
                draw_b_bone_boxes(OB_SOLID, pchan, xwidth, length, zwidth);
                
@@ -968,25 +1177,21 @@ static void draw_b_bone(int dt, int armflag, int boneflag, int constflag, unsign
                glDisable(GL_COLOR_MATERIAL);
                glDisable(GL_LIGHTING);
        }
-       else {  // wire
-               if (armflag & ARM_POSEMODE){
-                       if(constflag) {
-                               glEnable(GL_BLEND);
-                               
-                               if(constflag & PCHAN_HAS_STRIDE) glColor4ub(0, 0, 200, 80);
-                               else if(constflag & PCHAN_HAS_TARGET) glColor4ub(255, 150, 0, 80);
-                               else if(constflag & PCHAN_HAS_IK) glColor4ub(255, 255, 0, 80);
-                               else if(constflag & PCHAN_HAS_CONST) glColor4ub(0, 255, 120, 80);
-                               else BIF_ThemeColor4(TH_BONE_POSE);     // PCHAN_HAS_ACTION 
-                               
-                               draw_b_bone_boxes(OB_SOLID, pchan, xwidth, length, zwidth);
-                               
-                               glDisable(GL_BLEND);
+       else {  
+               /* wire */
+               if (armflag & ARM_POSEMODE) {
+                       if (constflag) {
+                               /* set constraint colours */
+                               if (set_pchan_glColor(PCHAN_COLOR_CONSTS, armflag, boneflag, constflag)) {
+                                       glEnable(GL_BLEND);
+                                       
+                                       draw_b_bone_boxes(OB_SOLID, pchan, xwidth, length, zwidth);
+                                       
+                                       glDisable(GL_BLEND);
+                               }
                                
                                /* restore colors */
-                               if (boneflag & BONE_ACTIVE) BIF_ThemeColorShade(TH_BONE_POSE, 40);
-                               else if (boneflag & BONE_SELECTED) BIF_ThemeColor(TH_BONE_POSE);
-                               else BIF_ThemeColor(TH_WIRE);
+                               set_pchan_glColor(PCHAN_COLOR_NORMAL, armflag, boneflag, constflag);
                        }
                }               
                
@@ -1003,7 +1208,7 @@ static void draw_bone(int dt, int armflag, int boneflag, int constflag, unsigned
        glScalef(length, length, length);
 
        /* set up solid drawing */
-       if(dt > OB_WIRE) {
+       if (dt > OB_WIRE) {
                glEnable(GL_COLOR_MATERIAL);
                glEnable(GL_LIGHTING);
                BIF_ThemeColor(TH_BONE_SOLID);
@@ -1011,61 +1216,56 @@ static void draw_bone(int dt, int armflag, int boneflag, int constflag, unsigned
        
        /* colors for posemode */
        if (armflag & ARM_POSEMODE) {
-               if(dt==OB_WIRE) {
-                       if (boneflag & BONE_ACTIVE) BIF_ThemeColorShade(TH_BONE_POSE, 40);
-                       else if (boneflag & BONE_SELECTED) BIF_ThemeColor(TH_BONE_POSE);
-                       else BIF_ThemeColor(TH_WIRE);
-               }
+               if (dt <= OB_WIRE)
+                       set_pchan_glColor(PCHAN_COLOR_NORMAL, armflag, boneflag, constflag);
                else 
-                       BIF_ThemeColor(TH_BONE_SOLID);
+                       set_pchan_glColor(PCHAN_COLOR_SOLID, armflag, boneflag, constflag);
        }
        
        
        draw_bone_points(dt, armflag, boneflag, id);
        
        /* now draw the bone itself */
-       
        if (id != -1) {
-               glLoadName ((GLuint) id|BONESEL_BONE);
+               glLoadName((GLuint) id|BONESEL_BONE);
        }
        
        /* wire? */
-       if(dt <= OB_WIRE) {
+       if (dt <= OB_WIRE) {
                /* colors */
                if (armflag & ARM_EDITMODE) {
                        if (boneflag & BONE_ACTIVE) BIF_ThemeColor(TH_EDGE_SELECT);
                        else if (boneflag & BONE_SELECTED) BIF_ThemeColorShade(TH_EDGE_SELECT, -20);
                        else BIF_ThemeColor(TH_WIRE);
                }
-               else if (armflag & ARM_POSEMODE){
-                       if(constflag) {
-                               glEnable(GL_BLEND);
-                               
-                               if(constflag & PCHAN_HAS_STRIDE) glColor4ub(0, 0, 200, 80);
-                               else if(constflag & PCHAN_HAS_TARGET) glColor4ub(255, 150, 0, 80);
-                               else if(constflag & PCHAN_HAS_IK) glColor4ub(255, 255, 0, 80);
-                               else if(constflag & PCHAN_HAS_CONST) glColor4ub(0, 255, 120, 80);
-                               else BIF_ThemeColor4(TH_BONE_POSE);     // PCHAN_HAS_ACTION 
+               else if (armflag & ARM_POSEMODE) {
+                       if (constflag) {
+                               /* draw constraint colors */
+                               if (set_pchan_glColor(PCHAN_COLOR_CONSTS, armflag, boneflag, constflag)) {      
+                                       glEnable(GL_BLEND);
                                        
-                               draw_bone_solid_octahedral();
-                               glDisable(GL_BLEND);
-
+                                       draw_bone_solid_octahedral();
+                                       
+                                       glDisable(GL_BLEND);
+                               }
+                               
                                /* restore colors */
-                               if (boneflag & BONE_ACTIVE) BIF_ThemeColorShade(TH_BONE_POSE, 40);
-                               else if (boneflag & BONE_SELECTED) BIF_ThemeColor(TH_BONE_POSE);
-                               else BIF_ThemeColor(TH_WIRE);
+                               set_pchan_glColor(PCHAN_COLOR_NORMAL, armflag, boneflag, constflag);
                        }
                }               
                draw_bone_octahedral();
        }
-       else {  /* solid */
-
-               BIF_ThemeColor(TH_BONE_SOLID);
+       else {  
+               /* solid */
+               if (armflag & ARM_POSEMODE)
+                       set_pchan_glColor(PCHAN_COLOR_SOLID, armflag, boneflag, constflag);
+               else
+                       BIF_ThemeColor(TH_BONE_SOLID);
                draw_bone_solid_octahedral();
        }
 
        /* disable solid drawing */
-       if(dt>OB_WIRE) {
+       if (dt > OB_WIRE) {
                glDisable(GL_COLOR_MATERIAL);
                glDisable(GL_LIGHTING);
        }
@@ -1073,20 +1273,17 @@ static void draw_bone(int dt, int armflag, int boneflag, int constflag, unsigned
 
 static void draw_custom_bone(Object *ob, int dt, int armflag, int boneflag, unsigned int id, float length)
 {
-       
        if(ob==NULL) return;
        
        glScalef(length, length, length);
        
        /* colors for posemode */
        if (armflag & ARM_POSEMODE) {
-               if (boneflag & BONE_ACTIVE) BIF_ThemeColorShade(TH_BONE_POSE, 40);
-               else if (boneflag & BONE_SELECTED) BIF_ThemeColor(TH_BONE_POSE);
-               else BIF_ThemeColor(TH_WIRE);
+               set_pchan_glColor(PCHAN_COLOR_NORMAL, armflag, boneflag, 0);
        }
        
        if (id != -1) {
-               glLoadName ((GLuint) id|BONESEL_BONE);
+               glLoadName((GLuint) id|BONESEL_BONE);
        }
        
        draw_object_instance(ob, dt, armflag & ARM_POSEMODE);
@@ -1098,8 +1295,8 @@ static void pchan_draw_IK_root_lines(bPoseChannel *pchan)
        bConstraint *con;
        bPoseChannel *parchan;
        
-       for(con= pchan->constraints.first; con; con= con->next) {
-               if(con->type == CONSTRAINT_TYPE_KINEMATIC) {
+       for (con= pchan->constraints.first; con; con= con->next) {
+               if (con->type == CONSTRAINT_TYPE_KINEMATIC) {
                        bKinematicConstraint *data = (bKinematicConstraint*)con->data;
                        int segcount= 0;
                        
@@ -1107,7 +1304,7 @@ static void pchan_draw_IK_root_lines(bPoseChannel *pchan)
                        glBegin(GL_LINES);
                        
                        /* exclude tip from chain? */
-                       if(!(data->flag & CONSTRAINT_IK_TIP))
+                       if ((data->flag & CONSTRAINT_IK_TIP)==0)
                                parchan= pchan->parent;
                        else
                                parchan= pchan;
@@ -1115,12 +1312,12 @@ static void pchan_draw_IK_root_lines(bPoseChannel *pchan)
                        glVertex3fv(parchan->pose_tail);
                        
                        /* Find the chain's root */
-                       while (parchan->parent){
+                       while (parchan->parent) {
                                segcount++;
                                if(segcount==data->rootbone || segcount>255) break; // 255 is weak
                                parchan= parchan->parent;
                        }
-                       if(parchan)
+                       if (parchan)
                                glVertex3fv(parchan->pose_head);
                        
                        glEnd();
@@ -1198,7 +1395,7 @@ static void draw_dof_ellipse(float ax, float az)
        glColor3ub(0, 0, 0);
 
        glBegin(GL_LINE_STRIP);
-       for(i=0; i<n; i++)
+       for (i=0; i<n; i++)
                bgl_sphere_project(staticSine[n-i-1]*ax, staticSine[i]*az);
        glEnd();
 }
@@ -1209,40 +1406,41 @@ static void draw_pose_dofs(Object *ob)
        bPoseChannel *pchan;
        Bone *bone;
        
-       for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+       for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
                bone= pchan->bone;
-               if(bone && !(bone->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG))) {
-                       if(bone->flag & BONE_SELECTED) {
-                               if(bone->layer & arm->layer) {
-                                       if(pchan->ikflag & (BONE_IK_XLIMIT|BONE_IK_ZLIMIT)) {
-                                               if(pose_channel_in_IK_chain(ob, pchan)) {
+               
+               if ( (bone) && !(bone->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG))) {
+                       if (bone->flag & BONE_SELECTED) {
+                               if (bone->layer & arm->layer) {
+                                       if (pchan->ikflag & (BONE_IK_XLIMIT|BONE_IK_ZLIMIT)) {
+                                               if (pose_channel_in_IK_chain(ob, pchan)) {
                                                        float corner[4][3], posetrans[3], mat[4][4];
                                                        float phi=0.0f, theta=0.0f, scale;
                                                        int a, i;
-
+                                                       
                                                        /* in parent-bone pose, but own restspace */
                                                        glPushMatrix();
-
+                                                       
                                                        VECCOPY(posetrans, pchan->pose_mat[3]);
                                                        glTranslatef(posetrans[0], posetrans[1], posetrans[2]);
-
-                                                       if(pchan->parent) {
+                                                       
+                                                       if (pchan->parent) {
                                                                Mat4CpyMat4(mat, pchan->parent->pose_mat);
                                                                mat[3][0]= mat[3][1]= mat[3][2]= 0.0f;
                                                                glMultMatrixf(mat);
                                                        }
-
+                                                       
                                                        Mat4CpyMat3(mat, pchan->bone->bone_mat);
                                                        glMultMatrixf(mat);
-
+                                                       
                                                        scale= bone->length*pchan->size[1];
                                                        glScalef(scale, scale, scale);
-
-                                                       if(pchan->ikflag & BONE_IK_XLIMIT) {
-                                                               if(pchan->ikflag & BONE_IK_ZLIMIT) {
+                                                       
+                                                       if (pchan->ikflag & BONE_IK_XLIMIT) {
+                                                               if (pchan->ikflag & BONE_IK_ZLIMIT) {
                                                                        float amin[3], amax[3];
-
-                                                                       for(i=0; i<3; i++) {
+                                                                       
+                                                                       for (i=0; i<3; i++) {
                                                                                amin[i]= sin(pchan->limitmin[i]*M_PI/360.0);
                                                                                amax[i]= sin(pchan->limitmax[i]*M_PI/360.0);
                                                                        }
@@ -1261,49 +1459,50 @@ static void draw_pose_dofs(Object *ob)
                                                        }
                                                        
                                                        /* arcs */
-                                                       if(pchan->ikflag & BONE_IK_ZLIMIT) {
+                                                       if (pchan->ikflag & BONE_IK_ZLIMIT) {
                                                                theta= 0.5*(pchan->limitmin[2]+pchan->limitmax[2]);
                                                                glRotatef(theta, 0.0f, 0.0f, 1.0f);
-
+                                                               
                                                                glColor3ub(50, 50, 255);        // blue, Z axis limit
                                                                glBegin(GL_LINE_STRIP);
-                                                               for(a=-16; a<=16; a++) {
+                                                               for (a=-16; a<=16; a++) {
                                                                        float fac= ((float)a)/16.0f;
                                                                        phi= fac*(M_PI/360.0f)*(pchan->limitmax[2]-pchan->limitmin[2]);
                                                                        
-                                                                       if(a==-16) i= 0; else i= 1;
+                                                                       i= (a == -16) ? 0 : 1;
                                                                        corner[i][0]= sin(phi);
                                                                        corner[i][1]= cos(phi);
                                                                        corner[i][2]= 0.0f;
                                                                        glVertex3fv(corner[i]);
                                                                }
                                                                glEnd();
-
+                                                               
                                                                glRotatef(-theta, 0.0f, 0.0f, 1.0f);
                                                        }                                       
-
-                                                       if(pchan->ikflag & BONE_IK_XLIMIT) {
-                                                               theta=  0.5*( pchan->limitmin[0]+pchan->limitmax[0]);
+                                                       
+                                                       if (pchan->ikflag & BONE_IK_XLIMIT) {
+                                                               theta=  0.5*(pchan->limitmin[0]+pchan->limitmax[0]);
                                                                glRotatef(theta, 1.0f, 0.0f, 0.0f);
-
+                                                               
                                                                glColor3ub(255, 50, 50);        // Red, X axis limit
                                                                glBegin(GL_LINE_STRIP);
-                                                               for(a=-16; a<=16; a++) {
+                                                               for (a=-16; a<=16; a++) {
                                                                        float fac= ((float)a)/16.0f;
                                                                        phi= 0.5f*M_PI + fac*(M_PI/360.0f)*(pchan->limitmax[0]-pchan->limitmin[0]);
-
-                                                                       if(a==-16) i= 2; else i= 3;
+                                                                       
+                                                                       i= (a == -16) ? 2 : 3;
                                                                        corner[i][0]= 0.0f;
                                                                        corner[i][1]= sin(phi);
                                                                        corner[i][2]= cos(phi);
                                                                        glVertex3fv(corner[i]);
                                                                }
                                                                glEnd();
-
+                                                               
                                                                glRotatef(-theta, 1.0f, 0.0f, 0.0f);
                                                        }
-
-                                                       glPopMatrix(); // out of cone, out of bone
+                                                       
+                                                       /* out of cone, out of bone */
+                                                       glPopMatrix(); 
                                                }
                                        }
                                }
@@ -1327,33 +1526,34 @@ static void draw_pose_channels(Base *base, int dt)
        
        /* hacky... prevent outline select from drawing dashed helplines */
        glGetFloatv(GL_LINE_WIDTH, &tmp);
-       if(tmp > 1.1) do_dashed= 0;
+       if (tmp > 1.1) do_dashed= 0;
        if (G.vd->flag & V3D_HIDE_HELPLINES) do_dashed= 0;
        
        /* precalc inverse matrix for drawing screen aligned */
-       if(arm->drawtype==ARM_ENVELOPE) {
+       if (arm->drawtype==ARM_ENVELOPE) {
                /* precalc inverse matrix for drawing screen aligned */
                mygetmatrix(smat);
                Mat4MulFloat3(smat[0], 1.0f/VecLength(ob->obmat[0]));
                Mat4Invert(imat, smat);
                
                /* and draw blended distances */
-               if(arm->flag & ARM_POSEMODE) {
+               if (arm->flag & ARM_POSEMODE) {
                        glEnable(GL_BLEND);
                        //glShadeModel(GL_SMOOTH);
                        
-                       if(G.vd->zbuf) glDisable(GL_DEPTH_TEST);
+                       if (G.vd->zbuf) glDisable(GL_DEPTH_TEST);
                        
-                       for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+                       for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
                                bone= pchan->bone;
-                               if(bone && !(bone->flag & (BONE_HIDDEN_P|BONE_NO_DEFORM|BONE_HIDDEN_PG))) {
-                                       if(bone->flag & (BONE_SELECTED))
-                                               if(bone->layer & arm->layer)
+                               if (bone && !(bone->flag & (BONE_HIDDEN_P|BONE_NO_DEFORM|BONE_HIDDEN_PG))) {
+                                       if (bone->flag & (BONE_SELECTED)) {
+                                               if (bone->layer & arm->layer)
                                                        draw_sphere_bone_dist(smat, imat, bone->flag, pchan, NULL);
+                                       }
                                }
                        }
                        
-                       if(G.vd->zbuf) glEnable(GL_DEPTH_TEST);
+                       if (G.vd->zbuf) glEnable(GL_DEPTH_TEST);
                        glDisable(GL_BLEND);
                        //glShadeModel(GL_FLAT);
                }
@@ -1364,67 +1564,80 @@ static void draw_pose_channels(Base *base, int dt)
        glEnable(GL_CULL_FACE);
        
        /* if solid we draw that first, with selection codes, but without names, axes etc */
-       if(dt>OB_WIRE) {
-               if(arm->flag & ARM_POSEMODE) index= base->selcol;
+       if (dt > OB_WIRE) {
+               if (arm->flag & ARM_POSEMODE) 
+                       index= base->selcol;
                
-               for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+               for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
                        bone= pchan->bone;
-                       if(bone && !(bone->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG))) {
-                               if(bone->layer & arm->layer) {
+                       
+                       if ( (bone) && !(bone->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG)) ) {
+                               if (bone->layer & arm->layer) {
                                        glPushMatrix();
                                        glMultMatrixf(pchan->pose_mat);
                                        
                                        /* catch exception for bone with hidden parent */
                                        flag= bone->flag;
-                                       if(bone->parent && (bone->parent->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG)))
+                                       if ( (bone->parent) && (bone->parent->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG)) )
                                                flag &= ~BONE_CONNECTED;
+                                               
+                                       /* set color-set to use */
+                                       set_pchan_colorset(ob, pchan);
                                        
-                                       if(pchan->custom && !(arm->flag & ARM_NO_CUSTOM))
+                                       if ((pchan->custom) && !(arm->flag & ARM_NO_CUSTOM))
                                                draw_custom_bone(pchan->custom, OB_SOLID, arm->flag, flag, index, bone->length);
-                                       else if(arm->drawtype==ARM_LINE)
+                                       else if (arm->drawtype==ARM_LINE)
                                                ;       /* nothing in solid */
-                                       else if(arm->drawtype==ARM_ENVELOPE)
+                                       else if (arm->drawtype==ARM_ENVELOPE)
                                                draw_sphere_bone(OB_SOLID, arm->flag, flag, 0, index, pchan, NULL);
-                                       else if(arm->drawtype==ARM_B_BONE)
+                                       else if (arm->drawtype==ARM_B_BONE)
                                                draw_b_bone(OB_SOLID, arm->flag, flag, 0, index, pchan, NULL);
-                                       else {
+                                       else
                                                draw_bone(OB_SOLID, arm->flag, flag, 0, index, bone->length);
-                                       }
+                                               
                                        glPopMatrix();
                                }
                        }
-                       if (index!= -1) index+= 0x10000;        // pose bones count in higher 2 bytes only
+                       
+                       if (index!= -1) 
+                               index+= 0x10000;        // pose bones count in higher 2 bytes only
                }
+               
                /* very very confusing... but in object mode, solid draw, we cannot do glLoadName yet, stick bones are drawn in next loop */
-               if(arm->drawtype!=ARM_LINE) {
-                       glLoadName (index & 0xFFFF);    // object tag, for bordersel optim
+               if (arm->drawtype != ARM_LINE) {
+                       /* object tag, for bordersel optim */
+                       glLoadName(index & 0xFFFF);     
                        index= -1;
                }
        }
        
        /* wire draw over solid only in posemode */
-       if( dt<=OB_WIRE || (arm->flag & ARM_POSEMODE) || arm->drawtype==ARM_LINE) {
-       
+       if ((dt <= OB_WIRE) || (arm->flag & ARM_POSEMODE) || (arm->drawtype==ARM_LINE)) {
                /* draw line check first. we do selection indices */
                if (arm->drawtype==ARM_LINE) {
-                       if (arm->flag & ARM_POSEMODE) index= base->selcol;
+                       if (arm->flag & ARM_POSEMODE) 
+                               index= base->selcol;
                }
                /* if solid && posemode, we draw again with polygonoffset */
-               else if (dt>OB_WIRE && (arm->flag & ARM_POSEMODE))
+               else if ((dt > OB_WIRE) && (arm->flag & ARM_POSEMODE)) {
                        bglPolygonOffset(1.0);
-               else
+               }
+               else {
                        /* and we use selection indices if not done yet */
-                       if (arm->flag & ARM_POSEMODE) index= base->selcol;
+                       if (arm->flag & ARM_POSEMODE) 
+                               index= base->selcol;
+               }
                
-               for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+               for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
                        bone= pchan->bone;
-                       if(bone && !(bone->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG))) {
-                               if(bone->layer & arm->layer) {
+                       
+                       if ((bone) && !(bone->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG))) {
+                               if (bone->layer & arm->layer) {
                                        if (do_dashed && bone->parent) {
                                                /*      Draw a line from our root to the parent's tip */
-                                               if(!(bone->flag & BONE_CONNECTED) ){
+                                               if ((bone->flag & BONE_CONNECTED)==0) {
                                                        if (arm->flag & ARM_POSEMODE) {
-                                                               glLoadName (index & 0xFFFF);    // object tag, for bordersel optim
+                                                               glLoadName(index & 0xFFFF);     // object tag, for bordersel optim
                                                                BIF_ThemeColor(TH_WIRE);
                                                        }
                                                        setlinestyle(3);
@@ -1434,29 +1647,29 @@ static void draw_pose_channels(Base *base, int dt)
                                                        glEnd();
                                                        setlinestyle(0);
                                                }
-                                               //      Draw a line to IK root bone
-                                               if(arm->flag & ARM_POSEMODE) {
-                                                       if(pchan->constflag & PCHAN_HAS_IK) {
-                                                               if(bone->flag & BONE_SELECTED) {
-                                                                       
-                                                                       if(pchan->constflag & PCHAN_HAS_TARGET) glColor3ub(200, 120, 0);
+                                               
+                                               /*      Draw a line to IK root bone */ 
+                                               //              TODO: make this draw with do_dashed off (V3D_HIDE_HELPLINES)
+                                               if (arm->flag & ARM_POSEMODE) {
+                                                       if (pchan->constflag & PCHAN_HAS_IK) {
+                                                               if (bone->flag & BONE_SELECTED) {
+                                                                       if (pchan->constflag & PCHAN_HAS_TARGET) glColor3ub(200, 120, 0);
                                                                        else glColor3ub(200, 200, 50);  // add theme!
-
-                                                                       glLoadName (index & 0xFFFF);
+                                                                       
+                                                                       glLoadName(index & 0xFFFF);
                                                                        pchan_draw_IK_root_lines(pchan);
                                                                }
                                                        }
                                                }
                                        }
                                        
-                                       if(arm->drawtype!=ARM_ENVELOPE) {
-                                               glPushMatrix();
+                                       glPushMatrix();
+                                       if (arm->drawtype != ARM_ENVELOPE)
                                                glMultMatrixf(pchan->pose_mat);
-                                       }
                                        
                                        /* catch exception for bone with hidden parent */
                                        flag= bone->flag;
-                                       if(bone->parent && (bone->parent->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG)))
+                                       if ((bone->parent) && (bone->parent->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG)))
                                                flag &= ~BONE_CONNECTED;
                                        
                                        /* extra draw service for pose mode */
@@ -1465,33 +1678,36 @@ static void draw_pose_channels(Base *base, int dt)
                                                constflag |= PCHAN_HAS_ACTION;
                                        if(pchan->flag & POSE_STRIDE)
                                                constflag |= PCHAN_HAS_STRIDE;
+                                               
+                                       /* set color-set to use */
+                                       set_pchan_colorset(ob, pchan);
 
-                                       if(pchan->custom && !(arm->flag & ARM_NO_CUSTOM)) {
-                                               if(dt<OB_SOLID)
+                                       if (pchan->custom && !(arm->flag & ARM_NO_CUSTOM)) {
+                                               if (dt < OB_SOLID)
                                                        draw_custom_bone(pchan->custom, OB_WIRE, arm->flag, flag, index, bone->length);
                                        }
-                                       else if(arm->drawtype==ARM_ENVELOPE) {
-                                               if(dt<OB_SOLID)
+                                       else if (arm->drawtype==ARM_ENVELOPE) {
+                                               if (dt < OB_SOLID)
                                                        draw_sphere_bone_wire(smat, imat, arm->flag, flag, constflag, index, pchan, NULL);
                                        }
-                                       else if(arm->drawtype==ARM_LINE)
+                                       else if (arm->drawtype==ARM_LINE)
                                                draw_line_bone(arm->flag, flag, constflag, index, pchan, NULL);
-                                       else if(arm->drawtype==ARM_B_BONE)
+                                       else if (arm->drawtype==ARM_B_BONE)
                                                draw_b_bone(OB_WIRE, arm->flag, flag, constflag, index, pchan, NULL);
-                                       else {
+                                       else
                                                draw_bone(OB_WIRE, arm->flag, flag, constflag, index, bone->length);
-                                       }
                                        
-                                       if(arm->drawtype!=ARM_ENVELOPE)
-                                               glPopMatrix();
+                                       glPopMatrix();
                                }
                        }
-                       if (index!= -1) index+= 0x10000;        // pose bones count in higher 2 bytes only
+                       
+                       /* pose bones count in higher 2 bytes only */
+                       if (index != -1) 
+                               index+= 0x10000;        
                }
                /* restore things */
-               if (arm->drawtype!=ARM_LINE && dt>OB_WIRE && (arm->flag & ARM_POSEMODE))
+               if ((arm->drawtype!=ARM_LINE) && (dt>OB_WIRE) && (arm->flag & ARM_POSEMODE))
                        bglPolygonOffset(0.0);
-               
        }       
        
        /* restore */
@@ -1502,31 +1718,35 @@ static void draw_pose_channels(Base *base, int dt)
                draw_pose_dofs(ob);
 
        /* finally names and axes */
-       if(arm->flag & (ARM_DRAWNAMES|ARM_DRAWAXES)) {
-               // patch for several 3d cards (IBM mostly) that crash on glSelect with text drawing
-               if((G.f & G_PICKSEL) == 0) {
+       if (arm->flag & (ARM_DRAWNAMES|ARM_DRAWAXES)) {
+               /* patch for several 3d cards (IBM mostly) that crash on glSelect with text drawing */
+               if ((G.f & G_PICKSEL) == 0) {
                        float vec[3];
                        
-                       if(G.vd->zbuf) glDisable(GL_DEPTH_TEST);
+                       if (G.vd->zbuf) glDisable(GL_DEPTH_TEST);
                        
-                       for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
-                               if((pchan->bone->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG))==0) {
-                                       if(pchan->bone->layer & arm->layer) {
+                       for (pchan=ob->pose->chanbase.first; pchan; pchan=pchan->next) {
+                               if ((pchan->bone->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG))==0) {
+                                       if (pchan->bone->layer & arm->layer) {
                                                if (arm->flag & (ARM_EDITMODE|ARM_POSEMODE)) {
                                                        bone= pchan->bone;
-                                                       if(bone->flag & BONE_SELECTED) BIF_ThemeColor(TH_TEXT_HI);
+                                                       
+                                                       if (bone->flag & BONE_SELECTED) BIF_ThemeColor(TH_TEXT_HI);
                                                        else BIF_ThemeColor(TH_TEXT);
                                                }
-                                               else if(dt > OB_WIRE) BIF_ThemeColor(TH_TEXT);
+                                               else if (dt > OB_WIRE)
+                                                       BIF_ThemeColor(TH_TEXT);
                                                
-                                               if (arm->flag & ARM_DRAWNAMES){
+                                               /*      Draw names of bone      */
+                                               if (arm->flag & ARM_DRAWNAMES) {
                                                        VecMidf(vec, pchan->pose_head, pchan->pose_tail);
                                                        glRasterPos3fv(vec);
                                                        BMF_DrawString(G.font, " ");
                                                        BMF_DrawString(G.font, pchan->name);
-                                               }                               
-                                               /*      Draw additional axes */
-                                               if( (arm->flag & ARM_DRAWAXES) && (arm->flag & ARM_POSEMODE) ){
+                                               }       
+                                               
+                                               /*      Draw additional axes on the bone tail  */
+                                               if ( (arm->flag & ARM_DRAWAXES) && (arm->flag & ARM_POSEMODE) ) {
                                                        glPushMatrix();
                                                        glMultMatrixf(pchan->pose_mat);
                                                        glTranslatef(0.0f, pchan->bone->length, 0.0f);
@@ -1537,10 +1757,9 @@ static void draw_pose_channels(Base *base, int dt)
                                }
                        }
                        
-                       if(G.vd->zbuf) glEnable(GL_DEPTH_TEST);
+                       if (G.vd->zbuf) glEnable(GL_DEPTH_TEST);
                }
        }
-
 }
 
 /* in editmode, we don't store the bone matrix... */
@@ -1549,10 +1768,10 @@ static void set_matrix_editbone(EditBone *eBone)
        float           delta[3],offset[3];
        float           mat[3][3], bmat[4][4];
        
-       /*      Compose the parent transforms (i.e. their translations) */
-       VECCOPY (offset, eBone->head);
+       /* Compose the parent transforms (i.e. their translations) */
+       VECCOPY(offset, eBone->head);
        
-       glTranslatef (offset[0],offset[1],offset[2]);
+       glTranslatef(offset[0],offset[1],offset[2]);
        
        VecSubf(delta, eBone->tail, eBone->head);       
        
@@ -1560,8 +1779,8 @@ static void set_matrix_editbone(EditBone *eBone)
        
        vec_roll_to_mat3(delta, eBone->roll, mat);
        Mat4CpyMat3(bmat, mat);
-                               
-       glMultMatrixf (bmat);
+               
+       glMultMatrixf(bmat);
        
 }
 
@@ -1584,35 +1803,37 @@ static void draw_ebones(Object *ob, int dt)
                glEnable(GL_BLEND);
                //glShadeModel(GL_SMOOTH);
                
-               if(G.vd->zbuf) glDisable(GL_DEPTH_TEST);
+               if (G.vd->zbuf) glDisable(GL_DEPTH_TEST);
 
-               for (eBone=G.edbo.first, index=0; eBone; eBone=eBone->next, index++){
-                       if(eBone->layer & arm->layer)
-                               if(!(eBone->flag & (BONE_HIDDEN_A|BONE_NO_DEFORM)))
-                                       if(eBone->flag & (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL))
+               for (eBone=G.edbo.first, index=0; eBone; eBone=eBone->next, index++) {
+                       if (eBone->layer & arm->layer) {
+                               if ((eBone->flag & (BONE_HIDDEN_A|BONE_NO_DEFORM))==0) {
+                                       if (eBone->flag & (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL))
                                                draw_sphere_bone_dist(smat, imat, eBone->flag, NULL, eBone);
+                               }
+                       }
                }
                
-               if(G.vd->zbuf) glEnable(GL_DEPTH_TEST);
+               if (G.vd->zbuf) glEnable(GL_DEPTH_TEST);
                glDisable(GL_BLEND);
                //glShadeModel(GL_FLAT);
        }
        
        /* if solid we draw it first */
-       if(dt>OB_WIRE && arm->drawtype!=ARM_LINE) {
+       if ((dt > OB_WIRE) && (arm->drawtype!=ARM_LINE)) {
                index= 0;
-               for (eBone=G.edbo.first, index=0; eBone; eBone=eBone->next, index++){
-                       if(eBone->layer & arm->layer) {
-                               if(!(eBone->flag & BONE_HIDDEN_A)) {
+               for (eBone=G.edbo.first, index=0; eBone; eBone=eBone->next, index++) {
+                       if (eBone->layer & arm->layer) {
+                               if ((eBone->flag & BONE_HIDDEN_A)==0) {
                                        glPushMatrix();
                                        set_matrix_editbone(eBone);
                                        
                                        /* catch exception for bone with hidden parent */
                                        flag= eBone->flag;
-                                       if(eBone->parent && ((eBone->parent->flag & BONE_HIDDEN_A) || (eBone->parent->layer & arm->layer)==0) )
+                                       if ( (eBone->parent) && ((eBone->parent->flag & BONE_HIDDEN_A) || (eBone->parent->layer & arm->layer)==0) )
                                                flag &= ~BONE_CONNECTED;
                                        
-                                       if(arm->drawtype==ARM_ENVELOPE)
+                                       if (arm->drawtype==ARM_ENVELOPE)
                                                draw_sphere_bone(OB_SOLID, arm->flag, flag, 0, index, NULL, eBone);
                                        else if(arm->drawtype==ARM_B_BONE)
                                                draw_b_bone(OB_SOLID, arm->flag, flag, 0, index, NULL, eBone);
@@ -1629,42 +1850,42 @@ static void draw_ebones(Object *ob, int dt)
        /* if wire over solid, set offset */
        index= -1;
        glLoadName(-1);
-       if(arm->drawtype==ARM_LINE) {
+       if (arm->drawtype==ARM_LINE) {
                if(G.f & G_PICKSEL)
                        index= 0;
        }
-       else if (dt>OB_WIRE) 
+       else if (dt > OB_WIRE) 
                bglPolygonOffset(1.0);
-       else if(arm->flag & ARM_EDITMODE) 
-               index= 0;       // do selection codes
+       else if (arm->flag & ARM_EDITMODE) 
+               index= 0;       /* do selection codes */
        
-       for (eBone=G.edbo.first; eBone; eBone=eBone->next){
-               if(eBone->layer & arm->layer) {
-                       if(!(eBone->flag & BONE_HIDDEN_A)) {
+       for (eBone=G.edbo.first; eBone; eBone=eBone->next) {
+               if (eBone->layer & arm->layer) {
+                       if ((eBone->flag & BONE_HIDDEN_A)==0) {
                                
                                /* catch exception for bone with hidden parent */
                                flag= eBone->flag;
-                               if(eBone->parent && ((eBone->parent->flag & BONE_HIDDEN_A) || (eBone->parent->layer & arm->layer)==0) )
+                               if ( (eBone->parent) && ((eBone->parent->flag & BONE_HIDDEN_A) || (eBone->parent->layer & arm->layer)==0) )
                                        flag &= ~BONE_CONNECTED;
                                
-                               if(arm->drawtype==ARM_ENVELOPE) {
-                                       if(dt<OB_SOLID)
+                               if (arm->drawtype == ARM_ENVELOPE) {
+                                       if (dt < OB_SOLID)
                                                draw_sphere_bone_wire(smat, imat, arm->flag, flag, 0, index, NULL, eBone);
                                }
                                else {
                                        glPushMatrix();
                                        set_matrix_editbone(eBone);
                                        
-                                       if(arm->drawtype==ARM_LINE) 
+                                       if (arm->drawtype == ARM_LINE) 
                                                draw_line_bone(arm->flag, flag, 0, index, NULL, eBone);
-                                       else if(arm->drawtype==ARM_B_BONE)
+                                       else if (arm->drawtype == ARM_B_BONE)
                                                draw_b_bone(OB_WIRE, arm->flag, flag, 0, index, NULL, eBone);
                                        else
                                                draw_bone(OB_WIRE, arm->flag, flag, 0, index, eBone->length);
-
+                                       
                                        glPopMatrix();
                                }
-                       
+                               
                                /* offset to parent */
                                if (eBone->parent) {
                                        BIF_ThemeColor(TH_WIRE);
@@ -1684,33 +1905,33 @@ static void draw_ebones(Object *ob, int dt)
        }
        
        /* restore */
-       if(arm->drawtype==ARM_LINE);
+       if (arm->drawtype==ARM_LINE);
        else if (dt>OB_WIRE) bglPolygonOffset(0.0);
        
        /* finally names and axes */
-       if(arm->flag & (ARM_DRAWNAMES|ARM_DRAWAXES)) {
+       if (arm->flag & (ARM_DRAWNAMES|ARM_DRAWAXES)) {
                // patch for several 3d cards (IBM mostly) that crash on glSelect with text drawing
-               if((G.f & G_PICKSEL) == 0) {
+               if ((G.f & G_PICKSEL) == 0) {
                        float vec[3];
                        
-                       if(G.vd->zbuf) glDisable(GL_DEPTH_TEST);
+                       if (G.vd->zbuf) glDisable(GL_DEPTH_TEST);
                        
-                       for (eBone=G.edbo.first, index=0; eBone; eBone=eBone->next, index++){
+                       for (eBone=G.edbo.first, index=0; eBone; eBone=eBone->next, index++) {
                                if(eBone->layer & arm->layer) {
-                                       if(!(eBone->flag & BONE_HIDDEN_A)) {
+                                       if ((eBone->flag & BONE_HIDDEN_A)==0) {
                                                
-                                               if(eBone->flag & BONE_SELECTED) BIF_ThemeColor(TH_TEXT_HI);
+                                               if (eBone->flag & BONE_SELECTED) BIF_ThemeColor(TH_TEXT_HI);
                                                else BIF_ThemeColor(TH_TEXT);
                                                
                                                /*      Draw name */
-                                               if(arm->flag & ARM_DRAWNAMES){
+                                               if (arm->flag & ARM_DRAWNAMES) {
                                                        VecMidf(vec, eBone->head, eBone->tail);
                                                        glRasterPos3fv(vec);
                                                        BMF_DrawString(G.font, " ");
                                                        BMF_DrawString(G.font, eBone->name);
                                                }                                       
                                                /*      Draw additional axes */
-                                               if(arm->flag & ARM_DRAWAXES){
+                                               if (arm->flag & ARM_DRAWAXES) {
                                                        glPushMatrix();
                                                        set_matrix_editbone(eBone);
                                                        glTranslatef(0.0f, eBone->length, 0.0f);
@@ -1722,7 +1943,7 @@ static void draw_ebones(Object *ob, int dt)
                                }
                        }
                        
-                       if(G.vd->zbuf) glEnable(GL_DEPTH_TEST);
+                       if (G.vd->zbuf) glEnable(GL_DEPTH_TEST);
                }
        }
 }
@@ -1829,12 +2050,12 @@ static void draw_pose_paths(Object *ob)
                                        else {
                                                /* green - on cfra */
                                                if (pchan->bone->flag & BONE_SELECTED) {
-                                                       intensity= 0.3;
+                                                       intensity= 0.5;
                                                }
                                                else {
-                                                       intensity= 0.8;
+                                                       intensity= 0.99;
                                                }
-                                               BIF_ThemeColorBlend(TH_CFRAME, TH_BACK, intensity);
+                                               BIF_ThemeColorBlendShade(TH_CFRAME, TH_BACK, intensity, 10);
                                        }       
                                        
                                        /* draw a vertex with this colour */ 
index e3d73f4cda351f013a0ced615aafc75feaf8031e..c7955fda2fccd21f336a3944f28d70244440e5fc 100644 (file)
@@ -1409,6 +1409,11 @@ static void draw_view_axis(void)
        float dx, dy;
        float h, s, v;
        
+       /* thickness of lines is proportional to k */
+       /*      (log(k)-1) gives a more suitable thickness, but fps decreased by about 3 fps */
+       glLineWidth(k / 10);
+       //glLineWidth(log(k)-1); // a bit slow
+       
        BIF_GetThemeColor3ubv(TH_GRID, (char *)gridcol);
        
        /* X */
@@ -1473,6 +1478,9 @@ static void draw_view_axis(void)
                glRasterPos2i(start + dx + 2, start + dy + ydisp + 2);
                BMF_DrawString(G.fonts, "z");
        }
+       
+       /* restore line-width */
+       glLineWidth(1.0);
 }
 
        
index 95192e42a5d436062f7e4a5ca16faabe734d8920..6c9e6ce1f6fee583cef03942047da3bf8e6dfd09 100644 (file)
@@ -981,7 +981,7 @@ void action_groups_group (short add_group)
                
                /* make sure not already in new-group */
                if (achan->grp != agrp) {
-                       if ((achan->grp) && (EXPANDED_AGRP(achan->grp))) { 
+                       if ((achan->grp==NULL) || (EXPANDED_AGRP(achan->grp))) { 
                                if (VISIBLE_ACHAN(achan) && SEL_ACHAN(achan)) {
                                        /* unlink from everything else */
                                        action_groups_removeachan(act, achan);
index 93ddb57ea66a414c88988350b253e2f8752ba9da..6fe2e032eed7202f5e7c2730fb26613a5e0b122c 100644 (file)
@@ -1204,7 +1204,9 @@ void test_editipo(int doit)
                
                if(G.sipo->ipo != ipo) {
                        G.sipo->ipo= ipo;
-                       if(ipo) G.v2d->cur= ipo->cur;
+                       /* if lock we don't copy from ipo, this makes the UI jump around confusingly */
+                       if(G.v2d->flag & V2D_VIEWLOCK);
+                       else if(ipo) G.v2d->cur= ipo->cur;
                        doit= 1;
                }
                if(G.sipo->from != from) {
@@ -1658,7 +1660,7 @@ void mouse_select_ipo(void)
        xo= mval[0]; 
        yo= mval[1];
        
-       while(get_mbut()&R_MOUSE) {             
+       while (get_mbut() & ((U.flag & USER_LMOUSESELECT)?L_MOUSE:R_MOUSE)) {           
                getmouseco_areawin(mval);
                if(abs(mval[0]-xo)+abs(mval[1]-yo) > 4) {
                        
index 0d22ce8744e848df310f462ebe73c1c3462ae950..34b49fde4f3df4e6145ba0c09373edb16b4bb870 100644 (file)
@@ -548,7 +548,7 @@ void BIF_InitTheme(void)
 
 char *BIF_ThemeColorsPup(int spacetype)
 {
-       char *cp= MEM_callocN(32*32, "theme pup");
+       char *cp= MEM_callocN(32*64, "theme pup");
        char *str = cp;
        
        if(spacetype==0) {
@@ -609,7 +609,7 @@ char *BIF_ThemeColorsPup(int spacetype)
                        str += sprintf(str, "Active Vert/Edge/Face %%x%d|", TH_EDITMESH_ACTIVE);
                        str += sprintf(str, "Normal %%x%d|", TH_NORMAL);
                        str += sprintf(str, "Bone Solid %%x%d|", TH_BONE_SOLID);
-                       str += sprintf(str, "Bone Pose %%x%d", TH_BONE_POSE);
+                       str += sprintf(str, "Bone Pose %%x%d|", TH_BONE_POSE);
                        str += sprintf(str, "Current Frame %%x%d", TH_CFRAME);
                        break;
                case SPACE_IPO:
index 582fa662e7e491385eae76b5ca51f1f5b4925e4a..b1d274d670e9c2f92d2972a30df4128e42283dd0 100644 (file)
@@ -3128,10 +3128,36 @@ static void set_userdef_iconfile_cb(void *menuindex, void *unused2)
 
 /* needed for event; choose new 'curmain' resets it... */
 static short th_curcol= TH_BACK;
+static short th_curcolset = 1;
 static char *th_curcol_ptr= NULL;
 static char th_curcol_arr[4]={0, 0, 0, 255};
 
-static void info_user_themebuts(uiBlock *block, short y1, short y2, short y3)
+static void info_user_theme_colsets_buts(uiBlock *block, short y1, short y2, short y3, short y4) 
+{
+       bTheme *btheme= U.themes.first;
+       ThemeWireColor *col_set= &btheme->tarm[(th_curcolset - 1)];
+       short y4label= y4-2; // sync this with info_user_themebuts
+       
+       /* Selector for set (currently only 20 sets) */
+       uiDefButS(block, NUM, B_REDR, "Color Set: ",    255,y1,200,20, &th_curcolset, 1, 20, 0, 0, "Current color set");
+       
+       /* "Solid" Color (unselected wire-color is derived from this) */
+       uiDefBut(block, LABEL,0,"Normal: ", 475,y4label,60,20,0, 0, 0, 0, 0, "");
+       uiDefButC(block, COL, B_UPDATE_THEME, "",               475,y1,50,y3-y1+20, col_set->solid, 0, 0, 0, 0, "Color to use for surface of bones");
+       
+       /* Selected Color */
+       uiDefBut(block, LABEL,0,"Selected: ", 575,y4label,60,20,0, 0, 0, 0, 0, "");
+       uiDefButC(block, COL, B_UPDATE_THEME, "",               575,y1,50,y3-y1+20, col_set->select, 0, 0, 0, 0, "Color to use for 'selected' bones");
+       
+       /* Active Color */
+       uiDefBut(block, LABEL,0,"Active: ", 675,y4label,60,20,0, 0, 0, 0, 0, "");
+       uiDefButC(block, COL, B_UPDATE_THEME, "",               675,y1,50,y3-y1+20, col_set->active, 0, 0, 0, 0, "Color to use for 'active' bones");
+       
+       /* Extra 'Options' */
+       uiDefButBitS(block, TOG, TH_WIRECOLOR_CONSTCOLS, B_UPDATE_THEME, "Use 'Constraint' Colouring",  885,y2,200,20, &col_set->flag, 0, 0, 0, 0, "Allow the use of colors indicating constraints/keyed status");
+}
+
+static void info_user_themebuts(uiBlock *block, short y1, short y2, short y3, short y4)
 {
        bTheme *btheme, *bt;
        int spacetype= 0;
@@ -3186,7 +3212,7 @@ static void info_user_themebuts(uiBlock *block, short y1, short y2, short y3)
        uiDefBut(block, TEX, B_NAME_THEME, "",                  255,y3,200,20, btheme->name, 1.0, 30.0, 0, 0, "Rename theme");
 
        /* main choices pup: note, it uses collums, and the seperators (%l) then have to fill both halves equally for the menu to work */
-       uiDefButS(block, MENU, B_CHANGE_THEME, "UI and Buttons %x1|%l|3D View %x2|%l|Ipo Curve Editor %x3|Action Editor %x4|"
+       uiDefButS(block, MENU, B_CHANGE_THEME, "UI and Buttons %x1|%l|Bone Color Sets %x17|%l|3D View %x2|%l|Ipo Curve Editor %x3|Action Editor %x4|"
                "NLA Editor %x5|%l|UV/Image Editor %x6|Video Sequence Editor %x7|Node Editor %x16|Timeline %x15|%l|Audio Window %x8|Text Editor %x9|%l|User Preferences %x10|"
                "Outliner %x11|Buttons Window %x12|%l|File Browser %x13|Image Browser %x14",
                                                                                                        255,y2,200,20, &curmain, 0, 0, 0, 0, "Specify theme for...");
@@ -3206,8 +3232,12 @@ static void info_user_themebuts(uiBlock *block, short y1, short y2, short y3)
        else if(curmain==14) spacetype= SPACE_IMASEL;
        else if(curmain==15) spacetype= SPACE_TIME;
        else if(curmain==16) spacetype= SPACE_NODE;
+       else if(curmain==17) { 
+               info_user_theme_colsets_buts(block, y1, y2, y3, y4); 
+               return; 
+       }
        else return; /* only needed while coding... when adding themes for more windows */
-       
+               
        /* color choices pup */
        if(curmain==1) {
                strp= BIF_ThemeColorsPup(0);
@@ -3379,7 +3409,7 @@ void drawinfospace(ScrArea *sa, void *spacedata)
         /* line 2: left x co-ord, top y co-ord, width, height */
 
        if(U.userpref == 6) {
-               info_user_themebuts(block, y1, y2, y3);
+               info_user_themebuts(block, y1, y2, y3, y4);
        }
        else if (U.userpref == 0) { /* view & controls */
 
index 5d2e7cd741054480e49e278f0011f3ea26e36d52..e69fabdd926db836560cb327c6f609724e14ba15 100644 (file)
@@ -561,7 +561,7 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr
                if (constraints_list_needinv(t, &pchan->constraints)) {
                        Mat3CpyMat4(tmat, pchan->constinv);
                        Mat3Inv(cmat, tmat);
-                       Mat3MulSerie(td->mtx, pchan->bone->bone_mat, pmat, cmat, omat, 0,0,0,0);    // dang mulserie swaps args
+                       Mat3MulSerie(td->mtx, pchan->bone->bone_mat, pmat, omat, cmat, 0,0,0,0);    // dang mulserie swaps args
                }
                else
                        Mat3MulSerie(td->mtx, pchan->bone->bone_mat, pmat, omat, 0,0,0,0,0);    // dang mulserie swaps args
@@ -570,7 +570,7 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr
                if (constraints_list_needinv(t, &pchan->constraints)) {
                        Mat3CpyMat4(tmat, pchan->constinv);
                        Mat3Inv(cmat, tmat);
-                       Mat3MulSerie(td->mtx, pchan->bone->bone_mat, cmat, omat, 0, 0,0,0,0);    // dang mulserie swaps args
+                       Mat3MulSerie(td->mtx, pchan->bone->bone_mat, omat, cmat, 0,0,0,0,0);    // dang mulserie swaps args
                }
                else 
                        Mat3MulMat3(td->mtx, omat, pchan->bone->bone_mat);  // Mat3MulMat3 has swapped args!