Creating a curve-based wireframe

243 views
Skip to first unread message

likage

unread,
May 31, 2017, 7:48:17 PM5/31/17
to Python Programming for Autodesk Maya
I am trying to 'extract and convert' all the edges of the polygon (based on selection) into curves, then parent the curves as one. This is like a curve-based wireframe model.

While Maya has a functionality that allows all edges to be converted into curves, but the functionality - "Polygon Edges to Curves", it works but not very ideal in my case as I would want all the created curves to be combined into one.

import maya.cmds as cmds
import pymel.core as pm

edges = cmds.filterExpand(cmds.polyListComponentConversion(te=1),sm=32,ex=1)
cur_list = []
for edge in edges:
    vtx = cmds.ls(cmds.polyListComponentConversion(edge,fe=1,tv=1),fl=1)
    p1 = cmds.pointPosition(vtx[0])
    p2 = cmds.pointPosition(vtx[1])
    created_curve = cmds.curve(d=1,p=(p1,p2))
    cur_list.append(created_curve)

# Select all the newly created curves
for cur in cur_list:
    cmds.select(cur, add=True)

# Get list of objects
shape_list = pm.ls(pm.listRelatives(c=True))
grp_list = pm.ls(pm.group(em=True, n='curve#'))
list_all = []
for obj in grp_list:
    list_all.extend(shape_list)
    list_all.extend(grp_list)

# Parent (shape) objects to one Curve
pm.select(list_all)
pm.parent(r=True, s=True)


While this code of mine does work, but if I tried to use it on a higher subdivision polygon, for example, create a normal pSphere and sets both its "Subdivisions Axis" and "Subdivisions Height" to 100, and execute the code I wrote.
What happens here is that:
  • Maya seems to be hanging
  • Took a very long while to be process (seems to be more than 1 hour plus before that current maya session of mine crashes.)
What can be done to minimize this long processing time? I am assuming that part of this 'long' time is due to the commands that I am using it to derive the vertex and creating them?

Justin Israel

unread,
May 31, 2017, 8:08:19 PM5/31/17
to python_in...@googlegroups.com
Did you profile the different parts of your code to know for sure?
 

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/71af008c-fbce-46a8-b150-887888e300bb%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Michael Boon

unread,
May 31, 2017, 8:37:45 PM5/31/17
to Python Programming for Autodesk Maya
Yeah read up on cProfile if you haven't already. It's really useful.

This section looks very slow
for edge in edges:
   vtx = cmds.ls(cmds.polyListComponentConversion(edge,fe=1,tv=1),fl=1)
   p1 = cmds.pointPosition(vtx[0])
   p2 = cmds.pointPosition(vtx[1])
   created_curve = cmds.curve(d=1,p=(p1,p2))
   cur_list.append(created_curve)
The cmds.ls would be slow, and the cmds.curve would too, but without profiling I'm not sure if both are significant here.
By switching to maya.api.OpenMaya and using an MFnMesh, you could iterate through the edges and find vertices much, much faster.
I assume you could also create one big, complex curve instead of thousands of small ones.  I'm not sure if you can do that using cmds or if you'd have to use the API for that too.

Some stuff further down might need work too. I think you can select all of cur_list in a single call, for example: cmds.select(cur_list)

This section:
for obj in grp_list:
   list_all.extend(shape_list)
   list_all.extend(grp_list)
will be very slow if grp_list is in the hundreds of thousands. 
I'm not sure you want to be adding both lists over and over again like that. You end up with a really gigantic list with a lot of duplicate entries, and it seems to be just so you can select it.

To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsub...@googlegroups.com.

Justin Israel

unread,
May 31, 2017, 9:07:34 PM5/31/17
to Python Programming for Autodesk Maya
Also:

for cur in cur_list:
    cmds.select(cur, add=True)

Can this not be done in a single call to select()?

To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/a5b72dff-2d28-40dd-9c98-5a02af3529b0%40googlegroups.com.

