### Subscribe to our free newsletter

To make sure you won't miss any valuable content we share with our community.

## Different Kinds of Lattice Structure Using Blender

In this article, we are going to directly use the Blender modifiers to create an aesthetic costume lattice structure in Blender. But, as we have said before, the purpose of creating these kinds of lattice structures is art and aesthetics, because the end result is more stochastic rather than deterministic. We start with adding a simple shape like a cube, cylinder, or cone and use modifiers to change the formation of the mesh, then use the Wireframe modifier to make a lattice form out of our mesh, after that, by using other modifiers like Multiresolution or smooth, we post-process our design.

## Using Blender Modifiers to Create A Lattice Structure

In this 3rd part of our tutorial, we are going to directly use the Blender modifiers to create an aesthetic costume lattice structure but as we have said before the purpose of creating this kind of lattice structure is art and aesthetics, because the end result is more stochastic rather than deterministic.

We start with adding a simple shape like a cube, cylinder, or cone and use modifiers to change the formation of the mesh, then use the Wireframe modifier to make a lattice form out of our mesh, after that, by using other modifiers like Multiresolution or smooth, we post-process our design. With that said, let’s get started:
1. creating a cone:
Click on add button, on top of the page and go to `mesh >> cone`. And you can see that a cone like below is created:

2. Modifying the object:
In the modifiers section, choose the multiresolution modifier and by using `Multiresulotion >> Subdivide`, you can subdivide (increase) the number of meshes on the object like the below photo:

3. Scaling:
Now, scale the the modified cone in x-y direction To get a shape like below:

4. Decreasing the number of meshes:
In the modifiers section, select the Decimate modifier and by using the `Decimate >> Unsubdivide`, decrease the number of meshes:

5. Creating a lattice form:
In the modifiers section, find the wireframe and use it to create lattice form of the object like below:

6. Finding the right thickness:
Change the thickness of the wireframe according to the size of the object. This part is a little bit tricky because if they are too thin, the wireframe will shrink at the time of smoothing and if they are too thick, they may not create a nice structure or holes may shrink instead of the wireframes.

7. Smoothing the object:
Use the Multiresolution modifier once again to make the object smoother:

8. Final scaling:
Scale the object according to your design preferences.

Notice that the procedure of designing the lattice structure is not the same for all the objects. It is very optional and based on your taste which method to choose.

In the next part, we are going to create a lattice structure using Blender for a different object with a few differences in the procedure.

## Tricky Parts of Designing Lattice Structures in Blender

In this section, we are going to directly use the Blender modifiers to create aesthetic costume lattice structures but as we have said before the purpose of creating this kind of lattice structure is art and aesthetics, because the end result is more stochastic rather than deterministic. The main focus of this section is to teach you the tricky parts of designing these structures.

Mesh structures:

The most important part of designing every lattice structure is the mesh formation and there are many ways to change the way the meshes are formed. Different mesh formations are as follows:
1. Triangular mesh
2. Voxel mesh
4. Blocks
5. Smooth
And so on.

The trickiest part about designing lattice structures is finding the best option for forming the meshes.

### Lattice Structure for A Clyinder

The next design we are going to work on is the lattice structure for a cylinder. The recommended steps are as follows:
1. Creating a cylinder:
From the top of the page, click on `Add >> Mesh >> Cylinder` and you will be able to see that we have a cylinder created in the origin.

2. Remesh the object in voxel form:
By using the Remesh modifier from the modifiers section, you can change the formation of the meshes from triangular to voxel-based.

3. Change the size of the voxels:
By selecting the remesh modifier from the modifiers section, you can remesh the object from triangular to voxel-based and also decrease the number of meshes leading to making it larger.

4. Subdivide the mesh
Using the Multi-resolution modifier, make the object smoother.

5. Unsubdivide the mesh:
Using the decimate modifier, unsubdivided the mesh so that we will have larger holes in our lattice structure. The reason why we subdivide and then unsubdivided is that the shape of the meshes changes and becomes more beautiful.

6. Wireframe modifier:
And then, use the Wireframe modifier to form the lattice shape.

7. thickness of the wireframe:
Change the thickness of the wireframe to reach the optimal shape.

8. Another subdivision:
Again, using the Multi-resolution modifier, subdivide the mesh to get a smooth shape.

You might want to have your own costume lattice shape to be applied to an object. In that case, we have a more complex process of placing the lattice objects on the main object and smoothing the end result. That kind of lattice is better to be performed with the aid of python blender API. In the next chapter, we work on the dependencies that will lead us to the costume shape lattice. The benefit of this kind of lattice is that the dimension of the main object will not be affected by the other modifiers that try to remesh it.

