@@ -139,7 +139,7 @@ def update_external_rigs(self, context):
139
139
for rig in rig_lists .rigs_dict ['external' ]['rig_list' ]:
140
140
r = utils .get_rig_type (rig , custom_rigs_folder )
141
141
try :
142
- r .add_parameters (RigifyParameters )
142
+ r .add_parameters (RigifyParameterValidator ( RigifyParameters , rig , RIGIFY_PARAMETER_TABLE ) )
143
143
except AttributeError :
144
144
pass
145
145
@@ -263,6 +263,58 @@ class RigifyParameters(bpy.types.PropertyGroup):
263
263
name = bpy .props .StringProperty ()
264
264
265
265
266
+ RIGIFY_PARAMETER_TABLE = { 'name' : ('DEFAULT' ,bpy .props .StringProperty ()) }
267
+
268
+ def format_property_spec (spec ):
269
+ """Turns the return value of bpy.props.SomeProperty(...) into a readable string."""
270
+ callback , params = spec
271
+ param_str = ["%s=%r" % (k , v ) for k ,v in params .items ()]
272
+ return "%s(%s)" % (callback .__name__ , ', ' .join (param_str ))
273
+
274
+ class RigifyParameterValidator (object ):
275
+ """
276
+ A wrapper around RigifyParameters that verifies properties
277
+ defined from rigs for incompatible redefinitions using a table.
278
+
279
+ Relies on the implementation details of bpy.props return values:
280
+ specifically, they just return a tuple containing the real define
281
+ function, and a dictionary with parameters. This allows comparing
282
+ parameters before the property is actually defined.
283
+ """
284
+ __params = None
285
+ __rig_name = ''
286
+ __prop_table = {}
287
+
288
+ def __init__ (self , params , rig_name , prop_table ):
289
+ self .__params = params
290
+ self .__rig_name = rig_name
291
+ self .__prop_table = prop_table
292
+
293
+ def __getattr__ (self , name ):
294
+ return getattr (self .__params , name )
295
+
296
+ def __setattr__ (self , name , val ):
297
+ # allow __init__ to work correctly
298
+ if hasattr (RigifyParameterValidator , name ):
299
+ return object .__setattr__ (self , name , val )
300
+
301
+ if not (isinstance (val , tuple ) and callable (val [0 ]) and isinstance (val [1 ], dict )):
302
+ print ("!!! RIGIFY RIG %s: INVALID DEFINITION FOR RIG PARAMETER %s: %r\n " % (self .__rig_name , name , val ))
303
+ return
304
+
305
+ if name in self .__prop_table :
306
+ cur_rig , cur_info = self .__prop_table [name ]
307
+ if val != cur_info :
308
+ print ("!!! RIGIFY RIG %s: REDEFINING PARAMETER %s AS:\n \n %s\n " % (self .__rig_name , name , format_property_spec (val )))
309
+ print ("!!! PREVIOUS DEFINITION BY %s:\n \n %s\n " % (cur_rig , format_property_spec (cur_info )))
310
+
311
+ # actually defining the property modifies the dictionary with new parameters, so copy it now
312
+ new_def = (val [0 ], val [1 ].copy ())
313
+
314
+ setattr (self .__params , name , val )
315
+ self .__prop_table [name ] = (self .__rig_name , new_def )
316
+
317
+
266
318
class RigifyArmatureLayer (bpy .types .PropertyGroup ):
267
319
268
320
def get_group (self ):
@@ -382,7 +434,7 @@ def update_mode(self, context):
382
434
for rig in rig_lists .rig_list :
383
435
r = utils .get_rig_type (rig )
384
436
try :
385
- r .add_parameters (RigifyParameters )
437
+ r .add_parameters (RigifyParameterValidator ( RigifyParameters , rig , RIGIFY_PARAMETER_TABLE ) )
386
438
except AttributeError :
387
439
pass
388
440
0 commit comments