| 
									
										
										
										
											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 ##### | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-07-25 06:40:16 +00:00
										 |  |  | # <pep8-80 compliant> | 
					
						
							| 
									
										
										
										
											2009-12-13 14:38:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-05 12:37:49 +00:00
										 |  |  | import bpy | 
					
						
							| 
									
										
										
										
											2011-08-12 06:57:00 +00:00
										 |  |  | from bpy.types import Operator | 
					
						
							| 
									
										
										
										
											2009-11-05 12:37:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-29 05:32:27 +00:00
										 |  |  | from bpy.props import EnumProperty | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-31 14:46:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-12 06:57:00 +00:00
										 |  |  | class MeshSelectInteriorFaces(Operator): | 
					
						
							| 
									
										
										
										
											2011-09-21 17:52:51 +00:00
										 |  |  |     '''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" | 
					
						
							| 
									
										
										
										
											2010-03-01 00:03:51 +00:00
										 |  |  |     bl_options = {'REGISTER', 'UNDO'} | 
					
						
							| 
									
										
										
										
											2009-11-05 12:37:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-09 01:37:09 +00:00
										 |  |  |     @classmethod | 
					
						
							|  |  |  |     def poll(cls, context): | 
					
						
							| 
									
										
										
										
											2010-01-13 17:58:26 +00:00
										 |  |  |         ob = context.active_object | 
					
						
							|  |  |  |         return (ob and ob.type == 'MESH') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def execute(self, context): | 
					
						
							| 
									
										
										
										
											2011-05-26 07:16:56 +00:00
										 |  |  |         from bpy_extras import mesh_utils | 
					
						
							| 
									
										
										
										
											2010-01-13 17:58:26 +00:00
										 |  |  |         ob = context.active_object | 
					
						
							| 
									
										
										
										
											2011-01-06 05:45:41 +00:00
										 |  |  |         context.tool_settings.mesh_select_mode = False, False, True | 
					
						
							| 
									
										
										
										
											2010-01-13 17:58:26 +00:00
										 |  |  |         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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-06 05:45:41 +00:00
										 |  |  |         face_list = mesh.faces[:] | 
					
						
							| 
									
										
										
										
											2010-01-13 17:58:26 +00:00
										 |  |  |         face_edge_keys = [face.edge_keys for face in face_list] | 
					
						
							| 
									
										
										
										
											2009-11-21 23:55:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-26 07:16:56 +00:00
										 |  |  |         edge_face_count = mesh_utils.edge_face_count_dict(mesh) | 
					
						
							| 
									
										
										
										
											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)): | 
					
						
							| 
									
										
										
										
											2010-07-15 16:56:04 +00:00
										 |  |  |                 face.select = True | 
					
						
							| 
									
										
										
										
											2010-01-13 17:58:26 +00:00
										 |  |  |             else: | 
					
						
							| 
									
										
										
										
											2010-07-15 16:56:04 +00:00
										 |  |  |                 face.select = 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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-12 06:57:00 +00:00
										 |  |  | class MeshMirrorUV(Operator): | 
					
						
							| 
									
										
										
										
											2010-01-13 17:58:26 +00:00
										 |  |  |     '''Copy mirror UV coordinates on the X axis based on a mirrored mesh''' | 
					
						
							| 
									
										
										
										
											2011-04-29 05:32:27 +00:00
										 |  |  |     bl_idname = "mesh.faces_mirror_uv" | 
					
						
							| 
									
										
										
										
											2010-01-13 17:58:26 +00:00
										 |  |  |     bl_label = "Copy Mirrored UV coords" | 
					
						
							| 
									
										
										
										
											2010-03-01 00:03:51 +00:00
										 |  |  |     bl_options = {'REGISTER', 'UNDO'} | 
					
						
							| 
									
										
										
										
											2010-01-31 14:46:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-19 19:25:20 +00:00
										 |  |  |     direction = EnumProperty( | 
					
						
							|  |  |  |             name="Axis Direction", | 
					
						
							|  |  |  |             items=(('POSITIVE', "Positive", ""), | 
					
						
							|  |  |  |                    ('NEGATIVE', "Negative", "")), | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2011-04-29 05:32:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-09 01:37:09 +00:00
										 |  |  |     @classmethod | 
					
						
							|  |  |  |     def poll(cls, context): | 
					
						
							| 
									
										
										
										
											2011-07-01 13:25:00 +00:00
										 |  |  |         obj = context.active_object | 
					
						
							|  |  |  |         return (obj and obj.type == 'MESH' and obj.data.uv_textures.active) | 
					
						
							| 
									
										
										
										
											2010-01-31 14:46:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-05 12:37:49 +00:00
										 |  |  |     def execute(self, context): | 
					
						
							| 
									
										
										
										
											2011-04-29 05:32:27 +00:00
										 |  |  |         DIR = (self.direction == 'NEGATIVE') | 
					
						
							| 
									
										
										
										
											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 = {} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-18 03:42:26 +00:00
										 |  |  |         vcos = [v.co.to_tuple(5) for v in mesh.vertices] | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-18 03:42:26 +00:00
										 |  |  |         #for i, v in enumerate(mesh.vertices): | 
					
						
							| 
									
										
										
										
											2010-01-13 17:58:26 +00:00
										 |  |  |         vmap = {} | 
					
						
							| 
									
										
										
										
											2011-07-25 06:40:16 +00:00
										 |  |  |         for mirror_a, mirror_b in ((mirror_gt, mirror_lt), | 
					
						
							|  |  |  |                                    (mirror_lt, mirror_gt)): | 
					
						
							| 
									
										
										
										
											2010-01-13 17:58:26 +00:00
										 |  |  |             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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-07-01 13:25:00 +00:00
										 |  |  |         active_uv_layer = mesh.uv_textures.active.data | 
					
						
							| 
									
										
										
										
											2010-01-13 17:58:26 +00:00
										 |  |  |         fuvs = [(uv.uv1, uv.uv2, uv.uv3, uv.uv4) for uv in active_uv_layer] | 
					
						
							| 
									
										
										
										
											2011-07-25 06:40:16 +00:00
										 |  |  |         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-07-15 16:56:04 +00:00
										 |  |  |         fuvsel = [(False not in uv.select_uv) for uv in active_uv_layer] | 
					
						
							| 
									
										
										
										
											2010-01-13 17:58:26 +00:00
										 |  |  |         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): | 
					
						
							| 
									
										
										
										
											2011-03-14 23:52:50 +00:00
										 |  |  |             verts = list(f.vertices) | 
					
						
							| 
									
										
										
										
											2010-01-13 17:58:26 +00:00
										 |  |  |             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): | 
					
						
							| 
									
										
										
										
											2010-08-18 03:42:26 +00:00
										 |  |  |             verts = [vmap.get(j) for j in f.vertices] | 
					
						
							| 
									
										
										
										
											2010-01-13 17:58:26 +00:00
										 |  |  |             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
										 |  |  |         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 | 
					
						
							| 
									
										
										
										
											2010-08-18 03:42:26 +00:00
										 |  |  |             v1 = faces[j].vertices[:] | 
					
						
							|  |  |  |             v2 = [vmap[k] for k in faces[i].vertices[:]] | 
					
						
							| 
									
										
										
										
											2010-01-31 14:46:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-06-21 02:16:22 +00:00
										 |  |  |             if len(v1) == len(v2): | 
					
						
							|  |  |  |                 for k in range(len(v1)): | 
					
						
							|  |  |  |                     k_map = v1.index(v2[k]) | 
					
						
							|  |  |  |                     uv1[k].xy = - (uv2[k_map].x - 0.5) + 0.5, 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'} |