## Translating Shapes of the Lattice Structure Using Blender

So far we have learned many ways to create lattice structures, but what we haven’t learned about is how we can create these holes with the shape that we want and the places that we choose to be. In this section, we are going to create a tool to translate our desired shape to the specified vertex of an object and then we will Boolean the difference between the translated object from the main object. We use many of the functions that we used in Creating a tool in Blender to instantly translate an object to the point we show with the cursor article.

### Python Scripts

So let’s get started:
``````
import  bpy
import bmesh
import math

####################################################################
#####                Utility Functions
####################################################################
class BOOLEAN_TYPE:
UNION = 'UNION'
DIFFERENCE = 'DIFFERENCE'
INTERSECT = 'INTERSECT'

def make_boolean(obj1, obj2, boolean_type):
if not obj1 or not obj2:
return

modifier = obj1.modifiers.new(name='booly', type='BOOLEAN')
modifier.object = obj2
modifier.operation = boolean_type

res = bpy.ops.object.modifier_apply({"object": obj1}, apply_as='DATA', mod-ifier=modifier.name)

assert "FINISHED" in res, "Error"

def solidify(obj,offset,thickness):

bpy.context.object.modifiers["Solidify"].offset = offset
bpy.context.object.modifiers["Solidify"].thickness = thickness
bpy.ops.object.modifier_apply(apply_as='DATA', modifier="Solidify")

```
```
The above function will convert a solid object to a shell of its shape.
``````
def object_closest_point_mesh(p, obj):

result, location, normal, face_index = obj.closest_point_on_mesh(p)
assert result, "Can't find closest point on mesh"
location = location.to_tuple()
normal = normal.to_tuple()
return location + normal  # return tuple of 6 floats

def obj_transform(filename, obj_name, size, location, angle):

ob = bpy.context.scene.objects[obj_name]       # Get the object
bpy.ops.object.select_all(action='DESELECT') # Deselect all objects
bpy.context.view_layer.objects.active = ob   # Make the cube the active object
ob.select_set(True)

obj = bpy.data.objects[obj_name]
obj.location = location

bpy.ops.transform.rotate(value=angle, orient_axis='Z',
orient_type='GLOBAL',
orient_matrix=((1, 0, 0), (0, 1, 0), (0, 0, 1)),
constraint_axis=(False, False, True))

def object_put_part2(part_name, point, obj, scale, obj_name):
vx,vy,vz,a,b,c = object_closest_point_mesh(point, obj)
a1 = math.atan2(b, a)
obj_transform(part_name, obj_name, scale, (point[0], point[1], point[2]), a1)

def get_vertex():
bm = bmesh.new()
ob = bpy.context.active_object
bm = bmesh.from_edit_mesh(ob.data)

points = []
for v in bm.verts:
if (v.select == True):
obMat = ob.matrix_world
points.append(obMat @ v.co)

for p in points:
pOb = bpy.data.objects.new("VertexPoint", None)
pOb.location = p
return p

def delete_object(objName):

bpy.ops.object.select_all(action='DESELECT')
bpy.data.objects[objName].select_set(True) # Blender 2.8x
bpy.ops.object.delete()

def get_object_by_name(obj_name):

assert obj_name in bpy.data.objects, "Error getting object by name:{}".format(obj_name)
obj = bpy.data.objects[obj_name]
return obj

####################################################################
########             Main Panel
####################################################################

class MainPanel(bpy.types.Panel):
bl_idname = "VIEW_PT_MainPanel"
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_category = 'Design Automation'

def draw(self, context):
layout = self.layout
layout.scale_y = 1.2

row = layout.row()
row.label(text= "Design Automation", icon= 'OBJECT_ORIGIN')
row = layout.row()
row.operator("wm_function.myop", text= "Create single Lattice")

####################################################################
####                  Main UI ّFunctions
####################################################################

class WM_Function_myOp(bpy.types.Operator):
"""Go to edit mode and determine the point then Click the button"""
bl_label = "Our customized function"
bl_idname = "wm_function.myop"

scale = bpy.props.FloatProperty(name= "Enter the scale of lattice", default= 1)
Lattice_Name = bpy.props.StringProperty(name= "Enter the scale of lattice", default= '')

def execute(self, context):

Scale = self.scale
Lattice_Name = self.Lattice_Name
point = get_vertex()
bpy.ops.object.editmode_toggle()
obj = get_object_by_name('Icosphere')
solidify(obj, 0, 0.02)
obj2 = get_object_by_name('%s'%Lattice_Name)
object_put_part2('%s'%Lattice_Name, point, obj, Scale, '%s'%Lattice_Name)
make_boolean(obj,obj2,'DIFFERENCE')
delete_object("VertexPoint")
return {'FINISHED'}

def invoke(self, context, event):

return context.window_manager.invoke_props_dialog(self)

```
```

#### What We Have Done in the Scripts Above

In the above def execute function, at first get the vertex of the object, then we will create the shell of the main object. After that, we get the name of the lattice shape that has been imported or created by the user. In the next step, we will translate the lattice to the specified point by the user and finally we apply the boolean difference function to the objects. Do not forget the below scripts related to registering and unregistering the classes.
``````
####################################################################
#####                     Register and Unregister
####################################################################

def register():
bpy.utils.register_class(MainPanel)
bpy.utils.register_class(WM_Function_myOp)

def unregister():
bpy.utils.unregister_class(MainPanel)
bpy.utils.unregister_class(WM_Function_myOp)

if __name__ == "__main__":
register()

```
```

### How to Use the Translating Tool

Now, it is time to test the panel we have designed and created. To do so, select a vertex on the object in edit mode:

Then, simply click on the button on the panel (Create single lattice).

And here we go! You can now see the lattice structure with the exact shape that you want on the object.

### Wrapping Up

In this tutorial, we have managed to design an aesthetic internal lattice structure manually without the need for any coding python scripts. The design process is easy, however, you need to repeat and practice it in order to easily deal with the tricky parts.

Then, we got familiar with the tricks of creating aesthetic internal lattice structures and how to mesh formations such as triangular, voxel-based, and other ones that can influence the beauty of the design of these objects.

Moreover, we have managed to design a panel using python scripts (Blender Python API) to create any number of lattices with any shape and any size on our object. The only thing that the user interface wants from the user is the vertex on which the lattice is going to be placed. We can use this panel to create our custom shape lattice structure with accurate dimensions.

## Creating Different Kinds of Internal Lattice Structure: A Complete Tutorial

In this article, we are going to design a scientific and accurate kind of lattice structure for a cube or other geometrical 3D shapes using Blender. The difference between a scientific and an aesthetic lattice structure is that in a scientific lattice structure we need accurate dimensions as opposed to aesthetic lattice structures where beauty is the priority. We use different methods for modeling the 2 kinds of lattice structures.

## An introduction to Internal Lattice Structure

Internal lattice structures are used for many different purposes. And there are many ways to design them in Blender or Meshmixer software, one of which is to use wireframes which gives you a low-quality lattice structure even if you utilize the modifier. It would mostly be useful for artistic purposes meaning that you cannot precisely determine the size of the holes and channels and the whole object itself.

We usually design our lattice structures this way when we want some aesthetics in our design but it lacks accuracy. The tool we use for this type of modeling is a wireframe modifier next to some other tools that can be used according to the preferences of the design.

As you can see, the above photo is the wireframe of a cube that is shrunk and has been made so modern and artistic that way but the problem is that it cannot be used for the cases that require size accuracy.

The design that we are going to work on is cube-like below. A kind of lattice structure that we can set its height, width, and length and we also determine the size of the holes and channels precisely.

We know that designing each one of these, takes many hours manually. However, if we design it through the code and design a panel with a button that receives all of the sizes and creates such an object, it takes only a few seconds to design any of these objects by any size, not to mention that, if we want a sphere shape to have such kinds of lattice structures we can simply intersect that object with this cube using the boolean modifier.

The only problem that we face when we design such kind of an object, is that in Blender boolean difference is not as robust as it should be and as a result, when we want to boolean difference a ton of these square-shaped cylinders, we face an object with so many open meshes and the result will be horrible. The fix here is to use a utility function we have written called makeUnionOpt which is an optimized function that uses joining as a way to boolean union several objects. Notice that instead of boolean difference, we can use union in other words instead of cutting through a large cube, we make our large lattice structure using a grid of small square-shaped cylinders that are placed in a sequence.

In this part of the tutorial, we focus on the utility functions that will help us design our main lattice structure.
``````
import  bpy

####################################################################
#####                Utility Functions
####################################################################

def rotation_X(object,D_yz):
context = bpy.context
scene = context.scene
cube = scene.objects.get(object)
bpy.ops.transform.rotate(value= D_yz, orient_axis='X',
orient_type='GLOBAL',
orient_matrix=((1, 0, 0), (0, 1, 0), (0, 0, 1)),
constraint_axis=(True, False,False ))

