header cleanup (no functional changes)
[blender.git] / source / blender / blenkernel / intern / texture.c
index 6d8c339d2b98e8cbf45728013532b044c91943b8..d344f79bb6caed1b34d6ac41f715266bd33d3518 100644 (file)
@@ -1,6 +1,4 @@
-/* texture.c
- *
- *
+/*
  * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  * ***** END GPL LICENSE BLOCK *****
  */
 
+/** \file blender/blenkernel/intern/texture.c
+ *  \ingroup bke
+ */
+
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
 #include "MEM_guardedalloc.h"
 
-#include "PIL_dynlib.h"
-
-
-
 #include "BLI_blenlib.h"
+#include "BLI_dynlib.h"
 #include "BLI_math.h"
 #include "BLI_kdopbvh.h"
+#include "BLI_utildefines.h"
 
 #include "DNA_key_types.h"
 #include "DNA_object_types.h"
@@ -52,6 +53,7 @@
 #include "DNA_brush_types.h"
 #include "DNA_node_types.h"
 #include "DNA_color_types.h"
+#include "DNA_particle_types.h"
 
 #include "IMB_imbuf.h"
 
@@ -68,7 +70,7 @@
 #include "BKE_icons.h"
 #include "BKE_node.h"
 #include "BKE_animsys.h"
-
+#include "BKE_colortools.h"
 
 /* ------------------------------------------------------------------------- */
 
