[Closed] Removing Edges and Vertices
Hello again!
I'm looking for a way to remove an edgeloop and their shared vertices from a poly.
Like pressing the 'remove' with CTRL pressed, but in maxscript.
Unfortunately this function is not directly available, so I have to remove edges and verts seperately.
However it seems that my vertex selection gets scrambled as soon as I use [color=White][b]$.buttonOp #remove[/b] [/color]to remove the edges.
It seems that after removing the edges, the vertices get sorted and have a different order.
The problem is that if I do this:
subObjectLevel = 2
$.buttonOp #selectEdgeLoop
$.convertSelection #Edge #Vertex
$.buttonOp #remove
subObjectLevel = 1
$.buttonOp #remove
It will also remove vertices on a star (where 3 or 5 loops meet), which will create polygons with 9 vertices and more. So I want to remove the star vertices from the vertex selection before removing.
Do you know a way to do this?
Hi harefort,
you cannot rely on edge and vertices indexing while adding or removing them, as you already found out, because they’re interactively changed. It is because you cannot have “holes” in vertex/edge/face list. If the poly object has 100 verts, and you delete the 50th, all the rest “shift” to “fill the gap”. I’m sorry to use so many double quotes, but the language is quite inaccurate, just to give the idea of what happens.
Stable selections can be achieved with flags. Look for polyop.setVertFlags and polyop.getVertsByFlag in MaxScript reference, just to mention a pair. The same works for edges and faces. You got 8 bit to set as you like from 25 to 32. Once an element, or a set of elements, is flagged, you can retrieve it no matter if its index has changed. So you can:
- get the edge loop
- get the verts along the loop and flag them
- remove the edges along the loop
- retrieve flagged verts and remove them by flag value
I hope it helps.
- Enrico
Thanks a ton! This seems to work … at least the right vertices disappear.
However, there’s still a sharp bend on the edges, right where the vertices used to be.
And when I use grow selection on a vertex next to a deleted vertex, it does not grow the selection in the direction of the recently deleted vertex.
So it seems like the vertex has been flagged as deleted but not really been removed from the mesh data.
Sheesh! This is more complicated than one would expect. :banghead:
How do you delete verts? I usually do it with the method:
(
iFlag = bit.set 0 32 true
polyOp.setVertFlags EditPoly baVertToRemove iFlag mask:iFlag undoable:true
EditPoly.remove selLevel:#Vertex flag:iFlag
)
This way never gave me problem. Don’t mess with private bits from 2 to 24, even if they have an explicit meaning like dead verts. Bit 1 can be quite safely used to manage selection.
- Enrico
Thanks again!
Works like a charm now.
But here's the real challenge ... if you can solve this, you're my hero! ;)
I try to make all my poly tools work with Editable_Poly and Edit_Poly and they sadly don't share many functions.
For some reason polyOps don't work with an Edit_Poly modifier.
For example:
polyOp.setVertFlags sPoly (aVerts-aStarVerts) iFlag mask:iFlag
-- sPoly: Edit_Poly:Edit Poly
>> MAXScript Rollout Handler Exception: -- Runtime error: EPoly operation on non-Editable Poly: Edit_Poly:Edit Poly <<
I encounter this problem alot and often end up creating helper functions that automatically chose the proper operation, depending on whether it’s called for an Editable_Poly or an Edit_Poly.
Maybe I’m doing something wrong, because the polyOps doc says that it should work with Edit_Poly aswell.
Any Ideas?
Hi harefort,
I wish I could help you, but I don’t know the answer. I stumbled upon the same issue, and couldn’t solve it by scripting. When I need to manipulate editable poly topology, my only solution is to work on node.baseObject because every modifier added (anyone correct me if I’m wrong) evaluates the object as mesh and not poly (i.e. MNMesh in sdk) because it’s internally faster to handle, or as the specific modifier requires, like the Edit_Poly.
The MaxScript reference in Edit_Poly Modifier page, states in example, about removing vertices:
Remove Vertex/Edge
No properties related to this feature are exposed. To press the Remove button, see the #RemoveVertex and #RemoveEdge operations in EditPolyMod Interface – Operation Methods
which leads me to think that MaxScript can’t do much more than allow manipulation of the Edit_Poly Modifier interface.
Regarding polyOp and polyOps be careful, they’re not aliases, but two diffrent structures holding different methods. You can see them by simply typing “polyOp” and “polyOps” in the listener. You will notice that polyOp has all the methods to modify the base topology, while polyOps has methods that represent Edit_Poly Modifier actions, like “startExtrudeFace” or “meshsmooth”. So if you got an Editable Poly object with some modifiers on the stack and an Edit_Poly Modifier and invoke a polyOp method, it is applied to the Editable_Poly baseObject, or throws an error.
This is what I got from experience and could be inaccurate or wrong, I’d really like to know if anyone knows a way to get around this problem, or if I missed something trivial too. Thanks.
- Enrico
Edit_Poly and Editable poly do a potential to drive me nuts.
Here's what I'm doing now and it works for both:
sPoly.buttonOp #selectEdgeLoop
sPoly.convertSelection #Edge #Vertex
local aVerts = sPoly.getSelection #Vertex
local aStarVerts = #{}
for each in aVerts do
(
local iEdgeCount = sPoly.getVertexEdgeCount each
if iEdgeCount != 4 then
(
if iEdgeCount == (sPoly.getVertexFaceCount each) then
(
append aStarVerts each
)
)
)
sPoly.setSelection #Vertex (aVerts-aStarVerts)
if classOf sPoly == Editable_Poly then (sPoly.buttonOp #remove) else (sPoly.buttonOp #RemoveEdge)
subObjectLevel = 1
if classOf sPoly == Editable_Poly then (sPoly.buttonOp #remove) else (sPoly.buttonOp #RemoveVertex)
subObjectLevel = 2
The difference is that it removes the vertices on the stars before doing any of the remove operations. So I don’t have to retrieve the vertex selection after removing the edges.