# Voxel Generator Programs

<span class="rvts6">A spatial entity will go through several stages in its lifetime. It is possible to provide custom logic for some of these stages. This version of the Voxel Farm platform allows running custom Python programs to produce volumetric spatial output. This type of program is known in the system as a Voxel Generator program.</span>

<span class="rvts6">Typically, a Voxel Generator program will go through the following stages:</span>

1. <span class="rvts6">Ask the user for input values, in case the generated object is parametric, and the user can provide values to these parameters.</span>
2. <span class="rvts6">Set the spatial entity bounds. This step is optional but should be always included because it allows the system to evaluate the spatial entity only within its known bounds, which is more efficient.</span>
3. <span class="rvts6">For each voxel in the spatial entity, emit a field density o other voxel attribute.</span>

##### <span class="rvts16">Initialization</span>

<span class="rvts6">Before anything else, the Python program must include the Voxel Farm Python library:</span>

```python
import voxelfarm
```

<span class="rvts6"> </span><span class="rvts6">Voxel Generator programs must make sure to initialize the Voxel Farm Python library by calling “voxelfarm.init()”:</span>

```python
voxelfarm.init()
```

<span class="rvts6"> </span><span class="rvts6">The program can then ask the user information about the entity using the “voxelfarm.input()” function:</span>

```python
h = voxelfarm.input(“altitude”, “Altitude”)
```

<span class="rvts6"> </span>

<span class="rvts6">At this point, if the program knows of the spatial bounds of the entity, the bounds can be set by calling “voxelfarm.set\_entity\_bounds\_x”, “voxelfarm.set\_entity\_bounds\_y” and “voxelfarm.set\_entity\_bounds\_z”.</span>

<span class="rvts6">  
</span>

```python
vf.set_entity_bounds_z(h - 1000, h + 1000)
```

<span class="rvts6"> </span>

<span class="rvts6">The program can either output voxel data, or field data. Field data will be contoured on the fly by the system and it is best suited for smooth surfaces. If the program needs to produce sharp edges and points, it is better to output voxel data.</span>

<span class="rvts6">  
</span>

##### <span class="rvts16">Field Data Output</span>

<span class="rvts6">To output field data, the Python program must iterate over each voxel in the field. The range of voxels in a field is found in the “voxelfarm.field” variable:</span>

<span class="rvts6">  
</span>

```python
for v in voxelfarm.field

       # will execute for each voxel “v” in the field
```

<span class="rvts6"> </span>

<span class="rvts6">To get the coordinates in project space of the voxel, use the “voxelfarm.get\_field\_origin” function:</span>

```python
for v in voxelfarm.field

       p = voxelfarm.get_field_origin(v) # returns tuple for xyz
```

<span class="rvts6"> </span>

<span class="rvts6">Using these coordinates, the user program can make useful computations. The program will have access to any Python library that is included in the Content Server. These computations eventually will produce a value for the field in the voxel’s origin. Voxel Farm will produce a surface wherever the field becomes zero. Places where the field is positive, will be considered “outside” the surface. Places where field is negative, will be considered solid and inside the surface.</span>

<span class="rvts6">To set the field value for the voxel, call the “voxelfarm.set\_field” function:</span>

```python
for v in voxelfarm.field

       p = voxelfarm.get_field_origin(v) # returns tuple for xyz

       field = MyFieldFunction(p) # a call to custom function that outputs the field

       voxelfarm.set_field(v, field)
```

<span class="rvts6"> </span>

<span class="rvts6">The following program creates an infinite plane with bumps on top of it:</span>

```python
import voxelfarm as vf

import math

vf.init()

h = vf.input("h", "Altitude")

vf.set_entity_bounds_z(h - 1000, h + 1000)

for v in vf.field:

    p = vf.get_field_origin(v)

    dh = 300 * (math.sin(0.001 * p[0]) + math.sin(0.001 * p[1]) + math.sin(0.001 * p[2]))

    dh = dh + 100 * (math.sin(0.01 * p[0]) + math.sin(0.01 * p[1]) +  + math.sin(0.01 * p[2]))

    vf.set_field(v, p[2] - h - dh)
```

<span class="rvts6"> </span>

##### <span class="rvts16">Voxel Data Output</span>

<span class="rvts6">Consider using Voxel Data output in cases where you need the resulting spatial entity to contain sharp features.</span>

<span class="rvts6">Voxel Farm’s voxel format allows for both sharp and smooth features. Once a spatial entity is built to output voxel data, its program must at least output a material definition for each voxel. Additional optional channels are a 3D surface vector and a color.</span>

<span class="rvts6">To output voxel data, the Python program must iterate over each voxel in the request. The range of voxels in a request is found in the “voxelfarm.voxels” variable:</span>

```python
for v in voxelfarm.voxels

       # will execute for each voxel “v” in the request
```

<span class="rvts6"> </span>

<span class="rvts6">To get the coordinates in project space of the voxel, use the “voxelfarm.get\_voxel\_origin” function:</span>

<span class="rvts6">  
</span>

```python
for v in voxelfarm.field

       p = voxelfarm.get_voxel_origin(v) # returns tuple for xyz
```

<span class="rvts6">Using these coordinates, the user program can make useful computations. The program will have access to any Python library that is included in the Content Server. These computations eventually will produce a value that will determine if the voxel is set as solid material, and which values should be used for color and the surface position inside the voxel.</span>

<span class="rvts6">To set the material for a voxel, call the “voxelfarm.set\_material” function:</span>

```python
for v in voxelfarm.field

       p = voxelfarm.get_field_origin(v) # returns tuple for xyz

       field = MyFieldFunction(p) # a call to custom function that outputs a field

       if (field < 0.0)

               voxelfarm.set_material(v, 1)
```

<span class="rvts6"> </span>

<span class="rvts6">The following program creates an infinite plane with bumps on top of it:</span>

```python
import voxelfarm as vf

import math

vf.init()

h = vf.input("h", "Altitude")

vf.set_entity_bounds_z(h - 1000, h + 1000)

for v in vf.voxels:

    p = vf.get_voxel_origin(v)

    dh = 300 * (math.sin(0.001 * p[0]) + math.sin(0.001 * p[1]) + math.sin(0.001 * p[2]))

    dh = dh + 100 * (math.sin(0.01 * p[0]) + math.sin(0.01 * p[1]) +  + math.sin(0.01 * p[2]))

    field = p[2] - h - dh

    if (field < 0.0):

        vf.set_material(v, 1)
```