Is there a way to smooth selected faces to make curved surface more precise?

This kind of mathematical accuracy is of course easier achieved by using nurbs oriented workflow, but it could be handy to have in mesh modeling workflow too.

There are commands like flatten and smooth vertices, but those commands try to make the surface more flat or planar and don¨t take into account the basic shape or geometry. So this wanted feature could set points to approximated curve and use that as reference to move the faces.

Subdivision-surface workflow could be a one option, but is not usable in this modeling scenario.


Original mesh. The selected faces shows the curved surface, of which I am talking about Original mesh. The selected faces shows the curved surface, of which I am talking about

Same mesh from above. Red curve indicates the wanted curvature of faces. Same mesh from above. Red curve indicates the wanted curvature of faces.

  • $\begingroup$ One idea would be generating a super-smooth geometry using nurbs or splines. Then using vertex groups and shrinkwrap modifier you could force vertices from one geometry to mimic the other. $\endgroup$ Jun 8, 2018 at 10:56
  • $\begingroup$ Good idea and could definitely work! But it sounds far too tedious to make when these situations comes a head quite often. $\endgroup$ Jun 8, 2018 at 11:04

3 Answers 3


Using the built-in smooth tool on two axes

Applicable to few cases

  1. Temporarily rotate your model so that one axis is close to parallel to the edge loop.
  2. Temporarily remove edges adjacent to the edge loops, so the edgeloop which needs smoothing are selected and not connected to anything else.
  3. Execute the smooth operation W < Smooth and set the Smoothing parameter to 0.5. Increase the iterations as desired.
  4. Reconnected the edges with the bridge edgeloop tool.
  5. Realign your model.

smooth edge loops

To script the functionality, start with a bmesh and the get the edge loop. Then implement your custom smoothing function.

I have hacked a short script together. This also works on curved surfaces.

  1. Select the starting edge of an edge loop.
  2. Select the ending edge of the edge loop. (They don't have to cover all of the edge loop.)
  3. Edit the smoothing and iterations variables and execute the script.

This also works with multiple edge loop simultaneously.

enter image description here

Another application example.
enter image description here

import bpy
import bmesh

def bm_from_me(me):
    if me.is_editmode:
        bm = bmesh.from_edit_mesh(me)
        bm = bmesh.new()
    return bm
def bm_to_me(bm, me):
    if bm.is_wrapped:
        bmesh.update_edit_mesh(me, False, False)

def get_loop_untill_selection(loop):
    verts = []
    while len(loop.vert.link_edges) == 4:
        loop = loop.link_loop_prev.link_loop_radial_prev.link_loop_prev
        if loop.edge.select == True:
            loop.edge.select = False
            return verts, loop.edge
    return [], None

def smooth_coordinates(coords, smoothing, iterations):
    for i in range(1, len(coords) - 1):
        med = (coords[i - 1] + coords[i + 1]) / 2
        coords[i] *= 1 - smoothing
        coords[i] += med * smoothing
    if iterations > 1:
        smooth_coordinates(coords, smoothing, iterations - 1)

def smooth_loop(e, smoothing = 0.5, iterations = 1):
    edges = []
    for edge in bm.edges:
        if edge.select:
            e = edge
            for start_loop in e.link_loops:
                verts, end_edge = get_loop_untill_selection(start_loop)
                if end_edge is not None:
                    verts.insert(0, start_loop.vert)
                    if (start_loop.vert == e.verts[0]):
                        verts.insert(0, e.verts[1])
                        verts.insert(0, e.verts[0])
                    for medge in [edge, end_edge]:
                        medge.select = False
                    if len(verts) > 2:
                        co = [v.co for v in verts]
                        smooth_coordinates(co, smoothing, iterations)
    for e in edges:
        e.select = True

me = bpy.context.object.data
bm = bm_from_me(me)
smoothing = 0.5
iterations = 2
smooth_loop(bm, smoothing, iterations)
bm_to_me(bm, me)
  • $\begingroup$ Wow, I am really impressed! Your first workaround is handy, but your script is something more awesome. Actually, in the last few days, I have learned a little bit of Blenders Python scripting and I was curious to know that does bmesh-libary has this kind of functionality. Or is it possible to make as you did. I think that you should turn this to addon ;) Thanks! Blender and its community really showed its power again. $\endgroup$ Jun 8, 2018 at 13:31
  • $\begingroup$ @Daniel Sounds great, feel free to experiment with the script, modify it and turn it into an addon yourself, once you are more proficient with python and the bpy module. Writing a quick example is fairly quick, but creating a tested, bugfree and versatile addon is much more time consuming, even if the quantity of the script remains the same. When I got some time, I'll add comments to document the functionality. $\endgroup$
    – Leander
    Jun 8, 2018 at 13:35

I am not sure I understand correctly. Are you trying to make the edge curve more smoothly?

I suggest selecting the edge. Make it straight first: Scale-Axis-0 (S x 0 for example). Then hide everything else (Shift-H). Then turn on proportional editing, select the center vertex and move it the way you want, use mousewheel to affect the other vertices by the necessary amount to make the edge curve nicely. Then make everything visible again (Alt-H).

If you do not hide the rest first the proportional editing will probably affect parts you do not want to move.

  • $\begingroup$ Nice, It worked well. But It was possible because in this example the amount of curvature is small. So if we come closer to sphere like object, this technique turns quite awkward. I hope that there cold be something faster. This kind of feature could improve mesh modeling for sure. And it doesn´t sound too hard to make what comes to coding. $\endgroup$ Jun 8, 2018 at 12:40

I accidentally found addon (not released yet) which is direct answer to my question:



You must log in to answer this question.

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