def rotation_Y(object,D_xz):
context = bpy.context
scene = context.scene
cube = scene.objects.get(object)
bpy.ops.transform.rotate(value= D_xz, orient_axis='Y',
orient_type='GLOBAL',
orient_matrix=((1, 0, 0), (0, 1, 0), (0, 0, 1)),
constraint_axis=(False, True,False ))

def rotation_Z(object,D_xy):
context = bpy.context
scene = context.scene
cube = scene.objects.get(object)
bpy.ops.transform.rotate(value= D_xy, orient_axis='Z',
orient_type='GLOBAL',
orient_matrix=((1, 0, 0), (0, 1, 0), (0, 0, 1)),
constraint_axis=(False, False,True ))

```
```
The above functions will determine the rotation of any object that is given in all different directions.
``````
def make_cube(name,Features):

lx = Features[0]
ly = Features[1]
lz = Features[2]

dx = Features[3]
dy = Features[4]
dz = Features[5]

rx = Features[6]
ry = Features[7]
rz = Features[8]

bpy.ops.transform.resize(value=(dx, dy, dz))
for obj in bpy.context.selected_objects:
obj.name = name
rotation_X(name,rx)
rotation_Y(name,ry)
rotation_Z(name,rz)

context = bpy.context
scene = context.scene
cube = scene.objects.get(name)
cube.location = (lx,ly,lz)

```
```
The above function will make a cube with the given name, location on all 3 axes, direction, and their dimension in length, width, and height (The size).
``````
def get_object_by_name(obj_name):
assert obj_name in bpy.data.objects, "Error getting object by name: {}".format(obj_name)
obj = bpy.data.objects[obj_name]

return obj

```
```
The above function will select an object from the list, using its name.
``````
def make_custom_context(*object_names, base_context=None, mode=None):
if base_context is not None:
ctx = base_context
else:
ctx = {}
if mode is not None:
assert mode in ('OBJECT', 'EDIT'), "Wrong mode used"
ctx['mode'] = mode
objs = [get_object_by_name(obj_name) for obj_name in object_names]
ctx['active_object'] = ctx['object'] = objs[0]
ctx['selected_editable_objects'] = ctx['selected_objects'] = objs
ctx['editable_objects'] = ctx['selectable_objects'] = ctx['visible_objects'] = objs

return ctx

def makeUnionOpt(*object_names):
ctx = bpy.context.copy()
if object_names:
ctx = make_custom_context(*object_names, base_context=ctx, mode='OBJECT')
bpy.ops.object.join(ctx)  # mostly the same as export/import combination

```
```
Using the 2 functions above, we will be able to boolean union a lot of objects altogether at once without bringing up any open or destroyed meshes. In the next part, we will make lattice structures using the above utility functions.

## Creating the Main Panel of Lattice Structure

In this second part of our tutorial, we want to create a panel in Blender to be able to easily design any shape of the lattice structure that we want with any size.

In the main panel, here we set the required button and the parameters that we want from the user.
``````
####################################################################
########             Main Panel
####################################################################

class MainPanel(bpy.types.Panel):
bl_idname = "VIEW_PT_MainPanel"
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_category = 'Design Automation'

def draw(self, context):
layout = self.layout
layout.scale_y = 1.2

row = layout.row()
row.label(text= "Design Automation", icon= 'OBJECT_ORIGIN')
row = layout.row()
row.operator("wm_function.myop", text= "Create Cube with internal lattice structures")

####################################################################
####                  Main UI ّFunctions
####################################################################

class WM_Function_myOp(bpy.types.Operator):
"""Click to apply our customized function"""
bl_label = "Our customized function"
bl_idname = "wm_function.myop"

ls = bpy.props.FloatProperty(name= "Enter the size of lattice", default= 0.25)
cw = bpy.props.FloatProperty(name= "Enter the WIDTH of the object", default= 2.5)
cl = bpy.props.FloatProperty(name= "Enter the LENGTH of the object", default= 5.0)
ch = bpy.props.FloatProperty(name= "Enter the HEIGHT of the object", default= 1.0)

def execute(self, context):

LATTICE_SIZE = self.ls
CUBE_WIDTH = self.cw
CUBE_LENGTH = self.cl
CUBE_HEIGHT = self.ch
return {'FINISHED'}

def invoke(self, context, event):
return context.window_manager.invoke_props_dialog(self)
```
```
After receiving the required parameters from the user, we will determine the number of square cylinders or rods in all 3 axis:
``````
nRodx = (CUBE_LENGTH / LATTICE_SIZE)+2
nRody = (CUBE_WIDTH / LATTICE_SIZE)+2
nRodz = (CUBE_HEIGHT / LATTICE_SIZE)+2

