~siretart/ubuntu/utopic/blender/libav10

« back to all changes in this revision

Viewing changes to release/scripts/addons_contrib/mesh_select_tools/mesh_extras.py

  • Committer: Reinhard Tartler
  • Date: 2014-05-31 01:50:05 UTC
  • mfrom: (14.2.27 sid)
  • Revision ID: siretart@tauware.de-20140531015005-ml6druahuj82nsav
mergeĀ fromĀ debian

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
import bpy, mathutils, math
 
2
from mathutils import geometry
 
3
 
 
4
# Get a matrix for the selected faces that you can use to do local transforms
 
5
def get_selection_matrix(faces=False):
 
6
        
 
7
        me = bpy.context.active_object.data
 
8
        
 
9
        if not faces:
 
10
                faces = get_selected_faces()
 
11
        
 
12
        yVec = mathutils.Vector()
 
13
        zVec = mathutils.Vector()
 
14
        
 
15
        # Ok so we have a basic matrix, but lets base it more on the mesh!
 
16
        for f in faces:
 
17
                        
 
18
                v1 = me.vertices[f.vertices[0]].co
 
19
                v2 = me.vertices[f.vertices[1]].co
 
20
                edge = v2-v1
 
21
                
 
22
                yVec += edge
 
23
                
 
24
                if len(f.vertices) == 4:
 
25
                        v1 = me.vertices[f.vertices[2]].co
 
26
                        v2 = me.vertices[f.vertices[3]].co
 
27
                        edge = v1-v2
 
28
                        
 
29
                        yVec += edge
 
30
                
 
31
                zVec += mathutils.Vector(f.normal)
 
32
                                        
 
33
        if not yVec.length:
 
34
                quat = zVec.to_track_quat('-Z', 'Y')
 
35
                tMat = quat.to_matrix()
 
36
                yVec = tMat[1]
 
37
                yVec = yVec.normalized()
 
38
        else:
 
39
                yVec = yVec.normalized()
 
40
        zVec = zVec.normalized()
 
41
        
 
42
        # Rotate yVec so it's 90 degrees to zVec
 
43
        cross =yVec.cross(zVec)
 
44
        vec = float(yVec.angle(zVec) - math.radians(90))
 
45
        mat = mathutils.Matrix.Rotation(vec, 3, cross)
 
46
        yVec =  (mat * yVec)
 
47
        
 
48
        xVec = yVec.cross(zVec)
 
49
        
 
50
        xVec = xVec.normalized()
 
51
        
 
52
        nMat = mathutils.Matrix((xVec, yVec, zVec))
 
53
        
 
54
        return nMat
 
55
 
 
56
 
 
57
 
 
58
# Get the selection radius (minimum distance of an outer edge to the centre)
 
59
def get_selection_radius():
 
60
 
 
61
        ob = bpy.context.active_object
 
62
 
 
63
        radius = 0.0
 
64
        
 
65
        # no use continueing if nothing is selected
 
66
        if contains_selected_item(ob.data.polygons):
 
67
        
 
68
                # Find the center of the selection
 
69
                cent = mathutils.Vector()
 
70
                nr = 0
 
71
                nonVerts = []
 
72
                selVerts = []
 
73
                for f in ob.data.polygons:
 
74
                        if f.select:
 
75
                                nr += 1
 
76
                                cent += f.center
 
77
                        else:
 
78
                                nonVerts.extend(f.vertices)
 
79
                                
 
80
                cent /= nr
 
81
                
 
82
                chk = 0
 
83
                
 
84
                # Now that we know the center.. we can figure out how close the nearest point on an outer edge is
 
85
                for e in get_selected_edges():
 
86
                
 
87
                        nonSection = [v for v in e.vertices if v in nonVerts]
 
88
                        if len(nonSection):
 
89
                        
 
90
                                v0 = ob.data.vertices[e.vertices[0]].co
 
91
                                v1 = ob.data.vertices[e.vertices[1]].co
 
92
                                
 
93
                                # If there's more than 1 vert of this edge on the outside... we need the edge length to be long enough too!
 
94
                                if len(nonSection) > 1:
 
95
                                        edge = v0 - v1
 
96
                                        edgeRad = edge.length * 0.5
 
97
                                        
 
98
                                        if edgeRad < radius or not chk:
 
99
                                                radius = edgeRad
 
100
                                                chk += 1
 
101
                                
 
102
                                int = geometry.intersect_point_line(cent, v0, v1)
 
103
                                
 
104
                                rad = cent - int[0]
 
105
                                l = rad.length
 
106
                                
 
107
                                if l < radius or not chk:
 
108
                                        radius = l
 
109
                                        chk += 1
 
110
                                        
 
111
        return radius
 
112
        
 
113
        
 
114
        
 
115
# Get the average length of the outer edges of the current selection
 
116
def get_shortest_outer_edge_length():
 
117
 
 
118
        ob = bpy.context.active_object
 
