import maya.OpenMaya as OpenMaya
import maya.mel as mel
def get_polygon_data(mObj):
conpolyList = []
num_of_vers_per_poly = []
vertex_positions = OpenMaya.MPointArray()
# Create an iterator for the polygons of the mesh
iterPolys = OpenMaya.MItMeshPolygon( mObj )
vtx_offest = 0
# Iterate through polys on current mesh
while not iterPolys.isDone():
verts_positions = OpenMaya.MPointArray ()
iterPolys.getPoints( verts_positions )
verts = OpenMaya.MIntArray()
iterPolys.getVertices( verts )
for v in reversed(verts):
conpolyList.append (v)
num_of_vers_per_poly.append(verts.length())
iterPolys.next()
iterVertex = OpenMaya.MItMeshVertex( mObj)
while not iterVertex.isDone():
mpoint = iterVertex.position()
vertex_positions.append(mpoint)
iterVertex.next()
vertex_positions = convert_mpoint_array_to_float_list_array(vertex_positions)
return vertex_positions, num_of_vers_per_poly, conpolyList
def get_mesh_creation_data(mesh_dag_path):
"""
Returns all mesh data, which needed to recreate surface.
:param mesh_dag_path: string with node dag_path
:returns result: dict with all mesh creation data.
"""
result = dict()
selection_list = OpenMaya.MSelectionList()
selection_list.add(mesh_dag_path)
dag_path = OpenMaya.MDagPath()
mobject = OpenMaya.MObject()
selection_list.getDagPath(0, dag_path)
selection_list.getDependNode(0, mobject)
mfn_mesh = OpenMaya.MFnMesh(dag_path)
vertex_positions, number_of_vertices_per_polygon, polygon_vertex_ids = get_polygon_data(mfn_mesh.object())
result["vertex_positions_raw_data"] = vertex_positions
result["number_of_vertices_per_polygon"] = number_of_vertices_per_polygon
result["vertex_indexes_per_polygon"] = polygon_vertex_ids
result["polygon_count"] = mfn_mesh.numPolygons()
return result
def create_mesh(mesh_creation_data, parent_mobj = None):
polygon_count = mesh_creation_data["polygon_count"]
vertex_positions_raw_data = mesh_creation_data["vertex_positions_raw_data"]
number_of_vertices_per_polygon = mesh_creation_data["number_of_vertices_per_polygon"]
vertex_indexes_per_polygon = mesh_creation_data["vertex_indexes_per_polygon"]
vertex_positions_mfloatpoints = convert_float_lists_array_to_mpoints_array(vertex_positions_raw_data)
meshFn = OpenMaya.MFnMesh()
try:
vertex_count = vertex_positions_mfloatpoints.length()
each_polygon_vertex_count = convert_floats_to_MIntArray(number_of_vertices_per_polygon)
polygon_connects = convert_floats_to_MIntArray(vertex_indexes_per_polygon)
createdMobject = meshFn.create(vertex_count, polygon_count, vertex_positions_mfloatpoints, each_polygon_vertex_count, polygon_connects)
return createdMobject
except Exception as e:
print(e)
def get_polygons_vertex_data(mfn_mesh):
"""
Returns polygon vertex ids for given mesh.
(what vertex each polygon have, vertex defined by vertex id)
:param mesh: string dag path to mesh
:returns list: list of vertex id's per polygon
"""
if mfn_mesh:
connected_polygons_list = []
number_of_vertices_per_polygon = []
# This shows how to use the MItMeshPolygon class to work with meshes
# Create an iterator for the polygons of the mesh
polys_iterator = OpenMaya.MItMeshPolygon( mfn_mesh.object() )
# Iterate through polys on current mesh
while not polys_iterator.isDone():
index_connected_faces = OpenMaya.MIntArray()
polys_iterator.getConnectedFaces(index_connected_faces)
for i in range( index_connected_faces.length() ):
connected_polygons_list.append (index_connected_faces[i])
number_of_vertices_per_polygon.append(index_connected_faces.length())
polys_iterator.next()
return connected_polygons_list, number_of_vertices_per_polygon
def get_vertex_pos_of_mesh(mfn_mesh, as_mpoint_array=False):
"""
Returns vertex positions of given mesh.
:param mesh: string dag path to mesh
:param as_mpoint_array: if True, function will return vertex positions as array of OpenMaya.MPoint objects,
by defaul False mean it will return vertex positions as as floats array
:returns list: by default returns list of integers with point coordinates, with as_mpoint_array=True will returns list of MPoint objects.
"""
if mfn_mesh:
mpoint_array = OpenMaya.MPointArray()
mfn_mesh.getPoints(mpoint_array)
if as_mpoint_array:
return mpoint_array
else:
point_list = convert_mpoint_array_to_float_list_array(mpoint_array)
return point_list
def convert_mpoint_array_to_float_list_array(mpoints_array):
floats_list = []
if mpoints_array:
for i in range(mpoints_array.length()):
mpoint = mpoints_array[i]
temp_list = []
for j in range(4):
temp_list.append(mpoint(j))
floats_list.append(temp_list)
return floats_list
def convert_float_lists_array_to_mpoints_array(float_list_array):
"""
Converts given list of lists with float coordinates to list of MPoint objects
:param float_list_array: list of integer lists
:returns vertex_positions_mpoints: list of MPoint objects.
"""
mfloat_point_array = OpenMaya.MFloatPointArray()
if float_list_array:
for vertex_coords_list in float_list_array:
mpoint_object = OpenMaya.MFloatPoint(*vertex_coords_list)
mfloat_point_array.append(mpoint_object)
return mfloat_point_array
def convert_floats_to_MIntArray(floats_array):
m_int_array_obj = OpenMaya.MIntArray()
if floats_array:
for v in floats_array:
m_int_array_obj.append(v)
return m_int_array_obj
mel.eval("polySphere -r 1 -sx 20 -sy 20 -ax 0 1 0 -cuv 2 -ch 1;")
# mesh to test recreation
mesh_shape_name = "pSphere1"
mesh_creation_data = get_mesh_creation_data(mesh_shape_name)
# returned mobj of recreated mesh
mobj = create_mesh(mesh_creation_data)