First new particle code:

-Many things not yet working properly :)
-Experimental new (hopefully more logical) categorization of buttons, feedback on this is very welcome.
-Separate render & draw types, for example now there is actually a render option "halo" instead of all the different point draw types.
-Particles get recalculated only from buttons that actually change something that has to be recalculated, for example changing visualization doesn't reset particles any more.
-Boid physics buttons are still missing as I'm currently redoing the whole boids code.
-Point caching is still very wip, so baking is not possible for example, but I added a few cache baking flags for rna that were/will be needed for particle buttons logic.
This commit is contained in:
Janne Karhu 2009-06-05 23:59:33 +00:00
parent 8cea65a323
commit 880c43ad5a
16 changed files with 996 additions and 129 deletions

View File

@ -1,25 +1,589 @@
import bpy
def particle_panel_enabled(psys):
return psys.point_cache.baked==False and psys.editable==False
def particle_panel_poll(context):
psys = context.particle_system
type = psys.settings.type
return psys != None and (type=='EMITTER' or type=='REACTOR'or type=='HAIR')
class ParticleButtonsPanel(bpy.types.Panel):
__space_type__ = "BUTTONS_WINDOW"
__region_type__ = "WINDOW"
__context__ = "particle"
def poll(self, context):
return (context.particle_system != None)
psys = context.particle_system
type = psys.settings.type
return psys != None and (type=='EMITTER' or type=='REACTOR'or type=='HAIR')
class PARTICLE_PT_particles(ParticleButtonsPanel):
__idname__= "PARTICLE_PT_particles"
__label__ = "Particles"
__label__ = "ParticleSystem"
def poll(self, context):
return (context.particle_system != None)
def draw(self, context):
layout = self.layout
psys = context.particle_system
part = psys.settings
#row = layout.row()
#row.itemL(text="Particle system datablock")
#row.itemL(text="Viewport")
#row.itemL(text="Render")
type = psys.settings.type
if(type!='EMITTER' and type!='REACTOR' and type!='HAIR'):
layout.itemL(text="No settings for fluid particles")
return
row = layout.row()
row.enabled = particle_panel_enabled(psys)
row.itemR(part, "type")
row.itemR(psys, "seed")
row = layout.row()
if part.type=='HAIR':
if psys.editable==True:
row.itemO("PARTICLE_OT_editable_set", text="Free Edit")
else:
row.itemO("PARTICLE_OT_editable_set", text="Make Editable")
subrow = row.row()
subrow.enabled = particle_panel_enabled(psys)
subrow.itemR(part, "hair_step")
elif part.type=='REACTOR':
row.itemR(psys, "reactor_target_object")
row.itemR(psys, "reactor_target_particle_system", text="Particle System")
class PARTICLE_PT_emission(ParticleButtonsPanel):
__idname__= "PARTICLE_PT_emission"
__label__ = "Emission"
def draw(self, context):
layout = self.layout
psys = context.particle_system
part = psys.settings
layout.enabled = particle_panel_enabled(psys)
row = layout.row()
#col.itemL(text="TODO: Rate instead of amount")
row.itemR(part, "amount")
row.itemL(text="")
split = layout.split()
col = split.column(align=True)
col.itemR(part, "start")
col.itemR(part, "end")
col = split.column(align=True)
col.itemR(part, "lifetime")
col.itemR(part, "random_lifetime", slider=True)
class PARTICLE_PT_cache(ParticleButtonsPanel):
__idname__= "PARTICLE_PT_cache"
__label__ = "Cache"
def poll(self, context):
psys = context.particle_system
type = psys.settings.type
return psys != None and (type=='EMITTER' or type== 'REACTOR')
def draw(self, context):
layout = self.layout
psys = context.particle_system
part = psys.settings
cache = psys.point_cache
#if cache.baked==True:
#layout.itemO("PARTICLE_OT_free_bake", text="BAKE")
#else:
row = layout.row()
#row.itemO("PARTICLE_OT_bake", text="BAKE")
row.itemR(cache, "start_frame")
row.itemR(cache, "end_frame")
#layout.row().itemL(text="No simulation frames in disk cache.")
class PARTICLE_PT_initial(ParticleButtonsPanel):
__idname__= "PARTICLE_PT_initial"
__label__ = "Initial values"
layout.itemR(part, "amount")
def draw(self, context):
layout = self.layout
psys = context.particle_system
part = psys.settings
layout.enabled = particle_panel_enabled(psys)
layout.row().itemL(text="Location from:")
box = layout.box()
row = box.row()
row.itemR(part, "trand")
col = row.column()
col.row().itemR(part, "emit_from", expand=True)
if part.emit_from=='FACE' or part.emit_from=='VOLUME':
row = box.row()
if part.distribution!='GRID':
row.itemR(part, "even_distribution")
else:
row.itemL(text="")
row.itemR(part, "distribution", expand=True)
row = box.row()
if part.distribution=='JIT':
row.itemR(part, "userjit", text="Particles/Face")
row.itemR(part, "jitter_factor", text="Jittering Amount", slider=True)
elif part.distribution=='GRID':
row.itemR(part, "grid_resolution")
#layout.row().itemL(text="")
layout.row().itemL(text="Velocity:")
box = layout.box()
row = box.row()
col = row.column()
col.itemR(part, "normal_factor")
if part.emit_from=='PARTICLE':
col.itemR(part, "particle_factor")
else:
col.itemR(part, "object_factor", slider=True)
col.itemR(part, "random_factor")
col = row.column(align=True)
col.itemL(text="TODO:")
col.itemL(text="Object aligned")
col.itemL(text="direction: X, Y, Z")
row = box.row()
col = row.column(align=True)
col.itemR(part, "tangent_factor")
col.itemR(part, "tangent_phase", slider=True)
col = row.column(align=True)
if part.type=='REACTOR':
col.itemR(part, "reactor_factor")
col.itemR(part, "reaction_shape", slider=True)
else:
col.itemL(text="")
layout.row().itemL(text="Rotation:")
box = layout.box()
box.row().itemR(part, "rotation_dynamic")
row = box.row()
col = row.column(align=True)
col.itemR(part, "rotation_mode", text="")
col.itemR(part, "random_rotation_factor", slider=True)
col = row.column(align=True)
col.itemR(part, "phase_factor", slider=True)
col.itemR(part, "random_phase_factor", text="Random", slider=True)
layout.row().itemL(text="Angular velocity:")
box = layout.box()
row = box.row()
row.itemR(part, "angular_velocity_mode", expand=True)
row.itemR(part, "angular_velocity_factor", text="")
class PARTICLE_PT_physics(ParticleButtonsPanel):
__idname__= "PARTICLE_PT_physics"
__label__ = "Physics"
def draw(self, context):
layout = self.layout
psys = context.particle_system
part = psys.settings
layout.enabled = layout.enabled = particle_panel_enabled(psys)
layout.itemR(part, "effector_group")
layout.itemL(text="General:")
box = layout.box()
row = box.row()
col = row.column(align=True)
col.itemR(part, "particle_size")
col.itemR(part, "random_size", slider=True)
col = row.column(align=True)
col.itemR(part, "mass")
col.itemR(part, "sizemass", text="Multiply mass with size")
layout.row().itemL(text="")
row = layout.row()
row.itemL(text="Physics Type:")
row.itemR(part, "physics_type", expand=True)
if part.physics_type != 'NO':
box = layout.box()
row = box.row()
if part.physics_type == 'NEWTON':
row.itemR(part, "integrator")
row = box.row()
col = row.column(align=True)
col.itemL(text="Forces:")
col.itemR(part, "brownian_factor")
col.itemR(part, "drag_factor", slider=True)
col.itemR(part, "damp_factor", slider=True)
row.column().itemR(part, "acceleration")
elif part.physics_type == 'KEYED':
row.itemR(psys, "keyed_first")
if psys.keyed_first==True:
row.itemR(psys, "timed_keys", text="Key timing")
else:
row.itemR(part, "keyed_time")
row = box.row()
row.itemL(text="Next key from object:")
row.itemR(psys, "keyed_object", text="")
row.itemR(psys, "keyed_particle_system")
if part.physics_type=='NEWTON' or part.physics_type=='BOIDS':
row = box.row()
row.itemR(part, "size_deflect")
row.itemR(part, "die_on_collision")
row.itemR(part, "sticky")
class PARTICLE_PT_render(ParticleButtonsPanel):
__idname__= "PARTICLE_PT_render"
__label__ = "Render"
def poll(self, context):
return (context.particle_system != None)
def draw(self, context):
layout = self.layout
psys = context.particle_system
part = psys.settings
row = layout.row()
row.itemR(part, "material")
col = row.column()
col.itemR(part, "emitter");
col.itemR(part, "parent");
col = row.column()
col.itemR(part, "unborn");
col.itemR(part, "died");
row = layout.row()
row.itemR(part, "ren_as", expand=True)
row = layout.row(align=True)
if part.ren_as == 'LINE':
row.itemR(part, "line_length_tail")
row.itemR(part, "line_length_head")
row.itemR(part, "velocity_length")
elif part.ren_as == 'PATH':
if (part.type!='HAIR' and psys.point_cache.baked==False):
box = layout.box()
box.itemL(text="Baked or keyed particles needed for correct rendering.")
return
row.itemR(part, "hair_bspline")
row.itemR(part, "render_step", text="Steps")
row = layout.row()
row.itemR(part, "abs_length")
col = row.column(align=True)
col.itemR(part, "absolute_length")
col.itemR(part, "random_length", slider=True)
#row = layout.row()
#row.itemR(part, "timed_path")
#col = row.column(align=True)
#col.active = part.timed_path == True
#col.itemR(part, "line_length_tail", text="Start")
#col.itemR(part, "line_length_head", text="End")
row = layout.row()
col = row.column()
col.itemR(part, "render_strand")
subrow = col.row()
subrow.active = part.render_strand == False
subrow.itemR(part, "render_adaptive")
col = row.column(align=True)
subrow = col.row()
subrow.active = part.render_adaptive or part.render_strand == True
subrow.itemR(part, "adaptive_angle")
subrow = col.row()
subrow.active = part.render_adaptive == True and part.render_strand == False
subrow.itemR(part, "adaptive_pix")
if part.type=='HAIR' and part.render_strand==True and part.child_type=='FACES':
layout.itemR(part, "enable_simplify")
if part.enable_simplify==True:
box = layout.box()
row = box.row()
row.itemR(part, "simplify_refsize")
row.itemR(part, "simplify_rate")
row.itemR(part, "simplify_transition")
row = box.row()
row.itemR(part, "viewport")
subrow = row.row()
subrow.active = part.viewport==True
subrow.itemR(part, "simplify_viewport")
elif part.ren_as == 'OBJECT':
row.itemR(part, "dupli_object")
elif part.ren_as == 'GROUP':
split = layout.split()
col = split.column()
row = col.row()
row.itemR(part, "whole_group")
subcol = row.column()
subcol.active = part.whole_group == False
subcol.itemR(part, "rand_group")
split.column().itemR(part, "dupli_group", text="")
elif part.ren_as == 'BILLBOARD':
row.itemL(text="Align:")
row.itemR(part, "billboard_lock", text="Lock")
row = layout.row()
row.itemR(part, "billboard_align", expand=True)
row = layout.row()
row.itemR(part, "billboard_object")
row = layout.row()
col = row.column(align=True)
col.itemL(text="Tilt:")
col.itemR(part, "billboard_tilt", text="Angle", slider=True)
col.itemR(part, "billboard_random_tilt", slider=True)
col = row.column()
col.itemR(part, "billboard_offset")
row = layout.row()
row.itemR(psys, "billboard_normal_uv")
row = layout.row()
row.itemR(psys, "billboard_time_index_uv")
row = layout.row()
row.itemL(text="Split uv's:")
row.itemR(part, "billboard_uv_split", text="Number of splits")
row = layout.row()
row.itemR(psys, "billboard_split_uv")
row = layout.row()
row.itemL(text="Animate:")
row.itemR(part, "billboard_animation", expand=True)
row.itemL(text="Offset:")
row.itemR(part, "billboard_split_offset", expand=True)
class PARTICLE_PT_draw(ParticleButtonsPanel):
__idname__= "PARTICLE_PT_draw"
__label__ = "Draw"
def poll(self, context):
return (context.particle_system != None)
def draw(self, context):
layout = self.layout
psys = context.particle_system
part = psys.settings
row = layout.row()
row.itemR(part, "draw_as", expand=True)
if part.draw_as=='NONE' or (part.ren_as=='NONE' and part.draw_as=='RENDER'):
return
path = (part.ren_as=='PATH' and part.draw_as=='RENDER') or part.draw_as=='PATH'
if path and part.type!='HAIR' and psys.point_cache.baked==False:
box = layout.box()
box.itemL(text="Baked or keyed particles needed for correct drawing.")
return
row = layout.row()
row.itemR(part, "display", slider=True)
if part.draw_as!='RENDER' or part.ren_as=='HALO':
row.itemR(part, "draw_size")
else:
row.itemL(text="")
row = layout.row()
col = row.column()
col.itemR(part, "show_size")
col.itemR(part, "velocity")
col.itemR(part, "num")
if part.physics_type == 'BOIDS':
col.itemR(part, "draw_health")
col = row.column()
if (path):
box = col.box()
box.itemR(part, "draw_step")
else:
col.itemR(part, "material_color", text="Use material color")
subcol = col.column()
subcol.active = part.material_color==False
#subcol.itemL(text="color")
#subcol.itemL(text="Override material color")
class PARTICLE_PT_children(ParticleButtonsPanel):
__idname__= "PARTICLE_PT_children"
__label__ = "Children"
def draw(self, context):
layout = self.layout
psys = context.particle_system
part = psys.settings
layout.row().itemR(part, "child_type", expand=True)
if part.child_type=='NONE':
return
row = layout.row()
col = row.column(align=True)
col.itemR(part, "child_nbr", text="Draw")
col.itemR(part, "rendered_child_nbr", text="Render")
col = row.column(align=True)
if part.child_type=='FACES':
col.itemR(part, "virtual_parents", slider=True)
else:
col.itemR(part, "child_radius", text="Radius")
col.itemR(part, "child_roundness", text="Roundness", slider=True)
col = row.column(align=True)
col.itemR(part, "child_size", text="Size")
col.itemR(part, "child_random_size", text="Random")
layout.row().itemL(text="Effects:")
row = layout.row()
col = row.column(align=True)
col.itemR(part, "clump_factor", slider=True)
col.itemR(part, "clumppow", slider=True)
col = row.column(align=True)
col.itemR(part, "rough_endpoint")
col.itemR(part, "rough_end_shape")
row = layout.row()
col = row.column(align=True)
col.itemR(part, "rough1")
col.itemR(part, "rough1_size")
col = row.column(align=True)
col.itemR(part, "rough2")
col.itemR(part, "rough2_size")
col.itemR(part, "rough2_thres", slider=True)
layout.row().itemL(text="Kink:")
layout.row().itemR(part, "kink", expand=True)
row = layout.row()
row.itemR(part, "kink_amplitude")
row.itemR(part, "kink_frequency")
row.itemR(part, "kink_shape", slider=True)
class PARTICLE_PT_vertexgroups(ParticleButtonsPanel):
__idname__= "PARTICLE_PT_vertexgroups"
__label__ = "Vertexgroups"
def draw(self, context):
layout = self.layout
psys = context.particle_system
part = psys.settings
layout.itemL(text="Nothing here yet.")
#row = layout.row()
#row.itemL(text="Vertex Group")
#row.itemL(text="Negate")
#row = layout.row()
#row.itemR(psys, "vertex_group_density")
#row.itemR(psys, "vertex_group_density_negate", text="")
#row = layout.row()
#row.itemR(psys, "vertex_group_velocity")
#row.itemR(psys, "vertex_group_velocity_negate", text="")
#row = layout.row()
#row.itemR(psys, "vertex_group_length")
#row.itemR(psys, "vertex_group_length_negate", text="")
#row = layout.row()
#row.itemR(psys, "vertex_group_clump")
#row.itemR(psys, "vertex_group_clump_negate", text="")
#row = layout.row()
#row.itemR(psys, "vertex_group_kink")
#row.itemR(psys, "vertex_group_kink_negate", text="")
#row = layout.row()
#row.itemR(psys, "vertex_group_roughness1")
#row.itemR(psys, "vertex_group_roughness1_negate", text="")
#row = layout.row()
#row.itemR(psys, "vertex_group_roughness2")
#row.itemR(psys, "vertex_group_roughness2_negate", text="")
#row = layout.row()
#row.itemR(psys, "vertex_group_roughness_end")
#row.itemR(psys, "vertex_group_roughness_end_negate", text="")
#row = layout.row()
#row.itemR(psys, "vertex_group_size")
#row.itemR(psys, "vertex_group_size_negate", text="")
#row = layout.row()
#row.itemR(psys, "vertex_group_tangent")
#row.itemR(psys, "vertex_group_tangent_negate", text="")
#row = layout.row()
#row.itemR(psys, "vertex_group_rotation")
#row.itemR(psys, "vertex_group_rotation_negate", text="")
#row = layout.row()
#row.itemR(psys, "vertex_group_field")
#row.itemR(psys, "vertex_group_field_negate", text="")
bpy.types.register(PARTICLE_PT_particles)
bpy.types.register(PARTICLE_PT_cache)
bpy.types.register(PARTICLE_PT_emission)
bpy.types.register(PARTICLE_PT_initial)
bpy.types.register(PARTICLE_PT_physics)
bpy.types.register(PARTICLE_PT_render)
bpy.types.register(PARTICLE_PT_draw)
bpy.types.register(PARTICLE_PT_children)
bpy.types.register(PARTICLE_PT_vertexgroups)

