# 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? – someonewithpc Dec 16 '15 at 21:28
• @someonewithpc, it is the same problem but I find two different solutions. It is not a duplicate – BetterEnglish Dec 16 '15 at 21:29
• What is a binary matrix? Do you mean a separate file containing binary 3D data? – Christopher Janzon Dec 16 '15 at 23:22
• I'm not sure I understand how this is different from your other question, can you elaborate? – Ray Mairlot Dec 17 '15 at 1:42
• @ChristopherJanzon, Could you please explain how to pointInsideMesh(point,ob) work in your code? – BetterEnglish Dec 21 '15 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. – BetterEnglish Dec 17 '15 at 5:26
• you can see my ansewer! – BetterEnglish Dec 17 '15 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/(1/resolution))
y_bla = int(size/(1/resolution))
z_bla = int(size/(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+(1/resolution)*x, location+(1/resolution)*y, location+(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=',') 