I am using a script to calculate the vorticity at each particle using the surrounding particles and set the angular velocity to be used by the shaders… I iterate through each particle, and then filter a list of particles to those that are within a certain distance of the given particle, into a new list. Then use some cross products with all the particles in that list to get my angular velocity. Is there some better way to be doing this? When I have a lot of particles it gets very slow. Here is the script:
import bpyimport mathutils
import math
import threading
threads = 14.0
def calcav(p,ps):
psorted = []
M = p.size*5
psl = list(filter(lambda q: (q.alive_state == 'ALIVE' and math.fabs(q.location[0]-p.location[0]) < M and math.fabs(q.location[1]-p.location[1]) < M and math.fabs(q.location[2]-p.location[2]) < M), ps))
for q in psl:
dist = (mathutils.Vector(q.location)- mathutils.Vector(p.location)).length
if dist < M and dist > 0 and len(psorted)<50:
psorted.append(q)
currentdist = dist
angularvel = mathutils.Vector((0,0,0))
if len(psorted)>0:
for i in range(len(psorted)):
angularvel += (mathutils.Vector(psorted[-1-i].location)- mathutils.Vector(p.location)).cross(mathutils.Vector(psorted[-1-i].velocity)- mathutils.Vector(p.velocity))/((mathutils.Vector(psorted[-1-i].location)- mathutils.Vector(p.location)).length**2)
angularvel/= len(psorted)
p.angular_velocity = (angularvel.x,angularvel.y,angularvel.z)
del psorted[:]
del psl[:]
def calclist(ps):
print('Start')
for p in ps:
if p.alive_state == 'ALIVE':
calcav(p,ps)
print('Done')
def my_handler(scene):
ps1 = bpy.context.scene.objects['SPH'].particle_systems[0]
ts = []
for i in range(int(threads)):
lb = int(math.floor((i/threads)*len(ps1.particles)))
print(lb)
ub = int(math.floor(((i+1.0)/threads)*len(ps1.particles)))
ts.append(threading.Thread(target= calclist, args=(ps1.particles[lb:ub],)))
ts[-1].start()
for t in ts:
t.join()
del ts[:]
def register():
bpy.app.handlers.render_pre.append(my_handler)
def unregister():
bpy.app.handlers.render_pre.remove(my_handler)
try:
unregister()
except ValueError:
pass
register()