这是一个解决方案,在上/下/左/右与网格变换(局部空间)对齐的规则下会相当一致,但也可能是世界空间。
我要做的第一件事是使用网格变换的平均面顶点位置,面法线和世界空间Y轴为每个网格面构建一个面相对坐标系。这涉及到一点向量数学,所以我将使用API来简化这一过程。第一部分将为每个人脸建立一个坐标系统,我们将把这些坐标系统存储到列表中供将来查询。见下文。
from maya import OpenMaya, cmds
meshTransform = 'polySphere'
meshShape = cmds.listRelatives(meshTransform, c=True)[0]
meshMatrix = cmds.xform(meshTransform, q=True, ws=True, matrix=True)
primaryUp = OpenMaya.MVector(*meshMatrix[4:7])
# have a secondary up vector for faces that are facing the same way as the original up
secondaryUp = OpenMaya.MVector(*meshMatrix[8:11])
sel = OpenMaya.MSelectionList()
sel.add(meshShape)
meshObj = OpenMaya.MObject()
sel.getDependNode(0, meshObj)
meshPolyIt = OpenMaya.MItMeshPolygon(meshObj)
faceNeighbors = []
faceCoordinates = []
while not meshPolyIt.isDone():
normal = OpenMaya.MVector()
meshPolyIt.getNormal(normal)
# use the seconary up if the normal is facing the same direction as the object Y
up = primaryUp if (1 - abs(primaryUp * normal)) > 0.001 else secondaryUp
center = meshPolyIt.center()
faceArray = OpenMaya.MIntArray()
meshPolyIt.getConnectedFaces(faceArray)
meshPolyIt.next()
faceNeighbors.append([faceArray[i] for i in range(faceArray.length())])
xAxis = up^normal
yAxis = normal^xAxis
matrixList = [xAxis.x, xAxis.y, xAxis.z, 0,
yAxis.x, yAxis.y, yAxis.z, 0,
normal.x, normal.y, normal.z, 0,
center.x, center.y, center.z, 1]
faceMatrix = OpenMaya.MMatrix()
OpenMaya.MScriptUtil.createMatrixFromList(matrixList, faceMatrix)
faceCoordinates.append(faceMatrix)
这些函数将查找并返回哪个面相对于面向特定方向(X和Y)的面。这使用点积来查看哪个面更具特定方向。这应该适用于任意数量的面,但它只会返回一个面朝大多数方向的面。
def getUpFace(faceIndex):
return getDirectionalFace(faceIndex, OpenMaya.MVector(0,1,0))
def getDownFace(faceIndex):
return getDirectionalFace(faceIndex, OpenMaya.MVector(0,-1,0))
def getRightFace(faceIndex):
return getDirectionalFace(faceIndex, OpenMaya.MVector(1,0,0))
def getLeftFace(faceIndex):
return getDirectionalFace(faceIndex, OpenMaya.MVector(-1,0,0))
def getDirectionalFace(faceIndex, axis):
faceMatrix = faceCoordinates[faceIndex]
closestDotProd = -1.0
nextFace = -1
for n in faceNeighbors[faceIndex]:
nMatrix = faceCoordinates[n] * faceMatrix.inverse()
nVector = OpenMaya.MVector(nMatrix(3,0), nMatrix(3,1), nMatrix(3,2))
dp = nVector * axis
if dp > closestDotProd:
closestDotProd = dp
nextFace = n
return nextFace
所以,你会这样称呼它:
getUpFace(123)
用数字为你想要得到的脸是“向上”从表面看来指数。
试试看看它是否满足您的需求。
所以不喜欢的种植选择?什么决定了他们的“方向”?他们的立场? –
我更新了与我的问题的图像示例问题,所以问题可以更好地理解。 – Dimitar
你需要考虑的是你用什么标准来确定什么是左/右/上/下。除非你的网格预定有4条边并且在一个公共轴上对齐,否则你需要提供“up”的定义。这个问题缺少这个关键要求来提供有用的答案。 – scottiedoo