Skip to content

Instantly share code, notes, and snippets.

@squarednob
Created September 30, 2017 19:05
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save squarednob/e9b79bbc2ccc205fb6dacb192fe2dcb3 to your computer and use it in GitHub Desktop.
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