Bacterial particle script for Blender.
import bpy | |
import numpy as np | |
import random | |
# Abbriviations. | |
obj = bpy.context.object | |
par_system = obj.particle_systems[0] | |
particles = par_system.particles | |
par_setting = particles.data.settings | |
par_len = par_setting.count | |
par_frame_start = par_setting.frame_start | |
par_frame_end = par_setting.frame_end | |
def preset(): | |
par_setting.lifetime = 500 | |
par_setting.normal_factor = 0 | |
par_setting.effector_weights.gravity = 0 | |
par_setting.physics_type = 'FLUID' | |
# Update physics_type by changing frame. | |
bpy.context.scene.frame_set(1) | |
par_setting.fluid.stiffness = 0.03 | |
par_setting.fluid.fluid_radius = 2 | |
par_setting.fluid.spring_force = 0.25 | |
# Make relocation particle index and birth frame. | |
def cellDivision(reloc_index,par_birth,birth_start,frame_step,initial_particles,growth_rate,division_sequential): | |
# start values. | |
prev_index = initial_particles | |
par_birth[:prev_index] = birth_start | |
reloc_index = np.append(reloc_index, np.arange(0,initial_particles,1)) | |
count = 1 | |
while prev_index < par_len: | |
next_index = prev_index*growth_rate | |
# Add randomness. | |
newborn = len(par_birth[prev_index:next_index]) | |
rand = np.random.randint(0,frame_step, size=newborn) | |
par_birth[prev_index:next_index] = (frame_step*count) - (rand*division_sequential) | |
# Newborn particles are relocated nearby existing particles. | |
reloc_index = np.append(reloc_index, np.arange(0, prev_index, 1)) | |
prev_index = next_index | |
count +=1 | |
reloc_index = reloc_index.astype(int) | |
return (reloc_index, par_birth) | |
# Set particle location thorugh key frames. | |
def setFrameLocation(reloc_index,par_birth,par_loc, | |
growth_mode,loc_range,initial_particles,x_axis,y_axis,z_axis): | |
frame_start = par_frame_start | |
if growth_mode == 'cell': | |
frame_end = bpy.context.scene.frame_end | |
else: | |
frame_end = par_frame_end | |
# The internal birth_time is automatically reset below. | |
for f in range(int(frame_start), int(frame_end)): | |
bpy.context.scene.frame_set(f) | |
par_index = np.where(par_birth == f) | |
if len(par_index[0]) > 0: | |
for i in par_index[0]: | |
# Set birth_time. | |
particles[i].birth_time = par_birth[i] | |
# Set new location. | |
par_i = 0 | |
if growth_mode == 'cell': | |
par_i = reloc_index[i] | |
elif growth_mode == 'proceed': | |
par_i = random.randint(0,initial_particles) | |
else: | |
par_i = random.randint(0,i) | |
new_loc = particles[par_i].location | |
# Add randomness. | |
rand_fac = 1 | |
rand_floor = 0.001 | |
rand_axis = np.random.random(3) * [x_axis, y_axis, z_axis] | |
rand_loc = np.random.uniform(-1,1,3) * (loc_range + rand_floor) | |
new_loc[0] += rand_loc[0] * rand_axis[0] * rand_fac | |
new_loc[1] += rand_loc[1] * rand_axis[1] * rand_fac | |
new_loc[2] += rand_loc[2] * rand_axis[2] * rand_fac | |
particles[i].location = new_loc | |
par_loc[i*3:(i*3)+3] = new_loc | |
return par_loc | |
def execute(growth_mode,birth_delay, birth_start,loc_range,x_axis,y_axis,z_axis, | |
initial_particles,frame_step,growth_rate,division_sequential): | |
# Reset memory. | |
par_system.seed += 1 | |
par_system.seed -= 1 | |
# Initial birth time list. | |
par_birth = np.array([0.0]*par_len, dtype='float') | |
particles.foreach_get('birth_time', par_birth) | |
# Initial location list. | |
par_loc = np.array([0,0,0]*par_len, dtype='float') | |
particles.foreach_get('location', par_loc) | |
# Particle's index to relocate the position. | |
reloc_index = np.array([]) | |
if growth_mode == 'cell': | |
reloc_index, par_birth = cellDivision(reloc_index,par_birth, | |
birth_start,frame_step,initial_particles,growth_rate,division_sequential) | |
par_birth = par_birth.astype(int) | |
par_loc = setFrameLocation(reloc_index,par_birth,par_loc, | |
growth_mode,loc_range,initial_particles,x_axis,y_axis,z_axis) | |
# Delay birth. | |
par_birth += birth_delay | |
# Set location and birthtime again. | |
if growth_mode == 'cell': | |
particles.foreach_set('location', par_loc) | |
particles.foreach_set('birth_time', par_birth) | |
bpy.context.scene.frame_current = 1 | |
# General parameters. | |
growth_mode = 'cell' # cell or proceed, or random. | |
birth_delay = 5 | |
birth_start = 1 | |
loc_range = 0.1 | |
x_axis = 0.1 | |
y_axis = 0.1 | |
z_axis = 0 | |
# Parametor for cell and proceed mode. | |
initial_particles = 3 | |
# Parameters for cell mode. | |
frame_step = 20 | |
growth_rate = 2 | |
division_sequential = 0 | |
preset() | |
execute(growth_mode,birth_delay,birth_start,loc_range,x_axis,y_axis,z_axis, | |
initial_particles,frame_step,growth_rate,division_sequential) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment