Skip to content

Instantly share code, notes, and snippets.

@danbradham
Created January 26, 2019 01:06
Show Gist options
  • Save danbradham/4d6dd939cb337a65c9202c203a5007be to your computer and use it in GitHub Desktop.
Save danbradham/4d6dd939cb337a65c9202c203a5007be to your computer and use it in GitHub Desktop.
Make it dynamic
from maya import cmds, mel
from contextlib import contextmanager
from mayakit.tags import tag, untag, query, search, message, unmessage, connect
@contextmanager
def selection(nodes=None):
old_selection = cmds.ls(sl=True)
try:
if nodes is not None:
cmds.select(nodes, replace=True)
yield
finally:
cmds.select(old_selection)
@contextmanager
def undo_chunk():
try:
cmds.undoInfo(openChunk=True)
yield
finally:
cmds.undoInfo(closeChunk=True)
def get_frame_range():
slider = mel.eval("$pytmp=$gPlayBackSlider")
frame_range = cmds.timeControl(slider, q=True, rangeArray=True)
if frame_range == [1.0, 2.0]:
frame_range = cmds.playbackOptions(q=True, minTime=True), cmds.playbackOptions(q=True, maxTime=True)
return [int(frame_range[0]), int(frame_range[1])]
def make_dynamic(xform, weight=0.8):
'''Make an xform dynamic'''
message(xform, "nucleus")
message(xform, "nParticle")
message(xform, "nParticleXform")
message(xform, "dyn_locator")
# Create objects
position = cmds.xform(xform, query=True, worldSpace=True, rotatePivot=True)
parti, parti_shape = cmds.nParticle(position=position)
cmds.setAttr(parti_shape + ".particleRenderType", 4)
cmds.goal(parti_shape, useTransformAsGoal=True, weight=weight, goal=xform)
nucleus = cmds.listConnections(parti_shape, type="nucleus")[0]
dyn_locator = cmds.spaceLocator()[0]
dyn_locator = cmds.rename(dyn_locator, xform + '_dyn')
cmds.connectAttr(parti_shape + '.centroid', dyn_locator + '.t')
connect("message", "nucleus", nucleus, xform)
connect("message", "nParticle", parti_shape, xform)
connect("message", "nParticleXform", parti, xform)
connect("message", "dyn_locator", dyn_locator, xform)
def make_selected_dynamic(weight=0.8):
xforms = cmds.ls(sl=True, transforms=True)
for xform in xforms:
make_dynamic(xform, weight=weight)
def bake_dynamic(xform):
dyn_loc_attr = xform + '.dyn_locator'
if not cmds.objExists(dyn_loc_attr):
cmds.warning("xform has no dynamics.")
return
dyn_locator = cmds.listConnections(dyn_loc_attr)
if not dyn_locator:
cmds.warning("Xform is not attached to a dyn locator")
return
dyn_locator = dyn_locator[0]
# Get Translate values from dyn_locator
start_frame = int(cmds.playbackOptions(q=True, minTime=True))
end_frame = int(cmds.playbackOptions(q=True, maxTime=True))
frame_range = list(range(start_frame, end_frame))
keys = []
old_frame = cmds.currentTime(q=True)
with undo_chunk():
for frame in frame_range:
cmds.currentTime(frame)
keys.append(cmds.getAttr(dyn_locator + '.translate')[0])
cmds.currentTime(old_frame)
# Set keyframes on xform
for frame, key in zip(frame_range, keys):
cmds.setKeyframe(xform + '.tx', value=key[0], time=frame)
cmds.setKeyframe(xform + '.ty', value=key[1], time=frame)
cmds.setKeyframe(xform + '.tz', value=key[2], time=frame)
nucleus = cmds.listConnections(xform + '.nucleus')[0]
parti = cmds.listConnections(xform + '.nParticleXform')[0]
parti_shape = cmds.listConnections(xform + '.nParticle')[0]
cmds.delete([nucleus, parti, parti_shape, dyn_locator])
def bake_selected_dynamic():
xforms = cmds.ls(sl=True, transforms=True)
for xform in xforms:
bake_dynamic(xform)
if __name__ == "__main__":
print(get_frame_range())
with undo_chunk():
with selection():
make_selected_dynamic(0.4)
bake_selected_dynamic()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment