[addon] mesh_3points_flat_trim_yi

Great job! I believe people making mechanical things will love it.

Actually it has been discussed at StackExchange here.

Here is my translated version, hopefuly more readable for English speakers (and allow me to name it “Coplanar by 3 Verts” here :stuck_out_tongue: )


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 being 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'}
        
def menu_func_MESH_OT_3points_flat_trim(self, context):
    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) 
    bpy.types.VIEW3D_PT_tools_meshedit.append(menu_func_MESH_OT_3points_flat_trim)
    
def unregister():
    bpy.types.VIEW3D_PT_tools_meshedit.remove(menu_func_MESH_OT_3points_flat_trim)
    bpy.utils.unregister_class(MESH_OT_3points_flat_trim)
    
 

if __name__ == "__main__":
    register()

1 Like