Showing posts with label pymel. Show all posts
Showing posts with label pymel. Show all posts

Tuesday, October 7, 2014

Rearrange your geometry group for tidiness!

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

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()

Wednesday, April 2, 2014

Placing a follicle - the smart way.

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 นี้ ของคุณ .
ในคลิปเขาแนะนำเทคนิคน่าสนใจมากเกี่ยวกับการย้ายตำแหน่ง 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