1
1
# TODO:
2
2
# - Exempt mirror-plane verts.
3
+ # - Check for intersected faces??
4
+ # - Would probably be O(n^m) or something.
5
+ # - Would need to check the post-modified mesh (e.g., Armature-deformed)
3
6
4
7
bl_info = {
5
8
"name" : "MeshLint: Like Spell-checking for your Meshes" ,
@@ -33,9 +36,11 @@ def __init__(self):
33
36
self .obj = bpy .context .active_object
34
37
self .ensure_edit_mode ()
35
38
self .b = bmesh .from_edit_mesh (self .obj .data )
39
+ self .num_problems_found = None
36
40
37
41
def find_problems (self ):
38
42
analysis = []
43
+ self .num_problems_found = 0
39
44
for lint in MeshLintAnalyzer .CHECKS :
40
45
sym = lint ['symbol' ]
41
46
should_check = getattr (bpy .context .scene , lint ['check_prop' ])
@@ -51,9 +56,13 @@ def find_problems(self):
51
56
indices = bad .get (elemtype , [])
52
57
report [elemtype ] = indices
53
58
lint ['count' ] += len (indices )
59
+ self .num_problems_found += len (indices )
54
60
analysis .append (report )
55
61
return analysis
56
62
63
+ def found_zero_problems (self ):
64
+ return 0 == self .num_problems_found
65
+
57
66
@classmethod
58
67
def none_analysis (cls ):
59
68
analysis = []
@@ -64,9 +73,15 @@ def none_analysis(cls):
64
73
return analysis
65
74
66
75
def ensure_edit_mode (self ):
76
+ self .previous_mode = bpy .context .mode
67
77
if 'EDIT_MESH' != bpy .context .mode :
68
78
bpy .ops .object .editmode_toggle ()
69
79
80
+ def restore_previous_mode (self ):
81
+ if 'EDIT_MESH' != self .previous_mode :
82
+ bpy .ops .object .editmode_toggle ()
83
+ self .previous_mode = None
84
+
70
85
CHECKS .append ({
71
86
'symbol' : 'tris' ,
72
87
'label' : 'Tris' ,
@@ -287,6 +302,11 @@ def execute(self, context):
287
302
MeshLintVitalizer .is_live = True
288
303
return {'FINISHED' }
289
304
305
+
306
+ def activate (obj ):
307
+ bpy .context .scene .objects .active = obj
308
+
309
+
290
310
class MeshLintSelector (bpy .types .Operator ):
291
311
'Uncheck boxes below to prevent those checks from running'
292
312
bl_idname = 'meshlint.select'
@@ -298,6 +318,17 @@ def poll(cls, context):
298
318
return has_active_mesh (context )
299
319
300
320
def execute (self , context ):
321
+ original_active = bpy .context .active_object
322
+ for obj in bpy .context .selected_objects :
323
+ activate (obj )
324
+ good = self .active_object_passes ()
325
+ if not good :
326
+ context .area .tag_redraw ()
327
+ return {'FINISHED' }
328
+ activate (original_active )
329
+ return {'FINISHED' }
330
+
331
+ def active_object_passes (self ):
301
332
analyzer = MeshLintAnalyzer ()
302
333
analyzer .enable_anything_select_mode ()
303
334
self .select_none ()
@@ -306,11 +337,15 @@ def execute(self, context):
306
337
for elemtype in ELEM_TYPES :
307
338
indices = lint [elemtype ]
308
339
analyzer .select_indices (elemtype , indices )
309
- context .area .tag_redraw ()
340
+ # TODO: Double-check this. I have the feeling it's already taken care
341
+ # of inside find_problems() --
310
342
# Record this so the first time the user hits "Continuous Check!" it
311
343
# doesn't spew out info they already knew:
312
344
MeshLintContinuousChecker .previous_analysis = analysis
313
- return {'FINISHED' }
345
+ clean = analyzer .found_zero_problems ()
346
+ if clean :
347
+ analyzer .restore_previous_mode ()
348
+ return clean
314
349
315
350
def select_none (self ):
316
351
bpy .ops .mesh .select_all (action = 'DESELECT' )
@@ -329,8 +364,7 @@ def poll(cls, context):
329
364
def draw (self , context ):
330
365
layout = self .layout
331
366
self .add_main_buttons (layout )
332
- if 'EDIT_MESH' == bpy .context .mode :
333
- self .add_rows (layout , context )
367
+ self .add_rows (layout , context )
334
368
335
369
def add_main_buttons (self , layout ):
336
370
split = layout .split ()
@@ -366,6 +400,7 @@ def add_rows(self, layout, context):
366
400
reward = 'ERROR'
367
401
row = col .row ()
368
402
row .prop (context .scene , lint ['check_prop' ], text = label , icon = reward )
403
+ # TODO: Make this iterate over selected.
369
404
if MeshLintControl .has_bad_name (active .name ):
370
405
col .row ().label (
371
406
'...and "%s" is not a great name, BTW.' % active .name )
0 commit comments