diff options
author | Janne Karhu <jhkarh@gmail.com> | 2008-04-02 21:48:46 +0400 |
---|---|---|
committer | Janne Karhu <jhkarh@gmail.com> | 2008-04-02 21:48:46 +0400 |
commit | 49c65433cc87ceb8a40b52ccf9ed22151c425f4b (patch) | |
tree | 27c26e928b246b4ae20a628026100b0ff12b06fc /source/blender | |
parent | bab535ce1add9e8984b777480e7793958fd0794b (diff) |
Fix for bug: [#8117] Particles with fluid broken
-Handling of fluid particles was not coded at all
-Now things should work properly, but as fluid particles are not very familiar to me I'd appreciate some thorough testing
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/intern/particle_system.c | 212 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 3 | ||||
-rw-r--r-- | source/blender/include/butspace.h | 1 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_particle_types.h | 1 | ||||
-rw-r--r-- | source/blender/src/buttons_editing.c | 10 | ||||
-rw-r--r-- | source/blender/src/buttons_object.c | 116 |
6 files changed, 268 insertions, 75 deletions
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index ec740dcd8a0..7f1d554d172 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -84,6 +84,22 @@ #include "RE_shader_ext.h" +/* fluid sim particle import */ +#ifndef DISABLE_ELBEEM +#include "DNA_object_fluidsim.h" +#include "LBM_fluidsim.h" +#include "elbeem.h" +#include <zlib.h> +#include <string.h> + +#ifdef WIN32 +#ifndef snprintf +#define snprintf _snprintf +#endif +#endif + +#endif // DISABLE_ELBEEM + /************************************************/ /* Reacting to system events */ /************************************************/ @@ -1452,7 +1468,7 @@ void initialize_particle(ParticleData *pa, int p, Object *ob, ParticleSystem *ps BLI_srandom(psys->seed+p); - if(part->from!=PART_FROM_PARTICLE){ + if(part->from!=PART_FROM_PARTICLE && part->type!=PART_FLUID){ ma=give_current_material(ob,part->omat); /* TODO: needs some work to make most blendtypes generally usefull */ @@ -1544,53 +1560,54 @@ static void initialize_all_particles(Object *ob, ParticleSystem *psys, ParticleS for(p=0, pa=psys->particles; p<totpart; p++, pa++) initialize_particle(pa,p,ob,psys,psmd); - /* store the derived mesh face index for each particle */ - icu=find_ipocurve(psys->part->ipo,PART_EMIT_FREQ); - if(icu){ - float time=psys->part->sta, end=psys->part->end; - float v1, v2, a=0.0f, t1,t2, d; - - p=0; - pa=psys->particles; - - calc_icu(icu,time); - v1=icu->curval; - if(v1<0.0f) v1=0.0f; - - calc_icu(icu,time+1.0f); - v2=icu->curval; - if(v2<0.0f) v2=0.0f; - - for(p=0, pa=psys->particles; p<totpart && time<end; p++, pa++){ - while(a+0.5f*(v1+v2) < (float)(p+1) && time<end){ - a+=0.5f*(v1+v2); - v1=v2; - time++; - calc_icu(icu,time+1.0f); - v2=icu->curval; - } - if(time<end){ - if(v1==v2){ - pa->time=time+((float)(p+1)-a)/v1; + if(psys->part->type != PART_FLUID) { + icu=find_ipocurve(psys->part->ipo,PART_EMIT_FREQ); + if(icu){ + float time=psys->part->sta, end=psys->part->end; + float v1, v2, a=0.0f, t1,t2, d; + + p=0; + pa=psys->particles; + + calc_icu(icu,time); + v1=icu->curval; + if(v1<0.0f) v1=0.0f; + + calc_icu(icu,time+1.0f); + v2=icu->curval; + if(v2<0.0f) v2=0.0f; + + for(p=0, pa=psys->particles; p<totpart && time<end; p++, pa++){ + while(a+0.5f*(v1+v2) < (float)(p+1) && time<end){ + a+=0.5f*(v1+v2); + v1=v2; + time++; + calc_icu(icu,time+1.0f); + v2=icu->curval; } - else{ - d=(float)sqrt(v1*v1-2.0f*(v2-v1)*(a-(float)(p+1))); - t1=(-v1+d)/(v2-v1); - t2=(-v1-d)/(v2-v1); + if(time<end){ + if(v1==v2){ + pa->time=time+((float)(p+1)-a)/v1; + } + else{ + d=(float)sqrt(v1*v1-2.0f*(v2-v1)*(a-(float)(p+1))); + t1=(-v1+d)/(v2-v1); + t2=(-v1-d)/(v2-v1); - /* the root between 0-1 is the correct one */ - if(t1>0.0f && t1<=1.0f) - pa->time=time+t1; - else - pa->time=time+t2; + /* the root between 0-1 is the correct one */ + if(t1>0.0f && t1<=1.0f) + pa->time=time+t1; + else + pa->time=time+t2; + } } - } - pa->dietime = pa->time+pa->lifetime; - pa->flag &= ~PARS_UNEXIST; - } - for(; p<totpart; p++, pa++){ - pa->flag |= PARS_UNEXIST; + pa->dietime = pa->time+pa->lifetime; + pa->flag &= ~PARS_UNEXIST; + } + for(; p<totpart; p++, pa++){ + pa->flag |= PARS_UNEXIST; + } } } } @@ -4416,6 +4433,105 @@ static void cached_step(Object *ob, ParticleSystemModifierData *psmd, ParticleSy distribute_particles(ob, psys, PART_FROM_CHILD); } } +static void particles_fluid_step(Object *ob, ParticleSystem *psys, int cfra) +{ + if(psys->particles){ + MEM_freeN(psys->particles); + psys->particles = 0; + psys->totpart = 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, 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 */ + alloc_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; + short shsize=0; + float convertSize=0.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++; + } + 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 +} /* Calculates the next state for all particles of the system */ /* In particles code most fra-ending are frames, time-ending are fra*timestep (seconds)*/ static void system_step(Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, float cfra) @@ -4435,7 +4551,7 @@ static void system_step(Object *ob, ParticleSystem *psys, ParticleSystemModifier execute_ipo((ID *)part, part->ipo); } - if(part->from!=PART_FROM_PARTICLE) + if(part->from!=PART_FROM_PARTICLE && part->type!=PART_FLUID) vg_size=psys_cache_vgroup(psmd->dm,psys,PSYS_VG_SIZE); if(part->type == PART_HAIR) { @@ -4446,6 +4562,12 @@ static void system_step(Object *ob, ParticleSystem *psys, ParticleSystemModifier return; } } + else if(part->type == PART_FLUID) { + particles_fluid_step(ob, psys, (int)cfra); + psys->cfra = cfra; + psys->recalc = 0; + return; + } else if(ELEM(part->phystype, PART_PHYS_NO, PART_PHYS_KEYED)) ; /* cache shouldn't be used for "none" or "keyed" physics */ else { diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index c8fe6387494..68e4978cf18 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -7412,6 +7412,9 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } + if(ob->fluidsimSettings && ob->fluidsimSettings->type == OB_FLUIDSIM_PARTICLE) + part->type = PART_FLUID; + free_effects(&ob->effect); printf("Old particle system converted to new system.\n"); diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h index 739cec7b9f3..b3e0e1a23e0 100644 --- a/source/blender/include/butspace.h +++ b/source/blender/include/butspace.h @@ -290,6 +290,7 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la #define B_FLUIDSIM_SELDIR 1451 #define B_FLUIDSIM_FORCEREDRAW 1452 #define B_FLUIDSIM_MAKEPART 1453 +#define B_FLUIDSIM_CHANGETYPE 1454 #define B_GROUP_RELINK 1460 #define B_OBJECT_IPOFLAG 1461 diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h index 18dba7f398d..2203de1c862 100644 --- a/source/blender/makesdna/DNA_particle_types.h +++ b/source/blender/makesdna/DNA_particle_types.h @@ -221,6 +221,7 @@ typedef struct ParticleSystem{ #define PART_EMITTER 0 #define PART_REACTOR 1 #define PART_HAIR 2 +#define PART_FLUID 3 /* part->flag */ #define PART_REACT_STA_END 1 diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 8080798c91f..144b266759d 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -1655,6 +1655,13 @@ void modifiers_explodeFacepa(void *arg1, void *arg2) emd->flag |= eExplodeFlag_CalcFaces; } +static int modifier_is_fluid_particles(ModifierData *md) { + if(md->type == eModifierType_ParticleSystem) { + if(((ParticleSystemModifierData *)md)->psys->part->type == PART_FLUID) + return 1; + } + return 0; +} static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco, int *yco, int index, int cageIndex, int lastCageIndex) { ModifierTypeInfo *mti = modifierType_getInfo(md->type); @@ -1732,7 +1739,8 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco uiBlockSetEmboss(block, UI_EMBOSSN); // deletion over the deflection panel - if(md->type!=eModifierType_Collision) + // fluid particle modifier can't be deleted here + if(md->type!=eModifierType_Collision && !modifier_is_fluid_particles(md)) { but = uiDefIconBut(block, BUT, B_MODIFIER_RECALC, VICON_X, x+width-70+40, y, 16, 16, NULL, 0.0, 0.0, 0.0, 0.0, "Delete modifier"); uiButSetFunc(but, modifiers_del, ob, md); diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index 1764e7de580..bdfa3b10969 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -2307,28 +2307,56 @@ void do_object_panels(unsigned short event) fluidsimBake(ob); break; case B_FLUIDSIM_MAKEPART: - { - PartEff *paf= NULL; - /* prepare fluidsim particle display */ - // simplified delete effect, create new - recalc some particles... - if(ob==NULL || ob->type!=OB_MESH) break; - ob->fluidsimSettings->type = 0; - // reset type, and init particle system once normally - paf= give_parteff(ob); - if( (BLI_countlist(&ob->effect)<MAX_EFFECT) && - (!paf)) { - // create new entry - copy_act_effect(ob); DAG_scene_sort(G.scene); } - paf = give_parteff(ob); - if(paf) { - paf->totpart = 1000; paf->sta = paf->end = 1.0; // generate some particles... - build_particle_system(ob); - ob->fluidsimSettings->type = OB_FLUIDSIM_PARTICLE; - } + if(ob==NULL || ob->type!=OB_MESH) break; + else { + ParticleSettings *part = psys_new_settings("PSys", G.main); + ParticleSystem *psys = MEM_callocN(sizeof(ParticleSystem), "particle_system"); + ModifierData *md; + ParticleSystemModifierData *psmd; + + part->type = PART_FLUID; + psys->part = part; + psys->flag |= PSYS_ENABLED; + + ob->fluidsimSettings->type = OB_FLUIDSIM_PARTICLE; + + BLI_addtail(&ob->particlesystem,psys); + + md= modifier_new(eModifierType_ParticleSystem); + sprintf(md->name, "FluidParticleSystem", BLI_countlist(&ob->particlesystem)); + psmd= (ParticleSystemModifierData*) md; + psmd->psys=psys; + BLI_addtail(&ob->modifiers, md); } allqueue(REDRAWVIEW3D, 0); allqueue(REDRAWBUTSOBJECT, 0); break; + case B_FLUIDSIM_CHANGETYPE: + if(ob && ob->particlesystem.first && ob->fluidsimSettings->type!=OB_FLUIDSIM_PARTICLE){ + ParticleSystem *psys; + for(psys=ob->particlesystem.first; psys; psys=psys->next) { + if(psys->part->type==PART_FLUID) { + /* clear modifier */ + ParticleSystemModifierData *psmd= psys_get_modifier(ob,psys); + BLI_remlink(&ob->modifiers, psmd); + modifier_free((ModifierData *)psmd); + + /* clear particle system */ + BLI_remlink(&ob->particlesystem,psys); + psys_free(ob,psys); + + BIF_undo_push("Delete particle system"); + + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWOOPS, 0); + break; + } + } + } + allqueue(REDRAWBUTSOBJECT, 0); + break; case B_FLUIDSIM_SELDIR: { ScrArea *sa = closest_bigger_area(); @@ -2966,6 +2994,7 @@ void do_effects_panels(unsigned short event) nr++; idtest= idtest->next; } + if(idtest==0) { /* new particle system */ if(id){ idtest= (ID *)psys_copy_settings((ParticleSettings *)id); @@ -2975,6 +3004,11 @@ void do_effects_panels(unsigned short event) } idtest->us--; } + else if(((ParticleSettings*)idtest)->type==PART_FLUID) { + error("Can't select fluid particles"); + break; + } + if(idtest!=id) { short nr=0; if(id==0){ /* no psys previously -> no modifier -> need to create that also */ @@ -3991,6 +4025,11 @@ static void object_panel_particle_children(Object *ob) if(uiNewPanel(curarea, block, "Children", "Particle", 1300, 0, 318, 204)==0) return; uiNewPanelTabbed("Extras", "Particle"); + if(part->type == PART_FLUID) { + uiDefBut(block, LABEL, 0, "No settings for fluid particles", butx,(buty-=2*buth),2*butw,buth, NULL, 0.0, 0, 0, 0, ""); + return; + } + uiDefButS(block, MENU, B_PART_ALLOC_CHILD, "Children from:%t|Faces%x2|Particles%x1|None%x0", butx,buty,butw,buth, &part->childtype, 14.0, 0.0, 0, 0, "Create child particles"); if(part->childtype==0) return; @@ -4141,6 +4180,11 @@ static void object_panel_particle_extra(Object *ob) block= uiNewBlock(&curarea->uiblocks, "object_panel_particle_extra", UI_EMBOSS, UI_HELV, curarea->win); if(uiNewPanel(curarea, block, "Extras", "Particle", 980, 0, 318, 204)==0) return; + if(part->type == PART_FLUID) { + uiDefBut(block, LABEL, 0, "No settings for fluid particles", butx,(buty-=2*buth),2*butw,buth, NULL, 0.0, 0, 0, 0, ""); + return; + } + uiDefBut(block, LABEL, 0, "Effectors:", butx,buty,butw,buth, NULL, 0.0, 0, 0, 0, ""); uiBlockBeginAlign(block); uiDefIDPoinBut(block, test_grouppoin_but, ID_GR, B_PART_RECALC, "GR:", butx, (buty-=buth), butw/2, buth, &part->eff_group, "Limit effectors to this Group"); @@ -4432,6 +4476,11 @@ static void object_panel_particle_physics(Object *ob) block= uiNewBlock(&curarea->uiblocks, "object_panel_particle_physics", UI_EMBOSS, UI_HELV, curarea->win); if(uiNewPanel(curarea, block, "Physics", "Particle", 320, 0, 318, 204)==0) return; + if(part->type == PART_FLUID) { + uiDefBut(block, LABEL, 0, "No settings for fluid particles", butx,(buty-=2*buth),2*butw,buth, NULL, 0.0, 0, 0, 0, ""); + return; + } + if(ob->id.lib) uiSetButLock(1, "Can't edit library data"); if(psys->flag & PSYS_EDITED || psys->flag & PSYS_PROTECT_CACHE) { @@ -4622,10 +4671,12 @@ static void object_panel_particle_system(Object *ob) id=NULL; idfrom=&ob->id; + if(psys==0 || psys->part->type != PART_FLUID) { /* browse buttons */ - uiBlockSetCol(block, TH_BUT_SETTING2); - butx= std_libbuttons(block, butx, buty, 0, NULL, B_PARTBROWSE, ID_PA, 0, id, idfrom, &(G.buts->menunr), B_PARTALONE, 0, B_PARTDELETE, 0, 0); - + uiBlockSetCol(block, TH_BUT_SETTING2); + butx= std_libbuttons(block, butx, buty, 0, NULL, B_PARTBROWSE, ID_PA, 0, id, idfrom, &(G.buts->menunr), B_PARTALONE, 0, B_PARTDELETE, 0, 0); + } + uiBlockSetCol(block, TH_AUTO); partact=psys_get_current_num(ob)+1; @@ -4639,12 +4690,19 @@ static void object_panel_particle_system(Object *ob) part=psys->part; - if(part==NULL) return; + if(part==NULL) + return; butx=0; buty-=5; - - uiDefButBitI(block, TOG, PSYS_ENABLED, B_PART_ENABLE, "Enabled", 0,(buty-=buth),100,buth, &psys->flag, 0, 0, 0, 0, "Sets particle system to be calculated and shown"); + + if(part->type == PART_FLUID) { + uiDefButBitI(block, TOG, PSYS_ENABLED, B_PART_ENABLE, "Enabled", 0, buty+5, 100,buth, &psys->flag, 0, 0, 0, 0, "Sets particle system to be calculated and shown"); + uiDefBut(block, LABEL, 0, "No settings for fluid particles", butx,(buty-=2*buth),2*butw,buth, NULL, 0.0, 0, 0, 0, ""); + return; + } + else + uiDefButBitI(block, TOG, PSYS_ENABLED, B_PART_ENABLE, "Enabled", 0,(buty-=buth),100,buth, &psys->flag, 0, 0, 0, 0, "Sets particle system to be calculated and shown"); if(part->type == PART_HAIR){ if(psys->flag & PSYS_EDITED) @@ -4806,13 +4864,13 @@ static void object_panel_fluidsim(Object *ob) } uiBlockBeginAlign(block); - uiDefButS(block, ROW, REDRAWBUTSOBJECT ,"Domain", 90, yline, 70,objHeight, &fss->type, 15.0, OB_FLUIDSIM_DOMAIN, 20.0, 1.0, "Bounding box of this object represents the computational domain of the fluid simulation."); - uiDefButS(block, ROW, REDRAWBUTSOBJECT ,"Fluid", 160, yline, 70,objHeight, &fss->type, 15.0, OB_FLUIDSIM_FLUID, 20.0, 2.0, "Object represents a volume of fluid in the simulation."); - uiDefButS(block, ROW, REDRAWBUTSOBJECT ,"Obstacle", 230, yline, 70,objHeight, &fss->type, 15.0, OB_FLUIDSIM_OBSTACLE,20.0, 3.0, "Object is a fixed obstacle."); + uiDefButS(block, ROW, B_FLUIDSIM_CHANGETYPE ,"Domain", 90, yline, 70,objHeight, &fss->type, 15.0, OB_FLUIDSIM_DOMAIN, 20.0, 1.0, "Bounding box of this object represents the computational domain of the fluid simulation."); + uiDefButS(block, ROW, B_FLUIDSIM_CHANGETYPE ,"Fluid", 160, yline, 70,objHeight, &fss->type, 15.0, OB_FLUIDSIM_FLUID, 20.0, 2.0, "Object represents a volume of fluid in the simulation."); + uiDefButS(block, ROW, B_FLUIDSIM_CHANGETYPE ,"Obstacle", 230, yline, 70,objHeight, &fss->type, 15.0, OB_FLUIDSIM_OBSTACLE,20.0, 3.0, "Object is a fixed obstacle."); yline -= lineHeight; - uiDefButS(block, ROW, REDRAWBUTSOBJECT ,"Inflow", 90, yline, 70,objHeight, &fss->type, 15.0, OB_FLUIDSIM_INFLOW, 20.0, 4.0, "Object adds fluid to the simulation."); - uiDefButS(block, ROW, REDRAWBUTSOBJECT ,"Outflow", 160, yline, 70,objHeight, &fss->type, 15.0, OB_FLUIDSIM_OUTFLOW, 20.0, 5.0, "Object removes fluid from the simulation."); + uiDefButS(block, ROW, B_FLUIDSIM_CHANGETYPE ,"Inflow", 90, yline, 70,objHeight, &fss->type, 15.0, OB_FLUIDSIM_INFLOW, 20.0, 4.0, "Object adds fluid to the simulation."); + uiDefButS(block, ROW, B_FLUIDSIM_CHANGETYPE ,"Outflow", 160, yline, 70,objHeight, &fss->type, 15.0, OB_FLUIDSIM_OUTFLOW, 20.0, 5.0, "Object removes fluid from the simulation."); uiDefButS(block, ROW, B_FLUIDSIM_MAKEPART ,"Particle", 230, yline, 70,objHeight, &fss->type, 15.0, OB_FLUIDSIM_PARTICLE,20.0, 3.0, "Object is made a particle system to display particles generated by a fluidsim domain object."); uiBlockEndAlign(block); yline -= lineHeight; |