Skip to content

Instantly share code, notes, and snippets.

@benmorgantd
Last active April 12, 2017 18:52
Show Gist options
  • Save benmorgantd/2cac4f59929702286cbf043bf854016c to your computer and use it in GitHub Desktop.
Save benmorgantd/2cac4f59929702286cbf043bf854016c to your computer and use it in GitHub Desktop.
import maya.cmds as cmds
# replaces the selected transform's shape with a new one
def changeShape(obj=None,type=None):
shapeTypes = ["cube", "circle", "square", "triangle"]
if type not in shapeTypes:
print "Shape type not recognized"
return
if not obj:
obj = cmds.ls(sl=1)
if cmds.objectType(obj) != "transform":
print "Error: Objects must be of type \"transform\" "
return
objShape = cmds.pickWalk(obj, d="down")
# get shape's bounding box for its world scale
# bounding box is ony for the SHAPE's bounding box.
# use shape's Center attribute (bounding box center) for new obj's translate
# use shape's boundingBoxSize attr for new obj's scale.
# *** this gives some really interesting behavior that could come in handy elsewhere!
# * the boundingBoxSize seems to be incorrect, but it is actually using
# the CVs as the full size and not the final approximated curve
# make our new shape
if type == "cube":
newObj = cmds.polyCube(n=obj[0] + "_newShape", ch=0)
cmds.connectAttr(objShape[0] + ".center", newObj[0] + ".translate")
cmds.connectAttr(objShape[0] + ".boundingBox.boundingBoxSize", newObj[0] + ".scale")
cmds.disconnectAttr(objShape[0] + ".center", newObj[0] + ".translate")
cmds.disconnectAttr(objShape[0] + ".boundingBox.boundingBoxSize", newObj[0] + ".scale")
# for a 3d shape change like a cube, it will be flattened to 0 on the Y axis unless we do something about that..
# Here we just set it to the same value of the sX value to keep it square, but if the object we're querying
# had an irregular shape, we'd have to manually make some changes here
# Also this assumes that the object has a 0 value in the Y axis, which might not always be the case.
# If the rotations have been brought on by the objet's rotate values, it will inherit those
if cmds.getAttr(newObj[0] + ".scaleX") < .0001 and cmds.getAttr(newObj[0] + ".scaleY") > .0001:
cmds.setAttr(newObj[0] + ".scaleX", cmds.getAttr(newObj[0] + ".scaleY"))
elif cmds.getAttr(newObj[0] + ".scaleX") < .0001 and cmds.getAttr(newObj[0] + ".scaleZ") > .0001:
cmds.setAttr(newObj[0] + ".scaleX", cmds.getAttr(newObj[0] + ".scaleZ"))
elif cmds.getAttr(newObj[0] + ".scaleY") < .0001 and cmds.getAttr(newObj[0] + ".scaleZ") > .0001:
cmds.setAttr(newObj[0] + ".scaleY", cmds.getAttr(newObj[0] + ".scaleZ"))
elif cmds.getAttr(newObj[0] + ".scaleY") < .0001 and cmds.getAttr(newObj[0] + ".scaleX") > .0001:
cmds.setAttr(newObj[0] + ".scaleY", cmds.getAttr(newObj[0] + ".scaleX"))
elif cmds.getAttr(newObj[0] + ".scaleZ") < .0001 and cmds.getAttr(newObj[0] + ".scaleX") > .0001:
cmds.setAttr(newObj[0] + ".scaleZ", cmds.getAttr(newObj[0] + ".scaleX"))
elif cmds.getAttr(newObj[0] + ".scaleZ") < .0001 and cmds.getAttr(newObj[0] + ".scaleY") > .0001:
cmds.setAttr(newObj[0] + ".scaleZ", cmds.getAttr(newObj[0] + ".scaleY"))
# make the cube not renderable
newObjShape = cmds.pickWalk(newObj,d="down")[0]
cmds.setAttr(newObjShape + ".overrideEnabled",1)
cmds.setAttr(newObjShape + ".overrideShading",0)
cmds.setAttr(newObjShape + ".castsShadows",0)
cmds.setAttr(newObjShape + ".receiveShadows",0)
cmds.setAttr(newObjShape + ".primaryVisibility",0)
elif type == "circle":
newObj = cmds.circle(n=obj[0] + "_newShape", ch=0, nr=(0, 1, 0))
cmds.connectAttr(objShape[0] + ".center", newObj[0] + ".translate")
cmds.connectAttr(objShape[0] + ".boundingBox.boundingBoxSize", newObj[0] + ".scale")
cmds.disconnectAttr(objShape[0] + ".center", newObj[0] + ".translate")
cmds.disconnectAttr(objShape[0] + ".boundingBox.boundingBoxSize", newObj[0] + ".scale")
# it ends up doubling the radius we want so let's fix that
cmds.setAttr(newObj[0] + ".scaleX", cmds.getAttr(newObj[0] + ".scaleX") / 2)
cmds.setAttr(newObj[0] + ".scaleY", cmds.getAttr(newObj[0] + ".scaleY") / 2)
cmds.setAttr(newObj[0] + ".scaleZ", cmds.getAttr(newObj[0] + ".scaleZ") / 2)
elif type == "square":
newObj = cmds.circle(n=obj[0] + "_newShape", ch=0, nr=(0, 1, 0), degree=1, sections=4)
cmds.xform(newObj, ro=(0, 45, 0))
cmds.connectAttr(objShape[0] + ".center", newObj[0] + ".translate")
cmds.connectAttr(objShape[0] + ".boundingBox.boundingBoxSize", newObj[0] + ".scale")
cmds.disconnectAttr(objShape[0] + ".center", newObj[0] + ".translate")
cmds.disconnectAttr(objShape[0] + ".boundingBox.boundingBoxSize", newObj[0] + ".scale")
# it ends up doubling the radius we want so let's fix that
cmds.setAttr(newObj[0] + ".scaleX", cmds.getAttr(newObj[0] + ".scaleX") / 2)
cmds.setAttr(newObj[0] + ".scaleY", cmds.getAttr(newObj[0] + ".scaleY") / 2)
cmds.setAttr(newObj[0] + ".scaleZ", cmds.getAttr(newObj[0] + ".scaleZ") / 2)
elif type == "triangle":
newObj = cmds.circle(n=obj[0] + "_newShape", ch=0, nr=(0, 1, 0), degree=1, sections=3)
cmds.xform(newObj, ro=(0, 180, 0))
cmds.connectAttr(objShape[0] + ".center", newObj[0] + ".translate")
cmds.connectAttr(objShape[0] + ".boundingBox.boundingBoxSize", newObj[0] + ".scale")
cmds.disconnectAttr(objShape[0] + ".center", newObj[0] + ".translate")
cmds.disconnectAttr(objShape[0] + ".boundingBox.boundingBoxSize", newObj[0] + ".scale")
# it ends up doubling the radius we want so let's fix that
cmds.setAttr(newObj[0] + ".scaleX", cmds.getAttr(newObj[0] + ".scaleX") / 2)
cmds.setAttr(newObj[0] + ".scaleY", cmds.getAttr(newObj[0] + ".scaleY") / 2)
cmds.setAttr(newObj[0] + ".scaleZ", cmds.getAttr(newObj[0] + ".scaleZ") / 2)
# finally, we can do the parenting
newObjShape = cmds.pickWalk(newObj, d="down")
# freeze the new object's transformations
cmds.makeIdentity(newObj, apply=1, t=1, r=1, s=1)
cmds.parent(newObjShape, obj, r=1, s=1)
# finally, delete the old shape and our newObj's transform node
cmds.delete(objShape, newObj)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment