svn merge -r 16593:16648 https://svn.blender.org/svnroot/bf-blender/trunk/blender
authorDaniel Genrich <daniel.genrich@gmx.net>
Sun, 21 Sep 2008 13:03:39 +0000 (13:03 +0000)
committerDaniel Genrich <daniel.genrich@gmx.net>
Sun, 21 Sep 2008 13:03:39 +0000 (13:03 +0000)
1  2 
source/blender/blenkernel/intern/depsgraph.c
source/blender/blenkernel/intern/particle_system.c
source/blender/blenloader/intern/readfile.c
source/blender/makesdna/DNA_ipo_types.h
source/blender/render/intern/source/convertblender.c
source/blender/src/editipo.c

index 96ea4fced9d8d67dbd73c0282d2ce0aef0a4453f,11e61989dfa36dcb8979fd2505e7aa15096fc788..7f4910a976505527ba2830d4b2d1dfa7c4534e1f
@@@ -865,12 -865,12 +865,12 @@@ DagNode * dag_get_sub_node (DagForest *
        return node;
  }
  
void dag_add_relation(DagForest *forest, DagNode *fob1, DagNode *fob2, short rel, char *name) 
static void dag_add_parent_relation(DagForest *forest, DagNode *fob1, DagNode *fob2, short rel, char *name) 
  {
-       DagAdjList *itA = fob1->child;
+       DagAdjList *itA = fob2->parent;
        
        while (itA) { /* search if relation exist already */
-               if (itA->node == fob2) {
+               if (itA->node == fob1) {
                        itA->type |= rel;
                        itA->count += 1;
                        return;
        }
        /* create new relation and insert at head. MALLOC alert! */
        itA = MEM_mallocN(sizeof(DagAdjList),"DAG adj list");
-       itA->node = fob2;
+       itA->node = fob1;
        itA->type = rel;
        itA->count = 1;
-       itA->next = fob1->child;
+       itA->next = fob2->parent;
        itA->name = name;
-       fob1->child = itA;
+       fob2->parent = itA;
  }
  
static void dag_add_parent_relation(DagForest *forest, DagNode *fob1, DagNode *fob2, short rel, char *name) 
void dag_add_relation(DagForest *forest, DagNode *fob1, DagNode *fob2, short rel, char *name) 
  {
-       DagAdjList *itA = fob2->parent;
+       DagAdjList *itA = fob1->child;
        
+       /* parent relation is for cycle checking */
+       dag_add_parent_relation(forest, fob1, fob2, rel, name);
        while (itA) { /* search if relation exist already */
-               if (itA->node == fob1) {
+               if (itA->node == fob2) {
                        itA->type |= rel;
                        itA->count += 1;
                        return;
        }
        /* create new relation and insert at head. MALLOC alert! */
        itA = MEM_mallocN(sizeof(DagAdjList),"DAG adj list");
-       itA->node = fob1;
+       itA->node = fob2;
        itA->type = rel;
        itA->count = 1;
-       itA->next = fob2->parent;
+       itA->next = fob1->child;
        itA->name = name;
-       fob2->parent = itA;
+       fob1->child = itA;
  }
  
  static char *dag_node_name(DagNode *node)
@@@ -966,6 -969,63 +969,63 @@@ static void dag_node_print_dependency_c
        printf("\n");
  }
  
+ static int dag_node_recurs_level(DagNode *node, int level)
+ {
+       DagAdjList *itA;
+       int newlevel;
+       node->color= DAG_BLACK; /* done */
+       newlevel= ++level;
+       
+       for(itA= node->parent; itA; itA= itA->next) {
+               if(itA->node->color==DAG_WHITE) {
+                       itA->node->ancestor_count= dag_node_recurs_level(itA->node, level);
+                       newlevel= MAX2(newlevel, level+itA->node->ancestor_count);
+               }
+               else
+                       newlevel= MAX2(newlevel, level+itA->node->ancestor_count);
+       }
+       
+       return newlevel;
+ }
+ static void dag_check_cycle(DagForest *dag)
+ {
+       DagNode *node;
+       DagAdjList *itA;
+       /* tag nodes unchecked */
+       for(node = dag->DagNode.first; node; node= node->next)
+               node->color= DAG_WHITE;
+       
+       for(node = dag->DagNode.first; node; node= node->next) {
+               if(node->color==DAG_WHITE) {
+                       node->ancestor_count= dag_node_recurs_level(node, 0);
+               }
+       }
+       
+       /* check relations, and print errors */
+       for(node = dag->DagNode.first; node; node= node->next) {
+               for(itA= node->parent; itA; itA= itA->next) {
+                       if(itA->node->ancestor_count > node->ancestor_count) {
+                               if(node->ob && itA->node->ob) {
+                                       printf("Dependency cycle detected:\n");
+                                       dag_node_print_dependency_cycle(dag, itA->node, node, itA->name);
+                               }
+                       }
+               }
+       }
+       /* parent relations are only needed for cycle checking, so free now */
+       for(node = dag->DagNode.first; node; node= node->next) {
+               while (node->parent) {
+                       itA = node->parent->next;
+                       MEM_freeN(node->parent);                        
+                       node->parent = itA;
+               }
+       }
+ }
  /*
   * MainDAG is the DAG of all objects in current scene
   * used only for drawing there is one also in each scene
@@@ -1603,6 -1663,8 +1663,8 @@@ void DAG_scene_sort(struct Scene *sce
        
        build_dag(sce, DAG_RL_ALL_BUT_DATA);
        
+       dag_check_cycle(sce->theDag);
        nqueue = queue_create(DAGQUEUEALLOC);
        
        for(node = sce->theDag->DagNode.first; node; node= node->next) {
@@@ -1969,6 -2031,12 +2031,6 @@@ static void dag_object_time_update_flag
                                                ob->shapeflag &= ~OB_SHAPE_TEMPLOCK;
                                        }
                                }
 -                              if((ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) && (ob->fluidsimSettings)) {
 -                                      // fluidsimSettings might not be initialized during load...
 -                                      if(ob->fluidsimSettings->type & (OB_FLUIDSIM_DOMAIN|OB_FLUIDSIM_PARTICLE)) {
 -                                              ob->recalc |= OB_RECALC_DATA; // NT FSPARTICLE
 -                                      }
 -                              }
                                if(ob->particlesystem.first)
                                        ob->recalc |= OB_RECALC_DATA;
                                break;
@@@ -2206,57 -2274,6 +2268,6 @@@ void DAG_object_update_flags(Scene *sce
  
  /* ******************* DAG FOR ARMATURE POSE ***************** */
  
- static int node_recurs_level(DagNode *node, int level)
- {
-       DagAdjList *itA;
-       int newlevel;
-       node->color= DAG_BLACK; /* done */
-       newlevel= ++level;
-       
-       for(itA= node->parent; itA; itA= itA->next) {
-               if(itA->node->color==DAG_WHITE) {
-                       itA->node->ancestor_count= node_recurs_level(itA->node, level);
-                       newlevel= MAX2(newlevel, level+itA->node->ancestor_count);
-               }
-               else
-                       newlevel= MAX2(newlevel, level+itA->node->ancestor_count);
-       }
-       
-       return newlevel;
- }
- static void pose_check_cycle(DagForest *dag)
- {
-       DagNode *node;
-       DagAdjList *itA;
-       /* tag nodes unchecked */
-       for(node = dag->DagNode.first; node; node= node->next)
-               node->color= DAG_WHITE;
-       
-       for(node = dag->DagNode.first; node; node= node->next) {
-               if(node->color==DAG_WHITE) {
-                       node->ancestor_count= node_recurs_level(node, 0);
-               }
-       }
-       
-       /* check relations, and print errors */
-       for(node = dag->DagNode.first; node; node= node->next) {
-               for(itA= node->parent; itA; itA= itA->next) {
-                       if(itA->node->ancestor_count > node->ancestor_count) {
-                               bPoseChannel *pchan= (bPoseChannel *)node->ob;
-                               bPoseChannel *parchan= (bPoseChannel *)itA->node->ob;
-                               
-                               if(pchan && parchan)  {
-                                       printf("Cycle detected:\n");
-                                       dag_node_print_dependency_cycle(dag, itA->node, node, itA->name);
-                               }
-                       }
-               }
-       }
- }
  /* we assume its an armature with pose */
  void DAG_pose_sort(Object *ob)
  {
                if(pchan->parent) {
                        node2 = dag_get_node(dag, pchan->parent);
                        dag_add_relation(dag, node2, node, 0, "Parent Relation");
-                       dag_add_parent_relation(dag, node2, node, 0, "Parent Relation");
                        addtoroot = 0;
                }
                for (con = pchan->constraints.first; con; con=con->next) {
                                                if(target) {
                                                        node2 = dag_get_node(dag, target);
                                                        dag_add_relation(dag, node2, node, 0, "Ipo Driver");
-                                                       dag_add_parent_relation(dag, node2, node, 0, "Ipo Driver");
  
                                                        /* uncommented this line, results in dependencies
                                                         * not being added properly for this constraint,
                                                if (target) {
                                                        node2= dag_get_node(dag, target);
                                                        dag_add_relation(dag, node2, node, 0, "IK Constraint");
-                                                       dag_add_parent_relation(dag, node2, node, 0, "IK Constraint");
  
                                                        if (con->type==CONSTRAINT_TYPE_KINEMATIC) {
                                                                bKinematicConstraint *data = (bKinematicConstraint *)con->data;
                                                                while (parchan) {
                                                                        node3= dag_get_node(dag, parchan);
                                                                        dag_add_relation(dag, node2, node3, 0, "IK Constraint");
-                                                                       dag_add_parent_relation(dag, node2, node3, 0, "IK Constraint");
                                                                        
                                                                        segcount++;
                                                                        if (segcount==data->rootbone || segcount>255) break; // 255 is weak
                }
                if (addtoroot == 1 ) {
                        dag_add_relation(dag, rootnode, node, 0, "Root Bone Relation");
-                       dag_add_parent_relation(dag, rootnode, node, 0, "Root Bone Relation");
                }
        }
  
-       pose_check_cycle(dag);
+       dag_check_cycle(dag);
        
        /* now we try to sort... */
        tempbase.first= tempbase.last= NULL;
index ee887bee2b1804bc5c392f4a808a28e7f6d55340,11e69262bbe8ca847ca706d9cbea525058b888e8..7aff0f0eb4954ca1d1a6bf4271120a2f36e03cd5
@@@ -156,7 -156,7 +156,7 @@@ void psys_reset(ParticleSystem *psys, i
                int p=0;
  
                for(; p<psys->totpart; p++, pa++)
-                       pa->flag = PARS_NO_DISP;
+                       pa->flag |= PARS_NO_DISP;
        }
  
        /* reset children */
@@@ -2110,22 -2110,18 +2110,18 @@@ static void react_to_events(ParticleSys
        for(re=psys->reactevents.first; re; re=re->next){
                birth=0;
                if(part->from==PART_FROM_PARTICLE){
-                       if(pa->num==re->pa_num){
+                       if(pa->num==re->pa_num && pa->alive==PARS_UNBORN){
                                if(re->event==PART_EVENT_NEAR){
                                        ParticleData *tpa = re->psys->particles+re->pa_num;
                                        float pa_time=tpa->time + pa->foffset*tpa->lifetime;
-                                       if(re->time > pa_time){
-                                               pa->alive=PARS_ALIVE;
+                                       if(re->time >= pa_time){
                                                pa->time=pa_time;
                                                pa->dietime=pa->time+pa->lifetime;
                                        }
                                }
                                else{
-                                       if(pa->alive==PARS_UNBORN){
-                                               pa->alive=PARS_ALIVE;
-                                               pa->time=re->time;
-                                               pa->dietime=pa->time+pa->lifetime;
-                                       }
+                                       pa->time=re->time;
+                                       pa->dietime=pa->time+pa->lifetime;
                                }
                        }
                }
                        dist=VecLenf(pa->state.co, re->state.co);
                        if(dist <= re->size){
                                if(pa->alive==PARS_UNBORN){
-                                       pa->alive=PARS_ALIVE;
                                        pa->time=re->time;
                                        pa->dietime=pa->time+pa->lifetime;
                                        birth=1;
@@@ -3127,6 -3122,10 +3122,10 @@@ static void deflect_particle(Object *po
                        if(through == 0 && (part->flag & PART_DIE_ON_COL || pd->flag & PDEFLE_KILL_PART)) {
                                pa->alive = PARS_DYING;
                                pa->dietime = pa->state.time + (cfra - pa->state.time) * dt;
+                               
+                               /* we have to add this for dying particles too so that reactors work correctly */
+                               VECADDFAC(co, co, col.nor, (through ? -0.0001f : 0.0001f));
                                VECCOPY(state->co, co);
                                VecLerpf(state->vel, pa->state.vel, state->vel, dt);
                                QuatInterpol(state->rot, pa->state.rot, state->rot, dt);
@@@ -4061,9 -4060,11 +4060,11 @@@ static void dynamics_step(Object *ob, P
                                pa_dfra = dfra;
                                pa_dtime = dtime;
  
+                               /* we need to calculate this once again because reactions might have changed pa->time */
+                               birthtime = pa->time + pa->loop * pa->lifetime;
                                dietime = birthtime + pa->lifetime;
  
-                               if(birthtime < cfra && birthtime >= psys->cfra){
+                               if(birthtime <= cfra && birthtime >= psys->cfra){
                                        /* particle is born some time between this and last step*/
                                        pa->alive = PARS_ALIVE;
                                        pa_dfra = cfra - birthtime;
                                                }
                                        }
  
-                                       push_reaction(ob,psys,p,PART_EVENT_NEAR,key);
                                        if(pa->alive == PARS_DYING){
                                                push_reaction(ob,psys,p,PART_EVENT_DEATH,key);
  
                                        }
                                        else
                                                key->time=cfra;
+                                       push_reaction(ob,psys,p,PART_EVENT_NEAR,key);
                                }
                        }
                }
@@@ -4333,7 -4334,7 +4334,7 @@@ void psys_changed_type(ParticleSystem *
  }
  
  static void particles_fluid_step(Object *ob, ParticleSystem *psys, int cfra)
 -{
 +{     
        if(psys->particles){
                MEM_freeN(psys->particles);
                psys->particles = 0;
  
        /* fluid sim particle import handling, actual loading of particles from file */
        #ifndef DISABLE_ELBEEM
 -      if( (1) && (ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) &&  // broken, disabled for now!
 -              (ob->fluidsimSettings)) { 
 -              ParticleSettings *part = psys->part;
 -              ParticleData *pa=0;
 -              char *suffix  = "fluidsurface_particles_####";
 -              char *suffix2 = ".gz";
 -              char filename[256];
 -              char debugStrBuffer[256];
 -              int  curFrame = G.scene->r.cfra -1; // warning - sync with derived mesh fsmesh loading
 -              int  p, j, numFileParts, totpart;
 -              int readMask, activeParts = 0, fileParts = 0;
 -              gzFile gzf;
 -
 -              if(ob==G.obedit) // off...
 -                      return;
 -
 -              // ok, start loading
 -              strcpy(filename, ob->fluidsimSettings->surfdataPath);
 -              strcat(filename, suffix);
 -              BLI_convertstringcode(filename, G.sce);
 -              BLI_convertstringframe(filename, curFrame); // fixed #frame-no 
 -              strcat(filename, suffix2);
 -
 -              gzf = gzopen(filename, "rb");
 -              if (!gzf) {
 -                      snprintf(debugStrBuffer,256,"readFsPartData::error - Unable to open file for reading '%s' \n", filename); 
 -                      //elbeemDebugOut(debugStrBuffer);
 -                      return;
 -              }
 -
 -              gzread(gzf, &totpart, sizeof(totpart));
 -              numFileParts = totpart;
 -              totpart = (G.rendering)?totpart:(part->disp*totpart)/100;
 +      {
 +              FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
                
 -              part->totpart= totpart;
 -              part->sta=part->end = 1.0f;
 -              part->lifetime = G.scene->r.efra + 1;
 -
 -              /* initialize particles */
 -              realloc_particles(ob, psys, part->totpart);
 -              initialize_all_particles(ob, psys, 0);
 -
 -              // set up reading mask
 -              readMask = ob->fluidsimSettings->typeFlags;
 -              
 -              for(p=0, pa=psys->particles; p<totpart; p++, pa++) {
 -                      int ptype=0;
 -
 -                      gzread(gzf, &ptype, sizeof( ptype )); 
 -                      if(ptype&readMask) {
 -                              activeParts++;
 -
 -                              gzread(gzf, &(pa->size), sizeof( float )); 
 -
 -                              pa->size /= 10.0f;
 -
 -                              for(j=0; j<3; j++) {
 -                                      float wrf;
 -                                      gzread(gzf, &wrf, sizeof( wrf )); 
 -                                      pa->state.co[j] = wrf;
 -                                      //fprintf(stderr,"Rj%d ",j);
 -                              }
 -                              for(j=0; j<3; j++) {
 -                                      float wrf;
 -                                      gzread(gzf, &wrf, sizeof( wrf )); 
 -                                      pa->state.vel[j] = wrf;
 -                              }
 -
 -                              pa->state.ave[0] = pa->state.ave[1] = pa->state.ave[2] = 0.0f;
 -                              pa->state.rot[0] = 1.0;
 -                              pa->state.rot[1] = pa->state.rot[2] = pa->state.rot[3] = 0.0;
 -
 -                              pa->alive = PARS_ALIVE;
 -                              //if(a<25) fprintf(stderr,"FSPARTICLE debug set %s , a%d = %f,%f,%f , life=%f \n", filename, a, pa->co[0],pa->co[1],pa->co[2], pa->lifetime );
 -                      } else {
 -                              // skip...
 -                              for(j=0; j<2*3+1; j++) {
 -                                      float wrf; gzread(gzf, &wrf, sizeof( wrf )); 
 +              if( fluidmd && fluidmd->fss) { 
 +                      FluidsimSettings *fss= fluidmd->fss;
 +                      ParticleSettings *part = psys->part;
 +                      ParticleData *pa=0;
 +                      char *suffix  = "fluidsurface_particles_####";
 +                      char *suffix2 = ".gz";
 +                      char filename[256];
 +                      char debugStrBuffer[256];
 +                      int  curFrame = G.scene->r.cfra -1; // warning - sync with derived mesh fsmesh loading
 +                      int  p, j, numFileParts, totpart;
 +                      int readMask, activeParts = 0, fileParts = 0;
 +                      gzFile gzf;
 +      
 +                      if(ob==G.obedit) // off...
 +                              return;
 +      
 +                      // ok, start loading
 +                      strcpy(filename, fss->surfdataPath);
 +                      strcat(filename, suffix);
 +                      BLI_convertstringcode(filename, G.sce);
 +                      BLI_convertstringframe(filename, curFrame); // fixed #frame-no 
 +                      strcat(filename, suffix2);
 +      
 +                      gzf = gzopen(filename, "rb");
 +                      if (!gzf) {
 +                              snprintf(debugStrBuffer,256,"readFsPartData::error - Unable to open file for reading '%s' \n", filename); 
 +                              //elbeemDebugOut(debugStrBuffer);
 +                              return;
 +                      }
 +      
 +                      gzread(gzf, &totpart, sizeof(totpart));
 +                      numFileParts = totpart;
 +                      totpart = (G.rendering)?totpart:(part->disp*totpart)/100;
 +                      
 +                      part->totpart= totpart;
 +                      part->sta=part->end = 1.0f;
 +                      part->lifetime = G.scene->r.efra + 1;
 +      
 +                      /* initialize particles */
 +                      realloc_particles(ob, psys, part->totpart);
 +                      initialize_all_particles(ob, psys, 0);
 +      
 +                      // set up reading mask
 +                      readMask = fss->typeFlags;
 +                      
 +                      for(p=0, pa=psys->particles; p<totpart; p++, pa++) {
 +                              int ptype=0;
 +      
 +                              gzread(gzf, &ptype, sizeof( ptype )); 
 +                              if(ptype&readMask) {
 +                                      activeParts++;
 +      
 +                                      gzread(gzf, &(pa->size), sizeof( float )); 
 +      
 +                                      pa->size /= 10.0f;
 +      
 +                                      for(j=0; j<3; j++) {
 +                                              float wrf;
 +                                              gzread(gzf, &wrf, sizeof( wrf )); 
 +                                              pa->state.co[j] = wrf;
 +                                              //fprintf(stderr,"Rj%d ",j);
 +                                      }
 +                                      for(j=0; j<3; j++) {
 +                                              float wrf;
 +                                              gzread(gzf, &wrf, sizeof( wrf )); 
 +                                              pa->state.vel[j] = wrf;
 +                                      }
 +      
 +                                      pa->state.ave[0] = pa->state.ave[1] = pa->state.ave[2] = 0.0f;
 +                                      pa->state.rot[0] = 1.0;
 +                                      pa->state.rot[1] = pa->state.rot[2] = pa->state.rot[3] = 0.0;
 +      
 +                                      pa->alive = PARS_ALIVE;
 +                                      //if(a<25) fprintf(stderr,"FSPARTICLE debug set %s , a%d = %f,%f,%f , life=%f \n", filename, a, pa->co[0],pa->co[1],pa->co[2], pa->lifetime );
 +                              } else {
 +                                      // skip...
 +                                      for(j=0; j<2*3+1; j++) {
 +                                              float wrf; gzread(gzf, &wrf, sizeof( wrf )); 
 +                                      }
                                }
 +                              fileParts++;
                        }
 -                      fileParts++;
 -              }
 -              gzclose( gzf );
 -
 -              totpart = psys->totpart = activeParts;
 -              snprintf(debugStrBuffer,256,"readFsPartData::done - particles:%d, active:%d, file:%d, mask:%d  \n", psys->totpart,activeParts,fileParts,readMask);
 -              elbeemDebugOut(debugStrBuffer);
 -      } // fluid sim particles done
 +                      gzclose( gzf );
 +      
 +                      totpart = psys->totpart = activeParts;
 +                      snprintf(debugStrBuffer,256,"readFsPartData::done - particles:%d, active:%d, file:%d, mask:%d  \n", psys->totpart,activeParts,fileParts,readMask);
 +                      elbeemDebugOut(debugStrBuffer);
 +              } // fluid sim particles done
 +      }
        #endif // DISABLE_ELBEEM
  }
  
index 928def7705926a5dbac520bf8bdc590b788be543,b013b51c026398924a6fc1b2b1aaf552b00e8081..797c986b7d082c05f3f7b1d8e52a88df6721001b
@@@ -37,9 -37,6 +37,9 @@@
  #ifdef WIN32
  #include "winsock2.h"
  #include "BLI_winstuff.h"
 +#ifndef INT_MAX
 +#include "limits.h"
 +#endif
  #endif
  
  #include <stdio.h> // for printf fopen fwrite fclose sprintf FILE
  #include "BKE_object.h"
  #include "BKE_particle.h"
  #include "BKE_pointcache.h"
- #include "BKE_property.h" // for get_property
+ #include "BKE_property.h" // for get_ob_property
  #include "BKE_sca.h" // for init_actuator
  #include "BKE_scene.h"
  #include "BKE_softbody.h"     // sbNew()
@@@ -3066,12 -3063,9 +3066,12 @@@ static void lib_link_object(FileData *f
                                }
                                act= act->next;
                        }
 -
 -                      if(ob->fluidsimSettings) {
 -                              ob->fluidsimSettings->ipo = newlibadr_us(fd, ob->id.lib, ob->fluidsimSettings->ipo);
 +                      
 +                      {
 +                              FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
 +                              
 +                              if(fluidmd && fluidmd->fss) 
 +                                      fluidmd->fss->ipo = newlibadr_us(fd, ob->id.lib, fluidmd->fss->ipo);
                        }
                        
                        /* texture field */
@@@ -3146,11 -3140,6 +3146,11 @@@ static void direct_link_modifiers(FileD
                        }
                        
                }
 +              else if (md->type==eModifierType_Fluidsim) {
 +                      FluidsimModifierData *fluidmd = (FluidsimModifierData*) md;
 +                      
 +                      fluidmd->fss= newdataadr(fd, fluidmd->fss);
 +              }
                else if (md->type==eModifierType_Collision) {
                        
                        CollisionModifierData *collmd = (CollisionModifierData*) md;
@@@ -3337,6 -3326,13 +3337,6 @@@ static void direct_link_object(FileDat
                        direct_link_pointcache(fd, sb->pointcache);
        }
        ob->fluidsimSettings= newdataadr(fd, ob->fluidsimSettings); /* NT */
 -      if(ob->fluidsimSettings) {
 -              // reinit mesh pointers
 -              ob->fluidsimSettings->orgMesh = NULL; //ob->data;
 -              ob->fluidsimSettings->meshSurface = NULL;
 -              ob->fluidsimSettings->meshBB = NULL;
 -              ob->fluidsimSettings->meshSurfNormals = NULL;
 -      }
  
        link_list(fd, &ob->particlesystem);
        direct_link_particlesystems(fd,&ob->particlesystem);
@@@ -5329,7 -5325,7 +5329,7 @@@ static void do_versions(FileData *fd, L
                        while (act) {
                                if(act->type==ACT_IPO) {
                                        ia= act->data;
-                                       prop= get_property(ob, ia->name);
+                                       prop= get_ob_property(ob, ia->name);
                                        if(prop) {
                                                ia->type= ACT_IPO_FROM_PROP;
                                        }
                                        }
                                }
  
 -                              if(ob->fluidsimSettings && ob->fluidsimSettings->type == OB_FLUIDSIM_PARTICLE)
 -                                      part->type = PART_FLUID;
 +                              
 +                              {
 +                                      FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
 +                                      if(fluidmd && fluidmd->fss && fluidmd->fss->type == OB_FLUIDSIM_PARTICLE)
 +                                              part->type = PART_FLUID;
 +                              }
  
                                free_effects(&ob->effect);
  
                        la->sun_intensity = 1.0;
                }
        }
 +      
 +      // convert fluids to modifier
 +      if(main->versionfile <= 246 && main->subversionfile < 1)
 +      {
 +              Object *ob;
 +              
 +              for(ob = main->object.first; ob; ob= ob->id.next) {
 +                      if(ob->fluidsimSettings)
 +                      {
 +                              FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifier_new(eModifierType_Fluidsim);
 +                              BLI_addhead(&ob->modifiers, (ModifierData *)fluidmd);
 +                              
 +                              MEM_freeN(fluidmd->fss);
 +                              fluidmd->fss = MEM_dupallocN(ob->fluidsimSettings);
 +                              fluidmd->fss->ipo = newlibadr_us(fd, ob->id.lib, ob->fluidsimSettings->ipo);
 +                              MEM_freeN(ob->fluidsimSettings);
 +                              
 +                              fluidmd->fss->lastgoodframe = INT_MAX;
 +                              fluidmd->fss->flag = 0;
 +                      }
 +              }
 +      }
 +      
  
        if(main->versionfile < 246 || (main->versionfile == 246 && main->subversionfile < 1)) {
                Mesh *me;
                }
        }
  
+       if (main->versionfile < 247 || (main->versionfile == 247 && main->subversionfile < 3)){
+               Object *ob;
+               for(ob = main->object.first; ob; ob= ob->id.next) {
+                       // Starting from subversion 3, ACTOR is a separate feature.
+                       // Before it was conditioning all the other dynamic flags
+                       if (!(ob->gameflag & OB_ACTOR))
+                               ob->gameflag &= ~(OB_GHOST|OB_DYNAMIC|OB_RIGID_BODY|OB_SOFT_BODY|OB_COLLISION_RESPONSE);
+               }
+       }
+       if (main->versionfile < 247 || (main->versionfile == 247 && main->subversionfile < 4)){
+               Scene *sce= main->scene.first;
+               while(sce) {
+                       if(sce->frame_step==0)
+                               sce->frame_step= 1;
+                       sce= sce->id.next;
+               }
+       }
        /* WATCH IT!!!: pointers from libdata have not been converted yet here! */
        /* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */
  
index f517bf14733575ea6284784aef9322b0a2652fe3,fe75148fb3b1fb954cf067fb69f9f7866e5b55eb..5be6dd727c04ec1abbe24f523d9a74f6688e2176
@@@ -24,7 -24,7 +24,7 @@@
   *
   * The Original Code is: all of this file.
   *
-  * Contributor(s): none yet.
+  * Contributor(s): Joshua Leung
   *
   * ***** END GPL LICENSE BLOCK *****
   */
  #define DNA_IPO_TYPES_H
  
  #include "DNA_listBase.h"
+ #include "DNA_curve_types.h"
  #include "DNA_vec_types.h"
  
  #include "DNA_ID.h"
  
+ /* -------------------------- Type Defines --------------------------- */
+ /* sometimes used - mainly for GE/Ketsji */
+ typedef short IPO_Channel;  
+ /* --- IPO Curve Driver --- */
+ /* IPO Curve Driver */
+ typedef struct IpoDriver {
+       struct Object *ob;                      /* target/driver ob */
+       short blocktype, adrcode;       /* sub-channel to use */
+       
+       short type, flag;                       /* driver settings */
+       char name[128];                         /* bone, or python expression here */
+ } IpoDriver;
+ /* --- IPO Curve --- */
+ /* IPO Curve */
+ typedef struct IpoCurve {
+       struct IpoCurve *next,  *prev;
+       
+       struct BPoint *bp;                                      /* array of BPoints (sizeof(BPoint)*totvert) - i.e. baked/imported data */
+       struct BezTriple *bezt;                         /* array of BezTriples (sizeof(BezTriple)*totvert)  - i.e. user-editable keyframes  */
+       rctf maxrct, totrct;                            /* bounding boxes */
+       short blocktype, adrcode, vartype;      /* blocktype= ipo-blocktype; adrcode= type of ipo-curve; vartype= 'format' of data */
+       short totvert;                                          /* total number of BezTriples (i.e. keyframes) on curve */
+       short ipo, extrap;                                      /* interpolation and extrapolation modes  */
+       short flag, rt;                                         /* flag= settings; rt= ??? */
+       float ymin, ymax;                                       /* minimum/maximum y-extents for curve */
+       unsigned int bitmask;                           /* ??? */
+       
+       float slide_min, slide_max;                     /* minimum/maximum values for sliders (in action editor) */
+       float curval;                                           /* value of ipo-curve for current frame */
+       
+       IpoDriver *driver;                                      /* pointer to ipo-driver for this curve */
+ } IpoCurve;
+ /* --- ID-Datablock --- */
  /* IPO Data-Block */
  typedef struct Ipo {
        ID id;
        short muteipo, pad;                     /* muteipo: either 0 or 1 (whether ipo block is muted) */       
  } Ipo;
  
- /* NOTE: IpoCurve struct is defined in DNA_curve_types.h, not in here... */
- /* sometimes used */
- typedef short IPO_Channel;  
+ /* ----------- adrcodes (for matching ipo-curves to data) ------------- */
  
  /* defines: are these duped or new? */
  #define IPOBUTY       17
  
  #define TOB_IPO       1
  #define IPO_DISPBITS  2
  #define IPO_DISPTIME  3
  
- /* ******************** */
+ /* ********** Object (ID_OB) ********** */
  
  #define OB_TOTIPO     30
  #define OB_TOTNAM     30
  #define OB_ROT_DIFF   100
  
  
- /* ******************** */
+ /* ********** Material (ID_MA) ********** */
  
  #define MA_TOTIPO     40
  #define MA_TOTNAM     26
  #define MAP_VARF      13
  #define MAP_DISP      14
  
- /* ******************** */
+ /* ********** Texture (ID_TE) ********** */
  
  #define TE_TOTIPO     26
  #define TE_TOTNAM     26
  #define TE_BRIGHT     25
  #define TE_CONTRA     26
  
- /* ******************** */
+ /* ******** Sequence (ID_SEQ) ********** */
  
  #define SEQ_TOTIPO    1
  #define SEQ_TOTNAM    1
  
  #define SEQ_FAC1      1
  
- /* ******************** */
+ /* ********* Curve (ID_CU) *********** */
  
  #define CU_TOTIPO     1
  #define CU_TOTNAM     1
  
  #define CU_SPEED      1
  
- /* ******************** */
+ /* ********* ShapeKey (ID_KE) *********** */
  
  #define KEY_TOTIPO    64
  #define KEY_TOTNAM    64
  #define KEY_SPEED     0
  #define KEY_NR                1
  
- /* ******************** */
+ /* ********* World (ID_WO) *********** */
  
  #define WO_TOTIPO     29
  #define WO_TOTNAM     16
  #define WO_STARDIST   15
  #define WO_STARSIZE   16
  
- /* ******************** */
+ /* ********** Lamp (ID_LA) ********** */
  
  #define LA_TOTIPO     21
  #define LA_TOTNAM     10
  #define LA_QUAD2      9
  #define LA_HALOINT    10
  
- /* ******************** */
+ /* ********* Camera (ID_CA) ************ */
  
- /* yafray: totipo & totnam +2 because of added curves */
  #define CAM_TOTIPO    7
  #define CAM_TOTNAM    7
  
  #define CAM_SHIFT_X           6
  #define CAM_SHIFT_Y           7
  
- /* ******************** */
+ /* ********* Sound (ID_SO) *********** */
  
  #define SND_TOTIPO    4
  #define SND_TOTNAM    4
  #define SND_PANNING   3
  #define SND_ATTEN     4
  
- /* ******************** */
+ /* ******* PoseChannel (ID_PO) ********* */
  
- #define AC_TOTIPO     10      /* __NLA */
+ #define AC_TOTIPO     10
  #define AC_TOTNAM     10
  
  #define AC_LOC_X      1
  #define AC_QUAT_Y     27
  #define AC_QUAT_Z     28
  
- /* ******************** */
- #define CO_TOTIPO     2       /* Constraint Ipos */
+ /* ******** Constraint (ID_CO) ********** */
+ #define CO_TOTIPO     2
  #define CO_TOTNAM     2
  
  #define CO_ENFORCE    1
  #define CO_HEADTAIL   2
- /*
- #define       CO_TIME         2
- #define CO_OFFSET_X   3
- #define CO_OFFSET_Y   4
- #define CO_OFFSET_Z   5
- #define CO_ORIENT_X   6
- #define CO_ORIENT_Y   7
- #define CO_ORIENT_Z   8
- #define CO_ROLL               9
- */
  
- /* ******************** */
- /* fluidsim ipos NT */
+ /* ****** FluidSim (ID_FLUIDSIM) ****** */
  
 -#define FLUIDSIM_TOTIPO       9
 -#define FLUIDSIM_TOTNAM       9
 +#define FLUIDSIM_TOTIPO       13
 +#define FLUIDSIM_TOTNAM       13
  
  #define FLUIDSIM_VISC   1
  #define FLUIDSIM_TIME   2
  
  #define FLUIDSIM_ACTIVE 9
  
 -/* ******* Particle (ID_PA) ******** */
 +#define FLUIDSIM_ATTR_FORCE_STR       10
 +#define FLUIDSIM_ATTR_FORCE_RADIUS    11
 +#define FLUIDSIM_VEL_FORCE_STR                12
 +#define FLUIDSIM_VEL_FORCE_RADIUS     13
 +
 +/* ******************** */
 +/* particle ipos */
++/* ******* Particle (ID_PA) ******** */
  #define PART_TOTIPO           25
  #define PART_TOTNAM           25
  
  #define PART_PD2_FMAXD        25
  
  
- /* these are IpoCurve specific */
- /* **************** IPO ********************* */
+ /* -------------------- Defines: Flags and Types ------------------ */
+ /* ----- IPO Curve Defines ------- */
  
  /* icu->vartype */
  #define IPO_CHAR              0
  #define IPO_FLOAT             4
  #define IPO_DOUBLE            5
  #define IPO_FLOAT_DEGR        6
        /* very special case, in keys */
  #define IPO_BEZTRIPLE 100
  #define IPO_BPOINT            101
  #define IPO_CONST             0
  #define IPO_LIN                       1
  #define IPO_BEZ                       2
- #define IPO_MIXED             3 /* not used yet */
+       /* not used yet */
+ #define IPO_MIXED             3 
  
  /* icu->extrap */
  #define IPO_HORIZ             0
  #define IPO_PROTECT           64
  #define IPO_MUTE              128
  
+ /* ---------- IPO Drivers ----------- */
+ /* offset in driver->name for finding second posechannel for rot-diff  */
+ #define DRIVER_NAME_OFFS      32 
+ /* driver->type */
+ #define       IPO_DRIVER_TYPE_NORMAL          0
+ #define       IPO_DRIVER_TYPE_PYTHON          1
+ /* driver->flag */
+       /* invalid flag: currently only used for buggy pydriver expressions */
+ #define IPO_DRIVER_FLAG_INVALID       (1<<0)
  #endif
  
  
index 33f32a4744e306fb4d41e553a2a1d6fa3d9a0ea7,45d79be2f62d68a74b41e6aecab85a875f9ca971..d5ac2fa17480fa56069c6d9e37ffc093a53383fe
@@@ -674,6 -674,94 +674,6 @@@ static void calc_vertexnormals(Render *
                MEM_freeN(vtangents);
  }
  
 -// NT same as calc_vertexnormals, but dont modify the existing vertex normals
 -// only recalculate other render data. If this is at some point used for other things than fluidsim,
 -// this could be made on option for the normal calc_vertexnormals
 -static void calc_fluidsimnormals(Render *re, ObjectRen *obr, int do_nmap_tangent)
 -{
 -      int a;
 -
 -      /* dont clear vertex normals here */
 -      // OFF for(a=0; a<obr->totvert; a++) { VertRen *ver= RE_findOrAddVert(obr, a); ver->n[0]=ver->n[1]=ver->n[2]= 0.0; }
 -      /* calculate cos of angles and point-masses, use as weight factor to add face normal to vertex */
 -      for(a=0; a<obr->totvlak; a++) {
 -              VlakRen *vlr= RE_findOrAddVlak(obr, a);
 -              if(vlr->flag & ME_SMOOTH) {
 -                      VertRen *v1= vlr->v1;
 -                      VertRen *v2= vlr->v2;
 -                      VertRen *v3= vlr->v3;
 -                      VertRen *v4= vlr->v4;
 -                      float n1[3], n2[3], n3[3], n4[3];
 -                      float fac1, fac2, fac3, fac4=0.0f;
 -
 -                      if(re->flag & R_GLOB_NOPUNOFLIP)
 -                              vlr->flag |= R_NOPUNOFLIP;
 -                      
 -                      VecSubf(n1, v2->co, v1->co);
 -                      Normalize(n1);
 -                      VecSubf(n2, v3->co, v2->co);
 -                      Normalize(n2);
 -                      if(v4==NULL) {
 -                              VecSubf(n3, v1->co, v3->co);
 -                              Normalize(n3);
 -                              fac1= saacos(-n1[0]*n3[0]-n1[1]*n3[1]-n1[2]*n3[2]);
 -                              fac2= saacos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2]);
 -                              fac3= saacos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2]);
 -                      }
 -                      else {
 -                              VecSubf(n3, v4->co, v3->co);
 -                              Normalize(n3);
 -                              VecSubf(n4, v1->co, v4->co);
 -                              Normalize(n4);
 -
 -                              fac1= saacos(-n4[0]*n1[0]-n4[1]*n1[1]-n4[2]*n1[2]);
 -                              fac2= saacos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2]);
 -                              fac3= saacos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2]);
 -                              fac4= saacos(-n3[0]*n4[0]-n3[1]*n4[1]-n3[2]*n4[2]);
 -
 -                              if(!(vlr->flag & R_NOPUNOFLIP)) {
 -                                      if( check_vnormal(vlr->n, v4->n) ) fac4= -fac4;
 -                              }
 -                      }
 -
 -                      //if(do_nmap_tangent)
 -                      //      calc_tangent_vector(obr, vlr, fac1, fac2, fac3, fac4);
 -              }
 -              if(do_nmap_tangent) {
 -                      /* tangents still need to be calculated for flat faces too */
 -                      /* weighting removed, they are not vertexnormals */
 -                      //calc_tangent_vector(obr, vlr);
 -              }
 -      }
 -
 -      /* do solid faces */
 -      for(a=0; a<obr->totvlak; a++) {
 -              VlakRen *vlr= RE_findOrAddVlak(obr, a);
 -              if((vlr->flag & ME_SMOOTH)==0) {
 -                      float *f1= vlr->v1->n;
 -                      if(f1[0]==0.0 && f1[1]==0.0 && f1[2]==0.0) VECCOPY(f1, vlr->n);
 -                      f1= vlr->v2->n;
 -                      if(f1[0]==0.0 && f1[1]==0.0 && f1[2]==0.0) VECCOPY(f1, vlr->n);
 -                      f1= vlr->v3->n;
 -                      if(f1[0]==0.0 && f1[1]==0.0 && f1[2]==0.0) VECCOPY(f1, vlr->n);
 -                      if(vlr->v4) {
 -                              f1= vlr->v4->n;
 -                              if(f1[0]==0.0 && f1[1]==0.0 && f1[2]==0.0) VECCOPY(f1, vlr->n);
 -                      }                       
 -              }
 -      }
 -      
 -      /* normalize vertex normals */
 -      for(a=0; a<obr->totvert; a++) {
 -              VertRen *ver= RE_findOrAddVert(obr, a);
 -              Normalize(ver->n);
 -              if(do_nmap_tangent) {
 -                      float *tav= RE_vertren_get_tangent(obr, ver, 0);
 -                      if(tav) Normalize(tav);
 -              }
 -      }
 -}
 -
  /* ------------------------------------------------------------------------- */
  /* Autosmoothing:                                                            */
  /* ------------------------------------------------------------------------- */
@@@ -3093,6 -3181,12 +3093,6 @@@ static void init_render_mesh(Render *re
                }
        }
  
 -      if((ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) &&
 -               (ob->fluidsimSettings->type & OB_FLUIDSIM_DOMAIN)&&
 -         (ob->fluidsimSettings->meshSurface) ) {
 -              useFluidmeshNormals = 1;
 -      }
 -
        mvert= dm->getVertArray(dm);
        totvert= dm->getNumVerts(dm);
  
                        if(do_autosmooth==0)    /* autosmooth on original unrotated data to prevent differences between frames */
                                MTC_Mat4MulVecfl(mat, ver->co);
    
 -                      if(useFluidmeshNormals) {
 -                              /* normals are inverted in render */
 -                              xn = -mvert->no[0]/ 32767.0;
 -                              yn = -mvert->no[1]/ 32767.0;
 -                              zn = -mvert->no[2]/ 32767.0;
 -                              /* transfor to cam  space */
 -                              ver->n[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
 -                              ver->n[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
 -                              ver->n[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
 -                      } // useFluidmeshNormals
 -
                        if(orco) {
                                ver->orco= orco;
                                orco+=3;
                        autosmooth(re, obr, mat, me->smoothresh);
                }
  
 -              if(useFluidmeshNormals) {
 -                      // do not recalculate, only init render data
 -                      calc_fluidsimnormals(re, obr, need_tangent||need_nmap_tangent);
 -              } else {
 -                      calc_vertexnormals(re, obr, need_tangent, need_nmap_tangent);
 -              }
 +              calc_vertexnormals(re, obr, need_tangent, need_nmap_tangent);
  
                if(need_stress)
                        calc_edge_stress(re, obr, me);
@@@ -3456,6 -3566,9 +3456,9 @@@ static GroupObject *add_render_lamp(Ren
        lar->r= lar->energy*la->r;
        lar->g= lar->energy*la->g;
        lar->b= lar->energy*la->b;
+       lar->shdwr= la->shdwr;
+       lar->shdwg= la->shdwg;
+       lar->shdwb= la->shdwb;
        lar->k= la->k;
  
        // area
  
        for(c=0; c<MAX_MTEX; c++) {
                if(la->mtex[c] && la->mtex[c]->tex) {
-                       lar->mode |= LA_TEXTURE;
+                       if (la->mtex[c]->mapto & LAMAP_COL) 
+                               lar->mode |= LA_TEXTURE;
+                       if (la->mtex[c]->mapto & LAMAP_SHAD)
+                               lar->mode |= LA_SHAD_TEX;
  
                        if(G.rendering) {
                                if(re->osa) {
@@@ -5175,7 -5291,7 +5181,7 @@@ static int load_fluidsimspeedvectors(Re
                //fsvec[0] = fsvec[1] = fsvec[2] = fsvec[3] = 0.; fsvec[2] = 2.; // NT fixed test
                for(j=0;j<3;j++) fsvec[j] = vverts[a].co[j];
                
 -              /* (bad) HACK insert average velocity if none is there (see previous comment */
 +              /* (bad) HACK insert average velocity if none is there (see previous comment) */
                if((fsvec[0] == 0.0) && (fsvec[1] == 0.0) && (fsvec[2] == 0.0))
                {
                        fsvec[0] = avgvel[0];
@@@ -5319,7 -5435,6 +5325,7 @@@ void RE_Database_FromScene_Vectors(Rend
                        oldobi= table->first;
                        for(obi= re->instancetable.first; obi && oldobi; obi= obi->next) {
                                int ok= 1;
 +                              FluidsimModifierData *fluidmd;
  
                                if(!(obi->obr->flag & R_NEED_VECTORS))
                                        continue;
                                }
  
                                // NT check for fluidsim special treatment
 -                              if((obi->ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) && (obi->ob->fluidsimSettings->type & OB_FLUIDSIM_DOMAIN)) {
 +                              fluidmd = (FluidsimModifierData *)modifiers_findByType(obi->ob, eModifierType_Fluidsim);
 +                              if(fluidmd && fluidmd->fss && (fluidmd->fss->type & OB_FLUIDSIM_DOMAIN)) {
                                        // use preloaded per vertex simulation data , only does calculation for step=1
                                        // NOTE/FIXME - velocities and meshes loaded unnecessarily often during the database_fromscene_vectors calls...
                                        load_fluidsimspeedvectors(re, obi, oldobi->vectors, step);
index fc0ac71908b00cf56ad05fa084d1db6b93387ce2,45641fc80ca5fb595fe740cbe1c608a9702094b5..9a7f8e652a7bcfa1565fc04b86494e677da0a112
@@@ -60,7 -60,6 +60,7 @@@
  #include "DNA_key_types.h"
  #include "DNA_lamp_types.h"
  #include "DNA_material_types.h"
 +#include "DNA_modifier_types.h"
  #include "DNA_object_types.h"
  #include "DNA_object_fluidsim.h"
  #include "DNA_particle_types.h"
@@@ -85,7 -84,6 +85,7 @@@
  #include "BKE_key.h"
  #include "BKE_main.h"
  #include "BKE_material.h"
 +#include "BKE_modifier.h"
  #include "BKE_particle.h"
  #include "BKE_texture.h"
  #include "BKE_utildefines.h"
@@@ -476,41 -474,19 +476,41 @@@ static void make_part_editipo(SpaceIpo 
  }
  
  // copied from make_seq_editipo
 -static void make_fluidsim_editipo(SpaceIpo *si) // NT
 +static void make_fluidsim_editipo(SpaceIpo *si, Object *ob) // NT
  {
        EditIpo *ei;
        int a;
        char *name;
 -      ei= si->editipo= MEM_callocN(FLUIDSIM_TOTIPO*sizeof(EditIpo), "fluidsim_editipo");
 -      si->totipo = FLUIDSIM_TOTIPO;
 -      for(a=0; a<FLUIDSIM_TOTIPO; a++) {
 +      int numipos = FLUIDSIM_TOTIPO;
 +      int ipo_start_index = 0;
 +      FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
 +      FluidsimSettings *fss= fluidmd->fss;
 +      
 +      // we don't need all fluid ipos for all types! - dg
 +      if(fss->type == OB_FLUIDSIM_CONTROL)
 +      {
 +              numipos = 4; // there are 4 fluid control ipos
 +              ipo_start_index = 9;
 +              
 +      }
 +      else if(fss->type == OB_FLUIDSIM_DOMAIN)
 +      {
 +              numipos = 5; // there are 5 ipos for fluid domains
 +      }
 +      else
 +      {
 +              numipos = 4; // there are 4 for the rest
 +              ipo_start_index = 5;
 +      }
 +              
 +      ei= si->editipo= MEM_callocN(numipos*sizeof(EditIpo), "fluidsim_editipo");
 +      si->totipo = numipos;
 +      for(a=ipo_start_index; a<ipo_start_index+numipos; a++) {
                //fprintf(stderr,"FSINAME %d %d \n",a,fluidsim_ar[a], (int)(getname_fluidsim_ei(fluidsim_ar[a]))  );
                name = getname_fluidsim_ei(fluidsim_ar[a]);
                strcpy(ei->name, name);
                ei->adrcode= fluidsim_ar[a];
 -              ei->col= ipo_rainbow(a, FLUIDSIM_TOTIPO);
 +              ei->col= ipo_rainbow(a, numipos);
                ei->icu= find_ipocurve(si->ipo, ei->adrcode);
                if(ei->icu) {
                        ei->flag = ei->icu->flag;
@@@ -974,7 -950,7 +974,7 @@@ static void make_editipo(void
        else if(G.sipo->blocktype==ID_FLUIDSIM) {
                if (ob) { // NT
                        ob->ipowin= ID_FLUIDSIM;
 -                      make_fluidsim_editipo(G.sipo);
 +                      make_fluidsim_editipo(G.sipo, ob);
                }
        }
        else if(G.sipo->blocktype==ID_PA) {
@@@ -1194,14 -1170,10 +1194,14 @@@ static void get_ipo_context(short block
                //              }
        }
        else if(blocktype==ID_FLUIDSIM) {
 -              if(ob && ( ob->fluidsimFlag & OB_FLUIDSIM_ENABLE)) {
 -                      FluidsimSettings *fss= ob->fluidsimSettings;
 -                      *from= (ID *)ob;
 -                      if(fss) *ipo= fss->ipo;
 +              if(ob)
 +              {
 +                      FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
 +                      if(fluidmd) {
 +                              FluidsimSettings *fss= fluidmd->fss;
 +                              *from= (ID *)ob;
 +                              if(fss) *ipo= fss->ipo;
 +                      }
                }
        }
        else if(blocktype==ID_PA) {
@@@ -1346,14 -1318,10 +1346,10 @@@ void update_editipo_flags(void
                        for(a=0; a<G.sipo->totipo; a++) {
                                if(ik->data[a]) {
                                        if(ik->flag & 1) {
-                                               ik->data[a]->f1 |= SELECT;
-                                               ik->data[a]->f2 |= SELECT;
-                                               ik->data[a]->f3 |= SELECT;
+                                               BEZ_SEL(ik->data[a]);
                                        }
                                        else {
-                                               ik->data[a]->f1 &= ~SELECT;
-                                               ik->data[a]->f2 &= ~SELECT;
-                                               ik->data[a]->f3 &= ~SELECT;
+                                               BEZ_DESEL(ik->data[a]);
                                        }
                                }
                        }
@@@ -1451,7 -1419,7 +1447,7 @@@ static short findnearest_ipovert(IpoCur
                                        if(ei->disptype!=IPO_DISPBITS && ei->icu->ipo==IPO_BEZ) {
                                                /* middle points get an advantage */
                                                temp= -3+abs(mval[0]- sco[0][0])+ abs(mval[1]- sco[0][1]);
-                                               if( bezt1->f1 & 1) temp+=5;
+                                               if( bezt1->f1 & SELECT) temp+=5;
                                                if(temp<dist) { 
                                                        hpoint= 0; 
                                                        *bezt= bezt1; 
@@@ -1542,18 -1510,18 +1538,18 @@@ void mouse_select_ipo(void
                        if(bezt) {
                                if(hand==1) {
                                        if(BEZSELECTED(bezt)) {
-                                               bezt->f1= bezt->f2= bezt->f3= 0;
+                                               BEZ_DESEL(bezt);
                                        }
                                        else {
-                                               bezt->f1= bezt->f2= bezt->f3= SELECT;
+                                               BEZ_SEL(bezt);
                                        }
                                }
                                else if(hand==0) {
-                                       if(bezt->f1 & SELECT) bezt->f1= 0;
+                                       if(bezt->f1 & SELECT) bezt->f1 &= ~SELECT;
                                        else bezt->f1= SELECT;
                                }
                                else {
-                                       if(bezt->f3 & SELECT) bezt->f3= 0;
+                                       if(bezt->f3 & SELECT) bezt->f3 &= ~SELECT;
                                        else bezt->f3= SELECT;
                                }
                        }                               
                        
                        if(bezt) {
                                if(hand==1) {
-                                       bezt->f1|= SELECT; bezt->f2|= SELECT; bezt->f3|= SELECT;
+                                       BEZ_SEL(bezt);
                                }
                                else if(hand==0) bezt->f1 |= SELECT;
                                else bezt->f3 |= SELECT;
@@@ -1913,10 -1881,9 +1909,10 @@@ Ipo *verify_ipo(ID *from, short blockty
                                }
                                else if (blocktype== ID_FLUIDSIM) {
                                        Object *ob= (Object *)from;
 -                                      
 -                                      if (ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) {
 -                                              FluidsimSettings *fss= ob->fluidsimSettings;
 +
 +                                      FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
 +                                      if(fluidmd) {
 +                                              FluidsimSettings *fss= fluidmd->fss;
                                                
                                                if ((fss->ipo==NULL) && (add))
                                                        fss->ipo= add_ipo("FluidsimIpo", ID_FLUIDSIM);
@@@ -2290,7 -2257,7 +2286,7 @@@ void add_duplicate_editipo(void
                                        while(b--) {
                                                *beztn= *bezt;
                                                if(bezt->f2 & SELECT) {
-                                                       beztn->f1= beztn->f2= beztn->f3= 0;
+                                                       BEZ_DESEL(beztn);
                                                        beztn++;
                                                        *beztn= *bezt;
                                                }
@@@ -3503,14 -3470,10 +3499,10 @@@ void make_ipokey(void
                        if(ik->data[a]) {
                                bezt= ik->data[a];
                                if(sel) {
-                                       bezt->f1 |= SELECT;
-                                       bezt->f2 |= SELECT;
-                                       bezt->f3 |= SELECT;
+                                       BEZ_SEL(bezt);
                                }
                                else {
-                                       bezt->f1 &= ~SELECT;
-                                       bezt->f2 &= ~SELECT;
-                                       bezt->f3 &= ~SELECT;
+                                       BEZ_DESEL(bezt);
                                }
                        }
                }
@@@ -3618,15 -3581,11 +3610,11 @@@ void make_ipokey_transform(Object *ob, 
                icu= icu->next;
        }
        
-       
-       ik= lb->first;
-       while(ik) {
-               /* map ipo-keys for drawing/editing if scaled ipo */
-               if (NLA_IPO_SCALED) {
+       if (NLA_IPO_SCALED) {
+               for (ik= lb->first; ik; ik= ik->next) {
+                       /* map ipo-keys for drawing/editing if scaled ipo */
                        ik->val= get_action_frame_inv(OBACT, ik->val);
                }
-               
-               ik= ik->next;
        }
  }
  
@@@ -4678,7 -4637,7 +4666,7 @@@ void duplicate_ipo_keys(Ipo *ipo
        for (icu=ipo->curve.first; icu; icu=icu->next){
                for (i=0; i<icu->totvert; i++){
                        /* If a key is selected */
-                       if (icu->bezt[i].f2 & 1){
+                       if (icu->bezt[i].f2 & SELECT){
                                /* Expand the list */
                                newbezt = MEM_callocN(sizeof(BezTriple) * (icu->totvert+1), "beztriple");
                                memcpy (newbezt, icu->bezt, sizeof(BezTriple) * (i+1));
                                MEM_freeN (icu->bezt);
                                icu->bezt=newbezt;
                                /* Unselect the current key*/
-                               icu->bezt[i].f1 &= ~ 1;
-                               icu->bezt[i].f2 &= ~ 1;
-                               icu->bezt[i].f3 &= ~ 1;
+                               BEZ_DESEL(&icu->bezt[i]);
                                i++;
                                /* Select the copied key */
-                               icu->bezt[i].f1 |= 1;
-                               icu->bezt[i].f2 |= 1;
-                               icu->bezt[i].f3 |= 1;
-                               
+                               BEZ_SEL(&icu->bezt[i]);
                        }
                }
        }