forked from franMarz/TexTools-Blender
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathop_select_islands_flipped.py
133 lines (93 loc) · 3.5 KB
/
op_select_islands_flipped.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import bpy
import bmesh
import operator
from mathutils import Vector
from collections import defaultdict
from math import pi
from . import utilities_uv
import imp
imp.reload(utilities_uv)
class op(bpy.types.Operator):
bl_idname = "uv.textools_select_islands_flipped"
bl_label = "Select Flipped"
bl_description = "Select all flipped UV islands"
bl_options = {'REGISTER', 'UNDO'}
@classmethod
def poll(cls, context):
if not bpy.context.active_object:
return False
if bpy.context.active_object.type != 'MESH':
return False
#Only in Edit mode
if bpy.context.active_object.mode != 'EDIT':
return False
#Only in UV editor mode
if bpy.context.area.type != 'IMAGE_EDITOR':
return False
##Requires UV map
if not bpy.context.object.data.uv_layers:
return False
#Not in Synced mode
if bpy.context.scene.tool_settings.use_uv_select_sync:
return False
return True
def execute(self, context):
select_flipped(context)
return {'FINISHED'}
def select_flipped(context):
bm = bmesh.from_edit_mesh(bpy.context.active_object.data)
uv_layers = bm.loops.layers.uv.verify()
bpy.context.scene.tool_settings.uv_select_mode = 'FACE'
bpy.ops.uv.select_all(action='SELECT')
islands = utilities_uv.getSelectionIslands()
bpy.context.scene.tool_settings.uv_select_mode = 'FACE'
bpy.context.scene.tool_settings.use_uv_select_sync = False
bpy.ops.uv.select_all(action='DESELECT')
for island in islands:
is_flipped = False
for face in island:
if is_flipped:
break
# Using 'Sum of Edges' to detect counter clockwise https://stackoverflow.com/questions/1165647/how-to-determine-if-a-list-of-polygon-points-are-in-clockwise-order
sum = 0
count = len(face.loops)
for i in range(count):
uv_A = face.loops[i][uv_layers].uv
uv_B = face.loops[(i+1)%count][uv_layers].uv
sum += (uv_B.x - uv_A.x) * (uv_B.y + uv_A.y)
if sum > 0:
# Flipped
is_flipped = True
break
# Select Island if flipped
if is_flipped:
for face in island:
for loop in face.loops:
loop[uv_layers].select = True
class Island_bounds:
faces = []
center = Vector([0,0])
min = Vector([0,0])
max = Vector([0,0])
def __init__(self, faces):
bm = bmesh.from_edit_mesh(bpy.context.active_object.data);
uv_layers = bm.loops.layers.uv.verify();
# Collect topology stats
self.faces = faces
#Select Island
bpy.ops.uv.select_all(action='DESELECT')
utilities_uv.set_selected_faces(faces)
bounds = utilities_uv.getSelectionBBox()
self.center = bounds['center']
self.min = bounds['min']
self.max = bounds['max']
def isEqual(A, B):
# Bounding Box AABB intersection?
min_x = max(A.min.x, B.min.x)
min_y = max(A.min.y, B.min.y)
max_x = min(A.max.x, B.max.x)
max_y = min(A.max.y, B.max.y)
if not (max_x < min_x or max_y < min_y):
return True
return False
bpy.utils.register_class(op)