Newer
Older
#filepathname = self.filepath.encode('utf-8', 'strict')
Thomas Larsson
committed
if not context.user_preferences.system.use_scripts_auto_execute:
MyError("Auto Run Python Scripts must be turned on.\nIt is found under\n File > User Preferences > File")
#bpy.ops.mhx.success('INVOKE_DEFAULT', message = self.filepath)
except MhxError:
print("Error when loading MHX file %s:\n" % self.filepath + theMessage)
if self.advanced:
writeDefaults()
self.advanced = False
global toggle, theScale, MhxBoolProps
readDefaults()
for (prop, name, desc, flag) in MhxBoolProps:
setattr(self, prop, mhxEval('(toggle&%s != 0)' % flag))
context.window_manager.fileselect_add(self)
return {'RUNNING_MODAL'}
Thomas Larsson
committed
###################################################################################
#
# Main panel
#
###################################################################################
MhxLayers = [
(( 0, 'Root', 'MhxRoot'),
( 1, 'Spine', 'MhxFKSpine')),
((10, 'Head', 'MhxHead'),
Thomas Larsson
committed
( 8, 'Face', 'MhxFace')),
(( 9, 'Tweak', 'MhxTweak'),
(16, 'Clothes', 'MhxClothes')),
#((17, 'IK Spine', 'MhxIKSpine'),
#((13, 'Inv FK Spine', 'MhxInvFKSpine')),
Thomas Larsson
committed
('Left', 'Right'),
(( 2, 'IK Arm', 'MhxIKArm'),
(18, 'IK Arm', 'MhxIKArm')),
(( 3, 'FK Arm', 'MhxFKArm'),
(19, 'FK Arm', 'MhxFKArm')),
(( 4, 'IK Leg', 'MhxIKLeg'),
(20, 'IK Leg', 'MhxIKLeg')),
(( 5, 'FK Leg', 'MhxFKLeg'),
(21, 'FK Leg', 'MhxFKLeg')),
((12, 'Extra', 'MhxExtra'),
(28, 'Extra', 'MhxExtra')),
(( 6, 'Fingers', 'MhxFingers'),
(22, 'Fingers', 'MhxFingers')),
(( 7, 'Links', 'MhxLinks'),
(23, 'Links', 'MhxLinks')),
((11, 'Palm', 'MhxPalm'),
(27, 'Palm', 'MhxPalm')),
]
OtherLayers = [
(( 1, 'Spine', 'MhxFKSpine'),
( 10, 'Head', 'MhxHead')),
(( 9, 'Tweak', 'MhxTweak'),
( 8, 'Face', 'MhxFace')),
('Left', 'Right'),
(( 3, 'Arm', 'MhxFKArm'),
(19, 'Arm', 'MhxFKArm')),
(( 5, 'Leg', 'MhxFKLeg'),
(21, 'Leg', 'MhxFKLeg')),
(( 7, 'Fingers', 'MhxLinks'),
(23, 'Fingers', 'MhxLinks')),
((11, 'Palm', 'MhxPalm'),
(27, 'Palm', 'MhxPalm')),
]
Thomas Larsson
committed
#
# class MhxMainPanel(bpy.types.Panel):
#
class MhxMainPanel(bpy.types.Panel):
bl_label = "MHX Main v %s" % bl_info["version"]
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
#bl_options = {'DEFAULT_CLOSED'}
@classmethod
def poll(cls, context):
return (context.object and context.object.MhxRig)
def draw(self, context):
layout = self.layout
layout.label("Layers")
layout.operator("mhx.pose_enable_all_layers")
layout.operator("mhx.pose_disable_all_layers")
rig = context.object
if rig.MhxRig == 'MHX':
layers = MhxLayers
else:
layers = OtherLayers
for (left,right) in layers:
Thomas Larsson
committed
row = layout.row()
if type(left) == str:
row.label(left)
row.label(right)
else:
for (n, name, prop) in [left,right]:
row.prop(rig.data, "layers", index=n, toggle=True, text=name)
Thomas Larsson
committed
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
layout.separator()
layout.label("Export/Import MHP")
layout.operator("mhx.saveas_mhp")
layout.operator("mhx.load_mhp")
class VIEW3D_OT_MhxEnableAllLayersButton(bpy.types.Operator):
bl_idname = "mhx.pose_enable_all_layers"
bl_label = "Enable all layers"
bl_options = {'UNDO'}
def execute(self, context):
rig,mesh = getMhxRigMesh(context.object)
for (left,right) in MhxLayers:
if type(left) != str:
for (n, name, prop) in [left,right]:
rig.data.layers[n] = True
return{'FINISHED'}
class VIEW3D_OT_MhxDisableAllLayersButton(bpy.types.Operator):
bl_idname = "mhx.pose_disable_all_layers"
bl_label = "Disable all layers"
bl_options = {'UNDO'}
def execute(self, context):
rig,mesh = getMhxRigMesh(context.object)
layers = 32*[False]
pb = context.active_pose_bone
if pb:
for n in range(32):
if pb.bone.layers[n]:
layers[n] = True
break
else:
layers[0] = True
if rig:
rig.data.layers = layers
return{'FINISHED'}
def saveMhpFile(rig, scn, filepath):
roots = []
for pb in rig.pose.bones:
if pb.parent is None:
roots.append(pb)
(pname, ext) = os.path.splitext(filepath)
mhppath = pname + ".mhp"
fp = open(mhppath, "w", encoding="utf-8", newline="\n")
for root in roots:
writeMhpBones(fp, root, None)
fp.close()
print("Mhp file %s saved" % mhppath)
def writeMhpBones(fp, pb, log):
if not isMuscleBone(pb):
b = pb.bone
if pb.parent:
mat = b.matrix_local.inverted() * b.parent.matrix_local * pb.parent.matrix.inverted() * pb.matrix
else:
mat = pb.matrix.copy()
maty = mat[1].copy()
matz = mat[2].copy()
mat[1] = matz
mat[2] = -maty
Thomas Larsson
committed
diff = mat - Matrix()
nonzero = False
for i in range(4):
if abs(diff[i].length) > 5e-3:
nonzero = True
break
if nonzero:
fp.write("%s\tmatrix" % pb.name)
for i in range(4):
row = mat[i]
fp.write("\t%.4f\t%.4f\t%.4f\t%.4f" % (row[0], row[1], row[2], row[3]))
fp.write("\n")
Thomas Larsson
committed
for child in pb.children:
writeMhpBones(fp, child, log)
def isMuscleBone(pb):
layers = pb.bone.layers
if (layers[14] or layers[15] or layers[30] or layers[31]):
return True
for cns in pb.constraints:
if (cns.type == 'STRETCH_TO' or
cns.type == 'TRANSFORM' or
cns.type == 'TRACK_TO' or
cns.type == 'IK' or
cns.type[0:5] == 'COPY_'):
return True
return False
def loadMhpFile(rig, scn, filepath):
Thomas Larsson
committed
unit = Matrix()
for pb in rig.pose.bones:
pb.matrix_basis = unit
Thomas Larsson
committed
(pname, ext) = os.path.splitext(filepath)
mhppath = pname + ".mhp"
fp = open(mhppath, "rU")
for line in fp:
words = line.split()
if len(words) < 4:
continue
Thomas Larsson
committed
try:
pb = rig.pose.bones[words[0]]
except KeyError:
print("Warning: Did not find bone %s" % words[0])
continue
if isMuscleBone(pb):
pass
Thomas Larsson
committed
elif words[1] == "quat":
Thomas Larsson
committed
q = Quaternion((float(words[2]), float(words[3]), float(words[4]), float(words[5])))
mat = q.to_matrix().to_4x4()
pb.matrix_basis = mat
Thomas Larsson
committed
elif words[1] == "gquat":
q = Quaternion((float(words[2]), float(words[3]), float(words[4]), float(words[5])))
mat = q.to_matrix().to_4x4()
maty = mat[1].copy()
matz = mat[2].copy()
mat[1] = -matz
mat[2] = maty
pb.matrix_basis = pb.bone.matrix_local.inverted() * mat
Thomas Larsson
committed
elif words[1] == "matrix":
rows = []
n = 2
for i in range(4):
rows.append((float(words[n]), float(words[n+1]), float(words[n+2]), float(words[n+3])))
n += 4
mat = Matrix(rows)
if pb.parent:
pb.matrix_basis = mat
else:
maty = mat[1].copy()
matz = mat[2].copy()
mat[1] = -matz
mat[2] = maty
pb.matrix_basis = pb.bone.matrix_local.inverted() * mat
Thomas Larsson
committed
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
elif words[1] == "scale":
pass
else:
print("WARNING: Unknown line in mcp file:\n%s" % line)
fp.close()
print("Mhp file %s loaded" % mhppath)
class VIEW3D_OT_LoadMhpButton(bpy.types.Operator):
bl_idname = "mhx.load_mhp"
bl_label = "Load MHP File"
bl_description = "Load a pose in MHP format"
bl_options = {'UNDO'}
filename_ext = ".mhp"
filter_glob = StringProperty(default="*.mhp", options={'HIDDEN'})
filepath = bpy.props.StringProperty(
name="File Path",
description="File path used for mhp file",
maxlen= 1024, default= "")
def execute(self, context):
loadMhpFile(context.object, context.scene, self.properties.filepath)
return {'FINISHED'}
def invoke(self, context, event):
context.window_manager.fileselect_add(self)
return {'RUNNING_MODAL'}
class VIEW3D_OT_SaveasMhpFileButton(bpy.types.Operator, ExportHelper):
bl_idname = "mhx.saveas_mhp"
bl_label = "Save MHP File"
bl_description = "Save current pose in MHP format"
bl_options = {'UNDO'}
filename_ext = ".mhp"
filter_glob = StringProperty(default="*.mhp", options={'HIDDEN'})
filepath = bpy.props.StringProperty(
name="File Path",
description="File path used for mhp file",
maxlen= 1024, default= "")
def execute(self, context):
saveMhpFile(context.object, context.scene, self.properties.filepath)
return {'FINISHED'}
def invoke(self, context, event):
context.window_manager.fileselect_add(self)
return {'RUNNING_MODAL'}
Thomas Larsson
committed
###################################################################################
#
# Lipsync panel
#
Thomas Larsson
committed
###################################################################################
#
# visemes
#
bodyLanguageVisemes = ({
'Rest' : [
Thomas Larsson
committed
('MouthWidth_L', 0),
('MouthWidth_R', 0),
('MouthNarrow_L', 0),
('MouthNarrow_R', 0),
('LipsPart', 0.6),
('UpLipsMidHeight', 0),
('LoLipsMidHeight', 0),
Thomas Larsson
committed
('LoLipsIn', 0),
Thomas Larsson
committed
('MouthOpen', 0),
Thomas Larsson
committed
('TongueBackHeight', 0),
('TongueHeight', 0),
Thomas Larsson
committed
],
Thomas Larsson
committed
('MouthWidth_L', 0),
('MouthWidth_R', 0),
('MouthNarrow_L', 0),
('MouthNarrow_R', 0),
('LipsPart', 0.4),
('UpLipsMidHeight', 0),
('LoLipsMidHeight', 0),
Thomas Larsson
committed
('LoLipsIn', 0),
Thomas Larsson
committed
('MouthOpen', 0),
Thomas Larsson
committed
('TongueBackHeight', 0),
('TongueHeight', 0),
Thomas Larsson
committed
],
Thomas Larsson
committed
('MouthWidth_L', 0),
('MouthWidth_R', 0),
('MouthNarrow_L', 0),
('MouthNarrow_R', 0),
('LipsPart', 0),
('UpLipsMidHeight', 0),
('LoLipsMidHeight', 0),
Thomas Larsson
committed
('LoLipsIn', 0),
Thomas Larsson
committed
('MouthOpen', 0),
Thomas Larsson
committed
('TongueBackHeight', 0),
('TongueHeight', 0),
Thomas Larsson
committed
],
Thomas Larsson
committed
('MouthWidth_L', 0),
('MouthWidth_R', 0),
('MouthNarrow_L', 1.0),
('MouthNarrow_R', 1.0),
('LipsPart', 0),
('UpLipsMidHeight', 0),
('LoLipsMidHeight', 0),
Thomas Larsson
committed
('LoLipsIn', 0),
Thomas Larsson
committed
('MouthOpen', 0.4),
Thomas Larsson
committed
('TongueBackHeight', 0),
('TongueHeight', 0),
Thomas Larsson
committed
],
Thomas Larsson
committed
('MouthWidth_L', 0),
('MouthWidth_R', 0),
('MouthNarrow_L', 0.9),
('MouthNarrow_R', 0.9),
('LipsPart', 0),
('UpLipsMidHeight', 0),
('LoLipsMidHeight', 0),
Thomas Larsson
committed
('LoLipsIn', 0),
Thomas Larsson
committed
('MouthOpen', 0.8),
Thomas Larsson
committed
('TongueBackHeight', 0),
('TongueHeight', 0),
Thomas Larsson
committed
],
Thomas Larsson
committed
('MouthWidth_L', 0),
('MouthWidth_R', 0),
('MouthNarrow_L', 0.5),
('MouthNarrow_R', 0.5),
('LipsPart', 0),
('UpLipsMidHeight', 0.2),
('LoLipsMidHeight', -0.2),
Thomas Larsson
committed
('LoLipsIn', 0),
Thomas Larsson
committed
('MouthOpen', 0),
Thomas Larsson
committed
('TongueBackHeight', 0),
('TongueHeight', 0),
Thomas Larsson
committed
],
Thomas Larsson
committed
('MouthWidth_L', 0.2),
('MouthWidth_R', 0.2),
('MouthNarrow_L', 0),
('MouthNarrow_R', 0),
('LipsPart', 1.0),
('UpLipsMidHeight', 0),
('LoLipsMidHeight', 0.3),
Thomas Larsson
committed
('LoLipsIn', 0.6),
Thomas Larsson
committed
('MouthOpen', 0),
Thomas Larsson
committed
('TongueBackHeight', 0),
('TongueHeight', 0),
Thomas Larsson
committed
],
Thomas Larsson
committed
('MouthWidth_L', 0),
('MouthWidth_R', 0),
('MouthNarrow_L', 0),
('MouthNarrow_R', 0),
('LipsPart', 0),
('UpLipsMidHeight', 0.5),
('LoLipsMidHeight', -0.7),
Thomas Larsson
committed
('LoLipsIn', 0),
Thomas Larsson
committed
('MouthOpen', 0),
Thomas Larsson
committed
('TongueBackHeight', 0),
('TongueHeight', 0),
Thomas Larsson
committed
],
Thomas Larsson
committed
('MouthWidth_L', 0.8),
('MouthWidth_R', 0.8),
('MouthNarrow_L', 0),
('MouthNarrow_R', 0),
('LipsPart', 0),
('UpLipsMidHeight', 1.0),
('LoLipsMidHeight', 0),
Thomas Larsson
committed
('LoLipsIn', 0),
Thomas Larsson
committed
('MouthOpen', 0),
Thomas Larsson
committed
('TongueBackHeight', 0),
('TongueHeight', 0),
Thomas Larsson
committed
],
Thomas Larsson
committed
('MouthWidth_L', 0.2),
('MouthWidth_R', 0.2),
('MouthNarrow_L', 0),
('MouthNarrow_R', 0),
('LipsPart', 0),
('UpLipsMidHeight', 0.6),
('LoLipsMidHeight', -0.6),
Thomas Larsson
committed
('LoLipsIn', 0),
Thomas Larsson
committed
('MouthOpen', 0.5),
Thomas Larsson
committed
('TongueBackHeight', 0),
('TongueHeight', 0),
Thomas Larsson
committed
],
Thomas Larsson
committed
('MouthWidth_L', 0),
('MouthWidth_R', 0),
('MouthNarrow_L', 0),
('MouthNarrow_R', 0),
('LipsPart', 0),
('UpLipsMidHeight', 0.4),
('LoLipsMidHeight', 0),
Thomas Larsson
committed
('LoLipsIn', 0),
Thomas Larsson
committed
('MouthOpen', 0.7),
Thomas Larsson
committed
('TongueBackHeight', 0),
('TongueHeight', 0),
Thomas Larsson
committed
],
Thomas Larsson
committed
('MouthWidth_L', 0),
('MouthWidth_R', 0),
('MouthNarrow_L', 0),
('MouthNarrow_R', 0),
('LipsPart', 0),
('UpLipsMidHeight', 0.5),
('LoLipsMidHeight', -0.6),
Thomas Larsson
committed
('LoLipsIn', 0),
Thomas Larsson
committed
('MouthOpen', 0.25),
Thomas Larsson
committed
('TongueBackHeight', 0),
('TongueHeight', 0),
Thomas Larsson
committed
],
Thomas Larsson
committed
('MouthWidth_L', 0),
('MouthWidth_R', 0),
('MouthNarrow_L', 0),
('MouthNarrow_R', 0),
('LipsPart', 0),
('UpLipsMidHeight', 0),
('LoLipsMidHeight', 0),
Thomas Larsson
committed
('LoLipsIn', 0),
Thomas Larsson
committed
('MouthOpen', 0.2),
Thomas Larsson
committed
('TongueBackHeight', 1.0),
('TongueHeight', 1.0)
Thomas Larsson
committed
],
Thomas Larsson
committed
('MouthWidth_L', 0),
('MouthWidth_R', 0),
('MouthNarrow_L', 0),
('MouthNarrow_R', 0),
('LipsPart', 0),
('UpLipsMidHeight', 0.5),
('LoLipsMidHeight', -0.5),
Thomas Larsson
committed
('LoLipsIn', 0),
Thomas Larsson
committed
('MouthOpen', -0.2),
Thomas Larsson
committed
('TongueBackHeight', 1.0),
('TongueHeight', 1.0),
Thomas Larsson
committed
],
Thomas Larsson
committed
('MouthWidth_L', 0),
('MouthWidth_R', 0),
('MouthNarrow_L', 0),
('MouthNarrow_R', 0),
('LipsPart', 0),
('UpLipsMidHeight', 0.5),
('LoLipsMidHeight', -0.5),
Thomas Larsson
committed
('LoLipsIn', 0),
Thomas Larsson
committed
('MouthOpen', -0.2),
Thomas Larsson
committed
('TongueBackHeight', 1.0),
('TongueHeight', 0),
Thomas Larsson
committed
],
Thomas Larsson
committed
'Blink' : [
Thomas Larsson
committed
('UpLidUp_L', 1),
('UpLidUp_R', 1),
Thomas Larsson
committed
('LoLidDown_L', 1),
('LoLidDown_R', 1)
Thomas Larsson
committed
],
Thomas Larsson
committed
'Unblink' : [
Thomas Larsson
committed
('UpLidUp_L', 0),
('UpLidUp_R', 0),
Thomas Larsson
committed
('LoLidDown_L', 0),
('LoLidDown_R', 0)
Thomas Larsson
committed
],
Thomas Larsson
committed
VisemePanelBones = {
'MouthOpen' : ('PJaw', (0,0.25)),
'UpLipsMidHeight' : ('PUpLipMid', (0,-0.25)),
'LoLipsMidHeight' : ('PLoLipMid', (0,-0.25)),
'LoLipsIn': ('PLoLipMid', (-0.25,0)),
'MouthWidth_L' : ('PMouth_L', (0.25,0)),
'MouthWidth_R' : ('PMouth_R', (-0.25,0)),
Thomas Larsson
committed
'MouthNarrow_L' : ('PMouth_L', (-0.25,0)),
'MouthNarrow_R' : ('PMouth_R', (0.25,0)),
Thomas Larsson
committed
'LipsPart' : ('PMouthMid', (0, -0.25)),
Thomas Larsson
committed
'TongueBackHeight': ('PTongue', (-0.25, 0)),
'TongueHeight' : ('PTongue', (0, -0.25)),
Thomas Larsson
committed
Thomas Larsson
committed
'UpLidUp_L' : ('PUpLid_L', (0,1.0)),
'UpLidUp_R' : ('PUpLid_R', (0,1.0)),
Thomas Larsson
committed
'LoLidDown_L' : ('PLoLid_L', (0,-1.0)),
'LoLidDown_R' : ('PLoLid_R', (0,-1.0)),
}
Thomas Larsson
committed
VisemeList = [
('Rest', 'Etc', 'AH'),
('MBP', 'OO', 'O'),
('R', 'FV', 'S'),
('SH', 'EE', 'EH'),
('TH', 'L', 'G')
]
#
# makeVisemes(ob, scn):
# class VIEW3D_OT_MhxMakeVisemesButton(bpy.types.Operator):
#
def makeVisemes(ob, scn):
Thomas Larsson
committed
rig = ob.parent
if ob.type != 'MESH':
print("Active object %s is not a mesh" % ob)
return
if not ob.data.shape_keys:
print("%s has no shapekeys" % ob)
return
try:
ob.data.shape_keys.key_blocks["VIS_Rest"]
print("Visemes already created")
return
Thomas Larsson
committed
except KeyError:
Thomas Larsson
committed
pass
Thomas Larsson
committed
try:
ob.data.shape_keys.key_blocks["MouthOpen"]
except KeyError:
print("Mesh does not have face shapes")
return
Thomas Larsson
committed
verts = ob.data.vertices
for (vis,shapes) in bodyLanguageVisemes.items():
if vis in ['Blink', 'Unblink']:
continue
Thomas Larsson
committed
vkey = ob.shape_key_add(name="VIS_%s" % vis)
print(vkey.name)
for n,v in enumerate(verts):
vkey.data[n].co = v.co
for (name,value) in shapes:
if name[-2:] == "_R":
continue
skey = ob.data.shape_keys.key_blocks[name]
factor = 0.75*value
for n,v in enumerate(verts):
vkey.data[n].co += factor*(skey.data[n].co - v.co)
Thomas Larsson
committed
print("Visemes made")
return
Thomas Larsson
committed
class VIEW3D_OT_MhxMakeVisemesButton(bpy.types.Operator):
bl_idname = "mhx.make_visemes"
bl_label = "Generate viseme shapekeys"
def execute(self, context):
makeVisemes(context.object, context.scene)
Thomas Larsson
committed
return{'FINISHED'}
Thomas Larsson
committed
#
# mohoVisemes
# magpieVisemes
#
Thomas Larsson
committed
"rest" : "Rest",
"etc" : "Etc",
"AI" : "AH",
"O" : "O",
"U" : "OO",
"WQ" : "AH",
"L" : "L",
"E" : "EH",
"MBP" : "MBP",
"FV" : "FV",
Thomas Larsson
committed
"CONS" : "Etc",
Thomas Larsson
committed
"AI" : "AH",
Thomas Larsson
committed
"E" : "EH",
"O" : "O",
"UW" : "AH",
"MBP" : "MBP",
"L" : "L",
"FV" : "FV",
"Sh" : "SH",
})
#
# setViseme(context, vis, setKey, frame):
# setBoneLocation(context, pbone, loc, mirror, setKey, frame):
# class VIEW3D_OT_MhxVisemeButton(bpy.types.Operator):
#
Thomas Larsson
committed
def getVisemeSet(context, rig):
Thomas Larsson
committed
if rig.MhxVisemeSet == "StopStaring":
return stopStaringVisemes
Thomas Larsson
committed
elif rig.MhxVisemeSet == "BodyLanguage":
return bodyLanguageVisemes
else:
raise MhxError("Unknown viseme set %s" % visset)
Thomas Larsson
committed
def setVisemeAlpha7(context, vis, visemes, setKey, frame):
Thomas Larsson
committed
(rig, mesh) = getMhxRigMesh(context.object)
isPanel = False
isProp = False
shapekeys = None
scale = 0.75
Thomas Larsson
committed
scale *= rig.pose.bones['PFace'].bone.length
isPanel = True
Thomas Larsson
committed
isProp = True
elif mesh:
shapekeys = mesh.data.shape_keys.key_blocks
Thomas Larsson
committed
for (skey, value) in visemes[vis]:
if isPanel:
(b, (x,z)) = VisemePanelBones[skey]
Thomas Larsson
committed
loc = mathutils.Vector((float(x*value),0,float(z*value)))
Thomas Larsson
committed
pb = rig.pose.bones[b]
pb.location = loc*scale
if setKey or context.tool_settings.use_keyframe_insert_auto:
for n in range(3):
pb.keyframe_insert('location', index=n, frame=frame, group=pb.name)
elif isProp:
Thomas Larsson
committed
try:
prop = rig[skey]
except:
continue
rig[skey] = value*scale
if setKey or context.tool_settings.use_keyframe_insert_auto:
Thomas Larsson
committed
rig.keyframe_insert('["%s"]' % skey, frame=frame, group="Visemes")
Thomas Larsson
committed
elif shapekeys:
try:
shapekeys[skey].value = value*scale
except:
continue
if setKey or context.tool_settings.use_keyframe_insert_auto:
Thomas Larsson
committed
shapekeys[skey].keyframe_insert("value", frame=frame)
class VIEW3D_OT_MhxVisemeButton(bpy.types.Operator):
bl_idname = 'mhx.pose_viseme'
bl_label = 'Viseme'
viseme = StringProperty()
def invoke(self, context, event):
(rig, mesh) = getMhxRigMesh(context.object)
visemes = getVisemeSet(context, rig)
setVisemeAlpha7(context, self.viseme, visemes, False, context.scene.frame_current)
return{'FINISHED'}
def readLipsync(context, filepath, offs, struct):
Thomas Larsson
committed
(rig, mesh) = getMhxRigMesh(context.object)
Thomas Larsson
committed
if rig.MhxVisemeSet:
visemes = getVisemeSet(context, rig)
else:
props = getProps(rig, "Mhv")
visemes = {}
oldKeys = []
for prop in props:
dummy,units = getUnitsFromString("x;"+rig[prop])
visemes[prop] = units
props = getProps(rig, "Mhsmouth")
auto = context.tool_settings.use_keyframe_insert_auto
auto = True
factor = rig.MhxStrength
Thomas Larsson
committed
shapekeys = getMhmShapekeys(rig, mesh)
context.scene.objects.active = rig
Thomas Larsson
committed
bpy.ops.object.mode_set(mode='POSE')
Thomas Larsson
committed
fp = open(filepath, "rU")
for line in fp:
words= line.split()
if len(words) < 2:
Thomas Larsson
committed
vis = struct[words[1]]
Thomas Larsson
committed
if rig.MhxVisemeSet:
setVisemeAlpha7(context, vis, visemes, True, frame)
Thomas Larsson
committed
else:
setMhmProps(rig, shapekeys, "Mhsmouth", visemes["Mhv"+vis], factor, auto, frame)
Thomas Larsson
committed
Thomas Larsson
committed
#setInterpolation(rig)
print("Lipsync file %s loaded" % filepath)
Thomas Larsson
committed
class VIEW3D_OT_MhxMohoButton(bpy.types.Operator, ImportHelper):
bl_idname = "mhx.pose_load_moho"
bl_label = "Load Moho (.dat)"
Thomas Larsson
committed
filename_ext = ".dat"
filter_glob = StringProperty(default="*.dat", options={'HIDDEN'})
Thomas Larsson
committed
filepath = StringProperty(subtype='FILE_PATH')
Thomas Larsson
committed
def execute(self, context):
readLipsync(context, self.properties.filepath, context.scene.frame_start - 1, MohoVisemes)
return{'FINISHED'}
def invoke(self, context, event):
context.window_manager.fileselect_add(self)
Thomas Larsson
committed
return {'RUNNING_MODAL'}
class MhxLipsyncPanel(bpy.types.Panel):
bl_label = "MHX Lipsync"
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
bl_options = {'DEFAULT_CLOSED'}
@classmethod
def poll(cls, context):
Thomas Larsson
committed
return hasProps(context.object, "Mhv")
def draw(self, context):
Thomas Larsson
committed
rig,mesh = getMhxRigMesh(context.object)
Thomas Larsson
committed
layout.label("No MHX rig found")
Thomas Larsson
committed
layout = self.layout
Thomas Larsson
committed
if not rig.MhxVisemeSet:
Thomas Larsson
committed
visemes = getProps(rig, "Mhv")
Thomas Larsson
committed
if not visemes:
layout.label("No visemes found")
return
Thomas Larsson
committed
layout.operator("mhx.pose_reset_expressions", text="Reset visemes").prefix="Mhsmouth"
layout.operator("mhx.pose_key_expressions", text="Key visemes").prefix="Mhsmouth"
Thomas Larsson
committed
layout.prop(rig, "MhxStrength")
layout.separator()
Thomas Larsson
committed
for prop in visemes:
if n % 3 == 0:
row = layout.row()
n = 0
Thomas Larsson
committed
row.operator("mhx.pose_mhm", text=prop[3:]).data="Mhsmouth;"+rig[prop]
n += 1
while n % 3 != 0:
row.label("")
n += 1
layout.separator()
row = layout.row()
Thomas Larsson
committed
row.operator("mhx.pose_mhm", text="Blink").data="Mhsmouth;eye_left_closure:1;eye_right_closure:1"
row.operator("mhx.pose_mhm", text="Unblink").data="Mhsmouth;eye_left_closure:0;eye_right_closure:0"
else:
Thomas Larsson
committed
for (vis1, vis2, vis3) in VisemeList:
row = layout.row()
row.operator("mhx.pose_viseme", text=vis1).viseme = vis1
row.operator("mhx.pose_viseme", text=vis2).viseme = vis2
row.operator("mhx.pose_viseme", text=vis3).viseme = vis3
layout.separator()
row = layout.row()
row.operator("mhx.pose_viseme", text="Blink").viseme = 'Blink'
row.operator("mhx.pose_viseme", text="Unblink").viseme = 'Unblink'
layout.separator()
layout.operator("mhx.make_visemes")
Thomas Larsson
committed
layout.separator()
row = layout.row()
Thomas Larsson
committed
row.operator("mhx.pose_load_moho")
Thomas Larsson
committed
# class VIEW3D_OT_MhxUpdateButton(bpy.types.Operator):
#
def updatePose(context):
scn = context.scene
Thomas Larsson
committed
scn.frame_current = scn.frame_current
bpy.ops.object.posemode_toggle()
bpy.ops.object.posemode_toggle()
return
class VIEW3D_OT_MhxUpdateButton(bpy.types.Operator):
bl_idname = "mhx.update"
bl_label = "Update"
def execute(self, context):
Thomas Larsson
committed
return{'FINISHED'}
Thomas Larsson
committed
###################################################################################
Thomas Larsson
committed
# Expression panels
Thomas Larsson
committed
###################################################################################
class VIEW3D_OT_MhxResetExpressionsButton(bpy.types.Operator):
bl_idname = "mhx.pose_reset_expressions"
bl_label = "Reset expressions"
Thomas Larsson
committed
prefix = StringProperty()
def execute(self, context):
Thomas Larsson
committed
rig,mesh = getMhxRigMesh(context.object)
Thomas Larsson
committed
shapekeys = getMhmShapekeys(rig, mesh)
clearMhmProps(rig, shapekeys, self.prefix, context.tool_settings.use_keyframe_insert_auto, context.scene.frame_current)
Thomas Larsson
committed
return{'FINISHED'}
class VIEW3D_OT_MhxKeyExpressionsButton(bpy.types.Operator):
bl_idname = "mhx.pose_key_expressions"
bl_label = "Key expressions"
Thomas Larsson
committed
prefix = StringProperty()
def execute(self, context):
Thomas Larsson
committed
rig,mesh = getMhxRigMesh(context.object)
frame = context.scene.frame_current
Thomas Larsson
committed
for prop in props:
Thomas Larsson
committed
return{'FINISHED'}
class VIEW3D_OT_MhxPinExpressionButton(bpy.types.Operator):
bl_idname = "mhx.pose_pin_expression"
bl_label = "Pin"
Thomas Larsson
committed
data = StringProperty()
def execute(self, context):
Thomas Larsson
committed
rig,mesh = getMhxRigMesh(context.object)
Thomas Larsson
committed
words = self.data.split(";")
prefix = words[0]
expression = words[1]
Thomas Larsson
committed
Thomas Larsson
committed
props = getProps(rig, prefix)
if context.tool_settings.use_keyframe_insert_auto:
frame = context.scene.frame_current
Thomas Larsson
committed
for prop in props:
Thomas Larsson
committed
if prop == expression:
rig[prop] = 1.0
else:
rig[prop] = 0.0
if abs(rig[prop] - old) > 1e-3:
Thomas Larsson
committed
else:
Thomas Larsson
committed
for prop in props:
Thomas Larsson
committed
if prop == expression:
rig[prop] = 1.0
else:
rig[prop] = 0.0
Thomas Larsson
committed
return{'FINISHED'}
Thomas Larsson
committed
def getMhmShapekeys(rig, mesh):
if rig.MhxShapekeyDrivers:
return None
else:
return mesh.data.shape_keys.key_blocks
Thomas Larsson
committed
Thomas Larsson
committed
def setMhmProps(rig, shapekeys, prefix, units, factor, auto, frame):
clearMhmProps(rig, shapekeys, prefix, auto, frame)
Thomas Larsson
committed
if shapekeys:
skey = prop[3:].replace("_","-")
shapekeys[skey].value = factor*value
if auto:
Thomas Larsson
committed
shapekeys[skey].keyframe_insert("value", frame=frame)
Thomas Larsson
committed
else:
rig[prop] = factor*value
if auto:
Thomas Larsson
committed
rig.keyframe_insert('["%s"]'%prop, frame=frame)
Thomas Larsson
committed
def clearMhmProps(rig, shapekeys, prefix, auto, frame):
props = getProps(rig, prefix)
for prop in props:
Thomas Larsson
committed
if shapekeys:
skey = prop[3:].replace("_","-")
shapekeys[skey].value = 0.0
if auto:
Thomas Larsson
committed
shapekeys[skey].keyframe_insert("value", frame=frame)
Thomas Larsson
committed
else:
rig[prop] = 0.0
if auto:
Thomas Larsson
committed
rig.keyframe_insert('["%s"]'%prop, frame=frame)
Thomas Larsson
committed
def getUnitsFromString(string):
Thomas Larsson
committed
words = string.split(";")
Thomas Larsson
committed
units = []
Thomas Larsson
committed
if word == "":
continue
Thomas Larsson
committed
unit = word.split(":")
Thomas Larsson
committed
prop = "Mhs" + unit[0]
value = float(unit[1])
Thomas Larsson
committed
return prefix,units
Thomas Larsson
committed
class VIEW3D_OT_MhxMhmButton(bpy.types.Operator):
bl_idname = "mhx.pose_mhm"
bl_label = "Mhm"
bl_options = {'UNDO'}
data = StringProperty()
Thomas Larsson
committed
def execute(self, context):
Thomas Larsson
committed
rig,mesh = getMhxRigMesh(context.object)
auto = context.tool_settings.use_keyframe_insert_auto
frame = context.scene.frame_current
Thomas Larsson
committed
shapekeys = getMhmShapekeys(rig, mesh)
Thomas Larsson
committed
prefix,units = getUnitsFromString(self.data)
Thomas Larsson
committed
setMhmProps(rig, shapekeys, prefix, units, rig.MhxStrength, auto, frame)
Thomas Larsson
committed
updatePose(context)
Thomas Larsson
committed
return{'FINISHED'}
Thomas Larsson
committed
def getProps(rig, prefix):
props = []
for prop in rig.keys():
if prop.startswith(prefix):
Thomas Larsson
committed
props.append(prop)
Thomas Larsson
committed
props.sort()
Thomas Larsson
committed
def hasProps(ob, prefix):
if ob is None:
return False
if ob.type == 'MESH' and ob.parent: