# Meshes with Python & Blender : Circles and Cylinders

05.10.2017 @ Tutorials

In the last part of this series we’ll look at mak­ing cir­cles and cylin­ders. They are a lot trick­i­er than it seems! We’ll be build­ing on every­thing from the pre­vi­ous parts, as well as doing some Bmesh to fix nor­mals.

## Setup

Let’s start import­ing the usu­al pack­ages and Bmesh. We will be using it to fix nor­mals at the end. Also bring back good old `object_from_data()` and `set_smooth()` from the pre­vi­ous part

The first step to mak­ing a cylin­der is mak­ing a 2D cir­cle.

## Making a circle

First, we need to put ver­tices in a cir­cle around a point. We’ll cal­cu­late the the angle at which each ver­tex is. This angle is actu­al­ly a polar coor­di­nate, so to get X, Y coor­di­nates we can use we’ll also to con­vert it to Cartesian. You can read more about the math on mathisfun.com and on Wikipedia Of course we are pass­ing the val­ue of Z, so we don’t need to cal­cu­late that. For the ini­tial cir­cle Z will be zero.

We can use this right away to make a cir­cle but it would only be a cir­cle of ver­tices. Let’s also add edges too. Adding edges to a cir­cle is pret­ty sim­ple. Just loop around each ver­tex and con­nect the cur­rent index plus the next one, then add the final edge which con­nects the last index with the first (zero). Following the lessons of part 4, let’s make a func­tion to make cir­cles.

It doesn’t seem like much, but it’s a sol­id first step.

You might see some mes­sages from `validate()` com­plain­ing about the nor­mals being zero. That’s because there are no faces to cal­cu­late nor­mals. We will come back and add a way to fill this cir­cle lat­er on, reusing the code that adds caps to the cylin­der

## Circles all the way up

What is a cylin­der if not a cir­cle extrud­ed in 3D space? To extrude the cir­cle in the Z axis we can loop through `vertex_circle()` giv­ing it increas­ing val­ues of Z.

Time to `make_cylinder()`

Notice `vertex_circle()` returns a list of ver­tices, so we need to use expand instead of append to keep the same list struc­ture. Also, we’re not adding edges here. We will flesh­ing out this mesh with actu­al faces, so there’s no need for edges. Making faces fol­lows the log­ic from the grids in part 1. Except this time, it goes around in a ring.

Just like in grids, the best way to fig­ure out is to turn on debug­ging and inspect­ing ver­tex indices. After all, this func­tion only needs to return the right num­bers. To make all faces across all rings and rows, we need to loop through both.

You might notice we are miss­ing the last face in each ring. The last face is a spe­cial case because the indices “rewind”.

We need to add a spe­cial case for that last face with a dif­fer­ent for­mu­la. On one side we need to grab ver­tices near the end of both rings, on the oth­er we need to grab the begin­ning verts. It’s sim­i­lar to the last edge in the cir­cle.

Now we have one good look­ing cylin­der.

We’re just miss­ing caps to com­plete the mesh.

## Capping the cylinder

There are two ways we can cap this cylin­der:

• Ngons. All ver­tices in the ring con­nect­ed as a sin­gle face.
• A tri­an­gle fan. A series of tri­an­gles con­nect­ing to a cen­tral ver­tex.

To make a tri­an­gle fan we need to put a ver­tex in the mid­dle of the ring, and then go loop the ring con­nect­ing ver­tices to it. On the oth­er hand, to make an Ngon only we just loop through the ver­tices’ indices and put them all in a sin­gle tuple. This is clear­er to see in the bot­tom cap code.

In the case of a tri­an­gles fan we also need to fill the last face sep­a­rate­ly. The code for `top_cap()` is sim­i­lar, but we have to off­set the num­ber of indices to get the indices in the top row.

Now we can call them in the cylin­der func­tion. Since we already pass­ing the cap type, we can make it a para­me­ter in `make_cylinder()` and let the caller pass `None` to dis­able caps.

## Filling the circle

A cylin­der is an extrud­ed cir­cle, remem­ber? Therefore the bot­tom ring is the same as the first cir­cle we made and we can now use the `bottom_cap()` func­tion to fill it. Note that if we make faces for the cir­cle, we don’t need to set­up edges.

## Smooth it up

Now that we have com­plet­ed the mesh, let’s pol­ish it. We can add a call to `set_smooth()` to enable it smooth shad­ing for it. We can also add some mod­i­fiers like we did in the last part. We’ll add some bev­el and an edge split to fix the shad­ing. We only want to add a bev­el mod­i­fi­er if we actu­al­ly have caps though.

If you try this you will find there’s some­thing wrong with the bot­tom cap. The bev­el mod­i­fi­er is mak­ing it look real­ly weird and dent­ed. This is usu­al­ly a sign of messed up nor­mals. Jump into edit mode and enable nor­mals from the Display pan­el.

As you can see, the nor­mals of the bot­tom cap are point­ing up, when they should actu­al­ly be point­ing down. We need to fix that to get a good bev­el. You can do that by going into edit mode, and press­ing `CTRL+N`. But there’s also a way to it in code.

## Fixing normals

In order to fix the nor­mals we’ll use one of bmesh oper­a­tors. These are dif­fer­ent from the reg­u­lar Blender oper­a­tors as they don’t depend on con­text. They will work as long as you give them a valid bmesh object.

Bmesh is a spe­cial Blender API that gives you very close access to the inter­nal mesh edit­ing API. It’s quite faster than oth­er meth­ods and more flex­i­ble. However, when it comes to cre­at­ing mesh­es from scratch Bmesh doesn’t offer any­thing too dif­fer­ent from the oth­er way. That’s why this series hasn’t touched on Bmesh until this point. In order to use bmesh we first cre­ate an bmesh object, then fill it with data (in this case using `from_mesh()`). Once we are fin­ished with it, we write the new data to the mesh and free the bmesh object from mem­o­ry.

I won’t get too deep in Bmesh now since that would take an entire sep­a­rate tuto­r­i­al. You can read more about Bmesh in the docs. For now, let’s make a func­tion that takes a mesh and fix­es it’s nor­mals.

Adding a call to this func­tion in `make_cylinder()` yields the final, awe­some look­ing cylin­der.

## Wrap up

That’s it for this tuto­r­i­al, and the whole series! I hope these tuto­ri­als have been use­ful for you, or at least learned a new trick or two. We have talked about mak­ing 2D grids, cubes, icos­pheres, cir­cles and cylin­ders. We’ve also gone into debug­ging, man­ag­ing com­plex­i­ty, set­ting smooth shad­ing, adding and apply­ing mod­i­fiers, recal­cu­lat­ing nor­mals and read­ing data from files. It’s quite a lot, but it’s only the begin­ning. There are plen­ty more things to explore and learn in Blender!

Things you can do for your­self:

• Use Bmesh instead of `from_pydata()` to build the mesh
• Make a new `vertex_circle()` that makes spi­rals instead of cir­cles
• Refactor the cap func­tions into a sin­gle one, that can make both caps, one or none.

Got any ques­tions, or sug­ges­tions for new tuto­ri­als? Leave a com­ment below!

All the posts you can read