```
```
We also apply a modification in the width, length, and height of the cube, as we want to place all of the holes inside the cube.
``````
CUBE_WIDTH = CUBE_WIDTH + LATTICE_SIZE*3
CUBE_LENGTH = CUBE_LENGTH + LATTICE_SIZE*3
CUBE_HEIGHT = CUBE_HEIGHT + LATTICE_SIZE*3

```
```
And we also determine the height of each square rod:
``````
rodHeightx = CUBE_LENGTH - LATTICE_SIZE*2
rodHeighty = CUBE_WIDTH - LATTICE_SIZE*2
rodHeightz = CUBE_HEIGHT - LATTICE_SIZE*2

```
```
And the starting point of where we want to start placing our rods:
``````
startx = CUBE_LENGTH/2 - LATTICE_SIZE*1.5
starty = CUBE_WIDTH/2 - LATTICE_SIZE*1.5
startz = CUBE_HEIGHT/2 - LATTICE_SIZE*1.5

```
```
Now, we use for loops to create and places all the cubes on `XY` plane:
``````
for i in range(int(nRodx/2)):
for j in range(int(nRody/2)):
make_cube("Cube",(startx-2*i*LATTICE_SIZE, starty-2*j*LATTICE_SIZE, 0, LATTICE_SIZE/2,
LATTICE_SIZE/2, rodHeightz/2, 0, 0, 0))
if((i+j) != 0):
makeUnionOpt('Cube','Cube.001')

```
```
Placing the vertical cubic cylinders: If we run the code up to here, we will get the following result. We will be able to see a large set of cubic cylinders that appear all at once, when we click the button (Create Cube with internal lattice structures):

### Placing the Horizontal Cubic Cylinders

We are not done yet. To get the complete lattice structure we should place the horizontal cubic cylinders. To do so, we should write the following for loops in the `def execute()` function after the for loops written for the vertical rods. we should place the rods in `XZ` plane (horizontal cubic cylinders) using the following script:
``````
for i in range(int(nRodx/2)):
for j in range(int(nRodz/2)):
make_cube("C",(startx-2*i*LATTICE_SIZE, 0, startz-2*j*LATTICE_SIZE,LATTICE_SIZE/2,rodHeighty/2,
LATTICE_SIZE/2, 0, 0, 0))
if((i+j) != 0):
makeUnionOpt('C', 'C.001')

```
```
The result up to here will be like this:

The above result looks much closer to the expected result. We only need another set of rods normal to `YZ` plane.

### Completing the Project

And finally, we should place the rods on `YZ` plane to get the complete model of internal lattice structure. The following code containing for loops should be writ-ten after the 2 previous set of for loops to serve our purpose:
``````
for i in range(int(nRody/2)):
for j in range(int(nRodz/2)):
make_cube("Cu", (0, starty-2*i*LATTICE_SIZE, startz-2*j*LATTICE_SIZE, rodHeightx/2,
LATTICE_SIZE/2, LATTICE_SIZE/2, 0, 0, 0))
if((i+j) != 0):
makeUnionOpt('Cu','Cu.001')

```
```
We also boolean union all three set of rods using the utility boolean union function we wrote in the last section:
``````
makeUnionOpt('Cu','C','Cube')
```
```
The result will be like this:

And do not forget to close the project to be able to use the panel for creating all the different shapes of lattice all around the object:
``````

####################################################################
#####                     Register and Unregister
####################################################################

def register():
bpy.utils.register_class(MainPanel)
bpy.utils.register_class(WM_Function_myOp)

def unregister():
bpy.utils.unregister_class(MainPanel)
bpy.utils.unregister_class(WM_Function_myOp)

if __name__ == "__main__":
register()

```
```
Now, using the above interface, you will be able to design and modify a robust internal lattice structure in a few seconds. You can also boolean intersect it with the shape that you want and make that shape have an internal lattice structure.

### Conclusion

In this tutorial, we have introduced all types of lattice structures including the ones in beauty and aesthetics are considered more important than accuracy of size and also the ones that accuracy of the dimensions is placed on top of our priorities. We have also managed to get started with the design of an internal lattice structure with accurate dimensions of height, width, and length for the object and the channels.

Finally, we have managed to complete the design tool for creating an internal lattice structure with accurate dimensions. Using the said tool which is provided in a panel, you can design a cube with a certain height, width, length, and internal lattice structures. Moreover, you can use the boolean intersect modifier to apply the said internal lattice structure on any object with any shape.