<p>Voxels are pretty much an interpolation of data points and you can only <em>smooth</em> them out by reducing the fidelity. Why? Because in acquiring the voxel, you already lost fidelity. Let me take you through an example.</p>
<h2>The basics</h2>
<p>For our basics we take a circle of Radius <span class="math-container">$R$</span>. It can be fully described the following: <span class="math-container">$$x^2+y^2=R$$</span> All solutions to this give us points on the circle.</p>
<p>Its representation as a single voxel with resolution length <span class="math-container">$r$</span> is that of a square. The square with its center on <span class="math-container">$\{0,0\}$</span> we will call the voxel of resolution <span class="math-container">$r$</span> around that coordinate. It is defined as <span class="math-container">$$x =\{0.5r,-0.5r\} \land y=\{-0.5r \to 0.5r\}$$</span> <span class="math-container">$$y=\{0.5r,-0.5r\}\land x=\{-0.5r \to 0.5r\}$$</span> Other squares then can be created by simply adding the respective cell's center's coordinates <span class="math-container">$\{a,b\}$</span> for <span class="math-container">$$x' =\{0.5r,-0.5r\}+a \land y'=\{-0.5r \to 0.5r\}+b$$</span> <span class="math-container">$$y'=\{0.5r,-0.5r\}+b\land x'=\{-0.5r \to 0.5r\}+a$$</span></p>
<p>Looks complicated? True, but you see: the first formula is a circle with radius <span class="math-container">$R$</span> containing an area of <span class="math-container">$A=\pi*R^2$</span>. The latter two blocks define the square of length <span class="math-container">$r$</span> and area <span class="math-container">$A=r^2$</span>. By clever positioning, the grid with <span class="math-container">$R=r$</span> has its <span class="math-container">$\{0,0\}$</span> Voxel wholly contained in that circle. Or in a picture, it looks like this, using <span class="math-container">$r=R=50$</span> (and thus a diameter of 100).</p>
<p><a href="https://i.sstatic.net/J1GWB.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/J1GWB.png" alt="50 unit radius circle, overlay of a 50 unit square grid" /></a></p>
<p>As you see, there is an area between the circle and the square - this is fidelity that is lost when converting to voxels. In a typical voxel transformation, there is only one choice: at which point of filling does a voxel get filled to 100% and at which it gets filled to 0%. Let's assume the circle there is actually a cylinder of 50 units height. Depending on where we set the cutoff, we now get one of three solutions. We could end with one voxel, using 50% as the cutoff point. We could end with a plus shape using 45% as the cutoff point or a square using any filling above 0% as a cutoff, as shown in the following picture.</p>
<p><a href="https://i.sstatic.net/fDiid.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/fDiid.png" alt="3 different voxel representations of the same cylinder of 50 unit radius using 50 unit wide cells" /></a></p>
<p>It gets even more complicated if you don't have the circle and the grid's center overlap like n the example above: there is a &quot;2x2x1&quot; voxel solution that reflects a <em>differently aligned</em> circle with the same cutoff point as the &quot;1x1x1&quot; solution! That circle is (in the next graphic) centered around <span class="math-container">$\{3.5 r,0.5 r\}$</span> and thus shifted half a unit up and right so its center overlaps with a corner of the voxels.</p>
<p><a href="https://i.sstatic.net/AKfwY.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/AKfwY.png" alt="a shifted circle in the same grid" /></a></p>
<h2>Lost fidelity can't be regained</h2>
<p>You see, you have lost a lot of fidelity in voxelizing. All circles have become squares. All squares <strong>also</strong> are squares. Likewise, all curves in between have become squares.</p>
<h2>The problem</h2>
<p>So, it is nigh impossible for a computer to identify, what once was a circle square or square before all was made squares. Think... Colors: I take a picture of a smiley. I split it in half and then desaturate the upper half of the right side to black and white and totally saturate the lower. Those are two different ways to totally loose the color information. In the upper case you retain <em>one</em> information more, because the algorithm of making all colors but black white retains the black information, while the lower parts algorithm only retains the outer shape.</p>
<p><a href="https://i.sstatic.net/KaApD.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/KaApD.png" alt="A Smiley, left side yellow and with a face, right side upper half desaturated to black and white, lower half oversaturated to only black." /></a></p>
<p>If you only had the black and white smiley, you have lost the information about its color in total. If you only have the black outline, you have lost also the information of the face.</p>
<p>Voxelizaion does loose about that much information, depending on the settings.</p>
<h2>Reversing Voxelisation is interpreting the voxel structure</h2>
<p>It's not possible for a computer algorithm to simply invert the process. However, there <strong>are</strong> ways to interpret a voxelized object and try to re-create one of the possible objects that have led to this item, assuming that an &quot;any fill is a voxel&quot; algorithm has been used.</p>
<p>For such, you'd import the model into a software such as Blender, solidify it so that it is one mesh without internal faces, and then running a smoothing operation. You don't get <em>the</em> object that generated that voxel structure, but you get <strong>an</strong> Object that would generate that voxel structure.</p>
<p><a href="https://i.sstatic.net/pAM2I.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/pAM2I.png" alt="Example of a solidified voxel-object undergoing a smoothing operation to generate one possible parent." /></a></p>
<p>How good the interpretation of the voxels is, depends on the resolution chosen in the start. If <span class="math-container">$r$</span> is small enough, then the resulting interpretation, together with some artistic definition of which corners are sharp and quite some manual post-processing (which requires the human eye) can lead to a somewhat good approximation of the actual object you believe lead to the voxel structure.</p>

CC BY-SA 4.0
2022-03-17T12:18:29.627Z
2022-03-17T12:18:29.627Z
Trish
<p>I have a (preferably in matlab) 3D array of Booleans describing a voxel structure. I want to turn this into an .stl file but I don't want the final result to have the jagged cubes.</p>
<p>I have tried putting the voxel array into a marching cube algorithm but the resulting STL is not a solid, some parts are infinitely thin sheets. I want every voxel to be represented by something solid.</p>
<p>Is there a way to achieve this?</p>

CC BY-SA 4.0
2022-03-20T00:59:34.743Z
I’d say that there’s something wrong with your Marching Cubes algorithm. It ought to produce a solid object. Then, you can smooth the triangles in that solid object.
bubba
CC BY-SA 4.0
2022-03-20T23:52:45.927Z
@bubba I think that was the case. I needed to surround the structure with 0, to make the code acknowledge the boundary as a facet of the solid.
Gappy Hilmore
<3d-models><stl>
Obtaining a smooth solid .stl from voxel data
Gappy Hilmore
# Obtaining a smooth solid .stl from voxel data

(Asked by: username_0 on 2022-03-16)

I have a (preferably in matlab) 3D array of Booleans describing a voxel structure. I want to turn this into an .stl file but I don't want the final result to have the jagged cubes.

I have tried putting the voxel array into a marching cube algorithm but the resulting STL is not a solid, some parts are infinitely thin sheets. I want every voxel to be represented by something solid.

Is there a way to achieve this?

**Tags:** 3d-models, stl

> **Comments:**
> **username_1**: I’d say that there’s something wrong with your Marching Cubes algorithm. It ought to produce a solid object. Then, you can smooth the triangles in that solid object.  
> **username_0**: @username_1 I think that was the case. I needed to surround the structure with 0, to make the code acknowledge the boundary as a facet of the solid.  

---

## 1 answers

### Answer by username_2 on 2022-03-17. Score: 2 | Accepted answer

Voxels are pretty much an interpolation of data points and you can only *smooth* them out by reducing the fidelity. Why? Because in acquiring the voxel, you already lost fidelity. Let me take you through an example.

## The basics

For our basics we take a circle of Radius $R$. It can be fully described the following: $$x^2+y^2=R$$ All solutions to this give us points on the circle.

Its representation as a single voxel with resolution length $r$ is that of a square. The square with its center on $\{0,0\}$ we will call the voxel of resolution $r$ around that coordinate. It is defined as $$x =\{0.5r,-0.5r\} \land y=\{-0.5r \to 0.5r\}$$ $$y=\{0.5r,-0.5r\}\land x=\{-0.5r \to 0.5r\}$$ Other squares then can be created by simply adding the respective cell's center's coordinates $\{a,b\}$ for $$x' =\{0.5r,-0.5r\}+a \land y'=\{-0.5r \to 0.5r\}+b$$ $$y'=\{0.5r,-0.5r\}+b\land x'=\{-0.5r \to 0.5r\}+a$$

Looks complicated? True, but you see: the first formula is a circle with radius $R$ containing an area of $A=\pi\*R^2$. The latter two blocks define the square of length $r$ and area $A=r^2$. By clever positioning, the grid with $R=r$ has its $\{0,0\}$ Voxel wholly contained in that circle. Or in a picture, it looks like this, using $r=R=50$ (and thus a diameter of 100).

[![50 unit radius circle, overlay of a 50 unit square grid](https://i.sstatic.net/J1GWB.png)](https://i.sstatic.net/J1GWB.png)

As you see, there is an area between the circle and the square - this is fidelity that is lost when converting to voxels. In a typical voxel transformation, there is only one choice: at which point of filling does a voxel get filled to 100% and at which it gets filled to 0%. Let's assume the circle there is actually a cylinder of 50 units height. Depending on where we set the cutoff, we now get one of three solutions. We could end with one voxel, using 50% as the cutoff point. We could end with a plus shape using 45% as the cutoff point or a square using any filling above 0% as a cutoff, as shown in the following picture.

[![3 different voxel representations of the same cylinder of 50 unit radius using 50 unit wide cells](https://i.sstatic.net/fDiid.png)](https://i.sstatic.net/fDiid.png)

It gets even more complicated if you don't have the circle and the grid's center overlap like n the example above: there is a "2x2x1" voxel solution that reflects a *differently aligned* circle with the same cutoff point as the "1x1x1" solution! That circle is (in the next graphic) centered around $\{3.5 r,0.5 r\}$ and thus shifted half a unit up and right so its center overlaps with a corner of the voxels.

[![a shifted circle in the same grid](https://i.sstatic.net/AKfwY.png)](https://i.sstatic.net/AKfwY.png)

## Lost fidelity can't be regained

You see, you have lost a lot of fidelity in voxelizing. All circles have become squares. All squares **also** are squares. Likewise, all curves in between have become squares.

## The problem

So, it is nigh impossible for a computer to identify, what once was a circle square or square before all was made squares. Think... Colors: I take a picture of a smiley. I split it in half and then desaturate the upper half of the right side to black and white and totally saturate the lower. Those are two different ways to totally loose the color information. In the upper case you retain *one* information more, because the algorithm of making all colors but black white retains the black information, while the lower parts algorithm only retains the outer shape.

[![A Smiley, left side yellow and with a face, right side upper half desaturated to black and white, lower half oversaturated to only black.](https://i.sstatic.net/KaApD.png)](https://i.sstatic.net/KaApD.png)

If you only had the black and white smiley, you have lost the information about its color in total. If you only have the black outline, you have lost also the information of the face.

Voxelizaion does loose about that much information, depending on the settings.

## Reversing Voxelisation is interpreting the voxel structure

It's not possible for a computer algorithm to simply invert the process. However, there **are** ways to interpret a voxelized object and try to re-create one of the possible objects that have led to this item, assuming that an "any fill is a voxel" algorithm has been used.

For such, you'd import the model into a software such as Blender, solidify it so that it is one mesh without internal faces, and then running a smoothing operation. You don't get *the* object that generated that voxel structure, but you get **an** Object that would generate that voxel structure.

[![Example of a solidified voxel-object undergoing a smoothing operation to generate one possible parent.](https://i.sstatic.net/pAM2I.png)](https://i.sstatic.net/pAM2I.png)

How good the interpretation of the voxels is, depends on the resolution chosen in the start. If $r$ is small enough, then the resulting interpretation, together with some artistic definition of which corners are sharp and quite some manual post-processing (which requires the human eye) can lead to a somewhat good approximation of the actual object you believe lead to the voxel structure.


---

