<?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)