1
$\begingroup$

I am newbie to blender and I want to know if it's possible to store or output to a file the particle motion details (like velocity vector of each particle, distance from all other particles, particle ID, etc.) at various time-stamps (like at time T than at T+ΔT, so on).

Or are there any other hacks to do so?

$\endgroup$

2 Answers 2

1
$\begingroup$

You can loop through the particles in a particle system and read the location and velocity of each particle.

For the distance you will need to calculate that for each particle. The distance is a pythagorean calculation.

import bpy
from math import sqrt

scn = bpy.context.scene
obj = bpy.context.object
p_system = obj.particle_systems['ParticleSystem']

def distance(p1, p2):
    return sqrt((p1[0]-p2[0])**2+(p1[1]-p2[1])**2+(p1[2]-p2[2])**2)

for f in range(scn.frame_start, scn.frame_end):
    scn.frame_set(f)
    print('At frame {}'.format(f))
    for i1,p1 in enumerate(p_system.particles):
        if p1.alive_state == 'ALIVE':
            print(' particle {} has a velocity of {}'.format(i1,p1.velocity))
            for i2,p2 in enumerate(p_system.particles):
                if p2.alive_state == 'ALIVE' and i1 != i2:
                    d = distance(p1.location,p2.location)
                    print('  particle {} is {:.4f} from particle {}'.format(i1,d,i2))
$\endgroup$
0
1
$\begingroup$

Another take on this, using vector maths, and optimizing the distance from each to all some.

Suggest just exporting particles location and velocity vectors. The distance between them can be calculated anytime from the data. As these are vectors, we don't need to define a distance function. The distance from particle p1 to p2 is d = (p1.location - p2.location).length The vector v = (p2 - p1).normalized() gives a unit vector pointing from p1 towards p2. If we travel d * v, the scalar distance times the direction, from p1 we will be at p2.

When calculating the distance of all particles in list to all others, can take advantage of transpose nature d(i, j) = d(j, i), in that don't need to find the distance from p300 to p0 if have already found the distance from p0 to p300. The direction vector from p0 to p300 is the same as p300 to p0, negated. v(i, j) = -v(j, i)

Change the calc_dist boolean to True to show distance calculations.

Test script, uses selected (active) particle system of active object.

import bpy

scn = bpy.context.scene
# active object
obj = bpy.context.object
# active particle system 
psys = obj.particle_systems.active
calc_dist = False # True calculate the distance between parts. 
f = scn.frame_start    
while f <= scn.frame_end: # iterate over whole frame range.
    scn.frame_set(f)    
    parts = [(i, p) for i, p in enumerate(psys.particles) if p.birth_time <= f <= p.die_time]
    #parts = [(i, p) for i, p in enumerate(psys.particles) if p.alive_state == 'ALIVE'] # equivalent
    print("Frame %4d %4d alive" % (f, len(parts)))
    print("-" * 72)
    while parts:
        i, p1 = parts.pop(0) # keep popping off left
        print("Particle %4d %s   %s " % (i , str(p1.location), str(p1.velocity)))
        if calc_dist:
            for j, p in parts:
                v = p1.location - p.location
                print("      -> %4d %12.4f" % (j, v.length))
    print("-" * 72)
    f += 1
$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .