2015-09-14 49 views
1

我一般編程Unity3D相關的東西,我還是很新的Maya的python API。如何在Maya中獲取正常臉部平均值?

我試圖做的是獲得當前選擇的面法線平均:

What I need to achieve

我實現到現在爲止是根據移動機械手定位於立方體的一個實例。

Code result

import maya.cmds as cmds 
import re #regular expression 

# get current position of the move manipulator 
pos = cmds.manipMoveContext('Move', q=True, p=True) 

# get the current selection 
selection = cmds.ls(sl=True) 

# trying to get the face normal angles of the current selection 
polyInfo = cmds.polyInfo(selection, fn=True) 
polyInfoArray = re.findall(r"[\w.-]+", polyInfo[0]) # convert the string to array with regular expression 
polyInfoX = float(polyInfoArray[2]) 
polyInfoY = float(polyInfoArray[3]) 
polyInfoZ = float(polyInfoArray[4]) 

print str(polyInfoX) + ', ' + str(polyInfoY) + ', ' + str(polyInfoZ) 

target = cmds.polyCube() 

cmds.move(pos[0], pos[1], pos[2], target) 

現在我唯一需要的是旋轉立方體的選擇

請面對平均法線,這方面有任何想法?

Maya有任何方法給我這些角度?我嘗試使用polyInfo與面法線旋轉,但我覺得我失去了一些東西......

編輯:

最終的解決方案(感謝@theodox)

import maya.cmds as cmds 

# get current position of the move manipulator 
pos = cmds.manipMoveContext('Move', query=True, position=True) 

# get the current selection 
selection = cmds.ls(selection=True) 

target = cmds.polyCube() 

cmds.move(pos[0], pos[1], pos[2], target) 

constr = cmds.normalConstraint(selection, target, aimVector = (0,0,1), worldUpType= 0) 
cmds.delete(constr) 

回答

1

可以實現你想要什麼而不解決問題中的問題。節點將使對象朝向最接近的可用面法線。如果你只是想要臉部對齊,你可以定位你的對象,然後創建並立即刪除一個normalConstraint。最小版本是:

constr = cmds.normalConstraint('reference_object', 
           'object_to_align', 
           aimVector = (0,0,1), 
           worldUpType= 0) 
cmds.delete(constr) 

其中目標向量是將與表面對齊的局部軸。 (如何進行對齊有很多選項,您應該查看normalConstraint命令中的文檔以獲取更多信息)。

要真正讓臉部正常,您可以使用polyNormalPerVertex命令來獲取臉部的頂點臉部法線(它們會以數字的形式返回,因此您無需對其進行正則表達式處理,您需要平均它們:

def face_normal(face): 
    vtxface = cmds.polyListComponentConversion(face, tvf = True) 
    xes = cmds.polyNormalPerVertex(vtxface, q=True, x =True) 
    yes = cmds.polyNormalPerVertex(vtxface, q=True, y =True) 
    zes = cmds.polyNormalPerVertex(vtxface, q=True, z =True) 
    divisor = 1.0/len(xes) 
    return sum(xes)* divisor, sum(yes) * divisor, sum(zes) * divisor 

但是這些都是在局部空間將它們轉換爲世界空間的唯一方法是將它們插入載體(使用Pymel或Maya的API),然後將它們相乘,對目標矩陣(也使用API​​)一旦你有了一個世界空間矢量,你可以用這個矢量作爲'目標矢量',世界向上並且這些矢量作爲一個新的矩陣f或你想要對齊的對象..

......所有這些都不是超級很難,但如果你還不知道API的話,這將是很多工作。這就是爲什麼我會首先嚐試正常的限制技巧。

+0

非常感謝@theodox!正常的約束解決了我的問題就像一個魅力,感謝替代! –