View File

@ -251,7 +251,7 @@ struct ParticleSystemModifierData *psys_get_modifier(struct Object *ob, struct P
struct ParticleSettings *psys_new_settings(char *name, struct Main *main);
struct ParticleSettings *psys_copy_settings(struct ParticleSettings *part);
void psys_flush_settings(struct Scene *scene, struct ParticleSettings *part, int event, int hair_recalc);
void psys_flush_particle_settings(struct Scene *scene, struct ParticleSettings *part, int recalc);
void make_local_particlesettings(struct ParticleSettings *part);
struct LinkNode *psys_using_settings(struct Scene *scene, struct ParticleSettings *part, int flush_update);

View File

@ -6347,8 +6347,7 @@ static void particleSystemModifier_deformVerts(
psmd->dm->getNumFaces(psmd->dm)!=psmd->totdmface){
/* in file read dm hasn't really changed but just wasn't saved in file */
psys->recalc |= PSYS_RECALC_HAIR;
psys->recalc |= PSYS_DISTR;
psys->recalc |= PSYS_RECALC_RESET;
psmd->flag |= eParticleSystemFlag_DM_changed;
psmd->totdmvert= psmd->dm->getNumVerts(psmd->dm);

View File

@ -348,8 +348,17 @@ void free_hair(ParticleSystem *psys, int softbody)
}
void free_keyed_keys(ParticleSystem *psys)
{
if(psys->particles && psys->particles->keys)
if(psys->particles && psys->particles->keys) {
ParticleData *pa;
int i, totpart=psys->totpart;
MEM_freeN(psys->particles->keys);
for(i=0, pa=psys->particles; i<totpart; i++,pa++){
pa->keys = NULL;
pa->totkey = 0;
}
}
}
void free_child_path_cache(ParticleSystem *psys)
{
@ -1739,12 +1748,12 @@ static void do_path_effectors(Scene *scene, Object *ob, ParticleSystem *psys, in
Normalize(force);
VECADDFAC(ca->co, (ca-1)->co, force, *length);
if(k < steps) {
VecSubf(vec, (ca+1)->co, ca->co);
*length = VecLength(vec);
}
VECADDFAC(ca->co, (ca-1)->co, force, *length);
}
static int check_path_length(int k, ParticleCacheKey *keys, ParticleCacheKey *state, float max_length, float *cur_length, float length, float *dvec)
{
@ -3052,42 +3061,22 @@ void make_local_particlesettings(ParticleSettings *part)
}
}
/* should be integrated to depgraph signals */
void psys_flush_settings(struct Scene *scene, ParticleSettings *part, int event, int hair_recalc)
void psys_flush_particle_settings(Scene *scene, ParticleSettings *part, int recalc)
{
Base *base;
Object *ob, *tob;
Base *base = scene->base.first;
ParticleSystem *psys;
int flush;
/* update all that have same particle settings */
for(base = scene->base.first; base; base= base->next) {
if(base->object->particlesystem.first) {
ob=base->object;
flush=0;
for(psys=ob->particlesystem.first; psys; psys=psys->next){
if(psys->part==part){
psys->recalc |= event;
if(hair_recalc)
psys->recalc |= PSYS_RECALC_HAIR;
flush++;
}
else if(psys->part->type==PART_REACTOR){
ParticleSystem *tpsys;
tob=psys->target_ob;
if(tob==0)
tob=ob;
tpsys=BLI_findlink(&tob->particlesystem,psys->target_psys-1);
if(tpsys && tpsys->part==part){
psys->recalc |= event;
flush++;
}
}
for(base = scene->base.first; base; base = base->next) {
flush = 0;
for(psys = base->object->particlesystem.first; psys; psys=psys->next) {
if(psys->part == part) {
psys->recalc |= recalc;
flush++;
}
if(flush)
DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
}
if(flush)
DAG_object_flush_update(scene, base->object, OB_RECALC_DATA);
}
}

View File

@ -4173,10 +4173,10 @@ static void psys_update_path_cache(Scene *scene, Object *ob, ParticleSystemModif
ParticleEditSettings *pset=&scene->toolsettings->particle;
int distr=0,alloc=0;
if((psys->part->childtype && psys->totchild != get_psys_tot_child(scene, psys)) || psys->recalc&PSYS_ALLOC)
if((psys->part->childtype && psys->totchild != get_psys_tot_child(scene, psys)) || psys->recalc&PSYS_RECALC_RESET)
alloc=1;
if(alloc || psys->recalc&PSYS_DISTR || (psys->vgroup[PSYS_VG_DENSITY] && (G.f & G_WEIGHTPAINT)))
if(alloc || psys->recalc&PSYS_RECALC_RESET || (psys->vgroup[PSYS_VG_DENSITY] && (G.f & G_WEIGHTPAINT)))
distr=1;
if(distr){
@ -4194,8 +4194,9 @@ static void psys_update_path_cache(Scene *scene, Object *ob, ParticleSystemModif
}
}
if((part->type==PART_HAIR || psys->flag&PSYS_KEYED) && (psys_in_edit_mode(scene, psys)
|| (part->type==PART_HAIR || part->draw_as==PART_DRAW_PATH))){
if((part->type==PART_HAIR || psys->flag&PSYS_KEYED) && ( psys_in_edit_mode(scene, psys) || (part->type==PART_HAIR
|| (part->ren_as == PART_DRAW_PATH && (part->draw_as == PART_DRAW_REND || psys->renderdata))))){
psys_cache_paths(scene, ob, psys, cfra, 0);
/* for render, child particle paths are computed on the fly */
@ -4247,7 +4248,7 @@ static void hair_step(Scene *scene, Object *ob, ParticleSystemModifierData *psmd
pa->flag &= ~PARS_NO_DISP;
}
if(psys->recalc & PSYS_DISTR)
if(psys->recalc & PSYS_RECALC_RESET)
/* need this for changing subsurf levels */
psys_calc_dmcache(ob, psmd->dm, psys);
@ -4367,16 +4368,14 @@ void psys_changed_type(ParticleSystem *psys)
psys->flag &= ~PSYS_KEYED;
if(part->type == PART_HAIR) {
part->draw_as = PART_DRAW_PATH;
part->rotfrom = PART_ROT_IINCR;
}
else {
free_hair(psys, 1);
if(ELEM4(part->ren_as, PART_DRAW_NOT, PART_DRAW_PATH, PART_DRAW_OB, PART_DRAW_GR)==0)
part->ren_as = PART_DRAW_PATH;
if(part->draw_as == PART_DRAW_PATH)
if(psys->part->phystype != PART_PHYS_KEYED)
part->draw_as = PART_DRAW_DOT;
if(ELEM3(part->draw_as, PART_DRAW_NOT, PART_DRAW_REND, PART_DRAW_PATH)==0)
part->draw_as = PART_DRAW_REND;
}
else
free_hair(psys, 1);
psys->softflag= 0;
@ -4574,7 +4573,7 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
init= 1;
}
if(psys->recalc & PSYS_DISTR) {
if(psys->recalc & PSYS_RECALC_RESET) {
distr= 1;
init= 1;
}
@ -4594,6 +4593,8 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
}
if(only_children_changed==0) {
free_keyed_keys(psys);
initialize_all_particles(ob, psys, psmd);
if(alloc)
@ -4747,8 +4748,8 @@ static void psys_to_softbody(Scene *scene, Object *ob, ParticleSystem *psys)
static int hair_needs_recalc(ParticleSystem *psys)
{
if((psys->flag & PSYS_EDITED)==0 &&
((psys->flag & PSYS_HAIR_DONE)==0 || psys->recalc & PSYS_RECALC_HAIR)) {
psys->recalc &= ~PSYS_RECALC_HAIR;
((psys->flag & PSYS_HAIR_DONE)==0 || psys->recalc & PSYS_RECALC_REDO)) {
psys->recalc &= ~PSYS_RECALC_REDO;
return 1;
}
@ -4778,6 +4779,9 @@ void particle_system_update(Scene *scene, Object *ob, ParticleSystem *psys)
if(!psmd->dm)
return;
if(psys->recalc & PSYS_RECALC_TYPE)
psys_changed_type(psys);
/* (re-)create hair */
if(psys->part->type==PART_HAIR && hair_needs_recalc(psys)) {
float hcfra=0.0f;

View File

@ -492,6 +492,8 @@ int BKE_ptcache_object_reset(Object *ob, int mode)
else
skip = 1;
}
else if((psys->recalc & PSYS_RECALC_RESET)==0)
skip = 1;
if(skip == 0) {
BKE_ptcache_id_from_particles(&pid, ob, psys);

View File

@ -8406,7 +8406,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
part->draw_as = PART_DRAW_PATH;
part->type = PART_HAIR;
psys->recalc |= PSYS_RECALC_HAIR;
psys->recalc |= PSYS_RECALC_REDO;
part->normfac *= fac;
part->randfac *= fac;
@ -8872,6 +8872,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
Mesh *me;
Scene *sce;
Tex *tx;
ParticleSettings *part;
for(screen= main->screen.first; screen; screen= screen->id.next) {
do_versions_windowmanager_2_50(screen);
@ -8913,6 +8914,23 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
for(me= main->mesh.first; me; me= me->id.next) {
me->drawflag= ME_DRAWEDGES|ME_DRAWFACES|ME_DRAWCREASES;
}
/* particle settings conversion */
for(part= main->particle.first; part; part= part->id.next) {
if(part->draw_as) {
if(part->draw_as == PART_DRAW_DOT) {
part->ren_as = PART_DRAW_HALO;
part->draw_as = PART_DRAW_REND;
}
else if(part->draw_as <= PART_DRAW_AXIS) {
part->ren_as = PART_DRAW_HALO;
}
else {
part->ren_as = part->draw_as;
part->draw_as = PART_DRAW_REND;
}
}
}
}
/* TODO: should be moved into one of the version blocks once this branch moves to trunk and we can

View File

@ -3759,7 +3759,7 @@ static int set_editable_exec(bContext *C, wmOperator *op)
PE_free_particle_edit(psys);
psys->flag &= ~PSYS_EDITED;
psys->recalc |= PSYS_RECALC_HAIR;
psys->recalc |= PSYS_RECALC_RESET;
DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
}

View File

@ -1274,7 +1274,7 @@ static void wpaint_exit(bContext *C, wmOperator *op)
for(psys= ob->particlesystem.first; psys; psys= psys->next) {
for(i=0; i<PSYS_TOT_VG; i++) {
if(psys->vgroup[i]==ob->actdef) {
psys->recalc |= PSYS_RECALC_HAIR;
psys->recalc |= PSYS_RECALC_RESET;
break;
}
}

View File

@ -3042,7 +3042,11 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
}
totpart=psys->totpart;
draw_as=part->draw_as;
if(part->draw_as==PART_DRAW_REND)
draw_as = part->ren_as;
else
draw_as = part->draw_as;
if(part->flag&PART_GLOB_TIME)
cfra=bsystem_time(scene, 0, (float)CFRA, 0.0f);
@ -3489,7 +3493,6 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
glColorPointer(3, GL_FLOAT, 0, cdata);
}
/* draw created data arrays */
switch(draw_as){
case PART_DRAW_AXIS:

View File

@ -395,6 +395,7 @@ static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn)
case ND_MODIFIER:
case ND_CONSTRAINT:
case ND_KEYS:
case ND_PARTICLE:
ED_region_tag_redraw(ar);
break;
}

View File

@ -106,6 +106,7 @@ typedef struct ParticleSettings {
/* physics modes */
short phystype, rotmode, avemode, reactevent;
short draw, draw_as, draw_size, childtype;
short ren_as, rt2[3];
/* number of path segments, power of 2 except */
short draw_step, ren_step;
short hair_step, keys_step;
@ -302,12 +303,12 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in
/* part->draw */
#define PART_DRAW_VEL 1
#define PART_DRAW_ANG 2
//#define PART_DRAW_PATH_LEN 2
#define PART_DRAW_SIZE 4
#define PART_DRAW_EMITTER 8 /* render emitter also */
//#define PART_DRAW_KEYS 16 /* not used anywhere */
#define PART_DRAW_ADAPT 32
#define PART_DRAW_COS 64
//#define PART_DRAW_HEALTH 16
//#define PART_DRAW_TIMED_PATH 32
//#define PART_DRAW_CACHED_PATH 64
#define PART_DRAW_BB_LOCK 128
#define PART_DRAW_PARENT 256
#define PART_DRAW_NUM 512
@ -341,9 +342,11 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in
#define PART_BB_OFF_LINEAR 1
#define PART_BB_OFF_RANDOM 2
/* part->draw as */
/* part->draw_as */
/* part->ren_as*/
#define PART_DRAW_NOT 0
#define PART_DRAW_DOT 1
#define PART_DRAW_HALO 1
#define PART_DRAW_CIRC 2
#define PART_DRAW_CROSS 3
#define PART_DRAW_AXIS 4
@ -352,6 +355,7 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in
#define PART_DRAW_OB 7
#define PART_DRAW_GR 8
#define PART_DRAW_BB 9
#define PART_DRAW_REND 10
/* part->integrator */
#define PART_INT_EULER 0
@ -382,11 +386,10 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in
#define PART_CHILD_FACES 2
/* psys->recalc */
#define PSYS_INIT 1
#define PSYS_DISTR 2
#define PSYS_ALLOC 4
#define PSYS_TYPE 8
#define PSYS_RECALC_HAIR 16
#define PSYS_RECALC_REDO 1 /* only do pathcache etc */
#define PSYS_RECALC_RESET 2 /* reset everything including pointcache */
#define PSYS_RECALC_TYPE 4 /* handle system type change */
#define PSYS_RECALC_CHILD 16 /* only child settings changed */
/* psys->flag */
#define PSYS_CURRENT 1

View File

@ -53,6 +53,13 @@ static void rna_def_pointcache(BlenderRNA *brna)
RNA_def_property_int_sdna(prop, NULL, "endframe");
RNA_def_property_range(prop, 1, 300000);
RNA_def_property_ui_text(prop, "End", "Frame on which the simulation stops.");
/* flags */
prop= RNA_def_property(srna, "baked", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", PTCACHE_BAKED);
prop= RNA_def_property(srna, "baking", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", PTCACHE_BAKING);
}
static void rna_def_collision(BlenderRNA *brna)

File diff suppressed because it is too large Load Diff

View File

@ -1459,7 +1459,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
if(part==NULL || pars==NULL || !psys_check_enabled(ob, psys))
return 0;
if(part->draw_as==PART_DRAW_OB || part->draw_as==PART_DRAW_GR || part->draw_as==PART_DRAW_NOT)
if(part->ren_as==PART_DRAW_OB || part->ren_as==PART_DRAW_GR || part->ren_as==PART_DRAW_NOT)
return 1;
/* 2. start initialising things */
@ -1522,7 +1522,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
sd.mcol = MEM_callocN(sd.totcol * sizeof(MCol), "particle_mcols");
/* 2.2 setup billboards */
if(part->draw_as == PART_DRAW_BB) {
if(part->ren_as == PART_DRAW_BB) {
int first_uv = CustomData_get_layer_index(&psmd->dm->faceData, CD_MTFACE);
bb.uv[0] = CustomData_get_named_layer_index(&psmd->dm->faceData, CD_MTFACE, psys->bb_uvname[0]);
@ -1577,7 +1577,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
Mat3Transp(nmat);
/* 2.6 setup strand rendering */
if(part->draw_as == PART_DRAW_PATH && psys->pathcache){
if(part->ren_as == PART_DRAW_PATH && psys->pathcache){
path_nbr=(int)pow(2.0,(double) part->ren_step);
if(path_nbr) {
@ -1884,10 +1884,10 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
continue;
VECCOPY(loc,state.co);
if(part->draw_as!=PART_DRAW_BB)
if(part->ren_as!=PART_DRAW_BB)
MTC_Mat4MulVecfl(re->viewmat,loc);
switch(part->draw_as) {
switch(part->ren_as) {
case PART_DRAW_LINE:
sd.line = 1;
sd.time = 0.0f;
@ -4379,7 +4379,7 @@ static int allow_render_dupli_instance(Render *re, DupliObject *dob, Object *obd
}
for(psys=obd->particlesystem.first; psys; psys=psys->next)
if(!ELEM5(psys->part->draw_as, PART_DRAW_BB, PART_DRAW_LINE, PART_DRAW_PATH, PART_DRAW_OB, PART_DRAW_GR))
if(!ELEM5(psys->part->ren_as, PART_DRAW_BB, PART_DRAW_LINE, PART_DRAW_PATH, PART_DRAW_OB, PART_DRAW_GR))
return 0;
/* don't allow lamp, animated duplis, or radio render */
@ -4402,7 +4402,7 @@ static void dupli_render_particle_set(Render *re, Object *ob, int timeoffset, in
if(ob->transflag & OB_DUPLIPARTS) {
for(psys=ob->particlesystem.first; psys; psys=psys->next) {
if(ELEM(psys->part->draw_as, PART_DRAW_OB, PART_DRAW_GR)) {
if(ELEM(psys->part->ren_as, PART_DRAW_OB, PART_DRAW_GR)) {
if(enable)
psys_render_set(ob, psys, re->viewmat, re->winmat, re->winx, re->winy, timeoffset);
else

View File

@ -197,6 +197,7 @@ typedef struct wmNotifier {
#define ND_KEYS (24<<16)
#define ND_GEOM_DATA (25<<16)
#define ND_CONSTRAINT (26<<16)
#define ND_PARTICLE (27<<16)
/* NC_MATERIAL Material */
#define ND_SHADING (30<<16)