forked from C-Core/UltimateTrimUV
-
Notifications
You must be signed in to change notification settings - Fork 0
/
island.py
144 lines (116 loc) · 4.5 KB
/
island.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
134
135
136
137
138
139
140
141
142
143
144
"""The Island module."""
import math
import os
import sys
import mathutils
from . import geometry, global_def, utils
class Island:
"""Create Island from a set() of faces.
:param island: a set() of face indexes.
:type island: set().
"""
def __init__(self, island):
self.faceList = island
def __iter__(self):
"""Iterate throught all face faces forming the island."""
for i in self.faceList:
yield i
def __len__(self):
"""Return the number of faces of this island."""
return len(self.faceList)
def __str__(self):
return str(self.faceList)
def __repr__(self):
return repr(self.faceList)
def __eq__(self, other):
"""Compare two island."""
return self.faceList == other
# properties
def BBox(self):
"""Return the bounding box of the island.
:return: a Rectangle rappresenting the bounding box of the island.
:rtype: :class:`.Rectangle`
"""
minX = minY = 1000
maxX = maxY = -1000
for face_id in self.faceList:
face = global_def.bm.faces[face_id]
for loop in face.loops:
u, v = loop[global_def.uvlayer].uv
minX = min(u, minX)
minY = min(v, minY)
maxX = max(u, maxX)
maxY = max(v, maxY)
return geometry.Rectangle(mathutils.Vector((minX, minY)),
mathutils.Vector((maxX, maxY)))
def angle(self):
"""Return the island angle.
:return: the angle of the island in radians.
:rtype: float
"""
uvList = []
for face_id in self.faceList:
face = global_def.bm.faces[face_id]
for loop in face.loops:
uv = loop[global_def.bm.loops.layers.uv.active].uv
uvList.append(uv)
angle = mathutils.geometry.box_fit_2d(uvList)
return angle
def size(self):
"""Return the island size.
:return: the size of the island(bounding box).
:rtype: :class:`.Size`
"""
bbox = self.BBox()
sizeX = bbox.right() - bbox.left()
sizeY = bbox.top() - bbox.bottom()
return geometry.Size(sizeX, sizeY)
# Transformation
def move(self, vector):
"""Move the island by vector.
Move the island by 'vector', by adding 'vector' to the curretnt uv
coords.
:param vector: the vector to add.
:rtype: :class:`mathutils.Vector`
"""
for face_id in self.faceList:
face = global_def.bm.faces[face_id]
for loop in face.loops:
loop[global_def.bm.loops.layers.uv.active].uv += vector
def rotate(self, angle):
"""Rotate the island on it's center by 'angle(radians)'.
:param angle: the angle(radians) of rotation.
:rtype: float
"""
center = self.BBox().center()
for face_id in self.faceList:
face = global_def.bm.faces[face_id]
for loop in face.loops:
uv_act = global_def.bm.loops.layers.uv.active
x, y = loop[uv_act].uv
xt = x - center.x
yt = y - center.y
xr = (xt * math.cos(angle)) - (yt * math.sin(angle))
yr = (xt * math.sin(angle)) + (yt * math.cos(angle))
# loop[global_def.bm.loops.layers.uv.active].uv = trans
loop[global_def.bm.loops.layers.uv.active].uv.x = xr + center.x
loop[global_def.bm.loops.layers.uv.active].uv.y = yr + center.y
def scale(self, scaleX, scaleY):
"""Scale the island by 'scaleX, scaleY'.
:param scaleX: x scale factor.
:type scaleX: float
:param scaleY: y scale factor
:type scaleY: float
"""
center = self.BBox().center()
for face_id in self.faceList:
face = global_def.bm.faces[face_id]
for loop in face.loops:
x = loop[global_def.bm.loops.layers.uv.active].uv.x
y = loop[global_def.bm.loops.layers.uv.active].uv.y
xt = x - center.x
yt = y - center.y
xs = xt * scaleX
ys = yt * scaleY
loop[global_def.bm.loops.layers.uv.active].uv.x = xs + center.x
loop[global_def.bm.loops.layers.uv.active].uv.y = ys + center.y