Announcements

Between mid-October and November, the content on AREA will be relocated to the Autodesk Community M&E Hub and the Autodesk Community Gallery. Learn more HERE.

How to move the pivot to the center of mass?

How to move the pivot to the center of mass?

ivan.antonovRTYBF
Explorer Explorer
1,864 Views
2 Replies
Message 1 of 3

How to move the pivot to the center of mass?

ivan.antonovRTYBF
Explorer
Explorer

Hi there.

I'd like to know if there is a way to put the pivot point to the center of mass of an object/selection.

«Modify>Center Pivot» puts the pivot point to the center of the bounding box, which is different and works terribly in some cases (like a single triangle for example).

0 Likes
Accepted solutions (1)
1,865 Views
2 Replies
Replies (2)
Message 2 of 3

Kahylan
Advisor
Advisor

Hi!

 

There is no default option to set your pivot to your center of mass, because that calculation can become very heavy and slow if you are working with millions of polygons and could potentially crash maya. But you can do so with a custom script.

 

This is a custom python script that centers the pivot of selected objects to the center of their collected mass (by calculation the barycenter of all their vertices):

import maya.cmds as mc

def centerToBarycenter():
    sel = mc.ls(sl = True, o = True)
    hil = mc.ls(hl = True)
    toBeProcessed = []
    for h in hil:
        if h in sel:
            sel.remove(h)
 
    vtxList = mc.filterExpand(sm=31)
    
    if vtxList == None:
        vtxList = []
    
    for t in toBeProcessed:
        vc = mc.ls(t +".vtx[*]", fl = True)
        if vc != []:
            vtxList = vtxList + vc
    
    xC = []
    yC = []
    zC = []
    
    for v in vtxList:
        pos = mc.xform(v, q= True, t = True, ws = True)
        xC.append(pos[0])
        yC.append(pos[1])
        zC.append(pos[2])
    
    posBC = (sum(xC)/len(xC),sum(yC)/len(yC),sum(zC)/len(zC))  
    for s in sel:
        if mc.objectType(s) == "mesh":
            s = mc.listRelatives(s, p = True)[0] 
        mc.xform(s, piv = posBC, ws = True)

centerToBarycenter() 

It's a script I wrote a while back as a training exercise and therefore is rather limited (only works on geometric objects, everything else is ignored). But it could be easily expanded to all your needs.

But as already mentioned, if you have high poly counts, proceed with caution.

 

I hope it helps!

Message 3 of 3

Kahylan
Advisor
Advisor
Accepted solution

I realised that there was a small mistake in the script I posted before. It worked well with Object selection or with component selection, but not with the two combined.

 

So I fixed that mistake, and since I had some time and was already on it I also expanded its functionality to also include nurbsCurves and nurbsSurfaces.

 

import maya.cmds as mc

def centerToBarycenter():
    sel = mc.ls(sl = True, o = True)
    hil = mc.ls(hl = True)

    toBeProcessed = []
    for s in sel:
        if mc.objectType(s) == "mesh" or mc.objectType(s) == "nurbsSurface" or mc.objectType(s) == "nurbsCurve":
            s = mc.listRelatives(s, p= True)[0]
        if s not in hil:
            toBeProcessed.append(s)
    
    vtxList = mc.filterExpand(sm=31)
    cvList = mc.filterExpand(sm = 28)
    
    if vtxList == None:
        vtxList = []
    if cvList == None:
        cvList = []
    compList = cvList +vtxList
    
    for t in toBeProcessed:
        vc = mc.ls(t +".vtx[*]", fl = True)
        cv = mc.ls(t +".cv[*]", fl = True)
        cvs = mc.ls(t +".cv[*][*]", fl = True)
        
        compList = compList + vc + cv + cvs
    
    xC = []
    yC = []
    zC = []
    
    for v in compList:
        pos = mc.xform(v, q= True, t = True, ws = True)
        xC.append(pos[0])
        yC.append(pos[1])
        zC.append(pos[2])
    if len(compList) != 0:
        posBC = (sum(xC)/len(xC),sum(yC)/len(yC),sum(zC)/len(zC))  
        for s in sel:
            if mc.objectType(s) == "mesh" or mc.objectType(s) == "nurbsSurface" or mc.objectType(s) == "nurbsCurve":
                s = mc.listRelatives(s, p = True)[0] 
            mc.xform(s, piv = posBC, ws = True)

centerToBarycenter()