Created
September 30, 2017 19:05
Star
You must be signed in to star a gist
Bacterial particle script for Blender.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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