Created
February 21, 2024 07:53
-
-
Save mourginakis/9b9f4a8571165ad979041dbbbda7aa8a to your computer and use it in GitHub Desktop.
This file contains hidden or 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 | |
from bpy import data as D | |
import itertools | |
import numpy as np | |
from scipy.signal import convolve | |
import time | |
import math | |
## PRELIM | |
## Installing packages for blender python: | |
## cd <blender-directory>/3.4/python/ | |
## bin/python3.10 lib/python3.10/ensurepip | |
## bin/python3.10 -m pip install scipy numpy | |
np.random.seed(0) | |
# Create new collection if it does not exist | |
if 'animatedcubes' not in bpy.data.collections: | |
targetcollection = D.collections.new("animatedcubes") | |
bpy.context.scene.collection.children.link(targetcollection) | |
## END PRELIM | |
class Lexicon: | |
boat = \ | |
""" | |
..... | |
..O.. | |
.O.O. | |
..OO. | |
..... | |
""" | |
toad = \ | |
""" | |
.OOO. | |
OOO.. | |
..... | |
""" | |
R_pentomino = \ | |
""" | |
..... | |
..@@. | |
.@@.. | |
..@.. | |
..... | |
""" | |
century = \ | |
""" | |
..OO. | |
OOO.. | |
.O... | |
""" | |
glider = \ | |
""" | |
.O. | |
..O | |
OOO | |
""" | |
gosper_glider_gun = \ | |
""" | |
........................O................................................ | |
......................O.O................................................ | |
............OO......OO............OO..................................... | |
...........O...O....OO............OO..................................... | |
OO........O.....O...OO................................................... | |
OO........O...O.OO....O.O................................................ | |
..........O.....O.......O................................................ | |
...........O...O......................................................... | |
............OO........................................................... | |
......................................................................... | |
......................................................................... | |
......................................................................... | |
......................................................................... | |
......................................................................... | |
......................................................................... | |
......................................................................... | |
......................................................................... | |
......................................................................... | |
......................................................................... | |
......................................................................... | |
......................................................................... | |
......................................................................... | |
......................................................................... | |
......................................................................... | |
......................................................................... | |
......................................................................... | |
......................................................................... | |
......................................................................... | |
......................................................................... | |
......................................................................... | |
......................................................................... | |
......................................................................... | |
......................................................................... | |
......................................................................... | |
......................................................................... | |
......................................................................... | |
......................................................................... | |
......................................................................... | |
......................................................................... | |
......................................................................... | |
......................................................................... | |
......................................................................... | |
......................................................................... | |
......................................................................... | |
......................................................................... | |
......................................................................... | |
......................................................................... | |
......................................................................... | |
......................................................................... | |
......................................................................... | |
......................................................................... | |
......................................................................... | |
......................................................................... | |
......................................................................... | |
......................................................................... | |
......................................................................... | |
......................................................................... | |
""" | |
pulsar = \ | |
""" | |
..OOO...OOO.. | |
............. | |
O....O.O....O | |
O....O.O....O | |
O....O.O....O | |
..OOO...OOO.. | |
............. | |
..OOO...OOO.. | |
O....O.O....O | |
O....O.O....O | |
O....O.O....O | |
............. | |
..OOO...OOO.. | |
""" | |
pinwheel = \ | |
""" | |
......OO..... | |
......OO..... | |
............. | |
....OOOO..... | |
OO.O....O.... | |
OO.O..O.O.... | |
...O...OO.OO. | |
...O.O..O.OO. | |
....OOOO..... | |
............. | |
....OO....... | |
....OO....... | |
............. | |
""" | |
_64p2h1v0 = \ | |
""" | |
............................... | |
.....OOO...............OOO..... | |
....O...O.............O...O.... | |
...OO....O...........O....OO... | |
..O.O.OO.OO...OOO...OO.OO.O.O.. | |
.OO.O....O.OO.OOO.OO.O....O.OO. | |
O....O...O....O.O....O...O....O | |
............O.....O............ | |
OO.......OO.........OO.......OO | |
""" | |
greyship_with_wick = \ | |
""" | |
............................................................... | |
............................................................... | |
............................................................... | |
............................................................... | |
............................................................... | |
............................................................... | |
............................................................... | |
............................................................... | |
............................................................... | |
............................................................... | |
............................................................... | |
............................................................... | |
............................................................... | |
............................................................... | |
............................................................... | |
............................................................... | |
............................................................... | |
............................................................... | |
............................................................... | |
............................................................... | |
............................................................... | |
............................................................... | |
............................................................... | |
............................................................... | |
............................................................... | |
............................................................... | |
............................................................... | |
............................................................... | |
............................................................... | |
............................................................... | |
............................................................... | |
............................................................... | |
............................................................... | |
............................................................... | |
............................................................... | |
............................................................... | |
............................................................... | |
........................O............O......................... | |
.......................OOO..........OOO........................ | |
.......................O.OO........OO.O........................ | |
........................OOO........OOO......................... | |
........................OOO........OOO......................... | |
........................OOO........OOO......................... | |
..........................OOOO..OOOO........................... | |
...........................OOO..OOO............................ | |
...........................OOO..OOO............................ | |
............................................................... | |
............................O....O............................. | |
...........................O.O..O.O............................ | |
.........................OO.OOOOOO.OO.......................... | |
.........................OO........OO.......................... | |
.......................O....OOOOOO....O........................ | |
.......................OOOOO..OO..OOOOO........................ | |
.....................O......OO..OO......O...................... | |
.....................OOOOOOO......OOOOOOO...................... | |
...................O........OO..OO........O.................... | |
...................OOOOOOOOO..OO..OOOOOOOOO.................... | |
.................O..........O....O..........O.................. | |
.................OOOOOOOOOOO..OO..OOOOOOOOOOO.................. | |
...............O............OOOOOO............O................ | |
...............OOOOOOOOOOOOO......OOOOOOOOOOOOO................ | |
.............O..............O....O..............O.............. | |
.............OOOOOOOOOOOOOOO......OOOOOOOOOOOOOOO.............. | |
...........O................OOOOOO................O............ | |
...........OOOOOOOOOOOOOOOOO......OOOOOOOOOOOOOOOOO............ | |
.O.......O..................OO..OO..................O.......O.. | |
OOO......OOOOOOOOOOOOOOOOOOO......OOOOOOOOOOOOOOOOOOO......OOO. | |
O.OO...O....................OOOOOO....................O...OO.O. | |
.OOO...OOOOOOOOOOOOOOOOOOOOO......OOOOOOOOOOOOOOOOOOOOO...OOO.. | |
.OOO.O......................OOOOOO......................O.OOO.. | |
.OO..OOOOOOOOOOOOOOOOOOOOOOO..OO..OOOOOOOOOOOOOOOOOOOOOOO..OO.. | |
......O.....................OO..OO.....................O....... | |
........OOOOOOOOOOOOOOOOOOOO......OOOOOOOOOOOOOOOOOOOO......... | |
......OO....................OO..OO....................OO....... | |
......OOOOOOOOOOOOOOOOOOOOOO..OO..OOOOOOOOOOOOOOOOOOOOOO....... | |
.....O..O...................O....O...................O..O...... | |
..........OOOOOOOOOOOOOOOOOO..OO..OOOOOOOOOOOOOOOOOO........... | |
....OO...O..................OOOOOO..................O...OO..... | |
..........OOOOOOOOOOOOOOOOOO......OOOOOOOOOOOOOOOOOO........... | |
..........OO................O....O................OO........... | |
...........O.OOOOOOOOOOOOOOO......OOOOOOOOOOOOOOO.O............ | |
...........O................OOOOOO................O............ | |
..........O...OOOOOOOOOOOOOO......OOOOOOOOOOOOOO...O........... | |
...........O.O..............OO..OO..............O.O............ | |
.........OO...OOOOOOOOOOOOOO......OOOOOOOOOOOOOO...OO.......... | |
..............O..............OOOO..............O............... | |
..............O..OOOOOOOOOOOO.OO.OOOOOOOOOOOO..O............... | |
............................................................... | |
.............OO....OOOOOOOOOOO..OOOOOOOOOOO....OO.............. | |
...............O..O........................O..O................ | |
..............O....OOOOOOOO........OOOOOOOO....O............... | |
..................OO.......OO....OO.......OO................... | |
................OO..O.OOOO..........OOOO.O..OO................. | |
................OO.O........OOOOOO........O.OO................. | |
.................OOOO..OO...OOOOOO...OO..OOOO.................. | |
..................O.O...O...OO..OO...O...O.O................... | |
..................OO.O...O..........O...O.OO................... | |
.....................O...O..........O...O...................... | |
.................O...OO.O............O.OO...O.................. | |
..................OOOO..O...O....O...O..OOOO................... | |
........................O...O....O...O......................... | |
........................O............O......................... | |
.........................O.O......O.O.......................... | |
""" | |
hivenudger2 = \ | |
""" | |
.....................O.O................... | |
....................O..O................... | |
...................OO...................... | |
..................O...O.................... | |
.................OOO.O..................... | |
..............OO........................... | |
.............O...OOOOO.......OOOO.....O..O. | |
............O...O............O...O...O..... | |
............O.....OO.........O.......O...O. | |
............OOO...OOOO........O..O...OOOO.. | |
.............O.......O..................... | |
.............OO...................OO....... | |
.............O.O..................OO....... | |
.............OO..OO.O........O.O..OO....... | |
..............O.OOO.O...O.OOOO.O..OO....... | |
.....................OO.O.OO..O...OO...OOO. | |
................OOOOOO.OO...OOOO..OO...OOO. | |
.................O....OOO......O..OO...OOO. | |
..................OO.....OO..OO...OO....... | |
...................O..O.....OOOO..OO....... | |
....................O.O.OO.....O..OO....... | |
..................................OO....... | |
........................................... | |
..............................O..O...OOOO.. | |
.............................O.......O...O. | |
.............................O...O...O..... | |
.............................OOOO.....O..O. | |
""" | |
@staticmethod | |
def matrix2str(m): | |
def row2str(row): | |
return ''.join(str(i) for i in row) + "\n" | |
s = ''.join([row2str(row) for row in m]) | |
s = s.replace('0', '.') | |
s = s.replace('1', '@') | |
return s | |
@staticmethod | |
def str_to_matrix(s): | |
"""Interpret string data from lexicon into a matrix""" | |
return np.array([[0 if c=='.' else 1 for c in row] | |
for row in s.split()], dtype=np.uint8) | |
class GameOfLife: | |
""" | |
1. Any live cell with two or three neighbors survives | |
2. Any dead cell with three live neighbors becomes a live cell | |
3. All other live cells die in next generation, all dead cells stay dead | |
Convolution logic adapted from mikelane on github | |
""" | |
default_grid_size = 10 | |
kernel = np.array([[1, 1, 1], [1, 0, 1], [1, 1, 1]], dtype=np.uint8) | |
def __init__(self, grid_size=default_grid_size): | |
self.i = 0 | |
self.grid_size = grid_size | |
self.grid_last = self.make_zeros(self.grid_size) | |
self.grid = self.make_zeros(self.grid_size) | |
self.grid_next = self.calculate_next() | |
def make_soup(self, n): | |
return np.random.randint(2, size=(n, n), dtype=np.uint8) | |
def make_zeros(self, n): | |
return np.zeros((n, n), dtype=np.uint8) | |
def superimpose(self, pattern): | |
"""Draw a pattern (np matrix) on top of a matrix of zeros""" | |
# m (down/row), n (across/columns) | |
m, n = pattern.shape | |
m1, n1 = self.grid.shape | |
# find the indexes of a 'pattern' sized block in the middle | |
b1, b2 = (m1//2 - m//2), (m1//2 + m//2 + 1) | |
v1, v2 = (n1//2 - n//2), (n1//2 + n//2 + 1) | |
self.grid[b1:b2, v1:v2] = pattern | |
self.grid_next = self.calculate_next() | |
def calculate_next(self): | |
C = convolve(self.grid, GameOfLife.kernel, mode='same') | |
next_grid = ( | |
((self.grid == 1) & (C > 1) & (C < 4)) | |
| ((self.grid == 0) & (C == 3)) | |
).astype(np.uint8) | |
return next_grid | |
def tick(self): | |
self.grid_last = self.grid | |
self.grid = self.grid_next | |
self.grid_next = self.calculate_next() | |
self.i += 1 | |
def get_tiles_that_did_change(self): | |
return self.grid_last ^ self.grid | |
def get_tiles_that_will_change(self): | |
# returns an np.matrix where 0 means the next square stays the same, 1 means it changes | |
# be careful here: both arrays are uint8, so you'll get an integer overflow | |
return self.grid ^ self.grid_next | |
def __str__(self): | |
"""Pretty print the grid""" | |
return Lexicon.matrix2str(self.grid) | |
################################################### | |
### State Mutating Functions | |
## LightCubes | |
def make_lightcube(location): | |
"""2m x 2m x 2m Cube""" | |
x, y, z = location | |
desiredname = f'cube#{x}.{y}' | |
if desiredname in D.collections['animatedcubes'].objects: | |
raise Exception(f'This cube {desiredname} already exists') | |
cube = D.objects['cube' ].copy() | |
inner = D.objects['inner' ].copy() | |
arealight = D.objects['arealight'].copy() | |
inner.parent = cube | |
arealight.parent = cube | |
D.collections['animatedcubes'].objects.link(cube) | |
D.collections['animatedcubes'].objects.link(inner) | |
D.collections['animatedcubes'].objects.link(arealight) | |
cube.location = location | |
cube.hide_render = False | |
inner.hide_render = False | |
arealight.hide_render = False | |
inner.hide_viewport = True # better fps during preview | |
arealight.hide_viewport = True # better fps during preview | |
cube.name = desiredname | |
return desiredname | |
def set_state_lightcube(name, state): | |
assert state == 1 or state == 0 | |
assert name.startswith('cube#') | |
cube = bpy.data.collections['animatedcubes'].objects[name] | |
x, y, z = cube.location | |
z = 2 * state # 2 or 0 | |
cube.location = (x, y, z) | |
def draw_keyframe_lightcube(name, frame): | |
assert name.startswith('cube#') | |
cube = bpy.data.collections['animatedcubes'].objects[name] | |
cube.keyframe_insert(data_path = 'location', frame=frame) | |
for fcurve in cube.animation_data.action.fcurves: | |
kf = fcurve.keyframe_points[-1] | |
kf.interpolation = 'EXPO' | |
def delete_keyframes_lightcube(name): | |
assert name.startswith('cube#') | |
cube = bpy.data.collections['animatedcubes'].objects[name] | |
if cube.animation_data is not None: | |
cube.animation_data_clear() | |
## Backdrop | |
def reset_backdrop(length): | |
"""Reset the backdrop to be a bowl that has a square hole in the bottom the (width,length) of length (meters)""" | |
# Wow, what an absolute challenge to get the backdrop working properly, especially | |
# since the rest of this project is done programmatically. The problem is that the backdrop | |
# Needs to be hollow on the bottom to let light through and give the depth illusion. | |
# Here's the best way I found: | |
# 1. Create a 'subtraction buffer' cube in the length width and height of all the tiles | |
# 2. Create a 'bowl' shape: essentially a cylinder with one face removed | |
# 3. Bevel this 'bowl' so that it's round on the bottom and shade autosmooth | |
# 4. Boolean subtract the subtraction buffer from the bowl, except for some reason | |
# union is the operation for difference, not difference, weird and annoying. | |
# Must have to do with the fact that the geometry has no thickness. | |
max_x, max_y = length, length | |
RE_BEVEL = False | |
if RE_BEVEL == True: | |
# BE CAREFUL! OVERWRITES DATA EVERY TIME! | |
try: D.objects.remove(D.objects['backdrop'], do_unlink=True) | |
except KeyError: pass | |
newbackdrop = D.objects['backdrop.backup'].copy() | |
newbackdrop.data = D.objects['backdrop.backup'].data | |
newbackdrop.name = 'backdrop' | |
newbackdrop.hide_render = False | |
D.collections['background'].objects.link(newbackdrop) | |
import bpy | |
def apply_transformations_with_context(obj): | |
# 1. Store the original active object and selection | |
original_active_object = bpy.context.view_layer.objects.active | |
original_selected_objects = bpy.context.selected_objects.copy() | |
# 2. Deselect all objects | |
bpy.ops.object.select_all(action='DESELECT') | |
# 3. Select and set the object as active | |
obj.select_set(True) | |
bpy.context.view_layer.objects.active = obj | |
# 4. Apply the transformations (in this example, only the scale) | |
bpy.ops.object.transform_apply(location=False, rotation=False, scale=True) | |
# 5. Restore the original selection and active object | |
for original_obj in original_selected_objects: | |
original_obj.select_set(True) | |
bpy.context.view_layer.objects.active = original_active_object | |
buffer_size = 3000 + max_x # at least twice as big, plus some extra space | |
# weird bug, dimension change must be called multiple times to close in on target Z value. | |
# do the transformations need to be applied??? | |
for _ in range(10): | |
# So apparently you need to set the transformations before you change the data. That's | |
# why we were running into that weird bug. We probably don't need this for loop anymore, | |
# but I"m going to keep it because it doesn't add much compute time and my sanity is failing. | |
apply_transformations_with_context(D.objects['backdrop']) | |
apply_transformations_with_context(D.objects['bufferminus']) | |
D.objects['backdrop'].dimensions = (max_x + buffer_size, max_y + buffer_size, buffer_size / 2) | |
if length == 80*2: | |
D.objects['backdrop'].location = (0, 0, -1.776) # when board is 80 | |
elif length == 120*2: | |
D.objects['backdrop'].location = (0, 0, -1.84) # when board is 120 | |
else: | |
raise NotImplementedError | |
D.objects['bufferminus'].dimensions = (max_x, max_y, 18.0) | |
D.objects['bufferminus'].location = (0, 0, 0) #(max_x / 2 - 1, max_y / 2 -1, 0) | |
## CubeBoard | |
def make_cubeboard(grid_size): | |
start = time.time() | |
names = [] | |
dummy_gameoflife = GameOfLife(grid_size) | |
for index, z in np.ndenumerate(dummy_gameoflife.grid): | |
x, y = index | |
normalized_position = ((x-grid_size/2)*2+1, (y-grid_size/2)*2+1, 0) | |
name = make_lightcube(normalized_position) | |
names.append(name) | |
assert len(names) == grid_size ** 2 | |
end = time.time() | |
print(f'Execute fn> make_cubeboard: {end-start}s', flush=True) | |
return names | |
def delete_cubeboard(): | |
# Flush any preexisting objects from collection | |
start = time.time() | |
# Fast method, deleting in a standarf for loop takes literal hours. | |
scene = bpy.data.scenes['Scene'] | |
collection = bpy.data.collections['animatedcubes'] | |
scene.collection.children.unlink(collection) | |
bpy.data.collections.remove(collection) | |
targetcollection = D.collections.new("animatedcubes") | |
bpy.context.scene.collection.children.link(targetcollection) | |
# this deletes orphaned data | |
bpy.ops.outliner.orphans_purge(do_local_ids=True, do_linked_ids=True, do_recursive=True) | |
end = time.time() | |
print(f'Execute fn> delete_cubeboard: {end-start}s', flush=True) | |
def delete_keyframes_cubeboard(): | |
start = time.time() | |
for obj in bpy.data.collections.get('animatedcubes').objects: | |
if obj.name.startswith('cube#'): | |
delete_keyframes_lightcube(obj.name) | |
end = time.time() | |
print(f'Execute fn> delete_keyframes_cubeboard: {end-start}s') | |
def draw_keyframes_cubeboard(pattern=Lexicon.toad, total_frames=30, speed=0.15): | |
"""sets all keyframes in the board for a specific pattern in the Lexicon""" | |
start = time.time() | |
# auto determine grid size | |
cubes = [obj for obj in bpy.data.collections.get('animatedcubes').objects if obj.name.startswith('cube#')] | |
number_of_cubes = len(cubes) | |
assert math.sqrt(number_of_cubes)**2 == number_of_cubes | |
grid_size = int(math.sqrt(number_of_cubes)) | |
# Create game of life simulation | |
game = GameOfLife(grid_size) | |
frame_begin = 0 | |
frame_step = int(1.0 / speed) | |
frame_end = total_frames + 1 | |
game.superimpose(Lexicon.str_to_matrix(pattern)) | |
def _draw_keyframes_single_frame(frame_number): | |
# only updates keyframes for tiles that will change to save compute | |
def _draw(index): | |
x, y = index | |
z = game.grid[x, y] | |
targetcube_name = f'cube#{(x-grid_size/2)*2+1}.{(y-grid_size/2)*2+1}' | |
set_state_lightcube(targetcube_name, z) | |
draw_keyframe_lightcube(targetcube_name, frame_number) | |
for index, c in np.ndenumerate(game.get_tiles_that_did_change()): | |
if c == 1: | |
_draw(index) | |
for index, c, in np.ndenumerate(game.get_tiles_that_will_change()): | |
if c == 1: | |
_draw(index) | |
# set initial states | |
for index, z in np.ndenumerate(game.grid): | |
x, y = index | |
targetcube_name = f'cube#{(x-grid_size/2)*2+1}.{(y-grid_size/2)*2+1}' | |
set_state_lightcube(targetcube_name, z) | |
# draw initial keyframes | |
_draw_keyframes_single_frame(frame_begin) | |
for frame_num in range(frame_begin+frame_step, frame_end, frame_step): | |
print(f'{frame_num}/{total_frames}. ', end='', flush=True) | |
game.tick() | |
# print(f'did change: {Lexicon.matrix2str(game.get_tiles_that_did_change())}') | |
# print(f'{game.i}: {str(game)}') | |
# print(f'will change: {Lexicon.matrix2str(game.get_tiles_that_will_change())}') | |
_draw_keyframes_single_frame(frame_num) | |
end = time.time() | |
print(f'\nExecute fn> draw_keyframes_cubeboard: {end-start}s') | |
## Main Script | |
print('\nStarting Script...') | |
## Example code for how to make a custom sized grid: (O(n^2) | |
# board reset for size 80: ~13s | |
# board reset for size 100: ~35s | |
# board reset for size 120: ~80s | |
# grid_size = 120 | |
# delete_cubeboard() | |
# reset_backdrop(grid_size*2) | |
# make_cubeboard(grid_size) | |
def render_toad(frames=390, reset=False): | |
"""complete""" | |
# Name: Toad | |
# Class: Oscillator | |
# Lifespan: Indefinite | |
# Discovered by: Simon Norton, 1970 | |
# URL: conwaylife.com/wiki/toad | |
if reset: | |
grid_size = 80 | |
delete_cubeboard() | |
reset_backdrop(grid_size*2) | |
make_cubeboard(grid_size) | |
# - - - - - - - - - - - - | |
bpy.data.scenes['Scene'].camera = bpy.data.objects['toadcam'] | |
total_frames = frames # set frames to something else for benchmarking | |
bpy.data.scenes['Scene'].frame_start = 0 | |
bpy.data.scenes["Scene"].frame_end=total_frames | |
delete_keyframes_cubeboard() | |
draw_keyframes_cubeboard(pattern=Lexicon.toad, total_frames=total_frames, speed=0.09) | |
def render_gosper_glider_gun(reset=False): | |
"""incomplete""" | |
# Name: Glider | |
# Class: Spaceship | |
# Discovered by: Richard K. Guy, 1969 | |
# URL: conwaylife.com/wiki/Glider | |
# ----- | |
# Name: Gosper Glider Gun | |
# Class: Gun | |
# Discovered by: Bill Gosper, 1970 | |
# URL: conwaylife.com/wiki/Gosper_glider_gun | |
if reset: | |
grid_size = 120 | |
delete_cubeboard() | |
reset_backdrop(grid_size*2) | |
make_cubeboard(grid_size) | |
# - - - - - - - - - - - - | |
bpy.data.scenes['Scene'].camera = bpy.data.objects['gliderguncam'] | |
total_frames = 1600+900 # 900/30fps = 36.6s | |
bpy.data.scenes['Scene'].frame_start = 1600 # 1600 is when it gets close to the edge | |
bpy.data.scenes["Scene"].frame_end=total_frames # Real render time: 1100 Frames | |
delete_keyframes_cubeboard() | |
draw_keyframes_cubeboard(pattern=Lexicon.gosper_glider_gun, total_frames=total_frames, speed=0.14) | |
def render_century(reset=False): | |
"""complete""" | |
# Name: Century | |
# Class: Hexomino | |
# Discovered by: Unknown | |
# Lifespan: 103 Generations | |
# URL: conwaylife.com/wiki/century | |
if reset: | |
grid_size = 80 | |
delete_cubeboard() | |
reset_backdrop(grid_size*2) | |
make_cubeboard(grid_size) | |
# - - - - - - - - - - - - - - | |
bpy.data.scenes['Scene'].camera = bpy.data.objects['centurycam'] | |
total_frames = 400 # Reaches steady state at ~330 | |
bpy.data.scenes['Scene'].frame_start=0 | |
bpy.data.scenes["Scene"].frame_end=total_frames | |
delete_keyframes_cubeboard() | |
draw_keyframes_cubeboard(pattern=Lexicon.century, total_frames=total_frames, speed=0.3) | |
def render_rpentomino(reset=False): | |
"""complete""" | |
# Name: R-pentomino | |
# Class: Methuselah | |
# Lifespan: 1103 Generations | |
# Discovered by: John Conway, 1969 | |
# URL: not set | |
if reset: | |
grid_size = 120 | |
delete_cubeboard() | |
reset_backdrop(grid_size*2) | |
make_cubeboard(grid_size) | |
# - - - - - - - - - - - - - - | |
bpy.data.scenes['Scene'].camera = bpy.data.objects['pentominocam'] | |
total_frames = 600 | |
bpy.data.scenes['Scene'].frame_start=0 | |
bpy.data.scenes["Scene"].frame_end=total_frames | |
delete_keyframes_cubeboard() | |
draw_keyframes_cubeboard(pattern=Lexicon.R_pentomino, total_frames=total_frames, speed=0.3) | |
def render_pulsar(reset=False): | |
"""complete""" | |
# Name: Pulsar | |
# Class: Oscillator | |
# Discovered by: John Conway, 1970 | |
# Lifespan: Indefinite | |
if reset: | |
grid_size = 80 | |
delete_cubeboard() | |
reset_backdrop(grid_size*2) | |
make_cubeboard(grid_size) | |
# - - - - - - - - - - - - - - | |
bpy.data.scenes['Scene'].camera = bpy.data.objects['pulsarcam'] | |
total_frames = 300 | |
bpy.data.scenes['Scene'].frame_start=0 | |
bpy.data.scenes["Scene"].frame_end=total_frames | |
delete_keyframes_cubeboard() | |
draw_keyframes_cubeboard(pattern=Lexicon.pulsar, total_frames=total_frames, speed=0.09) | |
def render_pinwheel(reset=False): | |
"""complete""" | |
# Name: Pinwheel | |
# Class: Oscillator | |
# Lifespan: Indefinite | |
# Discoverd by: Simon Norton, 1970 | |
# URL: conwaylife.com/wiki/Pinwheel | |
if reset: | |
grid_size = 80 | |
delete_cubeboard() | |
reset_backdrop(grid_size*2) | |
make_cubeboard(grid_size) | |
# - - - - - - - - - - - - - - | |
bpy.data.scenes['Scene'].camera = bpy.data.objects['pinwheelcam'] | |
total_frames = 460 | |
bpy.data.scenes['Scene'].frame_start=0 | |
bpy.data.scenes["Scene"].frame_end=total_frames | |
delete_keyframes_cubeboard() | |
draw_keyframes_cubeboard(pattern=Lexicon.pinwheel, total_frames=total_frames, speed=0.14) | |
def render_64P2H1V0(reset=False): | |
"""complete""" | |
# Name: 64P2H1V0 | |
# Class: Spaceship | |
# Lifespan: Indefinite | |
# Discovered by: Dean Hickerson, 1989 | |
# URL: conwaylife.com/wiki/64P2H1V0 | |
if reset: | |
grid_size = 80 | |
delete_cubeboard() | |
reset_backdrop(grid_size*2) | |
make_cubeboard(grid_size) | |
# - - - - - - - - - - - - - - | |
bpy.data.scenes['Scene'].camera = bpy.data.objects['p2cam'] | |
total_frames = 400 | |
bpy.data.scenes['Scene'].frame_start=0 | |
bpy.data.scenes["Scene"].frame_end=total_frames | |
delete_keyframes_cubeboard() | |
draw_keyframes_cubeboard(pattern=Lexicon._64p2h1v0, total_frames=total_frames, speed=0.14) | |
def render_greyship_with_wick(reset=False): | |
"""complete""" | |
# Name: Greyship with wick | |
# Class: Greyship | |
# Lifespan: Indefinite | |
# URL: conwaylife.com/wiki/Greyship | |
# Discovered by: Hartmut Holzwart, 2005 | |
if reset: | |
grid_size = 120 | |
delete_cubeboard() | |
reset_backdrop(grid_size*2) | |
make_cubeboard(grid_size) | |
# - - - - - - - - - - - - - - | |
bpy.data.scenes['Scene'].camera = bpy.data.objects['greyshipwickcam'] | |
total_frames = 490 | |
bpy.data.scenes['Scene'].frame_start=0 | |
bpy.data.scenes["Scene"].frame_end=total_frames | |
delete_keyframes_cubeboard() | |
draw_keyframes_cubeboard(pattern=Lexicon.greyship_with_wick, total_frames=total_frames, speed=0.14) | |
def render_hivenudger2(reset=False): | |
"""complete""" | |
# Name: Hivenudger 2 | |
# Class: Puffer | |
# URL: conwaylife.com/wiki/Hivenudger_2 | |
# Discovered by: Hartmut Holzwart, 1992 | |
if reset: | |
grid_size = 80 | |
delete_cubeboard() | |
reset_backdrop(grid_size*2) | |
make_cubeboard(grid_size) | |
# - - - - - - - - - - - - - - | |
bpy.data.scenes['Scene'].camera = bpy.data.objects['hivenudger2cam'] | |
total_frames = 400 | |
bpy.data.scenes['Scene'].frame_start=0 | |
bpy.data.scenes["Scene"].frame_end=total_frames | |
delete_keyframes_cubeboard() | |
draw_keyframes_cubeboard(pattern=Lexicon.hivenudger2, total_frames=total_frames, speed=0.14) | |
#render_toad(reset=True) # size=80 # frames=390 | |
#render_gosper_glider_gun(reset=True) # size=120 # frames=1100 | |
#render_century(reset=True) # size=80 # frames=400 | |
#render_rpentomino(reset=True) # size=120 # frames=600 | |
#render_pulsar(reset=True) # size=80 # frames=300 | |
#render_pinwheel(reset=True) # size=80 # frames=400 | |
render_64P2H1V0(reset=True) # size=80 # frames=400 | |
#render_greyship_with_wick(reset=True) # size=120 # frames=490 | |
#render_hivenudger2(reset=True) # size=80 # frames=400 | |
print('Ended Script. Viewport make take another 30 seconds to buffer new data.') | |
########################################################################################## | |
### EVERYTHING BELOW HERE IS UNFINISHED | |
### | |
### Timesscales: | |
### - 150frames/30fps = 5s | |
### - 300frames/30fps = 10s | |
### - 600frames/30fps = 20s | |
### - 900frames/30fps = 30s | |
### | |
### | |
# render at 30fps: 1s=30f; 2s=60f; 3s=90f; 4s=120f | |
# conwaylife.com/wiki/Glossary_of_basic_terms | |
def render_glider(): | |
"""incomplete""" | |
# Name: Glider | |
# Class: Spaceship | |
# Discovered by Richard K. Guy, 1969 | |
# URL: conwaylife.com/wiki/Glider | |
total_frames = 80 | |
bpy.data.scenes["Scene"].frame_end=total_frames | |
# CreateDisplay(size=40, frames=total_frames, cells=Lexicon.glider) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment