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)
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))
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')
)
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…
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:
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()