Newer
Older
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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
import bpy, mathutils, math
from mathutils import geometry
# Get a matrix for the selected faces that you can use to do local transforms
def get_selection_matrix(faces=False):
me = bpy.context.active_object.data
if not faces:
faces = get_selected_faces()
yVec = mathutils.Vector()
zVec = mathutils.Vector()
# Ok so we have a basic matrix, but lets base it more on the mesh!
for f in faces:
v1 = me.vertices[f.vertices[0]].co
v2 = me.vertices[f.vertices[1]].co
edge = v2-v1
yVec += edge
if len(f.vertices) == 4:
v1 = me.vertices[f.vertices[2]].co
v2 = me.vertices[f.vertices[3]].co
edge = v1-v2
yVec += edge
zVec += mathutils.Vector(f.normal)
if not yVec.length:
quat = zVec.to_track_quat('-Z', 'Y')
tMat = quat.to_matrix()
yVec = tMat[1]
yVec = yVec.normalized()
else:
yVec = yVec.normalized()
zVec = zVec.normalized()
# Rotate yVec so it's 90 degrees to zVec
cross =yVec.cross(zVec)
vec = float(yVec.angle(zVec) - math.radians(90))
mat = mathutils.Matrix.Rotation(vec, 3, cross)
yVec = (mat * yVec)
xVec = yVec.cross(zVec)
xVec = xVec.normalized()
nMat = mathutils.Matrix((xVec, yVec, zVec))
return nMat
# Get the selection radius (minimum distance of an outer edge to the centre)
def get_selection_radius():
ob = bpy.context.active_object
radius = 0.0
# no use continueing if nothing is selected
if contains_selected_item(ob.data.polygons):
# Find the center of the selection
cent = mathutils.Vector()
nr = 0
nonVerts = []
selVerts = []
for f in ob.data.polygons:
if f.select:
nr += 1
cent += f.center
else:
nonVerts.extend(f.vertices)
cent /= nr
chk = 0
# Now that we know the center.. we can figure out how close the nearest point on an outer edge is
for e in get_selected_edges():
nonSection = [v for v in e.vertices if v in nonVerts]
if len(nonSection):
v0 = ob.data.vertices[e.vertices[0]].co
v1 = ob.data.vertices[e.vertices[1]].co
# If there's more than 1 vert of this edge on the outside... we need the edge length to be long enough too!
if len(nonSection) > 1:
edge = v0 - v1
edgeRad = edge.length * 0.5
if edgeRad < radius or not chk:
radius = edgeRad
chk += 1
int = geometry.intersect_point_line(cent, v0, v1)
rad = cent - int[0]
l = rad.length
if l < radius or not chk:
radius = l
chk += 1
return radius
# Get the average length of the outer edges of the current selection
def get_shortest_outer_edge_length():
ob = bpy.context.active_object
min = False
me = ob.data
delVerts = []
for f in me.faces:
if not f.select:
delVerts.extend(f.vertices)
selEdges = [e.vertices for e in me.edges if e.select]
if len(selEdges) and len(delVerts):
for eVerts in selEdges:
v0 = eVerts[0]
v1 = eVerts[1]
if v0 in delVerts and v1 in delVerts:
ln = (me.vertices[v0].co - me.vertices[v1].co).length
if min is False or (ln > 0.0 and ln < min):
min = ln
return min
# Get the average length of the outer edges of the current selection
def get_average_outer_edge_length():
ob = bpy.context.active_object
ave = 0.0
me = ob.data
delFaces = [f.vertices for f in me.faces if not f.select]
selEdges = [e.vertices for e in me.edges if e.select]
if len(selEdges) and len(delFaces):
number = 0
for eVerts in selEdges:
v0 = eVerts[0]
v1 = eVerts[1]
for fVerts in delFaces:
if v0 in fVerts and v1 in fVerts:
number += 1
ave += (me.vertices[v0].co - me.vertices[v1].co).length
break
if number:
ave /= number
return ave
# Get the selected (or deselected items)
def get_selected(type='vertices',invert=False):
mesh = bpy.context.active_object.data
if type == 'vertices':
items = mesh.vertices
elif type == 'edges':
items = mesh.edges
else:
items = mesh.polygons
if invert:
L = [i for i in items if not i.select]
else:
L = [i for i in items if i.select]
return L
# See if the mesh has something selected
def has_selected(type='vertices',invert=False):
mesh = bpy.context.active_object.data
if type == 'vertices':
items = mesh.vertices
elif type == 'edges':
items = mesh.edges
else:
items = mesh.polygons
for i in items:
if not invert and i.select:
return True
elif invert and not i.select:
return True
return False
# Get all the selected vertices (mode is selected or deselected)
def get_selected_vertices(mode='selected'):
vertices = bpy.context.active_object.data.vertices
if mode == 'deselected':
L = [v for v in vertices if not v.select]
else:
L = [v for v in vertices if v.select]
return L
# Get all the selected edges (mode is selected or deselected)
def get_selected_edges(mode='selected'):
edges = bpy.context.active_object.data.edges
if mode == 'deselected':
L = [e for e in edges if not e.select]
else:
L = [e for e in edges if e.select]
return L
# Get all the selected faces (mode is selected or deselected)
def get_selected_faces(mode='selected'):
polygons = bpy.context.active_object.data.polygons
if mode == 'deselected':
L = [f for f in polygons if not f.select]
else:
L = [f for f in polygons if f.select]
return L
# See if there is at least one selected item in 'items'
def contains_selected_item(items):
for item in items:
if item.select:
return True
return False