### Using the built-in smooth tool on two axes <sup>Applicable to few cases</sup> 1. Temporarily rotate your model so that one axis is close to parallel to the edge loop. 1. Temporarily remove edges adjacent to the edge loops, so the edgeloop which needs smoothing are selected and not connected to anything else. 1. Execute the smooth operation <kbd>W</kbd> < Smooth and set the Smoothing parameter to 0.5. Increase the iterations as desired. 1. Reconnected the edges with the bridge edgeloop tool. 1. Realign your model. [![smooth edge loops][1]][1] To script the functionality, [start with a bmesh](https://blender.stackexchange.com/a/35282/30849) and the [get the edge loop](https://blender.stackexchange.com/a/79995/30849). 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][3]][3] <sub>Another application example.</sub> [![enter image description here][2]][2] import bpy import bmesh def bm_from_me(me): if me.is_editmode: bm = bmesh.from_edit_mesh(me) else: bm = bmesh.new() bm.from_mesh(me) return bm def bm_to_me(bm, me): if bm.is_wrapped: bmesh.update_edit_mesh(me, False, False) else: bm.to_mesh(me) me.update() 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 verts.append(loop.vert) if loop.edge.select == True: loop.edge.select = False print(loop.edge.select) 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]) else: verts.insert(0, e.verts[0]) for medge in [edge, end_edge]: edges.append(medge) 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) [1]: https://i.sstatic.net/DPbmz.gif [2]: https://i.sstatic.net/QgnL0.gif [3]: https://i.sstatic.net/1ZXRq.gif