2

I am trying to create Conway's game of life in blender, but every time I am getting the error

Info: Deleted 13 object(s)

Info: Saved "untitled2.blend"

Info: Deleted 12 object(s)

Info: Saved "untitled2.blend"

add_operation: Operation already exists - 4)Parameters Component : LSLineStyle( affects_directly_visible: false) has PARAMETERS_ENTRY() at 0000015542C29588 add_operation: Operation already exists - 4)Parameters Component : LSLineStyle( affects_directly_visible: true) has PARAMETERS_EVAL() at 0000015542C29448 add_operation: Operation already exists - 4)Parameters Component : LSLineStyle( affects_directly_visible: true) has PARAMETERS_EXIT() at 0000015542C29308 add_operation: Operation already exists - 13)Audio Component : SCScene( affects_directly_visible: true) has AUDIO_ENTRY() at 0000015542C28E08 add_operation: Operation already exists - 13)Audio Component : SCScene( affects_directly_visible: false) has SOUND_EVAL() at 000001551D479A88 add_operation: Operation already exists - 13)Audio Component : SCScene( affects_directly_visible: true) has AUDIO_VOLUME() at 000001551D479D08 add_operation: Operation already exists - 9)Sequencer Component : SCScene( affects_directly_visible: true) has SEQUENCES_EVAL() at 000001551D479948 add_operation: Operation already exists - 10)LayerCollections Component : SCScene( affects_directly_visible: true) has VIEW_LAYER_EVAL() at 000001551D478B88 add_operation: Operation already exists - 4)Parameters Component : SCScene( affects_directly_visible: true) has PARAMETERS_ENTRY() at 000001551D479088 add_operation: Operation already exists - 4)Parameters Component : SCScene( affects_directly_visible: true) has PARAMETERS_EVAL() at 000001551D4791C8 add_operation: Operation already exists - 4)Parameters Component : SCScene( affects_directly_visible: true) has PARAMETERS_EXIT() at 000001551D4787C8 add_operation: Operation already exists - 4)Parameters Component : SCScene( affects_directly_visible: true) has SCENE_EVAL() at 000001551D478188 Error : EXCEPTION_ACCESS_VIOLATION Address : 0x00007FF60DEB1C59 Module : blender.exe Thread : 00002cf4 Writing: C:\Users****\AppData\Local\Temp\untitled2.crash.txt

Here is the code

# adding system packages
import sys

sys.path.append("C:\Users\***\AppData\Roaming\Python\Python39\site-packages")

import bpy import numpy as np import random from scipy import signal import time import threading

remove exixting objects

bpy.ops.object.select_all(action='DESELECT') bpy.ops.object.delete()

set of active objects

active_objects = set()

#set the grid size grid_size = 20 grid = np.zeros((grid_size,)*3, dtype=int)

randomly place some 'n' 1s

#n = 10 #for i in range(n):

grid[random.randint(0, grid_size-1),

random.randint(0, grid_size-1),

random.randint(0, grid_size-1)] = 1

grid[10, 10, 10] = 1 grid[10, 10, 8] = 1 grid[10, 10, 12] = 1 grid[10, 8, 10] = 1 grid[10,12, 10] = 1 grid[12, 10, 10] = 1 grid[8,10,10] = 1

now place the cubes

for cor in zip(*np.where(grid == 1)): bpy.ops.mesh.primitive_cube_add(size=1, calc_uvs=False, location=cor) obj = bpy.context.object obj.name = str(cor) active_objects.add(cor)

now in next step we will calculate Conway's conditions

kernel = np.ones((3,3,3), dtype=int) kernel[1,1,1] = 0

def loop_generation(generation = 10, delay = 1):

global active_objects

for _ in range(generation):

    time.sleep(delay)

    convolution = signal.convolve(grid, kernel, mode='same')

    # extract the living cells
    new_living = set()
    for cord in zip(*np.where((convolution == 2) | (convolution == 3))):
        new_living.add(cord)

    to_kill = active_objects.difference(new_living)
    add_new = new_living.difference(active_objects)
    print(convolution)

    for del_cor in to_kill:
            bpy.data.objects.remove(bpy.data.objects[str(del_cor)])

    for new_cor in add_new:
        bpy.ops.mesh.primitive_cube_add(size=1,
                                    calc_uvs=False,
                                    location=new_cor)

        obj = bpy.context.view_layer.objects.active
        print(obj)
        #obj = bpy.context.object
        obj.name = str(new_cor)

    active_objects = new_living





if name == 'main': threading.Thread(target=loop_generation).start()

Epsi95
  • 193
  • 1
  • 9
  • 2
    Blender and threading do not always play well together. See first few posts https://blender.stackexchange.com/search?q=%5Bpython%5D+threading+ For what you are trying to achieve here, look at the Text Editor > Templates > Python > Modal Timer Operator Objects can be added removed based on its elapsed time. – batFINGER Sep 11 '21 at 13:49
  • 1
    https://blender.stackexchange.com/questions/181400/why-does-blender-crash-when-trying-to-place-objects-with-threading-timer – batFINGER Sep 11 '21 at 13:58
  • Thanks for the suggestion, it is working nicely, but there is lack of smoothness during function executionn – Epsi95 Sep 11 '21 at 14:47

1 Answers1

3

Finally solved the problem using timer, thanks @batFINGER

import sys
import bpy
import bmesh
import numpy as np
import random
from scipy import signal
import time
import mathutils

globals

color_turn = True mask = None new_living = None to_kill = None add_new = None

remove exixting objects

bpy.ops.object.select_all(action='DESELECT') bpy.ops.object.delete()

set of active objects

active_objects = set()

#set the grid size grid_size = 20 grid = np.zeros((grid_size,)*3, dtype=int)

randomly place some 'n' 1s

#n = 6 #for i in range(n):

grid[random.randint(0, (grid_size-1)//2),

random.randint(0, (grid_size-1)//2),

random.randint(0, (grid_size-1)//2)] = 1

for i in range(6,9): grid[10, 6, i] = 1 grid[10, 10, i] = 1 for i in range(7,10): grid[10, i, 5] = 1 grid[10, i, 9] = 1

red material

mat = bpy.data.materials.new("PKHG") mat.diffuse_color = (1.0,0.0,0.0,1.0)

now place the cubes

for cor in zip(*np.where(grid == 1)): bpy.ops.mesh.primitive_cube_add(size=1, calc_uvs=False, location=cor) obj = bpy.context.object obj.name = str(cor) active_objects.add(cor)

now in next step we will calculate Conway's conditions

kernel = np.ones((3,3,3), dtype=int) kernel[1,1,1] = 0

def create_cube(name, loc): bpyscene = bpy.context.scene

# Create an empty mesh and the object.
mesh = bpy.data.meshes.new(name)
basic_cube = bpy.data.objects.new(name, mesh)

# Add the object into the scene.
bpyscene.collection.objects.link(basic_cube)

# Construct the bmesh cube and assign it to the blender mesh.
bm = bmesh.new()
bmesh.ops.create_cube(bm, size=1.0, matrix=mathutils.Matrix.Translation(loc))
bm.to_mesh(mesh)
bm.free()

def loop_generation(delay = 1):

global active_objects, color_turn, mask, to_kill, add_new, new_living

# calculating the mask
if mask is None:
    convolution = signal.convolve(grid, kernel, mode='same')

    # Any live cell with 5-6 live neighbors survives
    mask_1 = ((convolution == 5) | (convolution == 6)) & (grid == 1)
    # Any dead cell with 4 live neighbors becomes a live cell
    mask_2 = (convolution == 4) & (grid == 0)
    mask = mask_1 | mask_2

    # extract the living cells
    new_living = set()
    for cord in zip(*np.where(mask)):
        new_living.add(cord)

    to_kill = active_objects.difference(new_living)
    add_new = new_living.difference(active_objects)

if color_turn:
    for del_cor in to_kill:
        bpy.data.objects[str(del_cor)].active_material = mat
    color_turn = not color_turn

    return delay

# update the grid
grid[:] = 0
grid[mask] = 1


for del_cor in to_kill:
    bpy.data.objects.remove(bpy.data.objects[str(del_cor)])

for new_cor in add_new:
    create_cube(str(new_cor), new_cor)

active_objects = new_living
color_turn = not color_turn
mask = None
return delay



if name == 'main': bpy.app.timers.register(loop_generation) ```

Epsi95
  • 193
  • 1
  • 9