Skip to content

Instantly share code, notes, and snippets.

@5agado
Created June 6, 2021 23:46
Show Gist options
  • Save 5agado/c1d378761e0e65913c7cb7390b397da0 to your computer and use it in GitHub Desktop.
Save 5agado/c1d378761e0e65913c7cb7390b397da0 to your computer and use it in GitHub Desktop.
Blender boolean slicing
import numpy as np
import bpy
from mathutils import Vector
from math import sin, cos, pi, copysign
def randomize_pos(obj, min, max):
axis = np.random.randint(0, 3)
new_axis_pos = np.random.uniform(min, max)
# x axis
if axis == 0:
obj.location = (new_axis_pos, 0, 0)
obj.rotation_euler = (0, 0, 1.57)
# y axis
elif axis == 1:
obj.location = (0, new_axis_pos, 0)
obj.rotation_euler = (0, 0, 0)
# z axis
elif axis == 2:
obj.location = (0, 0, new_axis_pos)
obj.rotation_euler = (1.57, 0, 0)
return axis
def rotate_vertex(v, angle, axis='z'):
# Define rotation matrix based on axis
if axis.lower() == 'x':
transform_matrix = np.array([[1, 0, 0],
[0, cos(angle), -sin(angle)],
[0, sin(angle), cos(angle)]])
elif axis.lower() == 'y':
transform_matrix = np.array([[cos(angle), 0, sin(angle)],
[0, 1, 0],
[-sin(angle), 0, cos(angle)]])
# default on z
else:
transform_matrix = np.array([[cos(angle), -sin(angle), 0],
[sin(angle), cos(angle), 0],
[0, 0, 1]])
# Apply rotation matrix to each point
v.co = transform_matrix @ np.array(v.co).reshape(3, 1)
objects = bpy.data.objects
origin = objects['origin']
cut = objects['cut']
cut_thickness = 0.005
nb_cuts = 13
np.random.seed(14)
new_axis_positions = np.linspace(-0.8, 0.8, 20)
new_axis_positions = np.random.choice(new_axis_positions, nb_cuts, replace=False)
with open("test_01.txt", 'w+') as f:
for i in range(nb_cuts):
bpy.context.view_layer.objects.active = origin
origin.select_set(True)
bool_op_name = f"bool {i}"
axis = randomize_pos(cut, new_axis_positions[i], new_axis_positions[i])
### Apply bool modifier
bool_op = origin.modifiers.new(type="BOOLEAN", name=bool_op_name)
bool_op.object = cut
bool_op.operation = 'DIFFERENCE'
bool_op.use_self = True
bpy.ops.object.modifier_apply(modifier=bool_op_name)
#for modifier in origin.modifiers:
# bpy.ops.object.modifier_apply(modifier=modifier.name)
### Shift + rotate vertices
shift = np.random.uniform(0.2, 0.3, 3) * np.random.choice([-1, 1], 3)
shift[axis] = 0.
angle = np.random.choice([0, pi/2], p=[0.2, 0.8])
for v in origin.data.vertices:
# adjust because of cut object thickness
cut_dist = v.co[axis] - cut.location[axis]
if abs(cut_dist) <= (cut_thickness*2):
new_pos = np.array(v.co)
new_pos[axis] = cut.location[axis] + copysign(0.000001, cut_dist)
v.co = Vector(new_pos)
# actual shift and rotation
if cut_dist > 0.:
v.co += Vector(shift)
rotate_vertex(v, angle, axis=['x', 'y', 'z'][axis])
# print vals
f.write(f"{axis};{list(cut.location)};{list(shift)};{angle}\n")
bpy.ops.mesh.separate(type='LOOSE')
bpy.context.scene.frame_end = (nb_cuts+1) * 15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment