1 # This program is free software; you can redistribute it and/or
2 # modify it under the terms of the GNU General Public License
3 # as published by the Free Software Foundation; either version 2
4 # of the License, or (at your option) any later version.
6 # This program is distributed in the hope that it will be useful,
7 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 # GNU General Public License for more details.
11 # You should have received a copy of the GNU General Public License
12 # along with this program; if not, write to the Free Software Foundation,
13 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15 Symmetry Tools: Find Asymmetric + Make Symmetric (by Sergey Sharybin)
17 Our character wasn’t completely symmetric in some parts where it was
18 supposed to, this could be by moving vertices by mistake or just reasons.
19 To fix this in a fast way, Sergey coded this two super useful tools:
22 Selects vertices that don’t have the same position on the opposite side.
25 Move selected vertices to match the position of those on the other side.
27 This tools may not apply on every single model out there, but I tried it
28 in many different characters and it worked. So probably better use it on
29 those models that were already symmetric at some point, modeled with a
30 mirror modifier or so.
31 Search (spacebar) for "Find Asymmetric", and "Make Symmetric""Settings".
33 > Developed during Caminandes Open Movie Project
38 from mathutils
import Vector
41 class AMTH_MESH_OT_find_asymmetric(bpy
.types
.Operator
):
44 Find asymmetric vertices
47 bl_idname
= "mesh.find_asymmetric"
48 bl_label
= "Find Asymmetric"
49 bl_options
= {"UNDO", "REGISTER"}
52 def poll(cls
, context
):
53 object = context
.object
55 return object.mode
== "EDIT" and object.type == "MESH"
58 def execute(self
, context
):
61 object = context
.object
62 bm
= bmesh
.from_edit_mesh(object.data
)
64 # Deselect all the vertices
69 if abs(v1
.co
[0]) < threshold
:
76 if v1
.co
[0] * v2
.co
[0] > 0.0:
79 mirror_coord
= Vector(v2
.co
)
81 if (mirror_coord
- v1
.co
).length_squared
< threshold
:
87 bm
.select_flush_mode()
89 bmesh
.update_edit_mesh(object.data
)
94 class AMTH_MESH_OT_make_symmetric(bpy
.types
.Operator
):
100 bl_idname
= "mesh.make_symmetric"
101 bl_label
= "Make Symmetric"
102 bl_options
= {"UNDO", "REGISTER"}
105 def poll(cls
, context
):
106 object = context
.object
108 return object.mode
== "EDIT" and object.type == "MESH"
111 def execute(self
, context
):
114 object = context
.object
115 bm
= bmesh
.from_edit_mesh(object.data
)
118 if v1
.co
[0] < threshold
:
124 closest_distance
= -1
128 if v2
.co
[0] > threshold
:
133 mirror_coord
= Vector(v2
.co
)
134 mirror_coord
[0] *= -1
135 distance
= (mirror_coord
- v1
.co
).length_squared
136 if closest_vert
is None or distance
< closest_distance
:
137 closest_distance
= distance
141 closest_vert
.select
= False
142 closest_vert
.co
= Vector(v1
.co
)
143 closest_vert
.co
[0] *= -1
149 closest_distance
= -1
152 mirror_coord
= Vector(v2
.co
)
153 mirror_coord
[0] *= -1
154 distance
= (mirror_coord
- v1
.co
).length_squared
155 if closest_vert
is None or distance
< closest_distance
:
156 closest_distance
= distance
160 v1
.co
= Vector(closest_vert
.co
)
163 bm
.select_flush_mode()
164 bmesh
.update_edit_mesh(object.data
)
169 def ui_symmetry_tools(self
, context
):
170 if bpy
.context
.mode
== 'EDIT_MESH':
171 self
.layout
.separator()
172 self
.layout
.operator(
173 AMTH_MESH_OT_find_asymmetric
.bl_idname
,
174 icon
="ALIGN_CENTER", text
="Find Asymmetric")
175 self
.layout
.operator(
176 AMTH_MESH_OT_make_symmetric
.bl_idname
,
177 icon
="ALIGN_JUSTIFY", text
="Make Symmetric")
181 bpy
.utils
.register_class(AMTH_MESH_OT_find_asymmetric
)
182 bpy
.utils
.register_class(AMTH_MESH_OT_make_symmetric
)
183 bpy
.types
.VIEW3D_MT_edit_mesh
.append(ui_symmetry_tools
)
187 bpy
.utils
.unregister_class(AMTH_MESH_OT_find_asymmetric
)
188 bpy
.utils
.unregister_class(AMTH_MESH_OT_make_symmetric
)
189 bpy
.types
.VIEW3D_MT_edit_mesh
.remove(ui_symmetry_tools
)