Creating a Mesh Procedurally

I would like to write a PyMel script that generates a single triangle mesh. Ultimately, I want to understand how to create a mesh in Maya via PyMell using raw verts and normals.

I know that I can create a sphere mesh like so


mySphere = pm.polySphere();

But if I want to make it in a more explicit fashion, I could to the following



import pymel.core as pm;

pm.newFile( force = True );
myTransform = pm.createNode( "transform", name="MyTransform" );
myShape = pm.createNode( "mesh", name="MyShape", parent=myTransform );
myPolySphere = pm.createNode( "polySphere", name="MyPolySphere" );

pm.connectAttr("MyPolySphere.output", "MyShape.inMesh" );

myGroup = pm.group( empty=True, name="MyGroup" );
pm.parent( myTransform, myGroup );

pm.setAttr( "{0}.radius".format(myPolySphere), 10.0 );


What I have learned is that I need a Shape/Mesh node which holds all the raw verts/normals/face information.
However the polySphere node is the mesh generator. In other words, it calculates the position of the verts on the sphere based on parameters passed into the node such as the Sphere’s radius.

Basically I want to do the same thing except I want to inject my own raw vert/normals/faces into my shape node. I want to start by creating a simple triangle. How would I go about this? How do I pass my own vert/normals/faces into a Mesh’s inMesh property? Thanks!

Maybe all I need to know is how to create a new “MeshVertex”
http://download.autodesk.com/us/maya/2011help/pymel/generated/classes/pymel.core.general/pymel.core.general.MeshVertex.html?highlight=meshvertex#pymel.core.general.MeshVertex

For example, is there are way to do the following?


import pymel.core as pm;

mesh = pm.createNode( "mesh", "MyMesh" );
# The following line does not work but how can I assign the vertex position "0,0,0" to the first vertex slot in the "MyMesh" object?
mesh.vrts[0] = MeshVertex( [0,0,0] );


For those interested, I was able to come up with a round about way of creating a triangle by starting with a cube, triangulating it, and then deleting all the faces except for the first one.


import pymel.core as pm;

pm.newFile( force=True );
transformObj, polyCube = pm.polyCube(name="MyCube");
pm.polyTriangulate( transformObj );

faceCount = pm.polyEvaluate( transformObj, face=True );
pm.polyDelFacet( "{0}.f[1:{1}]".format( transformObj, faceCount ) );

meshObj = transformObj.getShape();

# Position the triangle's verticies however you want.
pm.move( -1,0,0,    meshObj.vtx[0] );
pm.move( 0,1,0,     meshObj.vtx[1] );
pm.move( 1,0,0,     meshObj.vtx[2] );

Soon after writing this solution, I found the following command
polyCreateFacet
http://download.autodesk.com/us/maya/2011help/pymel/generated/functions/pymel.core.modeling/pymel.core.modeling.polyCreateFacet.html#pymel.core.modeling.polyCreateFacet

polyCreateFacet is probably much closer to what I want so I am going to try to rewrite the code to use that function instead of stripping down a poly cube.

For anyone interested, I was able to rewrite my previous code snippet in a much more direct fashion useing the createPolyFacet function like so,


import pymel.core as pm;

pm.newFile( force=True );


# make a triangle
verticies = [
(-1,0,0),
(0,1,0),
(1,0,0)
];

mesh = pm.polyCreateFacet(point=verticies, name="MyTriangle");
pm.move( -2,0,0, mesh );

# make a quad
verticies = [
(-1,0,0),
(-1,1,0),
(1,1,0),
(1,0,0)
];

mesh = pm.polyCreateFacet(point=verticies, name="MyQuad" );
pm.move( 2,0,0, mesh );

I am not quite sure how to specify the normals and colors but it looks like createPolyFacet does allow for assigning uvs as well. Very cool!

If you want to make a mesh, run a polyCreateFacet for each triangle, then grab the results, polyUnite them, polyMergeVert them, and delete their history.

