7
$\begingroup$

There is "remove doubles" function for removing overlapping vertices and it works nice. But sometimes I'd like to see which vertices will be merged in order to decide whether I actually need to remove them or not. So in this case selecting them first (specifying distance threshold) to highlight would be useful. Unfortunately I have not found any such option in "select all by trait"

$\endgroup$
  • $\begingroup$ I have been using Blender for years, never even thought about that feature. I'll be super interested in any answers that are posted. $\endgroup$ – VRM Nov 30 '16 at 23:35
5
$\begingroup$

Ok, here the script that adds button with such function to "Select all by trait menu". Feel free to improve

bl_info = {
    "name": "Select Doubles",
    "author": "Lambdadelta",
    "version": (1, 0),
    "blender": (2, 78, 0),
    "location": "(Edit Mode) Select > Select All by Trait",
    "description": "Select all duplicate vertices.",
    "warning": "",
    "wiki_url": "http://blender.stackexchange.com/questions/68326/select-all-overlapping-vertices",
    "category": "Mesh",
    }

import bmesh
import bpy
from mathutils import Vector, kdtree

def select_duplicate_vertices(context, distance):
    obj = bpy.context.object
    me = obj.data
    bm = bmesh.from_edit_mesh(me)
    verts = bm.verts
    verts.ensure_lookup_table()

    # Create a kd-tree from a mesh
    size = len(verts)
    kd = kdtree.KDTree(size)
    for i, vtx in enumerate(verts):
        kd.insert(vtx.co, i)
    kd.balance()

    # Deselect all
    bpy.ops.mesh.select_all(action = 'DESELECT')

    # Select duplicate vertices
    for i, vtx in enumerate(verts):
        vtx_group = []
        for (co, index, dist) in kd.find_range(vtx.co, distance):
            vtx_group.append(index)
        if len(vtx_group) > 1:
            #print(vtx_group)
            for index in vtx_group:
                verts[index].select = True

    # Switch to vertex select
    bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='VERT')

    # Show the updates in the viewport
    bmesh.update_edit_mesh(me, False)


class SelectDoubles(bpy.types.Operator):
    """Select duplicate vertices"""
    bl_idname = 'mesh.select_doubles'
    bl_label = 'Select Doubles'
    bl_options = {'REGISTER', 'UNDO'}

    distance = bpy.props.FloatProperty(                        
        name = "Distance",    
        subtype='DISTANCE',          
        default = 0.001,
        min = 0.0,
        max = 50.0,
        description = "Minimum distance between elements to select.",
        unit='LENGTH'
        )

    def execute(self, context):
        select_duplicate_vertices(context, self.distance)
        return {'FINISHED'}

    def invoke(self, context, event) :
        select_duplicate_vertices(context, self.distance)
        return {"FINISHED"}

def menu_func(self, context):
    self.layout.operator(SelectDoubles.bl_idname, text="Select Doubles")

def register():
   bpy.utils.register_class(SelectDoubles)
   bpy.types.VIEW3D_MT_edit_mesh_select_by_trait.append(menu_func)

def unregister():
    bpy.utils.unregister_class(SelectDoubles)
    bpy.types.VIEW3D_MT_edit_mesh_select_by_trait.remove(menu_func)

if __name__ == "__main__":
    register()
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.