| 
									
										
										
										
											2009-11-05 12:37:49 +00:00
										 |  |  | # ##### BEGIN GPL LICENSE BLOCK ##### | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | #  This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  | #  modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  | #  as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  | #  of the License, or (at your option) any later version. | 
					
						
							| 
									
										
										
										
											2009-11-21 23:55:14 +00:00
										 |  |  | # | 
					
						
							| 
									
										
										
										
											2009-11-05 12:37:49 +00:00
										 |  |  | #  This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  | #  but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  | #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  | #  GNU General Public License for more details. | 
					
						
							| 
									
										
										
										
											2009-11-21 23:55:14 +00:00
										 |  |  | # | 
					
						
							| 
									
										
										
										
											2009-11-05 12:37:49 +00:00
										 |  |  | #  You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  | #  along with this program; if not, write to the Free Software Foundation, | 
					
						
							| 
									
										
										
										
											2010-02-12 13:34:04 +00:00
										 |  |  | #  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							| 
									
										
										
										
											2009-11-05 12:37:49 +00:00
										 |  |  | # | 
					
						
							|  |  |  | # ##### END GPL LICENSE BLOCK ##### | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-31 14:46:28 +00:00
										 |  |  | # <pep8 compliant> | 
					
						
							| 
									
										
										
										
											2009-12-13 14:38:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-05 12:37:49 +00:00
										 |  |  | import bpy | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-31 14:46:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-13 17:58:26 +00:00
										 |  |  | class MeshSelectInteriorFaces(bpy.types.Operator): | 
					
						
							|  |  |  |     '''Select faces where all edges have more then 2 face users.''' | 
					
						
							| 
									
										
										
										
											2009-12-13 22:48:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-13 17:58:26 +00:00
										 |  |  |     bl_idname = "mesh.faces_select_interior" | 
					
						
							|  |  |  |     bl_label = "Select Interior Faces" | 
					
						
							|  |  |  |     bl_register = True | 
					
						
							|  |  |  |     bl_undo = True | 
					
						
							| 
									
										
										
										
											2009-11-05 12:37:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-13 17:58:26 +00:00
										 |  |  |     def poll(self, context): | 
					
						
							|  |  |  |         ob = context.active_object | 
					
						
							|  |  |  |         return (ob and ob.type == 'MESH') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def execute(self, context): | 
					
						
							|  |  |  |         ob = context.active_object | 
					
						
							|  |  |  |         bpy.ops.mesh.selection_type(type='FACE') | 
					
						
							|  |  |  |         is_editmode = (ob.mode == 'EDIT') | 
					
						
							|  |  |  |         if is_editmode: | 
					
						
							|  |  |  |             bpy.ops.object.mode_set(mode='OBJECT', toggle=False) | 
					
						
							| 
									
										
										
										
											2009-11-21 23:55:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-13 17:58:26 +00:00
										 |  |  |         mesh = ob.data | 
					
						
							| 
									
										
										
										
											2009-11-05 12:37:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-13 17:58:26 +00:00
										 |  |  |         face_list = [face for face in mesh.faces] | 
					
						
							|  |  |  |         face_edge_keys = [face.edge_keys for face in face_list] | 
					
						
							| 
									
										
										
										
											2009-11-21 23:55:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-13 17:58:26 +00:00
										 |  |  |         edge_face_count = mesh.edge_face_count_dict | 
					
						
							| 
									
										
										
										
											2009-11-05 12:37:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-13 17:58:26 +00:00
										 |  |  |         def test_interior(index): | 
					
						
							|  |  |  |             for key in face_edge_keys[index]: | 
					
						
							|  |  |  |                 if edge_face_count[key] < 3: | 
					
						
							|  |  |  |                     return False | 
					
						
							|  |  |  |             return True | 
					
						
							| 
									
										
										
										
											2009-11-05 12:37:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-13 17:58:26 +00:00
										 |  |  |         for index, face in enumerate(face_list): | 
					
						
							|  |  |  |             if(test_interior(index)): | 
					
						
							|  |  |  |                 face.selected = True | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 face.selected = False | 
					
						
							| 
									
										
										
										
											2009-11-05 12:37:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-13 17:58:26 +00:00
										 |  |  |         if is_editmode: | 
					
						
							|  |  |  |             bpy.ops.object.mode_set(mode='EDIT', toggle=False) | 
					
						
							|  |  |  |         return {'FINISHED'} | 
					
						
							| 
									
										
										
										
											2009-12-13 22:48:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-05 12:37:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-13 17:58:26 +00:00
										 |  |  | class MeshMirrorUV(bpy.types.Operator): | 
					
						
							|  |  |  |     '''Copy mirror UV coordinates on the X axis based on a mirrored mesh''' | 
					
						
							|  |  |  |     bl_idname = "mesh.faces_miror_uv" | 
					
						
							|  |  |  |     bl_label = "Copy Mirrored UV coords" | 
					
						
							| 
									
										
										
										
											2009-11-05 12:37:49 +00:00
										 |  |  |     bl_register = True | 
					
						
							|  |  |  |     bl_undo = True | 
					
						
							| 
									
										
										
										
											2010-01-31 14:46:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-05 12:37:49 +00:00
										 |  |  |     def poll(self, context): | 
					
						
							|  |  |  |         ob = context.active_object | 
					
						
							|  |  |  |         return (ob and ob.type == 'MESH') | 
					
						
							| 
									
										
										
										
											2010-01-31 14:46:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-05 12:37:49 +00:00
										 |  |  |     def execute(self, context): | 
					
						
							| 
									
										
										
										
											2010-01-13 17:58:26 +00:00
										 |  |  |         DIR = 1 # TODO, make an option | 
					
						
							| 
									
										
										
										
											2010-01-31 14:46:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-13 17:58:26 +00:00
										 |  |  |         from Mathutils import Vector | 
					
						
							| 
									
										
										
										
											2010-01-31 14:46:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-13 17:58:26 +00:00
										 |  |  |         ob = context.active_object | 
					
						
							|  |  |  |         is_editmode = (ob.mode == 'EDIT') | 
					
						
							|  |  |  |         if is_editmode: | 
					
						
							|  |  |  |             bpy.ops.object.mode_set(mode='OBJECT', toggle=False) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         mesh = ob.data | 
					
						
							| 
									
										
										
										
											2010-01-31 14:46:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-13 17:58:26 +00:00
										 |  |  |         # mirror lookups | 
					
						
							|  |  |  |         mirror_gt = {} | 
					
						
							|  |  |  |         mirror_lt = {} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												Mathutils refactor & include in sphinx generated docs, (TODO, include getset'ers in docs)
 - Mathutils.MidpointVecs --> vector.lerp(other, fac)
 - Mathutils.AngleBetweenVecs --> vector.angle(other)
 - Mathutils.ProjectVecs --> vector.project(other)
 - Mathutils.DifferenceQuats --> quat.difference(other)
 - Mathutils.Slerp --> quat.slerp(other, fac)
 - Mathutils.Rand: removed, use pythons random module
 - Mathutils.RotationMatrix(angle, size, axis_flag, axis) --> Mathutils.RotationMatrix(angle, size, axis); merge axis & axis_flag args
 - Matrix.scalePart --> Matrix.scale_part
 - Matrix.translationPart --> Matrix.translation_part
 - Matrix.rotationPart --> Matrix.rotation_part
 - toMatrix --> to_matrix
 - toEuler --> to_euler
 - toQuat --> to_quat
 - Vector.toTrackQuat --> Vector.to_track_quat
											
										 
											2010-01-25 09:44:04 +00:00
										 |  |  |         vcos = [v.co.to_tuple(5) for v in mesh.verts] | 
					
						
							| 
									
										
										
										
											2010-01-13 17:58:26 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         for i, co in enumerate(vcos): | 
					
						
							|  |  |  |             if co[0] > 0.0: | 
					
						
							|  |  |  |                 mirror_gt[co] = i | 
					
						
							|  |  |  |             elif co[0] < 0.0: | 
					
						
							|  |  |  |                 mirror_lt[co] = i | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 mirror_gt[co] = i | 
					
						
							|  |  |  |                 mirror_lt[co] = i | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         #for i, v in enumerate(mesh.verts): | 
					
						
							|  |  |  |         vmap = {} | 
					
						
							|  |  |  |         for mirror_a, mirror_b in (mirror_gt, mirror_lt), (mirror_lt, mirror_gt): | 
					
						
							|  |  |  |             for co, i in mirror_a.items(): | 
					
						
							|  |  |  |                 nco = (-co[0], co[1], co[2]) | 
					
						
							|  |  |  |                 j = mirror_b.get(nco) | 
					
						
							|  |  |  |                 if j is not None: | 
					
						
							|  |  |  |                     vmap[i] = j | 
					
						
							| 
									
										
										
										
											2010-01-31 14:46:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-13 17:58:26 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         active_uv_layer = None | 
					
						
							|  |  |  |         for lay in mesh.uv_textures: | 
					
						
							|  |  |  |             if lay.active: | 
					
						
							|  |  |  |                 active_uv_layer = lay.data | 
					
						
							|  |  |  |                 break | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         fuvs = [(uv.uv1, uv.uv2, uv.uv3, uv.uv4) for uv in active_uv_layer] | 
					
						
							|  |  |  |         fuvs_cpy = [(uv[0].copy(), uv[1].copy(), uv[2].copy(), uv[3].copy()) for uv in fuvs] | 
					
						
							| 
									
										
										
										
											2010-01-31 14:46:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-13 17:58:26 +00:00
										 |  |  |         # as a list | 
					
						
							|  |  |  |         faces = mesh.faces[:] | 
					
						
							| 
									
										
										
										
											2010-01-31 14:46:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-13 17:58:26 +00:00
										 |  |  |         fuvsel = [(False not in uv.uv_selected) for uv in active_uv_layer] | 
					
						
							|  |  |  |         fcents = [f.center for f in faces] | 
					
						
							| 
									
										
										
										
											2010-01-31 14:46:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-13 17:58:26 +00:00
										 |  |  |         # find mirror faces | 
					
						
							|  |  |  |         mirror_fm = {} | 
					
						
							|  |  |  |         for i, f in enumerate(faces): | 
					
						
							|  |  |  |             verts = f.verts[:] | 
					
						
							|  |  |  |             verts.sort() | 
					
						
							|  |  |  |             verts = tuple(verts) | 
					
						
							|  |  |  |             mirror_fm[verts] = i | 
					
						
							| 
									
										
										
										
											2010-01-31 14:46:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-13 17:58:26 +00:00
										 |  |  |         fmap = {} | 
					
						
							|  |  |  |         for i, f in enumerate(faces): | 
					
						
							|  |  |  |             verts = [vmap.get(j) for j in f.verts] | 
					
						
							|  |  |  |             if None not in verts: | 
					
						
							|  |  |  |                 verts.sort() | 
					
						
							|  |  |  |                 j = mirror_fm.get(tuple(verts)) | 
					
						
							|  |  |  |                 if j is not None: | 
					
						
							|  |  |  |                     fmap[i] = j | 
					
						
							| 
									
										
										
										
											2010-01-31 14:46:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-13 17:58:26 +00:00
										 |  |  |         done = [False] * len(faces) | 
					
						
							|  |  |  |         for i, j in fmap.items(): | 
					
						
							| 
									
										
										
										
											2010-01-31 14:46:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-13 17:58:26 +00:00
										 |  |  |             if not fuvsel[i] or not fuvsel[j]: | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             elif DIR == 0 and fcents[i][0] < 0.0: | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             elif DIR == 1 and fcents[i][0] > 0.0: | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # copy UVs | 
					
						
							| 
									
										
										
										
											2010-01-31 14:46:28 +00:00
										 |  |  |             uv1 = fuvs[i] | 
					
						
							|  |  |  |             uv2 = fuvs_cpy[j] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-13 17:58:26 +00:00
										 |  |  |             # get the correct rotation | 
					
						
							|  |  |  |             v1 = faces[j].verts[:] | 
					
						
							|  |  |  |             v2 = [vmap[k] for k in faces[i].verts[:]] | 
					
						
							| 
									
										
										
										
											2010-01-31 14:46:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-13 17:58:26 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |             for k in range(len(uv1)): | 
					
						
							|  |  |  |                 k_map = v1.index(v2[k]) | 
					
						
							| 
									
										
										
										
											2010-01-31 14:46:28 +00:00
										 |  |  |                 uv1[k].x = - (uv2[k_map].x - 0.5) + 0.5 | 
					
						
							| 
									
										
										
										
											2010-01-13 17:58:26 +00:00
										 |  |  |                 uv1[k].y = uv2[k_map].y | 
					
						
							| 
									
										
										
										
											2010-01-31 14:46:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-13 17:58:26 +00:00
										 |  |  |         if is_editmode: | 
					
						
							|  |  |  |             bpy.ops.object.mode_set(mode='EDIT', toggle=False) | 
					
						
							| 
									
										
										
										
											2009-11-05 12:37:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-13 17:58:26 +00:00
										 |  |  |         return {'FINISHED'} | 
					
						
							| 
									
										
										
										
											2009-11-05 12:37:49 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | # Register the operator | 
					
						
							| 
									
										
										
										
											2009-12-24 19:50:43 +00:00
										 |  |  | bpy.types.register(MeshSelectInteriorFaces) | 
					
						
							| 
									
										
										
										
											2010-01-13 17:58:26 +00:00
										 |  |  | bpy.types.register(MeshMirrorUV) | 
					
						
							| 
									
										
										
										
											2009-11-05 12:37:49 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | if __name__ == "__main__": | 
					
						
							| 
									
										
										
										
											2010-01-13 17:58:26 +00:00
										 |  |  |     # bpy.ops.mesh.faces_select_interior() | 
					
						
							|  |  |  |     bpy.ops.mesh.faces_miror_uv() |