Haven't got much time to update lately. Been busy with work.
Still, I managed to wrote a little script when my patience was out looking at a messy geo_grp from the model department.
Just select the root geo_grp, the script will reorder all the children under it alphabetically (groups will be ordered last).
import pymel.core as pm
import maya.OpenMaya as om
def rearrangeGeoGrp(geoGrp=None):
if not geoGrp:
try:
geoGrp = pm.selected(type='transform')[0]
except:
pass
if not geoGrp:
om.MGlobal.displayError('Select a geo group.')
return
exit = False
grps = [geoGrp]
while not exit:
nextGrps = []
for grp in grps:
children = grp.getChildren(type='transform')
if not children:
om.MGlobal.displayWarning('%s : is an empty group.' %grp.longName())
# seperate grps and plys
cgrps, plys = [], []
for c in children:
checkIfPly = False
try:
shp = c.getShape(ni=True)
if isinstance(shp, pm.nt.Mesh):
checkIfPly = True
except:
pass
if checkIfPly == True:
plys.append(c)
else:
cgrps.append(c)
nextGrps.append(c)
plys = sorted(plys)
cgrps = sorted(cgrps)
plys.extend(cgrps)
for i, item in enumerate(plys):
currentIndx = grp.getChildren(type='transform').index(item)
pm.reorder(item, r=((currentIndx * -1) + i))
if nextGrps:
grps = nextGrps
else:
exit = True
Rigging in Maya, scripting(MEL, Python), and a little bit of this and that I found useful.
Showing posts with label pymel. Show all posts
Showing posts with label pymel. Show all posts
Tuesday, October 7, 2014
Thursday, September 4, 2014
Resetting controller's transform with pymel
A tricky way to reset ctrl transform is to multiply the ctrl and the parent group matrices together and put the result to the parent then zero out ctrl transform. Whola! You got zeroed out ctrl where you put it.
#############################################
import pymel.core as pm
import maya.OpenMaya as om
def resetChannelBox(obj):
cbAttr = ['tx', 'ty', 'tz', 'rx', 'ry', 'rz', 'sx', 'sy', 'sz']
for a in cbAttr:
attr = obj.attr(a)
locked = False
if attr.isLocked() == True and obj.isReferenced() == False:
attr.unlock()
locked = True
try:
if 's' in a:
attr.set(1.00)
else:
attr.set(0.00)
except:
return False
if locked == True:
attr.lock()
return True
def resetCtrlTransform(objs=[]) :
if not objs:
objs = pm.selected(type='transform')
if not objs:
return
for obj in objs:
offsetGrp = obj.getParent()
if not offsetGrp:
om.MGlobal.displayWarning('%s has no parent. Continue.' %obj.nodeName())
continue
srcMtx = obj.getMatrix()
grpMtx = offsetGrp.getMatrix()
resultMtx = srcMtx * grpMtx
offsetGrp.setMatrix(resultMtx)
resetChannelBox(obj)
if isinstance(obj, pm.nt.Joint) == True:
obj.jointOrient.set([0.0, 0.0, 0.0])
resetCtrlTransform()
#############################################
import pymel.core as pm
import maya.OpenMaya as om
def resetChannelBox(obj):
cbAttr = ['tx', 'ty', 'tz', 'rx', 'ry', 'rz', 'sx', 'sy', 'sz']
for a in cbAttr:
attr = obj.attr(a)
locked = False
if attr.isLocked() == True and obj.isReferenced() == False:
attr.unlock()
locked = True
try:
if 's' in a:
attr.set(1.00)
else:
attr.set(0.00)
except:
return False
if locked == True:
attr.lock()
return True
def resetCtrlTransform(objs=[]) :
if not objs:
objs = pm.selected(type='transform')
if not objs:
return
for obj in objs:
offsetGrp = obj.getParent()
if not offsetGrp:
om.MGlobal.displayWarning('%s has no parent. Continue.' %obj.nodeName())
continue
srcMtx = obj.getMatrix()
grpMtx = offsetGrp.getMatrix()
resultMtx = srcMtx * grpMtx
offsetGrp.setMatrix(resultMtx)
resetChannelBox(obj)
if isinstance(obj, pm.nt.Joint) == True:
obj.jointOrient.set([0.0, 0.0, 0.0])
resetCtrlTransform()
Wednesday, April 2, 2014
Placing a follicle - the smart way.
I came across this tutorial on vimeo by marco d'ambros.
He shows a very interesting technic about re-positioning a joint after it was bound to a mesh without effecting the mesh deformation and still maintaining skin weight painted.But, that's not what I wanna talk about here.
Placing follicle on a mesh is kinda hard to get it at the exact point(of course, the mesh must not have overlap UVs). You have to tweak the U and V values around until it goes where you want, still, not the 'exact' point that you had in mind. In the tutorial he talked about his script(his comment) that place a follicle at exactly the point specified on the mesh or the closest possible. I wasn't be able to use it, because it was written using Maya python API 2.0. So, I dig into his code and modify some part of it to use the old python API and to better suite my needs. Take a look at my code. I commented on almost every line of it for you.
To run it just execute the whole function once select a vertex or 2 transforms(1.the mesh 2.any locator) and type:
createFollicleFromPosition()
PS. the script requires PyMel.
ไปเจอ tutorial นี้ ของคุณ marco d'ambros.
ในคลิปเขาแนะนำเทคนิคน่าสนใจมากเกี่ยวกับการย้ายตำแหน่ง joint หลังจากที่ bind skin ไปแล้ว โดยที่ไม่ต้องเพ้นเวทใหม่(ย้ายเอาดื้อๆเลย) น่าสนใจมาก
แต่..นั่นไม่ใช่ที่จะพูดถึงวันนี้
การแปะ follice บนโพลิกอนนั้นค่อนข้างยากที่จะวางในตำแน่งที่เราต้องการเป๊ะๆ(โพลีก้อนต้องไม่มี UV ซ้อนนะ) เราต้องนั่งปรับค่า U กับ V ไปทีละเล็กละน้อย เรื่อยๆ จนมันไปอยู่ในที่ๆเราต้องการ แต่ก็ยังไม่ "เป๊ะ" ในคลิปเขาพูดถึงสคริปของเขา(ในcomment) ที่เป็นสคริปสำหรับวาง follice บนจุดที่กำหนดบนผิวของโพลีก้อน(หรือถ้าไม่ใช่ก็ใกล้เคียงที่สุด) ผมเอาสคริปมาโมนิดหน่อย เนื่องจากเขาเขียนใช้ Maya Python API 2.0 ผมเลยโมให้มันใช้ API ตัวเก่า(เผื่อไว้) และก็โมส่วนอื่นๆให้มันใช้ง่ายขึ้นสำหรับผม
ลองอ่านสคริปดูครับ ผมคอมเมนต์ไว้เกือบทุกบรรทัดแล้ว
วิธีใช้ก็ execute ทั้งฟังก์ชั่นก่อนทีนึง แล้ว เลือก vertex หรือ เลือก transform 2 อัน(อันแรกคือ mesh อันสองคือ locator หรือกรุ๊ปอะไรก็ได้) แล้วพิม
createFollicleFromPosition()
ปล. จะใช้สคริปต้องมี PyMel นะเออ
THE LINK TO THE SCRIPT
Subscribe to:
Posts (Atom)