I want to make a box out of selected verts' bounding box in local space
1 Answer
$\begingroup$
$\endgroup$
2
Draw oriented bounding box
with GPU module
# suppose in edit mode
import bpy, gpu
import numpy as np
from mathutils import Vector
from gpu_extras.batch import batch_for_shader
def ret_obb(verts):
points = np.asarray(verts)
means = np.mean(points, axis=1)
cov = np.cov(points, y = None,rowvar = 0,bias = 1)
v, vect = np.linalg.eig(cov)
tvect = np.transpose(vect)
points_r = np.dot(points, np.linalg.inv(tvect))
co_min = np.min(points_r, axis=0)
co_max = np.max(points_r, axis=0)
xmin, xmax = co_min[0], co_max[0]
ymin, ymax = co_min[1], co_max[1]
zmin, zmax = co_min[2], co_max[2]
xdif = (xmax - xmin) * 0.5
ydif = (ymax - ymin) * 0.5
zdif = (zmax - zmin) * 0.5
cx = xmin + xdif
cy = ymin + ydif
cz = zmin + zdif
corners = np.array([
[cx - xdif, cy - ydif, cz - zdif],
[cx - xdif, cy + ydif, cz - zdif],
[cx + xdif, cy + ydif, cz - zdif],
[cx + xdif, cy - ydif, cz - zdif],
[cx - xdif, cy - ydif, cz + zdif],
[cx - xdif, cy + ydif, cz + zdif],
[cx + xdif, cy + ydif, cz + zdif],
[cx + xdif, cy - ydif, cz + zdif],
])
corners = np.dot(corners, tvect)
return [Vector((el[0], el[1], el[2])) for el in corners]
bpy.ops.object.mode_set(mode = 'OBJECT')
oj = bpy.context.object
verts = [v.co for v in oj.data.vertices if v.select]
obb_local = ret_obb(verts)
mat = oj.matrix_world
obb_world = [mat @ v for v in obb_local]
bpy.ops.object.mode_set(mode = 'EDIT')
# draw with GPU Module
coords = [(v[0], v[1], v[2]) for v in obb_world]
indices = (
(0, 1), (1, 2), (2, 3), (3, 0),
(4, 5), (5, 6), (6, 7), (7, 4),
(0, 4), (1, 5), (2, 6), (3, 7))
shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR')
batch = batch_for_shader(shader, 'LINES', {"pos": coords}, indices=indices)
def draw():
shader.bind()
shader.uniform_float("color", (1, 0, 0, 1))
batch.draw(shader)
bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_VIEW')
-
$\begingroup$ Where does the magic happen, what finds out the orientation of the bounding box? And is the orientation such that the bounding box has the smallest volume, or its biggest dimension is as small as possible, or it's some heuristic... Could you elaborate? $\endgroup$ Commented Sep 7, 2023 at 11:16
-
1$\begingroup$ Here is the same algorithm for minimum volume, a general search engine should be able to find an explanation: blender.stackexchange.com/questions/261049/… $\endgroup$– X YCommented Sep 7, 2023 at 12:01