119
 
 
120
        min = False
 
121
        me = ob.data
 
122
        
 
123
        delVerts = []
 
124
        for f in me.faces:
 
125
                if not f.select:
 
126
                        delVerts.extend(f.vertices)
 
127
        selEdges = [e.vertices for e in me.edges if e.select]
 
128
 
 
129
        if len(selEdges) and len(delVerts):
 
130
                
 
131
                for eVerts in selEdges:
 
132
                        
 
133
                        v0 = eVerts[0]
 
134
                        v1 = eVerts[1]
 
135
                        
 
136
                        if v0 in delVerts and v1 in delVerts:
 
137
                                ln = (me.vertices[v0].co - me.vertices[v1].co).length
 
138
                                if min is False or (ln > 0.0 and ln < min):
 
139
                                        min = ln
 
140
                                                
 
141
        return min
 
142
 
 
143
 
 
144
# Get the average length of the outer edges of the current selection
 
145
def get_average_outer_edge_length():
 
146
 
 
147
        ob = bpy.context.active_object
 
148
 
 
149
        ave = 0.0
 
150
        me = ob.data
 
151
        
 
152
        delFaces = [f.vertices for f  in me.faces if not f.select]
 
153
        selEdges = [e.vertices for e in me.edges if e.select]
 
154
 
 
155
        if len(selEdges) and len(delFaces):
 
156
        
 
157
                number = 0
 
158
                
 
159
                for eVerts in selEdges:
 
160
                        
 
161
                        v0 = eVerts[0]
 
162
                        v1 = eVerts[1]
 
163
                        
 
164
                        for fVerts in delFaces:
 
165
                                if v0 in fVerts and v1 in fVerts:
 
166
                                        number += 1
 
167
                                        ave += (me.vertices[v0].co - me.vertices[v1].co).length
 
168
                                        break
 
169
                                                
 
170
                if number:
 
171
                        ave /= number
 
172
                        
 
173
        return ave
 
174
 
 
175
 
 
176
        
 
177
# Get the selected (or deselected items)
 
178
def get_selected(type='vertices',invert=False):
 
179
        
 
180
        mesh = bpy.context.active_object.data
 
181
        
 
182
        if type == 'vertices':
 
183
                items = mesh.vertices
 
184
        elif type == 'edges':
 
185
                items = mesh.edges
 
186
        else:
 
187
                items = mesh.polygons
 
188
                
 
189
        if invert:
 
190
                L = [i for i in items if not i.select]
 
191
        else:
 
192
                L = [i for i in items if i.select]
 
193
        return L
 
194
        
 
195
        
 
196
        
 
197
# See if the mesh has something selected
 
198
def has_selected(type='vertices',invert=False):
 
199
        
 
200
        mesh = bpy.context.active_object.data
 
201
        
 
202
        if type == 'vertices':
 
203
                items = mesh.vertices
 
204
        elif type == 'edges':
 
205
                items = mesh.edges
 
206
        else:
 
207
                items = mesh.polygons
 
208
                
 
209
        for i in items:
 
210
                if not invert and i.select:
 
211
                        return True
 
212
                elif invert and not i.select:
 
213
                        return True
 
214
                        
 
215
        return False
 
216
                
 
217
                
 
218
 
 
219
# Get all the selected vertices (mode is selected or deselected)
 
220
def get_selected_vertices(mode='selected'):
 
221
 
 
222
        vertices = bpy.context.active_object.data.vertices
 
223
 
 
224
        if mode == 'deselected':
 
225
                L = [v for v in vertices if not v.select]
 
226
        else:
 
227
                L = [v for v in vertices if v.select]
 
228
        return L
 
229
        
 
230
        
 
231
        
 
232
# Get all the selected edges (mode is selected or deselected)
 
233
def get_selected_edges(mode='selected'):
 
234
 
 
235
        edges = bpy.context.active_object.data.edges
 
236
 
 
237
        if mode == 'deselected':
 
238
                L = [e for e in edges if not e.select]
 
239
        else:
 
240
                L = [e for e in edges if e.select]
 
241
        return L
 
242
 
 
243
 
 
244
        
 
245
# Get all the selected faces (mode is selected or deselected)
 
246
def get_selected_faces(mode='selected'):
 
247
        
 
248
        polygons = bpy.context.active_object.data.polygons
 
249
        
 
250
        if mode == 'deselected':
 
251
                L = [f for f in polygons if not f.select]
 
252
        else:
 
253
                L = [f for f in polygons if f.select]
 
254
        return L
 
255
        
 
256
        
 
257
        
 
258
# See if there is at least one selected item in 'items'
 
259
def contains_selected_item(items):
 
260
 
 
261
        for item in items:
 
262
                if item.select:
 
263
                        return True
 
264
                                
 
265
        return False
 
266
        
 
267
 
 
268
 
 
269
 
 
270
 
 
271
 
 
272
        
 
273
        
 
274
                
 
 
b'\\ No newline at end of file'