I have an array of values and I need to extrude each face - faces[i] - of an icosphere with the amount of arr[i] in the direction of it's normal.

I managed to extrude the face I have selected by hand and managed to get the list of all faces of the mesh, but can't find a way to combine these solutions.

  • $\begingroup$ Share what you have so far. $\endgroup$
    – iKlsR
    Jan 18, 2015 at 22:00
  • $\begingroup$ list(bpy.context.object.data.polygons) seems to give the faces. And bpy.ops.mesh.extrude_region_move('INVOKE_REGION_WIN', TRANSFORM_OT_translate={ "constraint_orientation": 'NORMAL', "value": (x, y, z)}) extrudes the face that is selected. $\endgroup$
    – mzdravkov
    Jan 18, 2015 at 23:37

2 Answers 2


bmesh.ops.extrude_discrete_faces takes a list of faces and extrudes them, leaving them in the original place with new joining geometry. If we take the ['faces'] part of the data returned by extrude_discrete_faces we have a list of faces that have been extruded, these are the 'original' faces only, not the extra joining faces.

For each of these extruded faces we take the face normal and multiply it by the distance you wish to move the face and use that in bmesh.ops.translate to position them where you want.

import bpy
import bmesh

# sample set for cube
extrude_values = [0.1,0.2,0.3,0.4,0.5,0.6]

obj = bpy.context.active_object
bm = bmesh.new()

extrude_faces = bmesh.ops.extrude_discrete_faces(bm, faces=bm.faces)['faces']

for f_idx in range(len(extrude_faces)):
    dr = extrude_faces[f_idx].normal * extrude_values[f_idx]
    bmesh.ops.translate(bm, verts=extrude_faces[f_idx].verts, vec=dr)


I would solve this problem by doing a LOT of analytic geometry and avoid bpy.ops as much as possible (because bpy.ops has cooties). In fact, part of what you want I already did in my spikify script for the azathoth boogie animation.

In my case I was interpolating between the triangle of the icosphere face and the degenerate tip of the spike. Here's an excerpt:

def fab_layer(verts, base_indices, layer, max_layers, max_radius):

    vavg = average( [ verts[vi] for vi in base_indices])

    tip = vavg * max_radius / vavg.magnitude

    rval_vi = []

    for i in range(len(base_indices)):
        v0 = verts[base_indices[i]]
        v1 = (v0 * (max_layers-layer) + tip*layer ) / max_layers
        idx = len(verts)

    return rval_vi

If you can mathematically decide what it means to "extrude" for your application (which will likely be different than mine) then you can come up with your own code.


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .