The first problem is that all objects have their origin at (0, 0, 0), so you cannot select objects based on position. You need to find the center of a cube by looking at the vertices.
The second problem is that you’re using transform operators and toggling modes. You should use low level api.
The third problem is using euler when you have multi-axis cumulative rotations. You should use quaternion instead. The downside is you can’t keyframe over 360 degrees rotation because quaternions take the shortest path, but it’s a small price to pay for avoiding axis roll issues and gimbal lock.
This is why I proposed using dynamic parenting.
Nevertheless, here’s a slightly edited version of your script.
import bpy,bmesh
for x in bpy.data.meshes:
bpy.data.meshes.remove(x)
for y in bpy.data.materials:
bpy.data.materials.remove(y)
for z in bpy.data.objects:
bpy.data.objects.remove(z)
black = (0,0,0,1)
red = (1,0,0,1)
yellow = (1,1,0,1)
green = (0,1,0,1)
blue = (0,0,1,1)
white = (1,1,1,1)
orange = (0.8,0.3,0,1)
colorlist = [red,green,orange,blue,white,yellow,black]
for i in range(-1,2):
for j in range(-1,2):
for k in range(-1,2):
bpy.ops.mesh.primitive_cube_add(
size = 1,
location = (i, j, k)
)
my_cube = bpy.context.object
my_cube.rotation_mode = "QUATERNION"
# ベベルを追加
bpy.ops.object.modifier_add(type = 'BEVEL')
bpy.ops.object.mode_set(mode = 'EDIT')
# 選択を解除
bpy.ops.mesh.select_all(action = 'DESELECT')
# my_cubeのメッシュデータを取得
bm = bmesh.from_edit_mesh(my_cube.data)
bm.faces.ensure_lookup_table()
if len(my_cube.data.materials) < 1:
for e in range(7):
mat = bpy.data.materials.new('Material.%d' %e)
mat.diffuse_color = colorlist[e]
my_cube.data.materials.append(mat)
for f in range(6):
bm.faces[f].material_index = f
my_cube.modifiers['Bevel'].material = 6
bpy.ops.object.mode_set(mode = 'OBJECT')
bpy.ops.object.mode_set(mode = 'OBJECT')
bpy.data.scenes['Scene'].frame_start = 0
bpy.data.scenes['Scene'].frame_end = 250
bpy.ops.object.select_all(action = 'SELECT')
bpy.ops.object.origin_set(type='ORIGIN_CURSOR')
bpy.data.scenes['Scene'].frame_current = 1
bpy.ops.anim.keyframe_insert_menu(type='Rotation')
def select(axis,position):
for object in bpy.data.objects:
if object.location[axis] == position:
bpy.ops.object.select_set(True)
axis = ['X','Y','Z']
from mathutils import Vector, Quaternion
from math import isclose
def get_cube_center(obj):
summed = Vector()
for vert in obj.data.vertices:
summed += vert.co
return obj.matrix_world @ summed / 8
def rotation(frame,select_axis,position,angle):
bpy.data.scenes['Scene'].frame_set(frame)
for ob in bpy.data.objects:
center = get_cube_center(ob)
if isclose(center[select_axis], position, abs_tol=0.1):
q_axis = [0.0, 0.0, 0.0]
q_axis[select_axis] = 1.0
q_delta = Quaternion(q_axis, angle)
q = q_delta @ ob.rotation_quaternion
ob.rotation_quaternion = q
bpy.ops.object.select_all(action = 'SELECT')
bpy.ops.anim.keyframe_insert_menu(type='Rotation')
rotation(20,0,-1,1.5708)