@@ -77,7 +79,7 @@ int test_dlerr(const char *name, const char *symbol)
 {
        char *err;
        
-       err= PIL_dynlib_get_error_as_string(NULL);
+       err= BLI_dynlib_get_error_as_string(NULL);
        if(err) {
                printf("var1: %s, var2: %s, var3: %s\n", name, symbol, err);
                return 1;
@@ -93,38 +95,38 @@ void open_plugin_tex(PluginTex *pit)
        int (*version)(void);
        
        /* init all the happy variables */
-       pit->doit= 0;
-       pit->pname= 0;
-       pit->stnames= 0;
-       pit->varstr= 0;
-       pit->result= 0;
-       pit->cfra= 0;
+       pit->doit= NULL;
+       pit->pname= NULL;
+       pit->stnames= NULL;
+       pit->varstr= NULL;
+       pit->result= NULL;
+       pit->cfra= NULL;
        pit->version= 0;
-       pit->instance_init= 0;
+       pit->instance_init= NULL;
        
        /* clear the error list */
-       PIL_dynlib_get_error_as_string(NULL);
+       BLI_dynlib_get_error_as_string(NULL);
 
-       /* no PIL_dynlib_close! multiple opened plugins... */
-       /* if(pit->handle) PIL_dynlib_close(pit->handle); */
+       /* no BLI_dynlib_close! multiple opened plugins... */
+       /* if(pit->handle) BLI_dynlib_close(pit->handle); */
        /* pit->handle= 0; */
 
        /* open the needed object */
-       pit->handle= PIL_dynlib_open(pit->name);
+       pit->handle= BLI_dynlib_open(pit->name);
        if(test_dlerr(pit->name, pit->name)) return;
 
-       if (pit->handle != 0) {
+       if (pit->handle != NULL) {
                /* find the address of the version function */
-               version= (int (*)(void)) PIL_dynlib_find_symbol(pit->handle, "plugin_tex_getversion");
+               version= (int (*)(void)) BLI_dynlib_find_symbol(pit->handle, "plugin_tex_getversion");
                if (test_dlerr(pit->name, "plugin_tex_getversion")) return;
                
-               if (version != 0) {
+               if (version != NULL) {
                        pit->version= version();
                        if( pit->version >= 2 && pit->version <=6) {
                                int (*info_func)(PluginInfo *);
                                PluginInfo *info= (PluginInfo*) MEM_mallocN(sizeof(PluginInfo), "plugin_info"); 
 
-                               info_func= (int (*)(PluginInfo *))PIL_dynlib_find_symbol(pit->handle, "plugin_getinfo");
+                               info_func= (int (*)(PluginInfo *))BLI_dynlib_find_symbol(pit->handle, "plugin_getinfo");
                                if (!test_dlerr(pit->name, "plugin_getinfo")) {
                                        info->instance_init = NULL;
 
@@ -168,9 +170,9 @@ PluginTex *add_plugin_tex(char *str)
        strcpy(pit->name, str);
        open_plugin_tex(pit);
        
-       if(pit->doit==0) {
-               if(pit->handle==0); //XXX error("no plugin: %s", str);
-               else ; //XXX error("in plugin: %s", str);
+       if(pit->doit==NULL) {
+               if(pit->handle==NULL) {;} //XXX error("no plugin: %s", str);
+               else {;} //XXX error("in plugin: %s", str);
                MEM_freeN(pit);
                return NULL;
        }
@@ -193,9 +195,9 @@ PluginTex *add_plugin_tex(char *str)
 
 void free_plugin_tex(PluginTex *pit)
 {
-       if(pit==0) return;
+       if(pit==NULL) return;
                
-       /* no PIL_dynlib_close: same plugin can be opened multiple times, 1 handle */
+       /* no BLI_dynlib_close: same plugin can be opened multiple times, 1 handle */
        MEM_freeN(pit); 
 }
 
@@ -218,9 +220,9 @@ void init_mapping(TexMapping *texmap)
        
        size_to_mat3( smat,texmap->size);
        
-       eul[0]= (M_PI/180.0f)*texmap->rot[0];
-       eul[1]= (M_PI/180.0f)*texmap->rot[1];
-       eul[2]= (M_PI/180.0f)*texmap->rot[2];
+       eul[0]= DEG2RADF(texmap->rot[0]);
+       eul[1]= DEG2RADF(texmap->rot[1]);
+       eul[2]= DEG2RADF(texmap->rot[2]);
        eul_to_mat3( rmat,eul);
        
        mul_m3_m3m3(mat, rmat, smat);
@@ -337,8 +339,11 @@ int do_colorband(ColorBand *coba, float in, float out[4])
                
                                if(cbd2->pos!=cbd1->pos)
                                        fac= (in-cbd1->pos)/(cbd2->pos-cbd1->pos);
-                               else
-                                       fac= 0.0f;
+                               else {
+                                       /* was setting to 0.0 in 2.56 & previous, but this
+                                        * is incorrect for the last element, see [#26732] */
+                                       fac= (a != coba->tot) ? 0.0f : 1.0f;
+                               }
                                
                                if (coba->ipotype==4) {
                                        /* constant */
@@ -368,10 +373,10 @@ int do_colorband(ColorBand *coba, float in, float out[4])
                                        out[1]= t[3]*cbd3->g +t[2]*cbd2->g +t[1]*cbd1->g +t[0]*cbd0->g;
                                        out[2]= t[3]*cbd3->b +t[2]*cbd2->b +t[1]*cbd1->b +t[0]*cbd0->b;
                                        out[3]= t[3]*cbd3->a +t[2]*cbd2->a +t[1]*cbd1->a +t[0]*cbd0->a;
-                                       CLAMP(out[0], 0.0, 1.0);
-                                       CLAMP(out[1], 0.0, 1.0);
-                                       CLAMP(out[2], 0.0, 1.0);
-                                       CLAMP(out[3], 0.0, 1.0);
+                                       CLAMP(out[0], 0.0f, 1.0f);
+                                       CLAMP(out[1], 0.0f, 1.0f);
+                                       CLAMP(out[2], 0.0f, 1.0f);
+                                       CLAMP(out[3], 0.0f, 1.0f);
                                }
                                else {
                                
@@ -403,16 +408,85 @@ void colorband_table_RGBA(ColorBand *coba, float **array, int *size)
                do_colorband(coba, (float)a/(float)CM_TABLE, &(*array)[a*4]);
 }
 
+int vergcband(const void *a1, const void *a2)
+{
+       const CBData *x1=a1, *x2=a2;
+
+       if( x1->pos > x2->pos ) return 1;
+       else if( x1->pos < x2->pos) return -1;
+       return 0;
+}
+
+CBData *colorband_element_add(struct ColorBand *coba, float position)
+{
+       int a;
+
+       if(coba->tot==MAXCOLORBAND) {
+               return NULL;
+       }
+       else if(coba->tot > 0) {
+               CBData *xnew;
+               float col[4];
+
+               do_colorband(coba, position, col);
+
+               xnew = &coba->data[coba->tot];
+               xnew->pos = position;
+
+               xnew->r = col[0];
+               xnew->g = col[1];
+               xnew->b = col[2];
+               xnew->a = col[3];
+       }
+
+       coba->tot++;
+       coba->cur = coba->tot-1;
+
+       for(a = 0; a < coba->tot; a++)
+               coba->data[a].cur = a;
+
+       qsort(coba->data, coba->tot, sizeof(CBData), vergcband);
+
+       for(a = 0; a < coba->tot; a++) {
+               if(coba->data[a].cur == coba->cur) {
+                       coba->cur = a;
+                       break;
+               }
+       }
+
+       return coba->data + coba->cur;
+}
+
+int colorband_element_remove(struct ColorBand *coba, int index)
+{
+       int a;
+
+       if(coba->tot < 2)
+               return 0;
+
+       if(index < 0 || index >= coba->tot)
+               return 0;
+
+       for(a = index; a < coba->tot; a++) {
+               coba->data[a] = coba->data[a + 1];
+       }
+       if(coba->cur) coba->cur--;
+       coba->tot--;
+       return 1;
+}
+
 /* ******************* TEX ************************ */
 
 void free_texture(Tex *tex)
 {
        free_plugin_tex(tex->plugin);
+       
        if(tex->coba) MEM_freeN(tex->coba);
        if(tex->env) BKE_free_envmap(tex->env);
        if(tex->pd) BKE_free_pointdensity(tex->pd);
        if(tex->vd) BKE_free_voxeldata(tex->vd);
        BKE_free_animdata((struct ID *)tex);
+       
        BKE_previewimg_free(&tex->preview);
        BKE_icon_delete((struct ID*)tex);
        tex->id.icon_id = 0;
@@ -451,6 +525,7 @@ void default_tex(Tex *tex)
        tex->nabla= 0.025;      // also in do_versions
        tex->bright= 1.0;
        tex->contrast= 1.0;
+       tex->saturation= 1.0;
        tex->filtersize= 1.0;
        tex->rfac= 1.0;
        tex->gfac= 1.0;
@@ -505,17 +580,40 @@ void default_tex(Tex *tex)
        tex->iuser.fie_ima= 2;
        tex->iuser.ok= 1;
        tex->iuser.frames= 100;
+       tex->iuser.sfra= 1;
        
        tex->preview = NULL;
 }
 
+void tex_set_type(Tex *tex, int type)
+{
+       switch(type) {
+                       
+               case TEX_VOXELDATA:
+                       if (tex->vd == NULL)
+                               tex->vd = BKE_add_voxeldata();
+                       break;
+               case TEX_POINTDENSITY:
+                       if (tex->pd == NULL)
+                               tex->pd = BKE_add_pointdensity();
+                       break;
+               case TEX_ENVMAP:
+                       if (tex->env == NULL)
+                               tex->env = BKE_add_envmap();
+                       break;
+       }
+       
+       tex->type = type;
+}
+
 /* ------------------------------------------------------------------------- */
 
 Tex *add_texture(const char *name)
 {
+       Main *bmain= G.main;
        Tex *tex;
 
-       tex= alloc_libblock(&G.main->tex, ID_TE, name);
+       tex= alloc_libblock(&bmain->tex, ID_TE, name);
        
        default_tex(tex);
        
@@ -528,7 +626,7 @@ void default_mtex(MTex *mtex)
 {
        mtex->texco= TEXCO_ORCO;
        mtex->mapto= MAP_COL;
-       mtex->object= 0;
+       mtex->object= NULL;
        mtex->projx= PROJ_X;
        mtex->projy= PROJ_Y;
        mtex->projz= PROJ_Z;
@@ -539,8 +637,12 @@ void default_mtex(MTex *mtex)
        mtex->size[0]= 1.0;
        mtex->size[1]= 1.0;
        mtex->size[2]= 1.0;
-       mtex->tex= 0;
-       mtex->texflag= MTEX_NEW_BUMP;
+       mtex->tex= NULL;
+
+       /* MTEX_BUMP_FLIPPED is temporary before 2.61 release to prevent flipping normals
+          when creating file in 2.60, opening it in 2.59, saving and opening in 2.60 again */
+       mtex->texflag= MTEX_3TAP_BUMP | MTEX_BUMP_OBJECTSPACE | MTEX_BUMP_FLIPPED;
+
        mtex->colormodel= 0;
        mtex->r= 1.0;
        mtex->g= 0.0;
@@ -581,14 +683,16 @@ void default_mtex(MTex *mtex)
        mtex->lifefac= 1.0f;
        mtex->sizefac= 1.0f;
        mtex->ivelfac= 1.0f;
-       mtex->pvelfac= 1.0f;
+       mtex->dampfac= 1.0f;
+       mtex->gravityfac= 1.0f;
+       mtex->fieldfac= 1.0f;
        mtex->normapspace= MTEX_NSPACE_TANGENT;
 }
 
 
 /* ------------------------------------------------------------------------- */
 
-MTex *add_mtex()
+MTex *add_mtex(void)
 {
        MTex *mtex;
        
@@ -599,6 +703,49 @@ MTex *add_mtex()
        return mtex;
 }
 
+/* slot -1 for first free ID */
+MTex *add_mtex_id(ID *id, int slot)
+{
+       MTex **mtex_ar;
+       short act;
+
+       give_active_mtex(id, &mtex_ar, &act);
+
+       if(mtex_ar==NULL) {
+               return NULL;
+       }
+       
+       if(slot==-1) {
+               /* find first free */
+               int i;          
+               for (i= 0; i < MAX_MTEX; i++) {
+                       if (!mtex_ar[i]) {
+                               slot= i;
+                               break;
+                       }
+               }
+               if(slot == -1) {
+                       return NULL;
+               }
+       }
+       else {
+               /* make sure slot is valid */
+               if(slot < 0 || slot >= MAX_MTEX) {
+                       return NULL;
+               }
+       }
+
+       if (mtex_ar[slot]) {
+               id_us_min((ID *)mtex_ar[slot]->tex);
+               MEM_freeN(mtex_ar[slot]);
+               mtex_ar[slot]= NULL;
+       }
+
+       mtex_ar[slot]= add_mtex();
+
+       return mtex_ar[slot];
+}
+
 /* ------------------------------------------------------------------------- */
 
 Tex *copy_texture(Tex *tex)
@@ -607,11 +754,7 @@ Tex *copy_texture(Tex *tex)
        
        texn= copy_libblock(tex);
        if(texn->type==TEX_IMAGE) id_us_plus((ID *)texn->ima);
-       else texn->ima= 0;
-       
-#if 0 // XXX old animation system
-       id_us_plus((ID *)texn->ipo);
-#endif // XXX old animation system
+       else texn->ima= NULL;
        
        if(texn->plugin) {
                texn->plugin= MEM_dupallocN(texn->plugin);
@@ -620,28 +763,68 @@ Tex *copy_texture(Tex *tex)
        
        if(texn->coba) texn->coba= MEM_dupallocN(texn->coba);
        if(texn->env) texn->env= BKE_copy_envmap(texn->env);
-       if(texn->pd) texn->pd= MEM_dupallocN(texn->pd);
+       if(texn->pd) texn->pd= BKE_copy_pointdensity(texn->pd);
        if(texn->vd) texn->vd= MEM_dupallocN(texn->vd);
-       
        if(tex->preview) texn->preview = BKE_previewimg_copy(tex->preview);
 
        if(tex->nodetree) {
-               ntreeEndExecTree(tex->nodetree);
-               texn->nodetree= ntreeCopyTree(tex->nodetree, 0); /* 0 == full new tree */
+               if (tex->nodetree->execdata) {
+                       ntreeTexEndExecTree(tex->nodetree->execdata, 1);
+               }
+               texn->nodetree= ntreeCopyTree(tex->nodetree); 
+       }
+       
+       return texn;
+}
+
+/* texture copy without adding to main dbase */
+Tex *localize_texture(Tex *tex)
+{
+       Tex *texn;
+       
+       texn= copy_libblock(tex);
+       BLI_remlink(&G.main->tex, texn);
+       
+       /* image texture: free_texture also doesn't decrease */
+       
+       if(texn->plugin) {
+               texn->plugin= MEM_dupallocN(texn->plugin);
+               open_plugin_tex(texn->plugin);
+       }
+       
+       if(texn->coba) texn->coba= MEM_dupallocN(texn->coba);
+       if(texn->env) {
+               texn->env= BKE_copy_envmap(texn->env);
+               id_us_min(&texn->env->ima->id);
+       }
+       if(texn->pd) texn->pd= BKE_copy_pointdensity(texn->pd);
+       if(texn->vd) {
+               texn->vd= MEM_dupallocN(texn->vd);
+               if(texn->vd->dataset)
+                       texn->vd->dataset= MEM_dupallocN(texn->vd->dataset);
+       }
+       
+       texn->preview = NULL;
+       
+       if(tex->nodetree) {
+               texn->nodetree= ntreeLocalize(tex->nodetree);
        }
        
        return texn;
 }
 
+
 /* ------------------------------------------------------------------------- */
 
 void make_local_texture(Tex *tex)
 {
+       Main *bmain= G.main;
        Tex *texn;
        Material *ma;
        World *wrld;
        Lamp *la;
        Brush *br;
+       ParticleSettings *pa;
        int a, local=0, lib=0;
 
        /* - only lib users: do nothing
@@ -649,24 +832,24 @@ void make_local_texture(Tex *tex)
                * - mixed: make copy
                */
        
-       if(tex->id.lib==0) return;
+       if(tex->id.lib==NULL) return;
 
        /* special case: ima always local immediately */
        if(tex->ima) {
-               tex->ima->id.lib= 0;
+               tex->ima->id.lib= NULL;
                tex->ima->id.flag= LIB_LOCAL;
-               new_id(0, (ID *)tex->ima, 0);
+               new_id(&bmain->image, (ID *)tex->ima, NULL);
        }
 
        if(tex->id.us==1) {
-               tex->id.lib= 0;
+               tex->id.lib= NULL;
                tex->id.flag= LIB_LOCAL;
-               new_id(0, (ID *)tex, 0);
+               new_id(&bmain->tex, (ID *)tex, NULL);
 
                return;
        }
        
-       ma= G.main->mat.first;
+       ma= bmain->mat.first;
        while(ma) {
                for(a=0; a<MAX_MTEX; a++) {
                        if(ma->mtex[a] && ma->mtex[a]->tex==tex) {
@@ -676,7 +859,7 @@ void make_local_texture(Tex *tex)
                }
                ma= ma->id.next;
        }
-       la= G.main->lamp.first;
+       la= bmain->lamp.first;
        while(la) {
                for(a=0; a<MAX_MTEX; a++) {
                        if(la->mtex[a] && la->mtex[a]->tex==tex) {
@@ -686,7 +869,7 @@ void make_local_texture(Tex *tex)
                }
                la= la->id.next;
        }
-       wrld= G.main->world.first;
+       wrld= bmain->world.first;
        while(wrld) {
                for(a=0; a<MAX_MTEX; a++) {
                        if(wrld->mtex[a] && wrld->mtex[a]->tex==tex) {
@@ -696,7 +879,7 @@ void make_local_texture(Tex *tex)
                }
                wrld= wrld->id.next;
        }
-       br= G.main->brush.first;
+       br= bmain->brush.first;
        while(br) {
                if(br->mtex.tex==tex) {
                        if(br->id.lib) lib= 1;
@@ -704,21 +887,31 @@ void make_local_texture(Tex *tex)
                }
                br= br->id.next;
        }
+       pa= bmain->particle.first;
+       while(pa) {
+               for(a=0; a<MAX_MTEX; a++) {
+                       if(pa->mtex[a] && pa->mtex[a]->tex==tex) {
+                               if(pa->id.lib) lib= 1;
+                               else local= 1;
+                       }
+               }
+               pa= pa->id.next;
+       }
        
        if(local && lib==0) {
-               tex->id.lib= 0;
+               tex->id.lib= NULL;
                tex->id.flag= LIB_LOCAL;
-               new_id(0, (ID *)tex, 0);
+               new_id(&bmain->tex, (ID *)tex, NULL);
        }
        else if(local && lib) {
                texn= copy_texture(tex);
                texn->id.us= 0;
                
-               ma= G.main->mat.first;
+               ma= bmain->mat.first;
                while(ma) {
                        for(a=0; a<MAX_MTEX; a++) {
                                if(ma->mtex[a] && ma->mtex[a]->tex==tex) {
-                                       if(ma->id.lib==0) {
+                                       if(ma->id.lib==NULL) {
                                                ma->mtex[a]->tex= texn;
                                                texn->id.us++;
                                                tex->id.us--;
@@ -727,11 +920,11 @@ void make_local_texture(Tex *tex)
                        }
                        ma= ma->id.next;
                }
-               la= G.main->lamp.first;
+               la= bmain->lamp.first;
                while(la) {
                        for(a=0; a<MAX_MTEX; a++) {
                                if(la->mtex[a] && la->mtex[a]->tex==tex) {
-                                       if(la->id.lib==0) {
+                                       if(la->id.lib==NULL) {
                                                la->mtex[a]->tex= texn;
                                                texn->id.us++;
                                                tex->id.us--;
@@ -740,11 +933,11 @@ void make_local_texture(Tex *tex)
                        }
                        la= la->id.next;
                }
-               wrld= G.main->world.first;
+               wrld= bmain->world.first;
                while(wrld) {
                        for(a=0; a<MAX_MTEX; a++) {
                                if(wrld->mtex[a] && wrld->mtex[a]->tex==tex) {
-                                       if(wrld->id.lib==0) {
+                                       if(wrld->id.lib==NULL) {
                                                wrld->mtex[a]->tex= texn;
                                                texn->id.us++;
                                                tex->id.us--;
@@ -753,10 +946,10 @@ void make_local_texture(Tex *tex)
                        }
                        wrld= wrld->id.next;
                }
-               br= G.main->brush.first;
+               br= bmain->brush.first;
                while(br) {
                        if(br->mtex.tex==tex) {
-                               if(br->id.lib==0) {
+                               if(br->id.lib==NULL) {
                                        br->mtex.tex= texn;
                                        texn->id.us++;
                                        tex->id.us--;
@@ -764,6 +957,19 @@ void make_local_texture(Tex *tex)
                        }
                        br= br->id.next;
                }
+               pa= bmain->particle.first;
+               while(pa) {
+                       for(a=0; a<MAX_MTEX; a++) {
+                               if(pa->mtex[a] && pa->mtex[a]->tex==tex) {
+                                       if(pa->id.lib==NULL) {
+                                               pa->mtex[a]->tex= texn;
+                                               texn->id.us++;
+                                               tex->id.us--;
+                                       }
+                               }
+                       }
+                       pa= pa->id.next;
+               }
        }
 }
 
@@ -771,6 +977,7 @@ void make_local_texture(Tex *tex)
 
 void autotexname(Tex *tex)
 {
+       Main *bmain= G.main;
        char texstr[20][15]= {"None"  , "Clouds" , "Wood", "Marble", "Magic"  , "Blend",
                "Stucci", "Noise"  , "Image", "Plugin", "EnvMap" , "Musgrave",
                "Voronoi", "DistNoise", "Point Density", "Voxel Data", "", "", "", ""};
@@ -779,7 +986,7 @@ void autotexname(Tex *tex)
        
        if(tex) {
                if(tex->use_nodes) {
-                       new_id(&G.main->tex, (ID *)tex, "Noddy");
+                       new_id(&bmain->tex, (ID *)tex, "Noddy");
                }
                else
                if(tex->type==TEX_IMAGE) {
@@ -789,12 +996,12 @@ void autotexname(Tex *tex)
                                BLI_splitdirstring(di, fi);
                                strcpy(di, "I.");
                                strcat(di, fi);
-                               new_id(&G.main->tex, (ID *)tex, di);
+                               new_id(&bmain->tex, (ID *)tex, di);
                        }
-                       else new_id(&G.main->tex, (ID *)tex, texstr[tex->type]);
+                       else new_id(&bmain->tex, (ID *)tex, texstr[tex->type]);
                }
-               else if(tex->type==TEX_PLUGIN && tex->plugin) new_id(&G.main->tex, (ID *)tex, tex->plugin->pname);
-               else new_id(&G.main->tex, (ID *)tex, texstr[tex->type]);
+               else if(tex->type==TEX_PLUGIN && tex->plugin) new_id(&bmain->tex, (ID *)tex, tex->plugin->pname);
+               else new_id(&bmain->tex, (ID *)tex, texstr[tex->type]);
        }
 }
 
@@ -802,16 +1009,20 @@ void autotexname(Tex *tex)
 
 Tex *give_current_object_texture(Object *ob)
 {
-       Material *ma;
+       Material *ma, *node_ma;
        Tex *tex= NULL;
        
-       if(ob==0) return 0;
-       if(ob->totcol==0 && !(ob->type==OB_LAMP)) return 0;
+       if(ob==NULL) return NULL;
+       if(ob->totcol==0 && !(ob->type==OB_LAMP)) return NULL;
        
        if(ob->type==OB_LAMP) {
                tex= give_current_lamp_texture(ob->data);
        } else {
                ma= give_current_material(ob, ob->actcol);
+
+               if((node_ma=give_node_material(ma)))
+                       ma= node_ma;
+
                tex= give_current_material_texture(ma);
        }
        
@@ -877,17 +1088,6 @@ Tex *give_current_material_texture(Material *ma)
                        tex= (Tex *)node->id;
                        ma= NULL;
                }
-               else {
-                       node= nodeGetActiveID(ma->nodetree, ID_MA);
-                       if(node) {
-                               ma= (Material*)node->id;
-                               if(ma) {
-                                       mtex= ma->mtex[(int)(ma->texact)];
-                                       if(mtex) tex= mtex->tex;
-                               }
-                       }
-               }
-               return tex;
        }
 
        if(ma) {
@@ -913,6 +1113,10 @@ int give_active_mtex(ID *id, MTex ***mtex_ar, short *act)
                *mtex_ar=               ((Lamp *)id)->mtex;
                if(act) *act=   (((Lamp *)id)->texact);
                break;
+       case ID_PA:
+               *mtex_ar=               ((ParticleSettings *)id)->mtex;
+               if(act) *act=   (((ParticleSettings *)id)->texact);
+               break;
        default:
                *mtex_ar = NULL;
                if(act) *act=   0;
@@ -937,6 +1141,9 @@ void set_active_mtex(ID *id, short act)
        case ID_LA:
                ((Lamp *)id)->texact= act;
                break;
+       case ID_PA:
+               ((ParticleSettings *)id)->texact= act;
+               break;
        }
 }
 
@@ -955,11 +1162,6 @@ void set_current_material_texture(Material *ma, Tex *newtex)
                        id_us_plus(&newtex->id);
                        ma= NULL;
                }
-               else {
-                       node= nodeGetActiveID(ma->nodetree, ID_MA);
-                       if(node)
-                               ma= (Material*)node->id;
-               }
        }
        if(ma) {
                int act= (int)ma->texact;
@@ -981,12 +1183,26 @@ void set_current_material_texture(Material *ma, Tex *newtex)
        }
 }
 
+int has_current_material_texture(Material *ma)
+{
+       bNode *node;
+
+       if(ma && ma->use_nodes && ma->nodetree) {
+               node= nodeGetActiveID(ma->nodetree, ID_TE);
+
+               if(node)
+                       return 1;
+       }
+
+       return (ma != NULL);
+}
+
 Tex *give_current_world_texture(World *world)
 {
        MTex *mtex= NULL;
        Tex *tex= NULL;
        
-       if(!world) return 0;
+       if(!world) return NULL;
        
        mtex= world->mtex[(int)(world->texact)];
        if(mtex) tex= mtex->tex;
@@ -1032,6 +1248,42 @@ void set_current_brush_texture(Brush *br, Tex *newtex)
        }
 }
 
+Tex *give_current_particle_texture(ParticleSettings *part)
+{
+       MTex *mtex= NULL;
+       Tex *tex= NULL;
+       
+       if(!part) return NULL;
+       
+       mtex= part->mtex[(int)(part->texact)];
+       if(mtex) tex= mtex->tex;
+       
+       return tex;
+}
+
+void set_current_particle_texture(ParticleSettings *part, Tex *newtex)
+{
+       int act= part->texact;
+
+       if(part->mtex[act] && part->mtex[act]->tex)
+               id_us_min(&part->mtex[act]->tex->id);
+
+       if(newtex) {
+               if(!part->mtex[act]) {
+                       part->mtex[act]= add_mtex();
+                       part->mtex[act]->texco= TEXCO_ORCO;
+                       part->mtex[act]->blendtype= MTEX_MUL;
+               }
+               
+               part->mtex[act]->tex= newtex;
+               id_us_plus(&newtex->id);
+       }
+       else if(part->mtex[act]) {
+               MEM_freeN(part->mtex[act]);
+               part->mtex[act]= NULL;
+       }
+}
+
 /* ------------------------------------------------------------------------- */
 
 EnvMap *BKE_add_envmap(void)
@@ -1111,6 +1363,14 @@ PointDensity *BKE_add_pointdensity(void)
        pd->totpoints = 0;
        pd->object = NULL;
        pd->psys = 0;
+       pd->psys_cache_space= TEX_PD_WORLDSPACE;
+       pd->falloff_curve = curvemapping_add(1, 0, 0, 1, 1);
+
+       pd->falloff_curve->preset = CURVE_PRESET_LINE;
+       pd->falloff_curve->cm->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
+       curvemap_reset(pd->falloff_curve->cm, &pd->falloff_curve->clipr, pd->falloff_curve->preset, CURVEMAP_SLOPE_POSITIVE);
+       curvemapping_changed(pd->falloff_curve, 0);
+
        return pd;
 } 
 
@@ -1122,7 +1382,7 @@ PointDensity *BKE_copy_pointdensity(PointDensity *pd)
        pdn->point_tree = NULL;
        pdn->point_data = NULL;
        if(pdn->coba) pdn->coba= MEM_dupallocN(pdn->coba);
-       
+       pdn->falloff_curve = curvemapping_copy(pdn->falloff_curve); /* can be NULL */
        return pdn;
 }
 
@@ -1136,7 +1396,12 @@ void BKE_free_pointdensitydata(PointDensity *pd)
                MEM_freeN(pd->point_data);
                pd->point_data = NULL;
        }
-       if(pd->coba) MEM_freeN(pd->coba);
+       if(pd->coba) {
+               MEM_freeN(pd->coba);
+               pd->coba = NULL;
+       }
+
+       curvemapping_free(pd->falloff_curve); /* can be NULL */
 }
 
 void BKE_free_pointdensity(PointDensity *pd)
@@ -1149,8 +1414,7 @@ void BKE_free_pointdensity(PointDensity *pd)
 void BKE_free_voxeldatadata(struct VoxelData *vd)
 {
        if (vd->dataset) {
-               if(vd->file_format != TEX_VD_SMOKE)
-                       MEM_freeN(vd->dataset);
+               MEM_freeN(vd->dataset);
                vd->dataset = NULL;
        }
 
@@ -1201,13 +1465,15 @@ int BKE_texture_dependsOnTime(const struct Tex *texture)
        else if(        texture->ima && 
                        ELEM(texture->ima->source, IMA_SRC_SEQUENCE, IMA_SRC_MOVIE)) {
                return 1;
-       } 
-#if 0 // XXX old animation system
-       else if(texture->ipo) {
-               // assume any ipo means the texture is animated
+       }
+       else if(texture->adt) {
+               // assume anything in adt means the texture is animated
+               return 1;
+       }
+       else if(texture->type == TEX_NOISE) {
+               // noise always varies with time
                return 1;
        }
-#endif // XXX old animation system
        return 0;
 }