Newer
Older
#
# correctRig(args):
#
def correctRig(args):
human = args[0]
Thomas Larsson
committed
print("CorrectRig %s" % human)
try:
ob = loadedData['Object'][human]
except:
ob.MhxShapekeyDrivers = (toggle&T_Shapekeys != 0 and toggle&T_ShapeDrivers != 0)
bpy.context.scene.objects.active = ob
bpy.ops.object.mode_set(mode='POSE')
amt = ob.data
cnslist = []
for pb in ob.pose.bones:
for cns in pb.constraints:
if cns.type == 'CHILD_OF':
cnslist.append((pb, cns, cns.influence))
cns.influence = 0
for (pb, cns, inf) in cnslist:
amt.bones.active = pb.bone
cns.influence = 1
#print("Childof %s %s %s %.2f" % (amt.name, pb.name, cns.name, inf))
bpy.ops.constraint.childof_clear_inverse(constraint=cns.name, owner='BONE')
bpy.ops.constraint.childof_set_inverse(constraint=cns.name, owner='BONE')
cns.influence = 0
for (pb, cns, inf) in cnslist:
cns.influence = inf
return
Thomas Larsson
committed
#
# postProcess(args)
#
def postProcess(args):
human = args[0]
Thomas Larsson
committed
print("Postprocess %s" % human)
ob = loadedData['Object'][human]
except:
ob = None
if toggle & T_Diamond == 0 and ob:
Thomas Larsson
committed
deleteDiamonds(ob)
return
#
# deleteDiamonds(ob)
# Delete joint diamonds in main mesh
# Invisio = material # 1
#
def deleteDiamonds(ob):
bpy.context.scene.objects.active = ob
if not bpy.context.object:
return
print("Delete helper geometry in %s" % bpy.context.object)
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_all(action='DESELECT')
bpy.ops.object.mode_set(mode='OBJECT')
me = ob.data
invisioNum = -1
for mn,mat in enumerate(me.materials):
if "Invis" in mat.name:
invisioNum = mn
break
if invisioNum < 0:
print("WARNING: Nu Invisio material found. Cannot delete helper geometry")
Thomas Larsson
committed
elif BMeshAware:
for f in me.polygons:
if f.material_index >= invisioNum:
for vn in f.vertices:
me.vertices[vn].select = True
Thomas Larsson
committed
else:
for f in me.faces:
if f.material_index >= invisioNum:
for vn in f.vertices:
me.vertices[vn].select = True
Thomas Larsson
committed
if BMeshAware and toggle&T_CrashSafe:
theMessage = "\n *** WARNING ***\nHelper deletion turned off due to Blender crash.\nHelpers can be deleted by deleting all selected vertices in Edit mode\n **********\n"
print(theMessage)
else:
bpy.ops.object.mode_set(mode='EDIT')
print("Do delete")
bpy.ops.mesh.delete(type='VERT')
print("Verts deleted")
bpy.ops.object.mode_set(mode='OBJECT')
print("Back to object mode")
Thomas Larsson
committed
# defaultKey(ext, args, tokens, data, exclude):
Thomas Larsson
committed
theProperty = None
def propNames(string):
Thomas Larsson
committed
global alpha7
#string = string.encode('utf-8', 'strict')
Thomas Larsson
committed
Thomas Larsson
committed
# Alpha 7 compatibility
if string[0:2] == "&_":
string = "Mhf"+string[2:]
alpha7 = True
elif string[0] == "&":
string = "Mha"+string[1:]
alpha7 = True
elif string[0] == "*":
string = "Mhs"+string[1:]
alpha7 = True
elif len(string) > 4 and string[0:4] == "Hide":
Thomas Larsson
committed
string = "Mhh"+string[4:]
alpha7 = True
Thomas Larsson
committed
if string[0] == "_":
return None,None
elif (len(string) > 3 and
string[0:3] in ["Mha", "Mhf", "Mhs", "Mhh", "Mhv", "Mhc"]):
Thomas Larsson
committed
return name, '["%s"]' % name
Thomas Larsson
committed
else:
Thomas Larsson
committed
proptype = args[0]
name = propNames(args[1])[0]
Thomas Larsson
committed
value = args[2]
rest = 'description="%s"' % args[3].replace("_", " ")
if len(args) > 4:
rest += ", " + args[4]
Thomas Larsson
committed
Thomas Larsson
committed
Thomas Larsson
committed
def defNewProp(name, proptype, rest):
prop = "%sProperty(%s)" % (proptype, rest)
Thomas Larsson
committed
setattr(bpy.types.Object, name, eval(prop)) # safe: only called from this file
Thomas Larsson
committed
Thomas Larsson
committed
def setProperty(args, var):
Thomas Larsson
committed
global theProperty
tip = ""
name = propNames(args[0])[0]
value = mhxEval(args[1])
Thomas Larsson
committed
if name:
Thomas Larsson
committed
if len(args) > 2:
tip = 'description="%s"' % args[2].replace("_", " ")
theProperty = (name, tip, value)
Thomas Larsson
committed
Thomas Larsson
committed
Thomas Larsson
committed
global theProperty
if theProperty is None:
return
(name, tip, value) = theProperty
if len(args) >= 2 and not isinstance(value, bool):
Thomas Larsson
committed
if "BOOLEAN" in args[1]:
Thomas Larsson
committed
else:
tip = tip + "," + args[1].replace(":", "=").replace('"', " ")
#expr = "bpy.types.Object.%s = %sProperty(%s)" % (name, proptype, tip)
if isinstance(value, bool):
prop = BoolProperty(tip)
elif isinstance(value, int):
prop = IntProperty(tip)
elif isinstance(value, float):
prop = FloatProperty(tip)
elif isinstance(value, string):
prop = StringProperty(tip)
setattr(bpy.types.Object, name, prop)
Thomas Larsson
committed
theProperty = None
Thomas Larsson
committed
def defaultKey(ext, args, tokens, var, exclude=[]):
return setProperty(args, var)
Thomas Larsson
committed
elif ext == 'PropKeys':
if ext == 'bpyops':
expr = "bpy.ops.%s" % args[0]
print(expr)
raise MhxError("MHX bug: calling %s" % expr)
Thomas Larsson
committed
Thomas Larsson
committed
if rnaType == 'Refer':
setattr(var, ext, loadedData[typ][name])
return
raise MhxError("Struct/Define!")
Thomas Larsson
committed
data = None
if data is None:
try:
creator = args[3]
except:
creator = None
try:
rna = mhxEval(var, locals())
data = mhxEval(creator)
Thomas Larsson
committed
data = None
# print("New struct", nvar, typ, data)
if rnaType == 'Define':
loadedData[typ][name] = data
if data:
for (key, val, sub) in tokens:
defaultKey(key, val, sub, data)
raise MhxError("PropertyRNA!")
#print("PropertyRNA ", ext, var)
for (key, val, sub) in tokens:
defaultKey(ext, val, sub, nvar, [])
return
elif rnaType == 'Array':
for n in range(1, len(args)):
nvar[n-1] = mhxEval(args[n], locals())
nvar[0] = mhxEval(args[1], locals())
Thomas Larsson
committed
raise MhxError("List!")
elt = mhxEval(val[1], locals())
setattr(var, ext, data)
return
raise MhxError("Matrix!")
i = 0
n = len(tokens)
for (key, val, sub) in tokens:
Thomas Larsson
committed
if key == 'row':
i += 1
return
else:
try:
data = loadedData[rnaType][args[1]]
raise MhxError("From loaded %s %s!" % (rnaType, args[1]))
except KeyError:
pass
data = mhxEval(rnaType, locals())
setattr(var, ext, data)
#
#
#
def pushOnTodoList(var, expr):
Thomas Larsson
committed
print("Unrecognized expression", expr)
return
print(dir(mhxEval(var)))
MyError(
"Unrecognized expression %s.\n" % expr +
"This can mean that Blender's python API has changed\n" +
"since the MHX file was exported. Try to export again\n" +
"from an up-to-date MakeHuman nightly build.\n" +
"Alternatively, your Blender version may be obsolete.\n" +
"Download an up-to-date version from www.graphicall.org")
Thomas Larsson
committed
Thomas Larsson
committed
if c == '0':
list.append(False)
else:
list.append(True)
return list
matrix = mathutils.Matrix()
Thomas Larsson
committed
if key == 'row':
matrix[i][0] = float(val[0])
matrix[i][1] = float(val[1])
matrix[i][2] = float(val[2])
matrix[i][3] = float(val[3])
i += 1
return matrix
def parseDefault(data, tokens, subkeys, exclude):
Thomas Larsson
committed
for (key, val, sub) in tokens:
if key in subkeys.keys():
for (key2, val2, sub2) in sub:
ndata = getattr(data, subkeys[key])
defaultKey(key2, val2, sub2, ndata)
defaultKey(key, val, sub, data, exclude)
def parseCollection(data, tokens, exclude):
Thomas Larsson
committed
# Utilities
Thomas Larsson
committed
"""
typeSplit = str(type(data)).split("'")
if typeSplit[0] != '<class ':
return None
classSplit = typeSplit[1].split(".")
if classSplit[0] == 'bpy' and classSplit[1] == 'types':
return classSplit[2]
elif classSplit[0] == 'bpy_types':
return classSplit[1]
else:
return None
if string == 'True':
return True
elif string == 'False':
return False
else:
Thomas Larsson
committed
"""
res = mhxEval(condition)
#print("%s = %s" % (condition, res))
return not res
except:
#print("%s invalid!" % condition)
return True
Thomas Larsson
committed
Thomas Larsson
committed
global toggle
scn = bpy.context.scene
for n in range(len(scn.layers)):
scn.layers[n] = True
print("clearScene %s %s" % (toggle & T_Replace, scn))
if not toggle & T_Replace:
return scn
for ob in scn.objects:
Thomas Larsson
committed
if ob.type in ['MESH', 'ARMATURE', 'EMPTY', 'CURVE', 'LATTICE']:
Thomas Larsson
committed
ob.name = "#" + ob.name
try:
bpy.ops.object.mode_set(mode='OBJECT')
except:
pass
Thomas Larsson
committed
for grp in bpy.data.groups:
grp.name = "#" + grp.name
#
# hideLayers(args):
# args = sceneLayers sceneHideLayers boneLayers boneHideLayers or nothing
#
def hideLayers(args):
if len(args) > 1:
sceneLayers = int(args[2], 16)
sceneHideLayers = int(args[3], 16)
boneLayers = int(args[4], 16)
# boneHideLayers = int(args[5], 16)
boneHideLayers = 0
else:
sceneLayers = 0x00ff
sceneHideLayers = 0
boneLayers = 0
boneHideLayers = 0
mask = 1
hidelayers = []
for n in range(20):
scn.layers[n] = True if sceneLayers & mask else False
if sceneHideLayers & mask:
hidelayers.append(n)
mask = mask << 1
for ob in scn.objects:
for n in hidelayers:
if ob.layers[n]:
ob.hide = True
ob.hide_render = True
Thomas Larsson
committed
if boneLayers:
human = args[1]
try:
ob = loadedData['Object'][human]
except:
return
mask = 1
hidelayers = []
for n in range(32):
ob.data.layers[n] = True if boneLayers & mask else False
if boneHideLayers & mask:
hidelayers.append(n)
mask = mask << 1
for b in ob.data.bones:
for n in hidelayers:
if b.layers[n]:
b.hide = True
return
Thomas Larsson
committed
#
# readDefaults():
# writeDefaults():
#
ConfigFile = '~/mhx_import.cfg'
def readDefaults():
global toggle, toggleSettings, theScale
path = os.path.realpath(os.path.expanduser(ConfigFile))
try:
fp = open(path, 'rU')
print('Storing defaults')
except:
print('Cannot open "%s" for reading' % path)
return
bver = ''
Thomas Larsson
committed
for line in fp:
words = line.split()
if len(words) >= 3:
try:
toggle = int(words[0],16)
theScale = float(words[1])
except:
Thomas Larsson
committed
print('Configuration file "%s" is corrupt' % path)
fp.close()
toggleSettings = toggle
return
def writeDefaults():
global toggleSettings, theScale
path = os.path.realpath(os.path.expanduser(ConfigFile))
try:
fp = open(path, 'w')
print('Storing defaults')
except:
print('Cannot open "%s" for writing' % path)
return
fp.write("%x %f Graphicall" % (toggleSettings, theScale))
fp.close()
###################################################################################
#
# Postprocessing of rigify rig
#
Thomas Larsson
committed
# rigifyMhx(context):
#
###################################################################################
Thomas Larsson
committed
class RigifyBone:
def __init__(self, eb):
self.name = eb.name
self.realname = None
self.realname1 = None
self.realname2 = None
self.fkname = None
self.ikname = None
Thomas Larsson
committed
Thomas Larsson
committed
self.head = eb.head.copy()
self.tail = eb.tail.copy()
self.roll = eb.roll
self.deform = eb.use_deform
self.parent = None
self.child = None
self.connect = False
self.original = False
Thomas Larsson
committed
self.extra = (eb.name in ["spine-1"])
Thomas Larsson
committed
def __repr__(self):
return ("<RigifyBone %s %s %s>" % (self.name, self.realname, self.realname1))
Thomas Larsson
committed
Thomas Larsson
committed
def rigifyMhx(context):
Thomas Larsson
committed
from collections import OrderedDict
print("Modifying MHX rig to Rigify")
Thomas Larsson
committed
scn = context.scene
Thomas Larsson
committed
ob = context.object
if ob.type == 'ARMATURE':
rig = ob
elif ob.type == 'MESH':
rig = ob.parent
else:
rig = None
if not(rig and rig.type == 'ARMATURE'):
raise NameError("Rigify: %s is neither an armature nor has armature parent" % ob)
rig.MhxRigify = True
scn.objects.active = rig
Thomas Larsson
committed
Thomas Larsson
committed
group = None
for grp in bpy.data.groups:
if rig.name in grp.objects:
group = grp
break
Thomas Larsson
committed
print("Group: %s" % group)
# Setup info about MHX bones
Thomas Larsson
committed
bones = OrderedDict()
bpy.ops.object.mode_set(mode='EDIT')
for eb in rig.data.edit_bones:
bone = bones[eb.name] = RigifyBone(eb)
Thomas Larsson
committed
if eb.parent:
Thomas Larsson
committed
bone.parent = eb.parent.name
bones[bone.parent].child = eb.name
Thomas Larsson
committed
bpy.ops.object.mode_set(mode='OBJECT')
# Create metarig
try:
bpy.ops.object.armature_human_metarig_add()
except AttributeError:
raise MyError("The Rigify add-on is not enabled. It is found under rigging.")
Thomas Larsson
committed
bpy.ops.object.location_clear()
bpy.ops.object.rotation_clear()
bpy.ops.object.scale_clear()
bpy.ops.transform.resize(value=(100, 100, 100))
bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)
Thomas Larsson
committed
# Fit metarig to default MHX rig
Thomas Larsson
committed
meta = context.object
bpy.ops.object.mode_set(mode='EDIT')
Thomas Larsson
committed
extra = []
Thomas Larsson
committed
for bone in bones.values():
Thomas Larsson
committed
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
try:
eb = meta.data.edit_bones[bone.name]
except KeyError:
eb = None
if eb:
eb.head = bone.head
eb.tail = bone.tail
eb.roll = bone.roll
bone.original = True
elif bone.extra:
extra.append(bone.name)
bone.original = True
eb = meta.data.edit_bones.new(bone.name)
eb.use_connect = False
eb.head = bones[bone.parent].tail
eb.tail = bones[bone.child].head
eb.roll = bone.roll
parent = meta.data.edit_bones[bone.parent]
child = meta.data.edit_bones[bone.child]
child.parent = eb
child.head = bones[bone.child].head
parent.tail = bones[bone.parent].tail
eb.parent = parent
eb.use_connect = True
Thomas Larsson
committed
Thomas Larsson
committed
# Add rigify properties to extra bones
bpy.ops.object.mode_set(mode='OBJECT')
Thomas Larsson
committed
for bname in extra:
pb = meta.pose.bones[bname]
Thomas Larsson
committed
pb["rigify_type"] = ""
# Generate rigify rig
bpy.ops.pose.rigify_generate()
Thomas Larsson
committed
gen = context.object
print("Generated", gen)
Thomas Larsson
committed
scn.objects.unlink(meta)
Thomas Larsson
committed
del meta
Thomas Larsson
committed
Thomas Larsson
committed
for bone in bones.values():
if bone.original:
setBoneName(bone, gen)
Thomas Larsson
committed
# Add extra bone to generated rig
Thomas Larsson
committed
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
bpy.ops.object.mode_set(mode='EDIT')
layers = 32*[False]
layers[1] = True
for bone in bones.values():
if not bone.original:
if bone.deform:
bone.realname = "DEF-" + bone.name
else:
bone.realname = "MCH-" + bone.name
eb = gen.data.edit_bones.new(bone.realname)
eb.head = bone.head
eb.tail = bone.tail
eb.roll = bone.roll
eb.use_deform = bone.deform
if bone.parent:
parent = bones[bone.parent]
if parent.realname:
eb.parent = gen.data.edit_bones[parent.realname]
elif parent.realname1:
eb.parent = gen.data.edit_bones[parent.realname1]
else:
print(bone)
eb.use_connect = (eb.parent != None and eb.parent.tail == eb.head)
eb.layers = layers
bpy.ops.object.mode_set(mode='OBJECT')
for bone in bones.values():
if not bone.original:
pb = gen.pose.bones[bone.realname]
db = rig.pose.bones[bone.name]
pb.rotation_mode = db.rotation_mode
for cns1 in db.constraints:
cns2 = pb.constraints.new(cns1.type)
Thomas Larsson
committed
fixConstraint(cns1, cns2, gen, bones)
# Add MHX properties
Thomas Larsson
committed
for key in rig.keys():
gen[key] = rig[key]
Thomas Larsson
committed
# Copy MHX bone drivers
Thomas Larsson
committed
if rig.animation_data:
for fcu1 in rig.animation_data.drivers:
rna,channel = fcu1.data_path.rsplit(".", 1)
pb = mhxEval("gen.%s" % rna)
Thomas Larsson
committed
fcu2 = pb.driver_add(channel, fcu1.array_index)
Thomas Larsson
committed
copyDriver(fcu1, fcu2, gen)
Thomas Larsson
committed
# Copy MHX morph drivers and change armature modifier
for ob in rig.children:
if ob.type == 'MESH':
ob.parent = gen
Thomas Larsson
committed
Thomas Larsson
committed
if ob.data.animation_data:
for fcu in ob.data.animation_data.drivers:
print(ob, fcu.data_path)
Thomas Larsson
committed
changeDriverTarget(fcu, gen)
Thomas Larsson
committed
if ob.data.shape_keys and ob.data.shape_keys.animation_data:
for fcu in ob.data.shape_keys.animation_data.drivers:
print(skey, fcu.data_path)
Thomas Larsson
committed
changeDriverTarget(fcu, gen)
Thomas Larsson
committed
for mod in ob.modifiers:
if mod.type == 'ARMATURE' and mod.object == rig:
Thomas Larsson
committed
mod.object = gen
Thomas Larsson
committed
if group:
group.objects.link(gen)
# Parent widgets under empty
empty = bpy.data.objects.new("Widgets", None)
scn.objects.link(empty)
empty.layers = 20*[False]
empty.layers[19] = True
Thomas Larsson
committed
empty.parent = gen
for ob in scn.objects:
if ob.type == 'MESH' and ob.name[0:4] == "WGT-" and not ob.parent:
ob.parent = empty
Thomas Larsson
committed
grp.objects.link(ob)
Thomas Larsson
committed
#Clean up
Thomas Larsson
committed
gen.show_x_ray = True
gen.data.draw_type = 'STICK'
Thomas Larsson
committed
gen.MhxRigify = False
Thomas Larsson
committed
name = rig.name
scn.objects.unlink(rig)
del rig
gen.name = name
bpy.ops.object.mode_set(mode='POSE')
Thomas Larsson
committed
print("MHX rig %s successfully rigified" % name)
Thomas Larsson
committed
Thomas Larsson
committed
def setBoneName(bone, gen):
fkname = bone.name.replace(".", ".fk.")
try:
gen.data.bones[fkname]
bone.fkname = fkname
bone.ikname = fkname.replace(".fk.", ".ik")
except KeyError:
pass
Thomas Larsson
committed
defname = "DEF-" + bone.name
try:
gen.data.bones[defname]
bone.realname = defname
return
except KeyError:
pass
Thomas Larsson
committed
Thomas Larsson
committed
defname1 = "DEF-" + bone.name + ".01"
try:
gen.data.bones[defname1]
bone.realname1 = defname1
bone.realname2 = defname1.replace(".01.", ".02.")
return
except KeyError:
pass
Thomas Larsson
committed
defname1 = "DEF-" + bone.name.replace(".", ".01.")
try:
gen.data.bones[defname1]
bone.realname1 = defname1
bone.realname2 = defname1.replace(".01.", ".02")
Thomas Larsson
committed
except KeyError:
pass
Thomas Larsson
committed
try:
gen.data.edit_bones[bone.name]
bone.realname = bone.name
except KeyError:
pass
Thomas Larsson
committed
def fixConstraint(cns1, cns2, gen, bones):
for key in dir(cns1):
if ((key[0] != "_") and
(key not in ["bl_rna", "type", "rna_type", "is_valid", "error_location", "error_rotation"])):
expr = ("cns2.%s = cns1.%s" % (key, key))
setattr(cns2, key, getattr(cns1, key))
Thomas Larsson
committed
cns2.target = gen
Thomas Larsson
committed
Thomas Larsson
committed
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
if cns1.type == 'STRETCH_TO':
bone = bones[cns1.subtarget]
if bone.realname:
cns2.subtarget = bone.realname
cns2.head_tail = cns1.head_tail
elif not bone.realname1:
print(bone)
halt
elif cns1.head_tail < 0.5:
cns2.subtarget = bone.realname1
cns2.head_tail = 2*cns1.head_tail
else:
cns2.subtarget = bone.realname2
cns2.head_tail = 2*cns1.head_tail-1
elif cns1.type == 'TRANSFORM':
bone = bones[cns1.subtarget]
if bone.fkname:
cns2.subtarget = bone.fkname
elif bone.ikname:
cns2.subtarget = bone.ikname
else:
cns2.subtarget = bone.realname
def copyDriver(fcu1, fcu2, id):
drv1 = fcu1.driver
drv2 = fcu2.driver
Thomas Larsson
committed
Thomas Larsson
committed
for var1 in drv1.variables:
var2 = drv2.variables.new()
var2.name = var1.name
var2.type = var1.type
targ1 = var1.targets[0]
targ2 = var2.targets[0]
targ2.id = id
targ2.data_path = targ1.data_path
Thomas Larsson
committed
Thomas Larsson
committed
drv2.type = drv1.type
drv2.expression = drv1.expression
drv2.show_debug_info = drv1.show_debug_info
def changeDriverTarget(fcu, id):
for var in fcu.driver.variables:
targ = var.targets[0]
Thomas Larsson
committed
targ.id = id
#
# class OBJECT_OT_RigifyMhxButton(bpy.types.Operator):
#
class OBJECT_OT_RigifyMhxButton(bpy.types.Operator):
bl_idname = "mhxrig.rigify_mhx"
bl_label = "Rigify MHX rig"
bl_options = {'UNDO'}
def execute(self, context):
Thomas Larsson
committed
rigifyMhx(context)
Thomas Larsson
committed
return{'FINISHED'}
#
# class RigifyMhxPanel(bpy.types.Panel):
#
class RigifyMhxPanel(bpy.types.Panel):
bl_label = "Rigify MHX"
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
Thomas Larsson
committed
@classmethod
def poll(cls, context):
Thomas Larsson
committed
return (context.object and context.object.MhxRigify)
def draw(self, context):
return
###################################################################################
###################################################################################
DEBUG = False
from bpy.props import StringProperty, FloatProperty, EnumProperty, BoolProperty
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
class ErrorOperator(bpy.types.Operator):
bl_idname = "mhx.error"
bl_label = "Error when loading MHX file"
def execute(self, context):
return {'RUNNING_MODAL'}
def invoke(self, context, event):
global theErrorLines
maxlen = 0
for line in theErrorLines:
if len(line) > maxlen:
maxlen = len(line)
width = 20+5*maxlen
height = 20+5*len(theErrorLines)
#self.report({'INFO'}, theMessage)
wm = context.window_manager
return wm.invoke_props_dialog(self, width=width, height=height)
def draw(self, context):
global theErrorLines
Thomas Larsson
committed
for line in theErrorLines:
self.layout.label(line)
def MyError(message):
global theMessage, theErrorLines, theErrorStatus
theMessage = message
theErrorLines = message.split('\n')
theErrorStatus = True
bpy.ops.mhx.error('INVOKE_DEFAULT')
raise MhxError(theMessage)
class MhxError(Exception):
def __init__(self, value):
self.value = value
def __str__(self):
return repr(self.value)
class SuccessOperator(bpy.types.Operator):
bl_idname = "mhx.success"
bl_label = "MHX file successfully loaded:"
message = StringProperty()
def execute(self, context):
return {'RUNNING_MODAL'}
def invoke(self, context, event):
wm = context.window_manager
return wm.invoke_props_dialog(self)
def draw(self, context):
self.layout.label(self.message + theMessage)
###################################################################################
#
# User interface
#
###################################################################################
Thomas Larsson
committed
from bpy_extras.io_utils import ImportHelper, ExportHelper
MhxBoolProps = [
("enforce", "Enforce version", "Only accept MHX files of correct version", T_EnforceVersion),
Thomas Larsson
committed
#("crash_safe", "Crash-safe", "Disable features that have caused Blender crashes", T_CrashSafe),
("mesh", "Mesh", "Use main mesh", T_Mesh),
("proxy", "Proxies", "Use proxies", T_Proxy),
#("armature", "Armature", "Use armature", T_Armature),
#("replace", "Replace scene", "Replace scene", T_Replace),
("cage", "Cage", "Load mesh deform cage", T_Cage),
("clothes", "Clothes", "Include clothes", T_Clothes),
("shapekeys", "Shapekeys", "Include shapekeys", T_Shapekeys),
("shapedrivers", "Shapekey drivers", "Include shapekey drivers", T_ShapeDrivers),
#("symm", "Symmetric shapes", "Keep shapekeys symmetric", T_Symm),
("diamond", "Helper geometry", "Keep helper geometry", T_Diamond),
("rigify", "Rigify", "Create rigify control rig", T_Rigify),
]
class ImportMhx(bpy.types.Operator, ImportHelper):
"""Import from MHX file format (.mhx)"""
bl_idname = "import_scene.makehuman_mhx"
bl_description = 'Import from MHX file format (.mhx)'
bl_label = "Import MHX"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
filename_ext = ".mhx"
filter_glob = StringProperty(default="*.mhx", options={'HIDDEN'})
filepath = StringProperty(subtype='FILE_PATH')
Thomas Larsson
committed
scale = FloatProperty(name="Scale", description="Default meter, decimeter = 1.0", default = theScale)
advanced = BoolProperty(name="Advanced settings", description="Use advanced import settings", default=False)
for (prop, name, desc, flag) in MhxBoolProps:
expr = '%s = BoolProperty(name="%s", description="%s", default=(toggleSettings&%s != 0))' % (prop, name, desc, flag)
exec(expr) # Trusted source: this file.
Thomas Larsson
committed
def draw(self, context):
layout = self.layout
layout.prop(self, "scale")
layout.prop(self, "advanced")
if self.advanced:
for (prop, name, desc, flag) in MhxBoolProps:
layout.prop(self, prop)
Thomas Larsson
committed
global toggle, toggleSettings, theScale, MhxBoolProps
if not self.advanced:
toggle = DefaultToggle
else:
toggle = T_Armature
for (prop, name, desc, flag) in MhxBoolProps:
expr = '(%s if self.%s else 0)' % (flag, prop)
toggle |= eval(expr) # trusted source: this file
toggleSettings = toggle
print("execute flags %x" % toggle)