Building tiling patterns in Blender is pretty easy if you know how to use the

**array**modifier... at least, it's usually easy if the tiling pattern repeats itself over space. For example, you can use the

**array**modifier to construct practically any pattern from one of the wallpaper groups.

But that's not what I'm talking about today. I want to talk about Penrose tiling. Penrose tiling is a non-periodic tiling pattern. This means means it

*does not*repeat itself as you move through space, and Blender's

**array**modifier therefore can't be used to construct the pattern. Instead, I used Blender's scripting tools to do Penrose tiling.

(

*)*

**Edit**: Penrose tiling is pentagonally symmetric, and you actually can use the array modifier speed up the process of making pentagonally symmetric patterns-**however**- this process would still require that you do most of the work by hand. Working by hand is slow, and it's very easy to make a mistake early in the process which later results in the pattern containing "hole"Check out what I made:

I was surprised that I couldn't find anything online about Penrose tiling in Blender, so I decided to write something up myself. The scripts I used are adapted from the algorithm described in this blog post I found about Penrose tiling. Please check out the link if you're curious about how the script works. If you want to skip this tutorial and just try out my Blender-adapted version of the script, I pasted it at the end of this post.

The steps of my process:

- Generate a Penrose patterned mesh with the script
- Use selection tricks to isolate specific patterns of edges in the mesh
- Dissolve those edges to make new shapes (stars, diamonds etc.)
- Edge split the shapes into islands. Separate the mesh into different objects according to shape.
- The rest. (Solidify, bevel, light, animate, render etc.)

Start by opening a new blender scene, open up the text editor, copy and paste my script, and press the

**Run Script**button. The script should generate a ten-sided grey disc in the 3D viewport. Boring.

Look at the disc in edit mode (

**right click**to select it, and hit

**tab**to enter edit mode). The disc is actually an interesting pattern of triangles. Less boring!

This is our base pattern. From here, I found a way to pull out more interesting patterns of shapes. Try mine out. If you come up with your own, please show me how you did it!

Go into edge mode (

**ctrl-tab**then

**2**). If you look, the mesh has edges of three different lengths. Select a short edge, then go to the menu

**Select -> Similar -> Length**.

Due to roundoff error, not all of the short edges are exactly the same length. Because of this, the

**select similar length**command might not get the edges you want. If you play with it's

**threshold**value (see picture below), you should be able to get all of the short edges in the mesh, resulting in a selection that looks like this:

Hit

**x**->

**Dissolve Edges**to make all the small edges disappear. The mesh should now look like this:

Do the same thing to the long edges. Select all of them and dissolve them.

That's the pattern at the top of this post! Cool!

So, at this point, we can start trying to pull shapes out of the pattern using some selection trickery. Warning: do exactly as I say in the order I say it, or it might not work.

Go into face-select mode (

**ctrl-tab**then

**3**), select a thin diamond, and

**select -> similar -> area**. You should get this:

Switch to vertex mode (

**ctrl-tab**then

**1**), and invert the selection (

**ctrl-i**). Deselect the loop of vertices on the edge of the mesh.

You should get this. The center of all the star shapes are selected. Dissolve them! (

**x -> Dissolve Vertices**).

Oo, now you have stars. See?

We can stillget some more shapes.

Switch to

**face select mode**, and select all the thin diamond faces again.

**Invert**the selection. Switch to

**edge mode**.

**Invert**the selection.

**Dissolve**the edges that remain selected. This trick should merge adjacent pairs of thin diamonds into an angular pac-man-like shape.

One more trick.

There are a few places in the mesh where four fat diamonds make an incomplete star. In vertex mode, select the center vertex of an incomplete star.

Now go

**Select->Similar->Amount of connecting edges**, switch to edge mode, and dissolve the selected edges.

The hard part is over, and the resulting pattern should look like this ->

If you're familiar with Blender, the rest of what I did was pretty straightforward, so I'll be brief.

We don't need to keep all the shapes as a single mesh anymore. Selecting all the vertices (

**ctrl-a**), and edge split everything (

**ctrl-e->Edge split**). Now if you select the stars (and only the stars... remember, use

**Select->Similar->Area**), you can split that set of polygons into a new object (

**p->Selection**). In this way, separate each set of shapes into their own mesh object.

Now we can select between shapes in object mode, and assign different materials (with different colours) depending on the shape.

Above, in this last image, you can see the modifiers I used and their settings.

I put in lights, built in a looping animation, and rendered. So, that's pretty much it!

One last comment: as you may have observed, Penrose tiling is pentagonally symmetric. Interestingly enough, this is the reason why Penrose tiling is non-periodic. The crystallographic restriction theorem proves that any regularly spaced 2D pattern can't be pentatonally symmetric. Just try it! If you attempt to create a tiling pattern of regular pentagons, you will fail!.

Now, you might be wondering why the python subdivision algorithm is using the golden ratio, φ. Well, I did some reading, and apparently φ (the golden ratio) appears a lot when you're working with pentagonal symmetry. This happens because the cosine of 72

**°**( which is one fifth of 360

**°**) is φ/2.

Happy tiling!

~ CG From Space

My Blender-adapted script:

import bpy

import bmesh

import math

from mathutils import Vector

subDivIterations = 6

goldenRatio = (1 + math.sqrt(5)) / 2

def subdivide(triangles):

result = []

for color, A, B, C in triangles:

if color == 0:

# Subdivide red triangle

P = A + (B - A) / goldenRatio

result += [(0, C, P, B), (1, P, C, A)]

else:

# Subdivide blue triangle

Q = B + (A - B) / goldenRatio

R = B + (C - B) / goldenRatio

result += [(1, R, C, A), (1, Q, R, B), (0, R, Q, A)]

return result

# Create wheel of red triangles around the origin

def createWheel():

triangles = []

for i in range(10):

theta_i = i*2.0*math.pi/10.0

theta_ip1 = (i+1)*2.0*math.pi/10.0

x_i = math.cos(theta_i)

x_ip1 = math.cos(theta_ip1)

y_i = math.sin(theta_i)

y_ip1 = math.sin(theta_ip1)

A = Vector((0.0,0.0,0.0))

B = Vector((x_i,y_i,0.0))

C = Vector((x_ip1,y_ip1,0.0))

if i % 2 == 0:

B, C = C, B # Make sure to mirror every second triangle

triangles.append((0, A, B, C))

return triangles

# Generate map of tiling

listTriangles = createWheel()

for x in range(subDivIterations):

listTriangles = subdivide(listTriangles)

# Construct the lists necessary for generation of geometry

listVertices = []

listFaces = []

for triangle in listTriangles:

# write the vertex coords to the list, and remember the vertex indices

# In Blender, the mesh data stores each vertex as a tuple of 3 floats.

newVertex1 = (triangle[1][0],triangle[1][1],triangle[1][2])

newVertex2 = (triangle[2][0],triangle[2][1],triangle[2][2])

newVertex3 = (triangle[3][0],triangle[3][1],triangle[3][2])

listVertices.append(newVertex1)

newVertex1_i = len(listVertices) - 1

listVertices.append(newVertex2)

newVertex2_i = len(listVertices) - 1

listVertices.append(newVertex3)

newVertex3_i = len(listVertices) - 1

# Define the faces by index numbers. Each faces is defined by a list of the vertex indices belonging to the face.

# For triangles you need to repeat the first vertex also in the fourth position.

newFace = (newVertex1_i,newVertex2_i,newVertex3_i)

listFaces.append(newFace)

# Build the mesh in Blender's API

mesh = bpy.data.meshes.new("penroseMesh") # create a new mesh

ob = bpy.data.objects.new("Pyramid", mesh) # create an object with that mesh

ob.location = Vector((0,0,0)) #by.context.scene.cursor_location # position object at 3d-cursor

bpy.context.scene.objects.link(ob) # Link object to scene

# Fill the mesh with verts, edges, faces

mesh.from_pydata(listVertices,[],listFaces) # edges or faces should be [], or you ask for problems

mesh.validate(True)

#mesh.update(calc_edges=True) # Update mesh with new data

bm = bmesh.new()

bm.from_mesh(mesh)

bmesh.ops.remove_doubles(bm, verts=bm.verts, dist=0.001)

bmesh.ops.recalc_face_normals(bm, faces=bm.faces)

bmesh.ops.reverse_faces(bm, faces=bm.faces)

bm.to_mesh(mesh)

mesh.update()

Cool stuff! Thanks for sharing!

ReplyDeleteVery interesting, and the video you made is fascinating to watch.

ReplyDeleteThanks for sharing!

ReplyDeleteThis comment has been removed by the author.

ReplyDeleteWith the operator "tris to quad" you have yet another pattern

Deletethanks

I have problems following the last selection steps: once the vertex of the incomplete stars are selected with "Amount of connecting edges" they are single vertex and switching to edge mode loose the selection.

ReplyDeleteI've tried growing the selection and dissolving the edges but I got a different pattern. How you make that last selection?

It should work if you've already done the bit where you merge a number of the thin diamonds. If you follow my instructions out of order it won't work.

DeleteHey thx for this great info

ReplyDeleteRobin, great script! I made some minor modifications and converted it to a Sverchok (blender addon) script for ScriptNode. If you are interested: https://github.com/nortikin/sverchok/issues/85#issuecomment-41896469

ReplyDeleteHey, that's cool!

DeleteWhat is Sverchok? I watched some videos, and it looks like a node based ... particle system ... or something?

Have you seen the other patterns from my newer post?

http://cgfromspace.blogspot.ca/2013/12/non-periodic-tiling-in-blender-chapter-2.html

I read a bit more:

DeleteThat project looks really exciting! I'll be trying it out this weekend :-)

sverchok - is programming of low-level-data as digits, vectors etc with nodes - height level tool. we are open to involve new progers while it version alpha. many job to be done.

DeleteI am editing an article by David Singmaster on "The utility of recreational mathematics" for publication in The UMAP Journal. We would like to reproduce in the article the first figure (yellow and orange) at

ReplyDeletehttp://cgfromspace.blogspot.com/2013/11/penrose-tiling-in-blender-building.html

Would you please contact me about it? Can't find an email address for you at the C.G. site.

Thanks,

Paul C

--

Paul J. Campbell

Editor, The UMAP Journal of Undergraduate Mathematics and Its Applications

http://www.comap.com/product/periodicals/index.html

Mathematics and Computer Science

Beloit College

700 College St.

Beloit, WI 53511-5595

USA

gracias... funciono perfecto en 2.74

ReplyDelete