# How to flatten a non-planar face to a targeted plane?

Let's take a non-planar quad here for a simple example, how to only move one vertex on it, to finally make it planar while keeping the other three vertices still?

• There is an addon for that called Make Coplanar github.com/ScottMichaud/blender-makecoplanar – Denis Aug 6 '15 at 13:54
• @Denis Thanks. I know that addon. And it currently didn't work like what I'm talking about here, esp. the bold part. – Leon Cheung Aug 6 '15 at 14:20
• A tool that moves only one vertex in a face to make it flat, while useful in some situations ~ seems quite specific. There needs to be a way to select the vertex and select the face... then move only that vertex... its possible of course. but seems like it could be some addon related to your exact needs. – ideasman42 Aug 20 '15 at 2:50
• @ideasman42 I've re-re-edited the title, for better description. – Leon Cheung Aug 20 '15 at 5:07

What @Denis suggested is good, I mean, it can be convenient sometimes with the help of view align. Besides, there are also other ways to do so:

Method 1:

1. Enable Snap, set Snap Element to Vertex.
2. Hold Shift and click on Edge Select button.
3. Use Normal as the Transform coordinate.
4. Use Active Element as the pivot center.
5. First select the vertex you want to move, then the edge that contains any two vertices on the target plane. Then R Y Y, then rotate until it snapped on another vertex on the same plane.

Method 2:

1. Temporarily triangulate the face.
2. Use Active Element as the pivot center.
3. Keep the target triangle selected, which is coplanar with that plane, then S Z Z 0.
4. Select the two triangles, press F to convert them back to quad.

Method 3:

1. Snap the vertex that you want to move to counter vertex.
2. Keep it activated, then G G to slide it along one edge, press C once or holding Alt to disable Clamp.
3. Repeat last step on another edge.

Method 4:

This is sort of similar to Denis's answer, but keeping current point of view unchanged (needed sometimes).

1. Select three vertices, create a new coordinate system based on current selection (or simply press Ctrl Alt Spacebar), and use it as current transform orientation.
2. Use Active Element as the pivot center.
3. First select the vertex you want to move, then select any one of the rest vertices, then S Z Z 0.

Method 5:

This is really a one-stop solution by using a script/addon coded by nirenyang, a friend from local community. After being requested, he made this for us, also posted on BA.

Here is my translated version of his script:

bl_info = {
"name": "Coplanar by 3 Verts",
"author": "NirenYang[BlenderCN]",
"version": (0, 1),
"blender": (2, 75, 5),
"location": "3d view - toolbar",
"description": "Make vertices coplanar using a plane defined by the first/last three selected verts.",
"warning": "",
"wiki_url": "",
"tracker_url": "",
"category": "mesh",
}

import bpy
import bmesh
from mathutils.geometry import intersect_line_plane, distance_point_to_plane, normal

enum_ref = [( 'first', 'First', 'Defined by the first three selected verts' ),
( 'last', 'Last', 'Defined by the last three selected verts' )]
class MESH_OT_3points_flat_trim(bpy.types.Operator):
"""
Manually pick three vertices to define the reference plane
"""
bl_idname = 'mesh.3points_flat_trim'
bl_label = 'Coplanar by 3 Verts'
bl_options = {'REGISTER', 'UNDO'}

ref_order = bpy.props.EnumProperty(name='Refferece Plane', description='Use the first/last three selected vertices to define the reference plane', items=enum_ref, default="last")
filter_distance = bpy.props.FloatProperty(name='Filter Distance', description='Only affects vertices further than this distance', default=0.0, precision=3, min=0.0)

@classmethod
def poll(cls, context):
obj = context.active_object
return (obj and obj.type == 'MESH')

def execute(self, context):
C = context
D = bpy.data
ob = C.active_object

#if bpy.app.debug != True:
#    bpy.app.debug = True
#    if C.active_object.show_extra_indices != True:
#        C.active_object.show_extra_indices = True

if ob.mode == 'OBJECT':
me = C.object.data
bm = bmesh.new()
bm.from_mesh(me)
else:
obj = C.edit_object
me = obj.data
bm = bmesh.from_edit_mesh(me)

bm.select_history.validate()
if len(bm.select_history) < 3:
self.report({'INFO'}, 'Pick three vertices first')
return {'CANCELLED'}

points3Index = []
points3 = []
_ordering = bm.select_history if self.ref_order=="first" else list(bm.select_history)[::-1]
for i in _ordering:
if len(points3) >= 3:
break
elif isinstance(i, bmesh.types.BMVert):
points3.append(i.co)
points3Index.append(i.index)
print(points3Index)
if len(points3) < 3:
self.report({'INFO'}, 'at least three vertices are needed to be selected')
return {'CANCELLED'}

points3Normal = normal(*points3)
for v in bm.verts:
if v.select and v.index not in points3Index:
_move = True
if self.filter_distance > 0.0:
_move = abs(distance_point_to_plane(v.co, points3[0], points3Normal)) < self.filter_distance
if _move == True:
v.co = intersect_line_plane(v.co, v.co+points3Normal, points3[0], points3Normal)

if ob.mode == 'OBJECT':
bm.to_mesh(me)
bm.free()
else:
bmesh.update_edit_mesh(me, True)

return {'FINISHED'}

self.layout.operator(MESH_OT_3points_flat_trim.bl_idname,
text=MESH_OT_3points_flat_trim.bl_label)

def register():
bpy.utils.register_class(MESH_OT_3points_flat_trim)

def unregister():
bpy.utils.unregister_class(MESH_OT_3points_flat_trim)

if __name__ == "__main__":
register()


Blender now has a tool to make faces flat.

Mesh -> Cleanup -> Make Planar Faces

This iteratively flattens faces, you can choose how much to move the vertices each iteration too.

• Where is that "Mesh" ? – Barafu Albino Aug 22 '17 at 18:37
• Edited answer.. – ideasman42 Aug 23 '17 at 1:52

You can do it manually in few steps.

1. Create a face of 3 vertices that you want to align to.
2. Hit Shift+7 to align the view to the normal of that face while the face is selected in face selection mode.
3. Hit Shift+S shortcut and select Cursor to Selected.
4. Change Pivot Point to Cursor and Transform Orientation to View.
5. Select the rest of the vertices, hit S button to scale, Z button twice to limit scale on the Z axis of the view and input 0.