# How to generate a 3D binary matrix after applying a remesh modifier

I apply a Remesh modifier (Blocks) on a mesh and I want to generate a 3D binary matrix (voxelization) where each cell contains 0 (the cell does not belongs to the mesh) or 1 (the cells belongs to the mesh).

• How is tied not s duplicate of your other recent question? Commented Dec 16, 2015 at 21:28
• @someonewithpc, it is the same problem but I find two different solutions. It is not a duplicate Commented Dec 16, 2015 at 21:29
• What is a binary matrix? Do you mean a separate file containing binary 3D data? Commented Dec 16, 2015 at 23:22
• I'm not sure I understand how this is different from your other question, can you elaborate? Commented Dec 17, 2015 at 1:42
• @ChristopherJanzon, Could you please explain how to pointInsideMesh(point,ob) work in your code? Commented Dec 21, 2015 at 17:01

Alright, if I understood your question correctly, you want a lot of ones and zeros from a 3D mesh. Here's a script:

import bpy

object = bpy.data.objects['Suzanne']
resolution = 20
file = open("C:\\tmp\\out.txt", 'w')

import mathutils
from mathutils import Vector
def pointInsideMesh(point,ob):
axes = [ mathutils.Vector((1,0,0)) ]
outside = False
for axis in axes:
mat = ob.matrix_world
mat.invert()
orig = mat*point
count = 0
while True:
location,normal,index = ob.ray_cast(orig,orig+axis*10000.0)
if index == -1: break
count += 1
orig = location + axis*0.00001
if count%2 == 0:
outside = True
break
return not outside

out = ""

for z in range(-resolution, resolution):
for y in range(-resolution, resolution):
for x in range(-resolution, resolution):
loc = Vector((x*bla, y*bla, z*bla))
print(loc)
if(pointInsideMesh(loc, object) == True):
out += '1'
else:
out += '0'
out += '\n'
out += '\n'
file.write(out)
file.close()


Again, I'm not fully sure this will answer your question, but I had fun making this script.

• thanks for your answer. I need just to save the binary value in a 3D matrix like nump.zeros((dimx, dimy, dimz)) then, I save the matrix as ,csv file. Commented Dec 17, 2015 at 5:26
• you can see my ansewer! Commented Dec 17, 2015 at 19:38

I changed the script so that it gets you a 3D numpy array, a 1D array, a CSV string and it writes that one to a file.

import bpy
import numpy as np
import mathutils
from mathutils import Vector

object = bpy.data.objects['Suzanne'] # Object
file = "C:\\tmp\\out.txt" # File output

resolution = 10 # Voxels per lengt unit
location = Vector((0.0,0.0,0.0)) # Center
size = Vector((1.0,1.0,1.0)) # Size

def pointInsideMesh(point,ob):
axes = [ mathutils.Vector((1,0,0)) ]
outside = False
for axis in axes:
mat = ob.matrix_world
mat.invert()
orig = mat*point
count = 0
while True:
location,normal,index = ob.ray_cast(orig,orig+axis*10000.0)
if index == -1: break
count += 1
orig = location + axis*0.00001
if count%2 == 0:
outside = True
break
return not outside

x_bla = int(size[0]/(1/resolution))
y_bla = int(size[1]/(1/resolution))
z_bla = int(size[2]/(1/resolution))

out=np.zeros((x_bla,y_bla,z_bla), dtype=np.int)

for z in range(-int(z_bla/2), int(z_bla/2)):
for y in range(-int(y_bla/2), int(y_bla/2)):
for x in range(-int(x_bla/2), int(x_bla/2)):
loc = Vector((location[0]+(1/resolution)*x, location[1]+(1/resolution)*y, location[2]+(1/resolution)*z))
if(pointInsideMesh(loc, object) == True):
out[x][y][z] = 1

out_1D = np.empty((x_bla*y_bla*z_bla), dtype=int)
out_csv = ""

count = 0
for z in out:
for y in z:
for x in y:
out_1D[count] = int(x)
count+=1
for a in out_1D:
out_csv += str(a)+","

print(out_csv)
out_file = open(file, "w")
out_file.write(out_csv)
out_file.close()


The way you use this script is changing 'Suzanne' in the top of the code with the name of the object you want to voxelize, change the rest of the parameters as you'd like and then do the following.

Choose screen layout Scripting, make a script and paste the script. With the script active, press Alt + P to run the script.

Your CSV file should end up where specified.

suppose that the object is located on (0,0,0) and we can put it in a 3D bounding box with defined by xmin,xmax, ymin,ymax and zmin zmax.

my code:

import bpy
import numpy as np
object = bpy.data.objects['modelPerson:Body']
#resolution = 20
xmin=-1
xmax=1
ymin=-1
ymax=1
zmin=0
zmax=1.75;
size =.02# size of voxel 2cm*2cm*2cm
matrix=np.zeros((len(np.arange(xmin,xmax,size)),len(np.arange(ymin,ymax,size)),len(np.arange(zmin,zmax,size))))
import mathutils
from mathutils import Vector
def pointInsideMesh(point,ob):
axes = [ mathutils.Vector((1,0,0)) ]
outside = False
for axis in axes:
mat = ob.matrix_world
mat.invert()
orig = mat*point
count = 0
while True:
location,normal,index = ob.ray_cast(orig,orig+axis*10000.0)
if index == -1: break
count += 1
orig = location + axis*0.00001
if count%2 == 0:
outside = True
break
return not outside

bla = 1
i=-1
for x in np.arange(xmin, xmax,size):
i=i+1
j=-1
for y in np.arange(ymin, ymax,size):
j=j+1
k=-1
for z in np.arange(0, zmax,size):
k=k+1
loc = Vector((x*bla, y*bla, z*bla))
print(loc)
if(pointInsideMesh(loc, object) == True):
matrix[i,j,k]=1
else:
matrix[i,j,k]=0
np.savetxt('matrix.csv', matrix.reshape(1,len(np.arange(xmin,xmax,size))*len(np.arange(ymin,ymax,size))*len(np.arange(zmin,zmax,size))),delimiter=',')