www.xbdev.net
xbdev - software development
Thursday April 30, 2026
Home | Contact | Support | Blender (.py) Scripts... Automating Blender ..
     
 

Blender (.py) Scripts...

Automating Blender ..

 

Blocks and Voxels Text


We can split the scene up into voxels (or cells) - do a quick ray intersection check - to convert the text (or object mesh) into blocks (Mincraft-like look).


The word for
The word for 'BLOCK' converted to bricks.


<?php
import bpy
import bmesh
from mathutils import Vector
import mathutils.bvhtree

# Clean up scene
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete(use_global=False)

# Create 3D text object
bpy.ops.object.text_add(location=(0, 0, 0))
text_obj = bpy.context.object
text_obj.data.body = "blocks"
text_obj.data.extrude = 0.1
text_obj.data.bevel_depth = 0.02
bpy.ops.object.convert(target='MESH')
bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY', center='BOUNDS')
bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)

# Get mesh and bounding box
mesh = text_obj.data
bbox_min = Vector((min(v.co.x for v in mesh.vertices),
                   min(v.co.y for v in mesh.vertices),
                   min(v.co.z for v in mesh.vertices)))
bbox_max = Vector((max(v.co.x for v in mesh.vertices),
                   max(v.co.y for v in mesh.vertices),
                   max(v.co.z for v in mesh.vertices)))
bbox_size = bbox_max - bbox_min

# Independent grid resolution per axis
res_x, res_y, res_z = 30, 15, 2  # <--- You can change these values
cell_size = Vector((bbox_size.x / res_x, bbox_size.y / res_y, bbox_size.z / res_z))

# Build bmesh and BVH tree for geometry queries
bm = bmesh.new()
bm.from_mesh(mesh)
bm.verts.ensure_lookup_table()
bm.faces.ensure_lookup_table()
bm.normal_update()
bvh = mathutils.bvhtree.BVHTree.FromBMesh(bm)

# Function: test if point is inside mesh using ray casting
def point_inside_mesh(point, bvh_tree):
    direction = Vector((1, 0, 0))  # +X direction
    count = 0
    hit = bvh_tree.ray_cast(point, direction)
    while hit[0]:
        count += 1
        point = hit[0] + direction * 0.001  # move slightly past hit
        hit = bvh_tree.ray_cast(point, direction)
    return count % 2 == 1

# Generate voxels
for x in range(res_x):
    for y in range(res_y):
        for z in range(res_z):
            center = bbox_min + Vector((x + 0.5, y + 0.5, z + 0.5)) * cell_size
            if point_inside_mesh(center, bvh):
                bpy.ops.mesh.primitive_cube_add(size=1, location=center)
                cube = bpy.context.object
                cube.dimensions = cell_size  # exact fit

# Hide original text mesh
text_obj.hide_viewport = True
text_obj.hide_render = True

print("Voxelization complete with custom resolution:", res_x, res_y, res_z)











 
Advert (Support Website)

 
 Visitor:
Copyright (c) 2002-2026 xbdev.net - All rights reserved.
Designated articles, tutorials and software are the property of their respective owners.