PyMel edges list

I have a polygonal geometry and I select pairs of edges manually.
Then I run the code:

import pymel.core as pm

edges = pm.ls(sl = 1)
print edges

For one pair of selected edges I get:
[MeshEdge(u’pCube3Shape.e[373:374]’)]
For another:
[MeshEdge(u’pCube3Shape.e[292]’), MeshEdge(u’pCube3Shape.e[303]’)]

How can I get the first list in the same way as a second (each edge should be a separate object [373] [374] instead of [373:374])?

Why I need this. I need to polyDuplicateEdge() for each pair of manually selected edges and it does not work if pair of edges has consecutive numbers:

listEdges = pm.ls(sl = 1)
listDone = []

for edge in listEdges:
    if not edge in listDone:
        connected = edge.connectedEdges()
        for i in connected:
            if i in listEdges:
                listDone.append(i)
                listDone.append(edge)
                pm.polyDuplicateEdge([edge, i], of=0.1)

try pm.ls(selected=True, flatten=True) the flatten flag will always return the list unpacked into individual edges.

2 Likes

Thanks, that’s works!
Is there any way to get a list of edges I get after polyDuplicateEdge() command?

It looks like it returns the node, you might be able to do a listConnections on the node, but that’s just a wild guess.

1 Like

Well… polyDuplicateEdge() returns a list of polyDuplicateEdge nodes, and I did not find a way to get new edges from those nodes.

I am trying to get new edges (or vertexes of edges) after polyDuplicateEdge() command (selected edges on the bottom image (they were selected manually))

The only way I see is not very elegant:

  • get the list of all edges before the command
  • get the list of all edges after the command
  • find the difference

Is there any better options?

Off the top of my head, I don’t believe so.
Given that list connections only returns the nodes, and not the components.

Exactly! So I am looking for options to get new edges in a different way…

Serious suggestion: Houdini? If you are really trying to get procedural with your modelling.

Otherwise, if I were trying to hack a solution without any research or checking the Maya API: Store the point positions before the split, and then re-find the old edge via proximity to that, and then find the closest edges to that. I assume they would be the closest edges, at least usually.

If this helps at all, this gets the closest point on a mesh to a position. You can pass a PyMEL datatype.Vector to pos
This is a really old script, so it is the old OpenMaya API. Tested in Maya 2018.5

import maya.OpenMaya as om
import pymel.core as pm

def select_closest_vert(geo, pos):
	space = om.MSpace.kWorld

	#get the MFnMesh of my polygon object
	dagPath = om.MDagPath()
	selection = om.MSelectionList()
	selection.add(geo.name())
	selection.getDagPath(0, dagPath)
	mfnMesh = om.MFnMesh(dagPath)

	pointA = om.MPoint(pos.x, pos.y, pos.z)
	pointB = om.MPoint()

	util = om.MScriptUtil()
	util.createFromInt(0)
	idPointer = util.asIntPtr()

	mfnMesh.getClosestPoint(pointA, pointB, space, idPointer)
	idx = om.MScriptUtil(idPointer).asInt()

	# at this point, idx only gets us to the nearest polygon.
	faceVerts = [geo.vtx[i] for i in geo.f[idx].getVertices()]
	def returnDist(item):
		return (pos - item.getPosition(space='world')).length()
	nearestPoints = [v for v in sorted(faceVerts,key=returnDist)]
	return nearestPoints[0]

closestPoint = select_closest_vert(
        pm.PyNode('pCube1'),
        pm.PyNode('locator1').getTranslation(space='world')
        )
2 Likes

Right, Houdini is a much more pleasant tool to work with geometry in particular and with 3D in general. Honestly, I have no Idea why anybody uses Maya or other 3d software these days (cos transition will be too expensive and painful for studios with a huge pipeline?) Unfortunately, our modeling department uses Maya so I made POC in Houdini and trying to recreate this in Maya to provide them requested tool.

I decide to go with closest points as well, referencing the Djx article “get closest vertex in Maya using python” (looks like the same solution that you provided). Let’s see what I will stuck with next…

Ah yes, that is likely where I got that script. I remember that page.

The way he does minLength =None caused bugs where it would sometimes return the wrong point for me. That was years ago. I forget the specifics.

I am reinventing the wheel and creating my own algorithm of getting the closest points.
It is working but slow, I will examine and optimize later, when I will finish basic functionality.

Here is what I have as source, what I done with a script and what do I need to get (split the top ace):

And this is more tricky then I expected! Cant understand how polySplit() is working, for one pair of edges i need to set distance to 0, for another to 1 to get same result:

pm.polySplit( ip=[(148, 0), (188, 0)] )
pm.polySplit( ip=[(125, 1), (117, 1)] )

But how can I determinate either 0 or 1 should I use for certain edge pair…

Couple of quick guesses:
Maybe you need to input your edge pairs in the same sorted order? I can see in your example 148 < 188, but 125 > 117. Maybe that matters?

Maybe look at the vert indexes for your edge pairs, and see if the order of the vertices on each edge lets you figure that out?

[EDIT]
Also, if you’ve got numpy available, getting the closest vert can be done very quickly. I ran this code on a 633k vert mesh, and it took about 0.05 seconds.

from maya import OpenMaya as om, cmds
import numpy as np
from ctypes import c_float

def getNumpyVerts(meshName):
    sel = om.MSelectionList()
    sel.add(meshName)
    dagPath = om.MDagPath()
    sel.getDagPath(0, dagPath)

    fnMesh = om.MFnMesh(dagPath)
    # rawPts is a SWIG float pointer
    rawPts = fnMesh.getRawPoints()
    ptCount = fnMesh.numVertices()

    cta = (c_float * 3 * ptCount).from_address(int(rawPts))
    out = np.ctypeslib.as_array(cta)

    # for safety, make a copy of out so I don't corrupt memory
    return np.copy(out)

def getClosest(pt, meshName):
    verts = getNumpyVerts(meshName)
    deltas = verts - np.array(pt)
    distSq = (deltas*deltas).sum(axis=1)
    closestVertIdx = np.argmin(distSq)
    return closestVertIdx

import time
start = time.time()
print "Closest Index", getClosest((1.5, 0, 0), 'pSphere1')
print "Took", start - time.time()
2 Likes