author Pablo Vazquez Fri, 18 Oct 2013 13:58:02 +0000 (13:58 +0000) committer Pablo Vazquez Fri, 18 Oct 2013 13:58:02 +0000 (13:58 +0000)
Mesh Symmetry tools
- Find Asymmetric vertices
- Make Symmetric vertices

More info at http://caminandes.com/development/improving-blender/

@@ -30,6 +30,7 @@ bl_info = {

import bpy

import bpy
+import bmesh
from bpy.types import Operator, AddonPreferences, Panel
from bpy.props import BoolProperty
from mathutils import Vector
from bpy.types import Operator, AddonPreferences, Panel
from bpy.props import BoolProperty
from mathutils import Vector
@@ -871,8 +872,137 @@ def particles_material_info(self, context):
ob.material_slots[len(ob.material_slots)-1].name))
# // FEATURE: Particles Material indicator

ob.material_slots[len(ob.material_slots)-1].name))
# // FEATURE: Particles Material indicator

+# FEATURE: Mesh Symmetry Tools by Sergey Sharybin
+class MESH_OT_find_asymmetric(Operator):
+    """
+    Find asymmetric vertices
+    """
+
+    bl_idname = "mesh.find_asymmetric"
+    bl_label = "Find Asymmetric"
+    bl_options = {'UNDO', 'REGISTER'}
+
+    @classmethod
+    def poll(cls, context):
+        object = context.object
+        if object:
+            return object.mode == 'EDIT' and object.type == 'MESH'
+        return False
+
+    def execute(self, context):
+        threshold = 1e-6
+
+        object = context.object
+        bm = bmesh.from_edit_mesh(object.data)
+
+        # Deselect all the vertices
+        for v in bm.verts:
+            v.select = False
+
+        for v1 in bm.verts:
+            if abs(v1.co[0]) < threshold:
+                continue
+
+            mirror_found = False
+            for v2 in bm.verts:
+                if v1 == v2:
+                    continue
+                if v1.co[0] * v2.co[0] > 0.0:
+                    continue
+
+                mirror_coord = Vector(v2.co)
+                mirror_coord[0] *= -1
+                if (mirror_coord - v1.co).length_squared < threshold:
+                    mirror_found = True
+                    break
+            if not mirror_found:
+                v1.select = True
+
+        bm.select_flush_mode()
+
+        bmesh.update_edit_mesh(object.data)
+
+        return {'FINISHED'}
+
+class MESH_OT_make_symmetric(Operator):
+    """
+    Make symmetric
+    """
+
+    bl_idname = "mesh.make_symmetric"
+    bl_label = "Make Symmetric"
+    bl_options = {'UNDO', 'REGISTER'}
+
+    @classmethod
+    def poll(cls, context):
+        object = context.object
+        if object:
+            return object.mode == 'EDIT' and object.type == 'MESH'
+        return False
+
+    def execute(self, context):
+        threshold = 1e-6
+
+        object = context.object
+        bm = bmesh.from_edit_mesh(object.data)
+
+        for v1 in bm.verts:
+            if v1.co[0] < threshold:
+                continue
+            if not v1.select:
+                continue
+
+            closest_vert = None
+            closest_distance = -1
+            for v2 in bm.verts:
+                if v1 == v2:
+                    continue
+                if v2.co[0] > threshold:
+                    continue
+                if not v2.select:
+                    continue
+
+                mirror_coord = Vector(v2.co)
+                mirror_coord[0] *= -1
+                distance = (mirror_coord - v1.co).length_squared
+                if closest_vert is None or distance < closest_distance:
+                    closest_distance = distance
+                    closest_vert = v2
+
+            if closest_vert:
+                closest_vert.select = False
+                closest_vert.co = Vector(v1.co)
+                closest_vert.co[0] *= -1
+            v1.select = False
+
+        for v1 in bm.verts:
+            if v1.select:
+                closest_vert = None
+                closest_distance = -1
+                for v2 in bm.verts:
+                    if v1 != v2:
+                        mirror_coord = Vector(v2.co)
+                        mirror_coord[0] *= -1
+                        distance = (mirror_coord - v1.co).length_squared
+                        if closest_vert is None or distance < closest_distance:
+                            closest_distance = distance
+                            closest_vert = v2
+                if closest_vert:
+                    v1.select = False
+                    v1.co = Vector(closest_vert.co)
+                    v1.co[0] *= -1
+
+        bm.select_flush_mode()
+        bmesh.update_edit_mesh(object.data)
+
+        return {'FINISHED'}
+# // FEATURE: Mesh Symmetry Tools by Sergey Sharybin
+
+
classes = (SCENE_OT_refresh,
classes = (SCENE_OT_refresh,
+           MESH_OT_find_asymmetric,
+           MESH_OT_make_symmetric,