Unfortunately this is slow :frowning:

You can speed it up a bit by wrapping it in a no-undo block

[QUOTE=Theodox;27417]If you want to make a mesh, run a polyCreateFacet for each triangle, then grab the results, polyUnite them, polyMergeVert them, and delete their history.

Unfortunately this is slow :frowning:

You can speed it up a bit by wrapping it in a no-undo block[/QUOTE]

You know, reading this makes me feel better about having to do that for a collision generator I made long ago.

You can make the stupid things the ‘right’ way in the API; it’s also much faster.-- but it has to be done via a plugin. If you run the exact same code outside an MPXPlugin you can never undo it. It’s such a wierd oversight in the maya command set :frowning:

Thanks for the feedback guys! Does “polyUnite” or “polyMergeVert” add the normals?

Thanks for the feedback guys! Does “polyUnite” or “polyMergeVert” add the normals?

So polyCreateFacet just creates faces, which have normal values, the unite will turn them all into one shape node, and the merge will remove duplicate vertices.

Its been awhile since I’ve built a mesh like this, but I believe the edges will just be set to ‘hard’ shading, which would mean that none of the vertex normals get averaged, but you can mess around with the polySoftEdge to smooth / soften edges as you need.

Wow that is very useful info R.White! Thanks!

the maya ascii file shows you how to assign data directly to mesh structures. i use this to assign skinweights, much faster than skinPercent. I have not tried this in python, probably works ok

createNode mesh -n “middle_mShape” -p “middle_m”;
setAttr -k off “.v”;
setAttr “.iog[0].og[0].gcl” -type “componentList” 1 “f[0:3]”;
setAttr “.vir” yes;
setAttr “.vif” yes;
setAttr “.uvst[0].uvsn” -type “string” “map1”;
setAttr -s 9 “.uvst[0].uvsp[0:8]” -type “float2” 0 0.25 0.11111111
0.25 0.11111111 0.375 0 0.375 0.22222222 0.25 0.22222222 0.375 0.11111111 0.5 0 0.5
0.22222222 0.5;
setAttr “.cuvs” -type “string” “map1”;
setAttr “.dcc” -type “string” “Ambient+Diffuse”;
setAttr “.covm[0]” 0 1 1;
setAttr “.cdvm[0]” 0 1 1;
setAttr -s 9 “.pt[0:8]” -type “float3” 0.89999998 1.9808265 -0.90187621
0 1.9808265 -0.876656 -0.89999998 1.9808265 -0.90187621 0.89999998 0.96832651 -0.90187621
0 0.96832651 -0.876656 -0.89999998 0.96832651 -0.90187621 0.89999998 -0.044173438
-0.90187621 0 -0.044173438 -0.876656 -0.89999998 -0.044173438 -0.90187621;
setAttr -s 9 “.vt[0:8]” -1 -2.25 0 0 -2.25 0 1 -2.25 0 -1 -1.125 0
0 -1.125 0 1 -1.125 0 -1 0 0 0 0 0 1 0 0;
setAttr -s 12 “.ed[0:11]” 0 1 0 0 3 0 1 2 0 1 4 1 2 5 0 3 4 1 3 6 0
4 5 1 4 7 1 5 8 0 6 7 0 7 8 0;
setAttr -s 4 -ch 16 “.fc[0:3]” -type “polyFaces”
f 4 0 3 -6 -2
mu 0 4 0 1 2 3
f 4 2 4 -8 -4
mu 0 4 1 4 5 2
f 4 5 8 -11 -7
mu 0 4 3 2 6 7
f 4 7 9 -12 -9
mu 0 4 2 5 8 6;
setAttr “.cd” -type “dataPolyComponent” Index_Data Edge 0 ;
setAttr “.cvd” -type “dataPolyComponent” Index_Data Vertex 0 ;
setAttr “.hfd” -type “dataPolyComponent” Index_Data Face 0 ;

1 Like