Newer
Older
Thomas Larsson
committed
rig = ob.parent
elif ob.type == 'ARMATURE':
rig = ob
else:
return False
for prop in rig.keys():
if prop.startswith(prefix):
return True
return False
class MhxExpressionsPanel(bpy.types.Panel):
bl_label = "MHX Expressions"
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
bl_options = {'DEFAULT_CLOSED'}
Thomas Larsson
committed
Thomas Larsson
committed
@classmethod
def poll(cls, context):
Thomas Larsson
committed
return hasProps(context.object, "Mhe")
Thomas Larsson
committed
def draw(self, context):
layout = self.layout
rig,mesh = getMhxRigMesh(context.object)
if not rig:
Thomas Larsson
committed
layout.label("No MHX rig found")
Thomas Larsson
committed
return
exprs = getProps(rig, "Mhe")
if not exprs:
Thomas Larsson
committed
layout.label("No expressions found")
Thomas Larsson
committed
return
Thomas Larsson
committed
layout.operator("mhx.pose_reset_expressions").prefix="Mhs"
layout.operator("mhx.pose_key_expressions").prefix="Mhs"
Thomas Larsson
committed
layout.prop(rig, "MhxStrength")
layout.separator()
for prop in exprs:
layout.operator("mhx.pose_mhm", text=prop[3:]).data="Mhs;"+rig[prop]
Thomas Larsson
committed
Thomas Larsson
committed
def drawShapePanel(self, context, prefix, name):
layout = self.layout
rig,mesh = getMhxRigMesh(context.object)
if not rig:
print("No MHX rig found")
return
if not rig.MhxShapekeyDrivers:
layout.label("No shapekey drivers.")
layout.label("Set %s values in mesh context instead" % name)
return
props = getProps(rig, prefix)
if not props:
layout.label("No %ss found" % name)
return
Thomas Larsson
committed
Thomas Larsson
committed
layout.operator("mhx.pose_reset_expressions", text="Reset %ss" % name).prefix=prefix
layout.operator("mhx.pose_key_expressions", text="Key %ss" % name).prefix=prefix
Thomas Larsson
committed
#layout.operator("mhx.update")
layout.separator()
for prop in props:
row = layout.split(0.85)
Thomas Larsson
committed
row.prop(rig, '["%s"]' % prop, text=prop[3:])
Thomas Larsson
committed
row.operator("mhx.pose_pin_expression", text="", icon='UNPINNED').data = (prefix + ";" + prop)
return
Thomas Larsson
committed
class MhxExpressionUnitsPanel(bpy.types.Panel):
Thomas Larsson
committed
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
bl_options = {'DEFAULT_CLOSED'}
Thomas Larsson
committed
@classmethod
def poll(cls, context):
Thomas Larsson
committed
return hasProps(context.object, "Mhs")
def draw(self, context):
Thomas Larsson
committed
drawShapePanel(self, context, "Mhs", "expression")
class MhxCustomShapePanel(bpy.types.Panel):
bl_label = "MHX Custom Shapes"
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
bl_options = {'DEFAULT_CLOSED'}
Thomas Larsson
committed
Thomas Larsson
committed
@classmethod
def poll(cls, context):
Thomas Larsson
committed
return hasProps(context.object, "Mhc")
Thomas Larsson
committed
def draw(self, context):
drawShapePanel(self, context, "Mhc", "custom shape")
Thomas Larsson
committed
Thomas Larsson
committed
#########################################
#
Thomas Larsson
committed
# FK-IK snapping.
Thomas Larsson
committed
#
#########################################
def getPoseMatrix(gmat, pb):
restInv = pb.bone.matrix_local.inverted()
parInv = pb.parent.matrix.inverted()
parRest = pb.parent.bone.matrix_local
return restInv * (parRest * (parInv * gmat))
Thomas Larsson
committed
else:
return restInv * gmat
Thomas Larsson
committed
Thomas Larsson
committed
def getGlobalMatrix(mat, pb):
gmat = pb.bone.matrix_local * mat
if pb.parent:
parMat = pb.parent.matrix
parRest = pb.parent.bone.matrix_local
return parMat * (parRest.inverted() * gmat)
else:
return gmat
Thomas Larsson
committed
def matchPoseTranslation(pb, src, auto):
pmat = getPoseMatrix(src.matrix, pb)
insertLocation(pb, pmat, auto)
Thomas Larsson
committed
Thomas Larsson
committed
Thomas Larsson
committed
def insertLocation(pb, mat, auto):
pb.location = mat.to_translation()
if auto:
pb.keyframe_insert("location", group=pb.name)
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.mode_set(mode='POSE')
Thomas Larsson
committed
def matchPoseRotation(pb, src, auto):
pmat = getPoseMatrix(src.matrix, pb)
insertRotation(pb, pmat, auto)
def printMatrix(string,mat):
print(string)
for i in range(4):
print(" %.4g %.4g %.4g %.4g" % tuple(mat[i]))
Thomas Larsson
committed
Thomas Larsson
committed
def insertRotation(pb, mat, auto):
Thomas Larsson
committed
q = mat.to_quaternion()
if pb.rotation_mode == 'QUATERNION':
pb.rotation_quaternion = q
if auto:
pb.keyframe_insert("rotation_quaternion", group=pb.name)
Thomas Larsson
committed
else:
pb.rotation_euler = q.to_euler(pb.rotation_mode)
if auto:
pb.keyframe_insert("rotation_euler", group=pb.name)
Thomas Larsson
committed
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.mode_set(mode='POSE')
Thomas Larsson
committed
def matchIkLeg(legIk, toeFk, mBall, mToe, mHeel, auto):
rmat = toeFk.matrix.to_3x3()
tHead = Vector(toeFk.matrix.col[3][:3])
ty = rmat.col[1]
tail = tHead + ty * toeFk.bone.length
try:
zBall = mBall.matrix.col[3][2]
except AttributeError:
return
Thomas Larsson
committed
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
zToe = mToe.matrix.col[3][2]
zHeel = mHeel.matrix.col[3][2]
x = Vector(rmat.col[0])
y = Vector(rmat.col[1])
z = Vector(rmat.col[2])
if zHeel > zBall and zHeel > zToe:
# 1. foot.ik is flat
if abs(y[2]) > abs(z[2]):
y = -z
y[2] = 0
else:
# 2. foot.ik starts at heel
hHead = Vector(mHeel.matrix.col[3][:3])
y = tail - hHead
y.normalize()
x -= x.dot(y)*y
x.normalize()
z = x.cross(y)
head = tail - y * legIk.bone.length
# Create matrix
gmat = Matrix()
gmat.col[0][:3] = x
gmat.col[1][:3] = y
gmat.col[2][:3] = z
gmat.col[3][:3] = head
pmat = getPoseMatrix(gmat, legIk)
insertLocation(legIk, pmat, auto)
insertRotation(legIk, pmat, auto)
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
def matchPoleTarget(pb, above, below, auto):
x = Vector(above.matrix.col[1][:3])
y = Vector(below.matrix.col[1][:3])
p0 = Vector(below.matrix.col[3][:3])
n = x.cross(y)
if abs(n.length) > 1e-4:
z = x - y
n = n/n.length
z -= z.dot(n)*n
p = p0 + z/z.length*3.0
else:
p = p0
gmat = Matrix.Translation(p)
pmat = getPoseMatrix(gmat, pb)
insertLocation(pb, pmat, auto)
def matchPoseReverse(pb, src, auto):
gmat = src.matrix
tail = gmat.col[3] + src.length * gmat.col[1]
rmat = Matrix((gmat.col[0], -gmat.col[1], -gmat.col[2], tail))
rmat.transpose()
pmat = getPoseMatrix(rmat, pb)
pb.matrix_basis = pmat
insertRotation(pb, pmat, auto)
def matchPoseScale(pb, src, auto):
pmat = getPoseMatrix(src.matrix, pb)
pb.scale = pmat.to_scale()
if auto:
pb.keyframe_insert("scale", group=pb.name)
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.mode_set(mode='POSE')
Thomas Larsson
committed
def snapFkArm(context, data):
Thomas Larsson
committed
rig = context.object
prop,old,suffix = setSnapProp(rig, data, 1.0, context, False)
auto = context.scene.tool_settings.use_keyframe_insert_auto
print("Snap FK Arm%s" % suffix)
snapFk,cnsFk = getSnapBones(rig, "ArmFK", suffix)
Thomas Larsson
committed
(uparmFk, loarmFk, handFk) = snapFk
snapIk,cnsIk = getSnapBones(rig, "ArmIK", suffix)
(uparmIk, loarmIk, elbow, elbowPt, handIk) = snapIk
Thomas Larsson
committed
matchPoseRotation(uparmFk, uparmIk, auto)
matchPoseScale(uparmFk, uparmIk, auto)
Thomas Larsson
committed
matchPoseRotation(loarmFk, loarmIk, auto)
matchPoseScale(loarmFk, loarmIk, auto)
restoreSnapProp(rig, prop, old, context)
Thomas Larsson
committed
Thomas Larsson
committed
try:
matchHand = rig["MhaHandFollowsWrist" + suffix]
except KeyError:
matchHand = True
if matchHand:
matchPoseRotation(handFk, handIk, auto)
matchPoseScale(handFk, handIk, auto)
#muteConstraints(cnsFk, False)
Thomas Larsson
committed
return
def snapIkArm(context, data):
Thomas Larsson
committed
rig = context.object
prop,old,suffix = setSnapProp(rig, data, 0.0, context, True)
auto = context.scene.tool_settings.use_keyframe_insert_auto
print("Snap IK Arm%s" % suffix)
snapIk,cnsIk = getSnapBones(rig, "ArmIK", suffix)
Thomas Larsson
committed
(uparmIk, loarmIk, elbow, elbowPt, handIk) = snapIk
snapFk,cnsFk = getSnapBones(rig, "ArmFK", suffix)
Thomas Larsson
committed
(uparmFk, loarmFk, handFk) = snapFk
Thomas Larsson
committed
Thomas Larsson
committed
matchPoseTranslation(handIk, handFk, auto)
matchPoseRotation(handIk, handFk, auto)
matchPoleTarget(elbowPt, uparmFk, loarmFk, auto)
Thomas Larsson
committed
#matchPoseRotation(uparmIk, uparmFk, auto)
#matchPoseRotation(loarmIk, loarmFk, auto)
restoreSnapProp(rig, prop, old, context)
#muteConstraints(cnsIk, False)
Thomas Larsson
committed
return
def snapFkLeg(context, data):
Thomas Larsson
committed
rig = context.object
prop,old,suffix = setSnapProp(rig, data, 1.0, context, False)
auto = context.scene.tool_settings.use_keyframe_insert_auto
print("Snap FK Leg%s" % suffix)
Thomas Larsson
committed
snap,_ = getSnapBones(rig, "Leg", suffix)
(upleg, loleg, foot, toe) = snap
snapIk,cnsIk = getSnapBones(rig, "LegIK", suffix)
Thomas Larsson
committed
(uplegIk, lolegIk, kneePt, ankleIk, legIk, footRev, toeRev, mBall, mToe, mHeel) = snapIk
snapFk,cnsFk = getSnapBones(rig, "LegFK", suffix)
Thomas Larsson
committed
(uplegFk, lolegFk, footFk, toeFk) = snapFk
Thomas Larsson
committed
matchPoseRotation(uplegFk, uplegIk, auto)
matchPoseScale(uplegFk, uplegIk, auto)
matchPoseRotation(lolegFk, lolegIk, auto)
matchPoseScale(lolegFk, lolegIk, auto)
Thomas Larsson
committed
restoreSnapProp(rig, prop, old, context)
Thomas Larsson
committed
matchPoseReverse(footFk, footRev, auto)
matchPoseReverse(toeFk, toeRev, auto)
Thomas Larsson
committed
#muteConstraints(cnsFk, False)
Thomas Larsson
committed
return
def snapIkLeg(context, data):
Thomas Larsson
committed
rig = context.object
prop,old,suffix = setSnapProp(rig, data, 0.0, context, True)
auto = scn.tool_settings.use_keyframe_insert_auto
print("Snap IK Leg%s" % suffix)
snapIk,cnsIk = getSnapBones(rig, "LegIK", suffix)
Thomas Larsson
committed
(uplegIk, lolegIk, kneePt, ankleIk, legIk, footRev, toeRev, mBall, mToe, mHeel) = snapIk
snapFk,cnsFk = getSnapBones(rig, "LegFK", suffix)
Thomas Larsson
committed
(uplegFk, lolegFk, footFk, toeFk) = snapFk
Thomas Larsson
committed
legIkToAnkle = rig["MhaLegIkToAnkle" + suffix]
if legIkToAnkle:
matchPoseTranslation(ankleIk, footFk, auto)
Thomas Larsson
committed
#matchPoseTranslation(legIk, legFk, auto)
#matchPoseRotation(legIk, legFk, auto)
matchIkLeg(legIk, toeFk, mBall, mToe, mHeel, auto)
Thomas Larsson
committed
matchPoseReverse(toeRev, toeFk, auto)
matchPoseReverse(footRev, footFk, auto)
matchPoleTarget(kneePt, uplegFk, lolegFk, auto)
Thomas Larsson
committed
#matchPoseRotation(uplegIk, uplegFk, auto)
#matchPoseRotation(lolegIk, lolegFk, auto)
if not legIkToAnkle:
matchPoseTranslation(ankleIk, footFk, auto)
restoreSnapProp(rig, prop, old, context)
#muteConstraints(cnsIk, False)
Thomas Larsson
committed
SnapBonesAlpha8 = {
"Arm" : ["upper_arm", "forearm", "hand"],
Thomas Larsson
committed
"ArmFK" : ["upper_arm.fk", "forearm.fk", "hand.fk"],
Thomas Larsson
committed
"ArmIK" : ["upper_arm.ik", "forearm.ik", None, "elbow.pt.ik", "hand.ik"],
"Leg" : ["thigh", "shin", "foot", "toe"],
Thomas Larsson
committed
"LegFK" : ["thigh.fk", "shin.fk", "foot.fk", "toe.fk"],
"LegIK" : ["thigh.ik", "shin.ik", "knee.pt.ik", "ankle.ik", "foot.ik", "foot.rev", "toe.rev", "ball.marker", "toe.marker", "heel.marker"],
Thomas Larsson
committed
}
Thomas Larsson
committed
Thomas Larsson
committed
def getSnapBones(rig, key, suffix):
Thomas Larsson
committed
try:
Thomas Larsson
committed
pb = rig.pose.bones["UpLeg_L"]
Thomas Larsson
committed
except KeyError:
Thomas Larsson
committed
pb = None
Thomas Larsson
committed
Thomas Larsson
committed
if pb is not None:
raise NameError("MakeHuman alpha 7 not supported after Blender 2.68")
try:
rig.pose.bones["thigh.fk.L"]
names = SnapBonesAlpha8[key]
suffix = '.' + suffix[1:]
except KeyError:
names = None
Thomas Larsson
committed
if not names:
raise NameError("Not an mhx armature")
Thomas Larsson
committed
Thomas Larsson
committed
pbones = []
Thomas Larsson
committed
for name in names:
Thomas Larsson
committed
if name:
try:
pb = rig.pose.bones[name+suffix]
except KeyError:
pb = None
Thomas Larsson
committed
pbones.append(pb)
if pb is not None:
for cns in pb.constraints:
if cns.type == 'LIMIT_ROTATION' and not cns.mute:
constraints.append(cns)
Thomas Larsson
committed
else:
pbones.append(None)
return tuple(pbones),constraints
def muteConstraints(constraints, value):
for cns in constraints:
cns.mute = value
Thomas Larsson
committed
Thomas Larsson
committed
class VIEW3D_OT_MhxSnapFk2IkButton(bpy.types.Operator):
bl_idname = "mhx.snap_fk_ik"
Thomas Larsson
committed
data = StringProperty()
Thomas Larsson
committed
def execute(self, context):
bpy.ops.object.mode_set(mode='POSE')
if rig.MhxSnapExact:
rig["MhaRotationLimits"] = 0.0
if self.data[:6] == "MhaArm":
snapFkArm(context, self.data)
elif self.data[:6] == "MhaLeg":
snapFkLeg(context, self.data)
Thomas Larsson
committed
return{'FINISHED'}
Thomas Larsson
committed
Thomas Larsson
committed
class VIEW3D_OT_MhxSnapIk2FkButton(bpy.types.Operator):
bl_idname = "mhx.snap_ik_fk"
Thomas Larsson
committed
data = StringProperty()
Thomas Larsson
committed
def execute(self, context):
bpy.ops.object.mode_set(mode='POSE')
if rig.MhxSnapExact:
rig["MhaRotationLimits"] = 0.0
if self.data[:6] == "MhaArm":
snapIkArm(context, self.data)
elif self.data[:6] == "MhaLeg":
snapIkLeg(context, self.data)
Thomas Larsson
committed
return{'FINISHED'}
Thomas Larsson
committed
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
def setSnapProp(rig, data, value, context, isIk):
words = data.split()
prop = words[0]
oldValue = rig[prop]
rig[prop] = value
ik = int(words[1])
fk = int(words[2])
extra = int(words[3])
oldIk = rig.data.layers[ik]
oldFk = rig.data.layers[fk]
oldExtra = rig.data.layers[extra]
rig.data.layers[ik] = True
rig.data.layers[fk] = True
rig.data.layers[extra] = True
updatePose(context)
if isIk:
oldValue = 1.0
oldIk = True
oldFk = False
else:
oldValue = 0.0
oldIk = False
oldFk = True
oldExtra = False
return (prop, (oldValue, ik, fk, extra, oldIk, oldFk, oldExtra), prop[-2:])
Thomas Larsson
committed
def restoreSnapProp(rig, prop, old, context):
updatePose(context)
(oldValue, ik, fk, extra, oldIk, oldFk, oldExtra) = old
rig[prop] = oldValue
rig.data.layers[ik] = oldIk
rig.data.layers[fk] = oldFk
rig.data.layers[extra] = oldExtra
updatePose(context)
Thomas Larsson
committed
class VIEW3D_OT_MhxToggleFkIkButton(bpy.types.Operator):
bl_idname = "mhx.toggle_fk_ik"
bl_label = "FK - IK"
Thomas Larsson
committed
toggle = StringProperty()
Thomas Larsson
committed
def execute(self, context):
words = self.toggle.split()
rig = context.object
prop = words[0]
Thomas Larsson
committed
value = float(words[1])
Thomas Larsson
committed
onLayer = int(words[2])
offLayer = int(words[3])
rig.data.layers[onLayer] = True
rig.data.layers[offLayer] = False
rig[prop] = value
# Don't do autokey - confusing.
#if context.tool_settings.use_keyframe_insert_auto:
Thomas Larsson
committed
# rig.keyframe_insert('["%s"]' % prop, frame=scn.frame_current)
Thomas Larsson
committed
return{'FINISHED'}
Thomas Larsson
committed
#
# MHX FK/IK Switch panel
#
Thomas Larsson
committed
class MhxFKIKPanel(bpy.types.Panel):
bl_label = "MHX FK/IK Switch"
Thomas Larsson
committed
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
#bl_options = {'DEFAULT_CLOSED'}
Thomas Larsson
committed
Thomas Larsson
committed
@classmethod
def poll(cls, context):
return (context.object and context.object.MhxRig == 'MHX')
Thomas Larsson
committed
def draw(self, context):
Thomas Larsson
committed
rig = context.object
Thomas Larsson
committed
layout = self.layout
Thomas Larsson
committed
row = layout.row()
row.label("")
row.label("Left")
row.label("Right")
Thomas Larsson
committed
layout.label("FK/IK switch")
Thomas Larsson
committed
row = layout.row()
row.label("Arm")
Thomas Larsson
committed
self.toggleButton(row, rig, "MhaArmIk_L", " 3", " 2")
self.toggleButton(row, rig, "MhaArmIk_R", " 19", " 18")
Thomas Larsson
committed
row = layout.row()
row.label("Leg")
Thomas Larsson
committed
self.toggleButton(row, rig, "MhaLegIk_L", " 5", " 4")
self.toggleButton(row, rig, "MhaLegIk_R", " 21", " 20")
Thomas Larsson
committed
layout.label("IK Influence")
row = layout.row()
row.label("Arm")
row.prop(rig, '["MhaArmIk_L"]', text="")
row.prop(rig, '["MhaArmIk_R"]', text="")
row = layout.row()
row.label("Leg")
row.prop(rig, '["MhaLegIk_L"]', text="")
row.prop(rig, '["MhaLegIk_R"]', text="")
Thomas Larsson
committed
try:
ok = (rig["MhxVersion"] >= 12)
except:
ok = False
if not ok:
layout.label("Snapping only works with MHX version 1.12 and later.")
return
Thomas Larsson
committed
layout.separator()
layout.label("Snapping")
row = layout.row()
row.label("Rotation Limits")
row.prop(rig, '["MhaRotationLimits"]', text="")
row.prop(rig, "MhxSnapExact", text="Exact Snapping")
Thomas Larsson
committed
layout.label("Snap Arm bones")
Thomas Larsson
committed
row = layout.row()
Thomas Larsson
committed
row.operator("mhx.snap_fk_ik", text="Snap L FK Arm").data = "MhaArmIk_L 2 3 12"
row.operator("mhx.snap_fk_ik", text="Snap R FK Arm").data = "MhaArmIk_R 18 19 28"
Thomas Larsson
committed
row = layout.row()
Thomas Larsson
committed
row.operator("mhx.snap_ik_fk", text="Snap L IK Arm").data = "MhaArmIk_L 2 3 12"
row.operator("mhx.snap_ik_fk", text="Snap R IK Arm").data = "MhaArmIk_R 18 19 28"
Thomas Larsson
committed
layout.label("Snap Leg bones")
Thomas Larsson
committed
row = layout.row()
Thomas Larsson
committed
row.operator("mhx.snap_fk_ik", text="Snap L FK Leg").data = "MhaLegIk_L 4 5 12"
row.operator("mhx.snap_fk_ik", text="Snap R FK Leg").data = "MhaLegIk_R 20 21 28"
row = layout.row()
row.label("IK Leg")
Thomas Larsson
committed
row.operator("mhx.snap_ik_fk", text="Snap L IK Leg").data = "MhaLegIk_L 4 5 12"
row.operator("mhx.snap_ik_fk", text="Snap R IK Leg").data = "MhaLegIk_R 20 21 28"
Thomas Larsson
committed
Thomas Larsson
committed
def toggleButton(self, row, rig, prop, fk, ik):
if rig[prop] > 0.5:
row.operator("mhx.toggle_fk_ik", text="IK").toggle = prop + " 0" + fk + ik
else:
row.operator("mhx.toggle_fk_ik", text="FK").toggle = prop + " 1" + ik + fk
Thomas Larsson
committed
###################################################################################
#
# Posing panel
#
Thomas Larsson
committed
###################################################################################
#
# class MhxDriversPanel(bpy.types.Panel):
#
class MhxDriversPanel(bpy.types.Panel):
bl_label = "MHX Drivers"
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
bl_options = {'DEFAULT_CLOSED'}
Thomas Larsson
committed
@classmethod
def poll(cls, context):
Thomas Larsson
committed
return (context.object and context.object.MhxRig == 'MHX')
def draw(self, context):
Thomas Larsson
committed
lrProps = []
Thomas Larsson
committed
lrFaceProps = []
faceProps = []
plist = list(context.object.keys())
plist.sort()
for prop in plist:
if prop[0:3] == 'Mha':
if prop[-2:] == '_L':
Thomas Larsson
committed
lrProps.append(prop[:-2])
Thomas Larsson
committed
props.append(prop)
elif prop[0:3] == 'Mhf':
if prop[-2:] == '_L':
lrFaceProps.append(prop[:-2])
elif prop[-2:] != '_R':
faceProps.append(prop)
Thomas Larsson
committed
ob = context.object
layout = self.layout
Thomas Larsson
committed
for prop in props:
Thomas Larsson
committed
layout.prop(ob, '["%s"]' % prop, text=prop[3:])
Thomas Larsson
committed
layout.separator()
row = layout.row()
row.label("Left")
row.label("Right")
for prop in lrProps:
row = layout.row()
Thomas Larsson
committed
row.prop(ob, '["%s"]' % (prop+"_L"), text=prop[3:])
row.prop(ob, '["%s"]' % (prop+"_R"), text=prop[3:])
Thomas Larsson
committed
if faceProps:
layout.separator()
layout.label("Face shapes")
Thomas Larsson
committed
for prop in faceProps:
Thomas Larsson
committed
layout.prop(ob, '["%s"]' % prop, text=prop[3:])
Thomas Larsson
committed
layout.separator()
row = layout.row()
row.label("Left")
row.label("Right")
for prop in lrFaceProps:
row = layout.row()
Thomas Larsson
committed
row.prop(ob, '["%s"]' % (prop+"_L"), text=prop[3:])
row.prop(ob, '["%s"]' % (prop+"_R"), text=prop[3:])
Thomas Larsson
committed
Thomas Larsson
committed
###################################################################################
Thomas Larsson
committed
###################################################################################
#
# class MhxVisibilityPanel(bpy.types.Panel):
#
class MhxVisibilityPanel(bpy.types.Panel):
bl_label = "MHX Visibility"
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
bl_options = {'DEFAULT_CLOSED'}
Thomas Larsson
committed
@classmethod
def poll(cls, context):
return (context.object and context.object.MhxRig)
def draw(self, context):
ob = context.object
Thomas Larsson
committed
layout = self.layout
props = list(ob.keys())
props.sort()
for prop in props:
Thomas Larsson
committed
if prop[0:3] == "Mhh":
Thomas Larsson
committed
layout.prop(ob, '["%s"]' % prop, text="Hide %s" % prop[3:])
Thomas Larsson
committed
layout.separator()
layout.operator("mhx.update_textures")
layout.separator()
layout.operator("mhx.add_hiders")
layout.operator("mhx.remove_hiders")
Thomas Larsson
committed
class VIEW3D_OT_MhxUpdateTexturesButton(bpy.types.Operator):
bl_idname = "mhx.update_textures"
bl_label = "Update"
Thomas Larsson
committed
def execute(self, context):
scn = context.scene
for mat in bpy.data.materials:
if mat.animation_data:
try:
mat["MhxDriven"]
except:
continue
for driver in mat.animation_data.drivers:
prop = mat.path_resolve(driver.data_path)
value = driver.evaluate(scn.frame_current)
prop[driver.array_index] = value
Thomas Larsson
committed
return{'FINISHED'}
class VIEW3D_OT_MhxAddHidersButton(bpy.types.Operator):
bl_idname = "mhx.add_hiders"
bl_label = "Add Hide Property"
def execute(self, context):
rig = context.object
for ob in context.scene.objects:
if ob.select and ob != rig:
Thomas Larsson
committed
prop = "Mhh%s" % ob.name
Thomas Larsson
committed
defNewProp(prop, "Bool", "default=False")
Thomas Larsson
committed
rig[prop] = False
addHider(ob, "hide", rig, prop)
addHider(ob, "hide_render", rig, prop)
Thomas Larsson
committed
return{'FINISHED'}
def addHider(ob, attr, rig, prop):
fcu = ob.driver_add(attr)
drv = fcu.driver
drv.type = 'SCRIPTED'
drv.expression = "x"
drv.show_debug_info = True
var = drv.variables.new()
var.name = "x"
targ = var.targets[0]
targ.id = rig
targ.data_path = '["%s"]' % prop
return
class VIEW3D_OT_MhxRemoveHidersButton(bpy.types.Operator):
bl_idname = "mhx.remove_hiders"
bl_label = "Remove Hide Property"
Thomas Larsson
committed
def execute(self, context):
rig = context.object
for ob in context.scene.objects:
if ob.select and ob != rig:
ob.driver_remove("hide")
ob.driver_remove("hide_render")
Thomas Larsson
committed
del rig["Mhh%s" % ob.name]
Thomas Larsson
committed
return{'FINISHED'}
###################################################################################
#
# Common functions
#
Thomas Larsson
committed
###################################################################################
Thomas Larsson
committed
# getMhxRigMesh(ob):
Thomas Larsson
committed
def pollMhx(ob):
if not ob:
return False
elif ob.type == 'ARMATURE':
return ob.MhxRig
elif ob.type == 'MESH':
par = ob.parent
return (par and (par.type == 'ARMATURE') and par.MhxRig)
else:
return False
Thomas Larsson
committed
def getMhxRigMesh(ob):
if ob.type == 'ARMATURE':
for mesh in ob.children:
if mesh.MhxMesh and ob.MhxRig:
return (ob, mesh)
Thomas Larsson
committed
return (ob, None)
elif ob.type == 'MESH':
par = ob.parent
if (par and par.type == 'ARMATURE' and par.MhxRig):
if ob.MhxMesh:
return (par, ob)
else:
return (par, None)
else:
Thomas Larsson
committed
return (None, None)
return (None, None)
Thomas Larsson
committed
#
# setInterpolation(rig):
#
def setInterpolation(rig):
if not rig.animation_data:
return
act = rig.animation_data.action
if not act:
return
for fcu in act.fcurves:
for pt in fcu.keyframe_points:
pt.interpolation = 'LINEAR'
fcu.extrapolation = 'CONSTANT'
return
Thomas Larsson
committed
###################################################################################
#
# initialize and register
#
Thomas Larsson
committed
###################################################################################
def menu_func(self, context):
self.layout.operator(ImportMhx.bl_idname, text="MakeHuman (.mhx)...")
Thomas Larsson
committed
bpy.types.Object.MhxVersionStr = StringProperty(name="Version", default="", maxlen=128)
bpy.types.Object.MhAlpha8 = BoolProperty(default=True)
bpy.types.Object.MhxMesh = BoolProperty(default=False)
bpy.types.Object.MhxRig = StringProperty(default="")
Thomas Larsson
committed
bpy.types.Object.MhxVisemeSet = StringProperty(default="")
bpy.types.Object.MhxRigify = BoolProperty(default=False)
bpy.types.Object.MhxSnapExact = BoolProperty(default=False)
bpy.types.Object.MhxShapekeyDrivers = BoolProperty(default=True)
Thomas Larsson
committed
bpy.types.Object.MhxStrength = FloatProperty(
name = "Expression strength",
description = "Multiply expression with this factor",
default=1.0, min=-1.0, max=2.0
)
Campbell Barton
committed
bpy.utils.register_module(__name__)
Thomas Larsson
committed
bpy.utils.unregister_module(__name__)
Thomas Larsson
committed
try:
bpy.types.INFO_MT_file_import.remove(menu_func)
except:
pass
if __name__ == "__main__":
unregister()