I wrote a blender script that duplicates an object, rotates it, and eventually creates a mosaic, data looks like this: [x,x,x, o,o,o, x,x,x,], where x is 90 degrees and o is 180, for example. Creating a "board" of the rotated objects.
The problem is that my mosaic consists of 17,000 objects and blender crashes when ever I run the script. It worked great when I was only creating 30/40 objects in my first tests but 17k is just too much to handle that. Routine:
- Duplicate the active object and move it to the right (or down and to the left if the row ends
- Rotates that active object
- Repeat both steps
I'm fairly new to blender, is there a better way to achieve that? I tried to run the script on the default cube and that crashed too. Also, I tried adding time.sleep(0.1) to slow it down or something but that also crashes:
import bpy.ops
from math import radians
from mathutils import Matrix
import time
def move_obj(x, y, z):
bpy.ops.object.duplicate_move(OBJECT_OT_duplicate={"linked":True, "mode":'TRANSLATION'}, TRANSFORM_OT_translate={"value":(x, y, z), "orient_type":'GLOBAL', "orient_matrix":((1, 0, 0), (0, 1, 0), (0, 0, 1)), "orient_matrix_type":'GLOBAL', "constraint_axis":(True, False, False), "mirror":True, "use_proportional_edit":False, "proportional_edit_falloff":'SMOOTH', "proportional_size":1, "use_proportional_connected":False, "use_proportional_projected":False, "snap":False, "snap_target":'CLOSEST', "snap_point":(0, 0, 0), "snap_align":False, "snap_normal":(0, 0, 0), "gpencil_strokes":False, "cursor_transform":False, "texture_space":False, "remove_on_cancel":False, "release_confirm":False, "use_accurate":False})
def rotate_object(rot_mat):
obj = bpy.context.active_object
orig_loc, orig_rot, orig_scale = obj.matrix_world.decompose()
orig_loc_mat = Matrix.Translation(orig_loc)
orig_rot_mat = orig_rot.to_matrix().to_4x4()
orig_scale_mat = (Matrix.Scale(orig_scale[0],4,(1,0,0)) @
Matrix.Scale(orig_scale[1],4,(0,1,0)) @
Matrix.Scale(orig_scale[2],4,(0,0,1)))
obj.matrix_world = orig_loc_mat @ rot_mat @ orig_rot_mat @ orig_scale_mat
def rotate_dice(num):
if num == 2: rotate_object( Matrix.Rotation(radians(90), 4, 'X')) #2
if num == 3: rotate_object( Matrix.Rotation(radians(270), 4, 'Z')) #3
if num == 4: rotate_object( Matrix.Rotation(radians(270), 4, 'X')) #4
if num == 5: rotate_object( Matrix.Rotation(radians(90), 4, 'Z')) #5
if num == 6: rotate_object( Matrix.Rotation(radians(180), 4, 'X')) #6
def rotate_to_one(num):
if num == 2: rotate_object( Matrix.Rotation(radians(-90), 4, 'X')) #2
if num == 3: rotate_object( Matrix.Rotation(radians(-270), 4, 'Z')) #3
if num == 4: rotate_object( Matrix.Rotation(radians(-270), 4, 'X')) #4
if num == 5: rotate_object( Matrix.Rotation(radians(-90), 4, 'Z')) #5
if num == 6: rotate_object( Matrix.Rotation(radians(-180), 4, 'X')) #6
def dup(to, fro, x, z):
move_obj(x, 0, z)
rotate_to_one(fro)
rotate_dice(to)
dice_arr = [1,2,3,4,5,1,2,3,4,5] // actually 17,000 entries long (removed for post)
break_on = 119
def run_arr():
counter = 0
last_index = 1
movement_amount = 2.075
count = 0
for i in dice_arr:
if count == break_on:
dup(i, last_index, -movement_amount * break_on, -movement_amount)
count = 0
else:
count = count + 1
dup(i, last_index, movement_amount, 0)
last_index = i
time.sleep(0.1)
run_arr()
Edit: Blender doesn't seem to "Crash", it just hangs and is not responsive. How do I speed this up or let it run and so I can see the incremental changes?