Andres Weber

unread,
Jun 1, 2017, 8:21:08 PM6/1/17
to Python Programming for Autodesk Maya
Okay so there's lots of things wrong with this code.  I'll start with the fact that every single call to selection (with the replace flag) updates your viewport and slows down your operation due to a screen refresh.  Secondly there's lots of redundant work with lists going on.  Lastly pymel is slow...if you can avoid it I would so I remade your code using only cmds.  The unnecessary use of pymel.core.ls just means you take even more time to encapsulate all your objects with PyNodes and pymel isn't even providing a benefit as you're not using it in an OOD way but just mimicking the same cmds usage style.  Secondly you'll find that passing actual arguments to your maya commands rather than relying on the selection to be correct at that specific moment that function gets executed is just rife with issues and possible bugs.  


And here's the code if you don't want to visit the link:
import maya.cmds as cmds


cmds
.refresh(suspend=True)
selection_edges
= cmds.filterExpand(cmds.polyListComponentConversion(te=1), sm=32, ex=1)

curve_transforms
= []
for edge in selection_edges:
    vertices
= cmds.ls(cmds.polyListComponentConversion(edge, fe=1, tv=1), fl=1)
    created_curve
= cmds.curve(d=1, p=[cmds.pointPosition(vertex) for vertex in vertices])
    curve_transforms
.append(created_curve)


# Get list of objects

shapes
= [cmds.listRelatives(transform)[0] for transform in curve_transforms]

curve_transform
= cmds.group(em=True)
pm
.parent(shapes, curve_transform, r=True, s=True)

cmds
.delete(curve_transforms)

cmds
.refresh(suspend=False)


I've kept your code using the same logic, just cleaned up a bit.  What Michael and Justin said were totally on the money.  Michael's suggestion would require a bit of time to develop that algorithm...I've personally wanted to take it on at many points but it's honestly not super simple so I moved on usually but he's totally correct.  The fact that there's so many curves being created and you have to reparent them etc means that's where your real computation time is being eaten up.  The fact that Maya needs to draw every single curve separately instead of one curve shape node is what's really going to screw you over in the end as well since this is literally the worst thing you can do to Maya.  It does NOT like it when you have tons of separate objects in your scene that draw to the viewport, no matter what type they are. 

This code falls down completely and slows to a trickle on objects denser than even something like 2k faces so unless you are only wireframing super simple objects, this is NOT the approach you want and you need to spend some time thinking about a more efficient way of building the curves.  Even just querying positions then ordering them properly etc to build one mega curve would be much, much faster especially using the API.  

If anyone on this list knows of an algorithm to build these edge following, smart curves I'm all ears, since as a rigger, it would be great to have my hands on that.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsub...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsub...@googlegroups.com.

zeth willie

unread,
Jun 2, 2017, 3:58:24 PM6/2/17
to Python Programming for Autodesk Maya
Just as an aside, since I know this a python for maya group and don't want to derail this into some kind of flame war, but stuff like this is ridiculously easy in Houdini as compared to Maya. Don't know if you're there yet, but at some point, it just becomes easier to say "f*** it" and bite the bullet for certain things and do them in another app. There's a free version, I believe, and the learning curve isn't too bad for relatively simple things like making procedure geo/curves and spitting them out as objs to use in Maya. Check out these guys for some interesting recipes and walkthroughs of stuff that I can't picture doing reasonably in Maya. Entagma: https://vimeo.com/174958114 (I can't remember if this specific video has exactly what you need, but it's in the neighborhood, I believe). 
<back to maya stuff. . .>

zeth willie

unread,
Jun 2, 2017, 4:00:47 PM6/2/17
to Python Programming for Autodesk Maya
Sorry for a second post, but also wanted to mention that I've used the Houdini Asset system in Maya for things like this with some success (I wasn't doing the Houdini bits on those jobs). So you can make pretty complicated actions automated with variable inputs. . . 
Reply all
Reply to author
Forward
0 new messages