I have object like this:

enter image description here

I want to cut it in half and flatten it to something like plane. In other words I want create flat map of this maze - all simple ways are welcome.


  • 3
    $\begingroup$ plane > cylinder would be easier... $\endgroup$
    – Robin Betts
    Commented Jul 3, 2020 at 11:47

3 Answers 3


This might work..

It's a script which gets as close as I can to inverting the Simple Deform > Bend modifier.

It's not very general, and makes some assumptions:

  • The Cylindrical version is circular in XY, up in Z.
  • That it has a cut gap at min Y around X=0. If there are coincident vertices where the gap is, in the illustration, the result can be usable, but untidy (the script doesn't know the difference between 0 and 360 degrees).
  • The object has all its transforms applied, and its origin is at its XY center.

Select the object in Object Mode, and run this:

import bpy
from math import atan2, sqrt

cyl = bpy.context.object
if cyl:
    flt = cyl.copy()
    me = flt.data.copy()
    flt.data = me    
min_r = float("inf")
for v in me.vertices:
    x, y, z = v.co
    r = v.co.xy.length
    theta = atan2(x, y)
    v.co = theta, r, z
    min_r = min(r, min_r)
for v in me.vertices:
    v.co.x *= min_r  
    v.co.y -= min_r

flt.location.y += min_r

Which should produce a straightened version (green, derived from blue), scaled and located, ready to be bent back by Simple Deform > Bend.

enter image description here

The Bend modifier uses the bounding box of the straightened object. Because of the gap, the required bend is not quite 360 degrees. In the example .blend, the match is reached at about 356 degrees.

enter image description here

Lurking Pythonistas / bpyists are welcome to improve or correct the style of this script.

  • 3
    $\begingroup$ Oh, that animation is very neat :). $\endgroup$ Commented Jul 3, 2020 at 22:24
  • $\begingroup$ @JachymMichal ..the question of how to unbend something so it can be bent back again using the modifier has come up a few times.. $\endgroup$
    – Robin Betts
    Commented Jul 4, 2020 at 5:41
  • 1
    $\begingroup$ @Markus von Broady ... just seen this post referenced.. belated thanks for the tidy-ups! $\endgroup$
    – Robin Betts
    Commented May 23, 2022 at 5:40

Bmesh script

enter image description here

Splitting script to bisect first, copy, and then "unfurl" copy and join as shapes

Similarly to a cylindrical UV projection can "unwrap" a cylinder from cylindrical coordinates to flat.

(Just seen RobinBetts excellent answer, doing much the same.)

Some Pre Pro on mesh

Firstly going to be a lot easier to set origin to geometry (bounds) Can also be done via bounding box

enter image description here

which in this case puts it in pipe centre. The xy coordinate vector of any vertex gives its distance from the pipe axis.

enter image description here

Have also removed the coplanar faces of the "nut end". (Would need to be poked to axis line to unfurl nicely)

The script

Bisects the pipe with a cutting plane.

Have arbitrarily chosen the ZY plane to chop the pipe where locally Y > 0 (the top looking down)

Select a vertex as unfurl radius

Run in edit mode. Select a vertex you wish to be the xy radius to unfurl radius r to XY plane. The height will be the xy radius take r, the Y value the old z value and the x the longitude angle (remember arc length = angle in radians.)

enter image description here

Script. Edit mode select vertex. then run script. (Alters the mesh, so as always backup first / run on copy etc)

import bpy
import bmesh
from mathutils import Vector
from math import copysign, pi

context = bpy.context

ob = context.object
me = ob.data

bm = bmesh.from_edit_mesh(me)

v_r = bm.select_history.active
r = v_r.co.xy.length

assert(isinstance(v_r, bmesh.types.BMVert), "Select a Vert")
cut = bmesh.ops.bisect_plane(
        geom=[f for f in bm.faces if all(v.co.y > 0 for v in f.verts)] + [e for e in bm.edges if all(v.co.y > 0 for v in e.verts)] + [v for v in bm.verts if v.co > 0],
        plane_no=(1, 0, 0),
for g in cut:
    g.select = True

        edges=[e for e in cut if isinstance(e, bmesh.types.BMEdge)],
        verts=[v for v in cut if isinstance(v, bmesh.types.BMVert)],

# now "unfurl"

up = Vector((0, -1))
for v in bm.verts:
    co = v.co.copy()
    angle = -up.angle_signed(v.co.xy)
    if 1 + up.dot(v.co.xy.normalized()) < 1e-4:
        # meridian 
        fv = sum((f.calc_center_median().x 
            for f in v.link_faces)
                 ) / len(v.link_faces)
        angle = copysign(angle, fv)
    v.co.y = co.z
    v.co.z = co.xy.length - r
    v.co.x = angle * r

  • 1
    $\begingroup$ I've just figured out how you're dealing with 0. Very nice. $\endgroup$
    – Robin Betts
    Commented Jul 4, 2020 at 5:32

Here is a solution that seems to work:

  • Select your cylinder, go in Edit mode, create or select the frontal vertical edge and rip it with V or cut with the knife (K), with the through option enable (Z).

enter image description here

  • Create a plane, subdivide it vertically.

enter image description here

  • Give you plane a Simple Deform modifier / Bend mode, choose an Angle Deform of 360° so that it contains the cylinder. If the plane doesn't bend correctly try to apply its rotation.

enter image description here

  • Give your cylinder a Surface Deform modifier with the plane as Target, click on Bind.

  • Disable the plane's Simple Deform visibility, the cylinder should flatten.

enter image description here

  • Apply the cylinder's Surface Deform modifier, you now have a flat mesh, you may need to give some small corrections.

enter image description here

  • $\begingroup$ For my mesh this method not work or I do something wrong. Can you try this method on this mesh: sendgb.com/qZ1UCADib30? $\endgroup$
    – shinji
    Commented Jul 3, 2020 at 13:23
  • $\begingroup$ yes your original mesh is a bit messy, I'm not sure it's easy to fix $\endgroup$
    – moonboots
    Commented Jul 3, 2020 at 13:48

You must log in to answer this question.

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