Animating Particle System Particle Count

Hi All,

It is well known that one of the biggest limitations to the Blender particle system is the fact that you can not animate the particle count with keyframes. But I wondered, what would happen if a script, running in an event handler, tried to make the change. Surely this would crash Blender, right…?

It looks like you can actually do this. I assumed the particle count was a read-only parameter but when I tried to write to it, it worked fine. It seems to render Ok as well. Simple testing done on Blender Internal and Cycles using the official 2.65 release of Blender, 64 bit.


import bpy

def pre_frame_change(scene):
    particle_rate = 2  #Multiplier per frame
    ob_emitter = bpy.data.objects.get('emitter')
    if ob_emitter != None:
        #print("PASSED: Emitter check.")
        if ob_emitter.particle_systems:
            #print("PASSED: Particle System check.")
            ps = ob_emitter.particle_systems[0] 
            if ps != None:
                settings = ps.settings
                fc = scene.frame_current
                settings.count = fc * particle_rate
                   
bpy.app.handlers.frame_change_pre.append(pre_frame_change)

The rate is fixed in this example, but it probably could be fetched from a custom property and actually animated so the rate could grow and shrink.

Attachments


1 Like

Here is some extended code that detects if the emitter is managing a set of keyed particles targets. If so, it will synchronize the particle count on all targets with the master particle system.


import bpy

def pre_frame_change(scene):
    particle_rate = 2  #Multiplier per frame
    fc = scene.frame_current
    new_count = 2000 + fc * particle_rate
    ob_emitter = bpy.data.objects.get('emitter_keyed')
    if ob_emitter != None:
        #print("PASSED: Emitter check.")
        if ob_emitter.particle_systems:
            #print("PASSED: Particle System check.")
            ps = ob_emitter.particle_systems[0] 
            if ps != None:
                settings = ps.settings
                settings.count = new_count
                if settings.physics_type == 'KEYED':
                    # If Keyed particles, set the target systems to match as well.
                    for t in ps.targets:
                        ob_t = t.object
                        if ob_t != None:
                            if ob_t.particle_systems:
                                if t.system <= len(ob_t.particle_systems):
                                    ndx = t.system-1
                                    t_ps = ob_t.particle_systems[ndx]
                                    settings = t_ps.settings
                                    settings.count = new_count
                                else:
                                    # Particle system index is out of range for target.
                                    pass
                        else:
                            # No need to set this target count because it is ourself.
                            pass
                   
bpy.app.handlers.frame_change_pre.append(pre_frame_change)

Here is the script essentially running in AddOn mode. I’m calling it APC.
It manages multiple emitters and adds a custom property to Particle System panel that can be keyframed.

Pull down the BLEND file and press Play. It seems to work in all modes. Hair, Emitter, Newtonian, Boids, Fluid and Keyed.

Attachments

265_addon_apc_atoms_particle_count_1a.blend (89.1 KB)


wow!!! i am looking how to uses this…
nice work!
many thanks :wink:

Hmm, i added a couple of keyframes to the larger plane so the emiiter goes from 1 to 500 then 5000 then back to 500, and changed the emit end frames to 160 frames and adjusted the animation to fit the leangth
the first 500 emit noramlly but when it goes over that keyframe the next 5000 are all (seemingly) emmitteed together and fall straight down


what would make this work better is if you could also keyframe the start value, so the additional particles begin to emit at the keyframe they are born

This is hack, so I doubt it can be improved upon because it is not supported by the API. This is just to have fun until we get node based particles.

There might be a problem going down in count.

Its a fun hack though, it looks like it will be good for recreating rainfall, starting with a few drops then a deluge tapreing off to the last few drops. there is a slight issue when the number drops but i am sure this can be disguised in the editing process. nice job :slight_smile:

Very nice! However, it goes in the direction of what I was looking for but it is not exactly what I need. It seems that this script requires to start with a particle count of at least 1. I am looking for a way to switch on the particle system at a certain frame. I saw that I one can set the start frame in the particle system but then I observe some strange behaviour at the beginning. Some of the particles are going reverse.
As a work around if this is not possible I was considering to try to connect the particles with a material and keyframe then the transparency of the material.

An easy way to do that, even with the standard particle system is to use an object based particle and simply animate the hide_render (camera icon in the outliner)of the object source on or off. This will turn off all particles in the scene at once. You can also add a blend texture as a density map to the particle system itself. This allows you to ramp up the amount of particles generated over time.

Yo guys, i always love if i find exactly the right litlle bit of code or an addon that i wanted to use, thanks for this cool litlle code! I have one ‘problem’ though.
I’ve been making a weird litlle artistic scene of a charachter used as an emmitter of thousand of litlle uv-sphere who cary the texture of the original character. (i was very hapy to find out that that all worked, when it did!) The particlesystem has newton physics with a normal of 0 and follows regular gravity. Now i used this code to make the rain of spheres become heavier and eventually also dry down. A pretty simple us of the code, i thought. But when i render it, it seems to kind of recalculate the position and amount of the spheres every frame in a way that it doesn’t follow the natural gravitational path downwards. There are many frames in between where the particles are totally out of place. So when i look at the animation it seems like it glitching a couple of times a second.

any idea how to fix this?:spin:

Does anyone know how to reach the matrix / location of each particle when KEYED is used?

I tried using emitter with object, but it doesnt return the proper location. When i use this for an external render engine all the keyed particles stick to the key emitter?

Example of the render

Example of the 3d viewport

This is the code for getting the matrix of each particle using object. This doesnt work for keyed objects though

if psys.settings.render_type == 'OBJECT' and psys.settings.dupli_object:
    name = psys.settings.dupli_object.name
    package = Package()
    package.name = name
    package.alias = name
    i = 0
    for p in psys.particles:
        if (psys.settings.type == 'EMITTER' and p.alive_state == "ALIVE"):
            pm = p.rotation.to_matrix() * p.size
            frame = [pm[0][0], pm[0][1], pm[0][2], p.location[0],
                     pm[1][0], pm[1][1], pm[1][2], p.location[1],
                     pm[2][0], pm[2][1], pm[2][2], p.location[2]
                     ]
            package.addFrame(frame)

Guys, maybe you could help me with this related issue?


It would be great it the total count is automatically adjusted based on a vertex density.
Thanks!

@Atom doest work.
as soon as I insert the key.
particles stop to updating