1
$\begingroup$

how do I rotate the mesh around its center using the bmesh.rotate

import bpy
import bmesh
import mathutils

tech_list = ["TechA"]
for tech in tech_list:
    # these lines create the bmesh with the techA as text
    bpy.data.curves.new(type="FONT", name='label').body = tech
    label = bpy.data.objects.new("label", bpy.data.curves['label'])
    meshed_up = bmesh.new()
    meshed_up.from_mesh(label.to_mesh())

    # this transform_matrix places the mesh in the correct position
    # But still mirrored :(
    transform_matrix = mathutils.Matrix.Rotation(1.5708, 4, 'Z').to_4x4()
    transform_matrix = mathutils.Matrix.Rotation(3.1415, 4, 'X').to_4x4() @ transform_matrix
    # transform_matrix = mathutils.Matrix.Rotation(selet center of mesh, not X-axis)
    meshed_up.transform(transform_matrix)

    # and then we create a mesh for object and link and clean
    label_mesh = bpy.data.meshes.new("label")
    meshed_up.to_mesh(label_mesh)
    meshed_up.free()
    bpy.data.curves.remove(bpy.data.curves['label'])
    label_object = bpy.data.objects.new(tech, label_mesh)
    bpy.context.collection.objects.link(label_object)

# EOF

As you can see, so far all is well but the label is still mirrored, it should now be rotated in place 3.14 radians around its own x-axis, but I don't know how

so far, still to rotate in bounding box X

$\endgroup$

1 Answer 1

1
$\begingroup$

I would do this using the bmesh rotation operator, rather than computing the transformation matrices, as it seems like easier code to read. Basically you need the bounding box center, which can be calculated thusly:

from mathutils import Vector
# code up to creating label as an object
center = sum((Vector(b) for b in label.bound_box), Vector())
center /= 8

and instead of the transformations use bmesh.ops.rotate:

from mathutils import Matrix
from math import radians
# code up to where you calculate transforms.
# replace everything up to the call to transform with this:
rotation_Z = Matrix.Rotation(radians(90), 4, 'Z')
bmesh.ops.rotate(meshed_up, cent=center, matrix=rotation_Z, verts=meshed_up.verts)

rotation_X = Matrix.Rotation(radians(180), 4, 'X')
bmesh.ops.rotate(meshed_up, cent=center, matrix=rotation_X, verts=meshed_up.verts)

or, putting it all together:

import bpy
import bmesh
from mathutils import Matrix, Vector
from math import radians

tech_list = ["TechA"]
for tech in tech_list:
    # these lines create the bmesh with the techA as text
    bpy.data.curves.new(type="FONT", name='label').body = tech
    label = bpy.data.objects.new("label", bpy.data.curves['label'])
    center = sum((Vector(b) for b in label.bound_box), Vector())
    center /= 8
    meshed_up = bmesh.new()
    meshed_up.from_mesh(label.to_mesh())

    rotation_Z = Matrix.Rotation(radians(90), 4, 'Z')
    bmesh.ops.rotate(meshed_up, cent=center, matrix=rotation_Z, verts=meshed_up.verts)
    rotation_X = Matrix.Rotation(radians(180), 4, 'X')
    bmesh.ops.rotate(meshed_up, cent=center, matrix=rotation_X, verts=meshed_up.verts)

    # and then we create a mesh for object and link and clean
    label_mesh = bpy.data.meshes.new("label")
    meshed_up.to_mesh(label_mesh)
    meshed_up.free()
    bpy.data.curves.remove(bpy.data.curves['label'])
    label_object = bpy.data.objects.new(tech, label_mesh)
    bpy.context.collection.objects.link(label_object)

By the way, I left the rotation on X in, but it's what's causing your mirroring. If you remove the two lines with rotation_X in them, you won't have the mirror.

Had you wanted to continue to use the transform matrix, you would need to calculate a new center of rotation. This just seems clearer to read and easier to follow.

Look at this answer to see how to convert the code to use any arbitrary axis for rotation.

$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .