def get_matrix_from_face(mfn_mesh, point, face_id):
"""
!@Brief Get matrix from point position and face id.
Take normal, tangent, binormal of all face vertex and average it.
@type mfn_mesh: OpenMaya.MFnMesh
@param mfn_mesh: MFnMesh for get point orientation
@type point: MFloatPoint
@param point: Position on face.
@type face_id: int
@param face_id: Face id
@rtype: pymel.Core.datatypes.Matrix
@return: Matrix found
"""
# Get normal
normals = OpenMaya.MFloatVectorArray()
mfn_mesh.getFaceVertexNormals(face_id, normals)
normal = average_vector_array(normals)
# Get tangent
tangents = OpenMaya.MFloatVectorArray()
mfn_mesh.getFaceVertexTangents(face_id, tangents)
tangent = average_vector_array(tangents)
# Get binormal
binormal = tangent ^ normal
binormal.normalize()
# Force normal perpendicalary
normal = binormal ^ tangent
normal.normalize()
# Create matrix
from pymel import core as pmc
matrix = pmc.datatypes.Matrix(
[tangent.x, tangent.y, tangent.z, 0.0],
[normal.x, normal.y, normal.z, 0.0],
[binormal.x, binormal.y, binormal.z, 0.0],
[point.x, point.y, point.z, 1.0]
)
return matrix
def average_vector_array(vector_array):
"""
!@Brief Average MVector array
@type vector_array: OpenMaya.MVectorArray / OpenMaya.MFloatVectorArray
:param vector_array: Vector array to average
@rtype: OpenMaya.MVector
@return: Vector average
"""
if not isinstance(vector_array, (OpenMaya.MVectorArray, OpenMaya.MFloatVectorArray)):
raise BaseException("Invalid argument !!!\n\tArgument must be a MVectorArray.")
m_vector = OpenMaya.MVector()
for idx in xrange(vector_array.length()):
m_vector += OpenMaya.MVector(vector_array[idx])
m_vector /= vector_array.length()
m_vector.normalize()
return m_vector