[Closed] Weld Border edges/vertices from different elements
Helo guys,
Let’s say I have a object with many many faces :
- explode this object in smaller object of X faces
- do some interactive operation (vertex painting here)
- reattach all the objects in one single object
Question:
How can I reattach the objects properly ?
I tried with that:
local firstNode = detachedNodes[1]
if detachedNodes.count > 1 do
(
with undo off
(
local fnCacheAttach = polyop.attach
for i=2 to detachedNodes.count do
(
fnCacheAttach firstNode detachedNodes[i]
)
-- weld elements borders
firstNode.edgeWeldThreshold = 0.00001
polyop.weldEdgesByThreshold firstNode #{1..(firstNode.GetNumEdges())} -- weld only border edges
)
)
Problem:
It is also welding vertices on the same border. I need to weld vertices which are only located on different borders (differents elements).
Maybe I missed some useful function in polyop or something because I’m not very familiar to mesh operations…
Have you any idea ?
does this work for you
firstnode.vertWeldThreshold = 0.00001
polyop.weldVertsByThreshold firstnode #all
scrub that I don’t know what I’m talking about
Hi Klunk,
Unfortunately, it won’t work because it will weld vertices in the same border, too.
I want it to weld together only vertices from two different borders.
Don’t hesitate to tell me if it is not clear enough :).
Basically, I need a function whose pseudo-code would be:
for each element e
for each border b of element e
for each vertex v1 of the border b
for each vertex v2 of the other borders
if (distance v1 v2) < threshold then weld
This is totally unoptimized but this is the idea
Here is one way that might work. Memory usage is fine, but there is a lot of room for speed optimization. I hope it helps or you can find something useful on it.
fn WeldElementsEdges node threshold:0.00001 =
(
_getvertsusingface = polyop.getvertsusingface
_getfacesusingvert = polyop.getfacesusingvert
_getelementsusingface = polyop.getelementsusingface
_getvert = polyop.getvert
elements = #()
weldverts = #{}
openverts = polyop.getvertsusingedge node (polyop.getopenedges node)
for j in openverts do
(
face = _getfacesusingvert node j
element = _getelementsusingface node face
elementverts = (_getvertsusingface node element)*openverts
append elements elementverts
for i in elementverts do deleteitem openverts i
)
for j = 1 to elements.count do
(
otherverts = #{}
for i = j+1 to elements.count do join otherverts elements[i]
for i in elements[j] do
(
vpos = _getvert node i
for v in otherverts do
(
if (distance vpos (_getvert node v)) <= threshold do
(
append weldverts i
append weldverts v
for x in elements do deleteitem x v
)
)
)
)
polyop.setvertselection node weldverts -- visualize welded vertices
node.weldthreshold = threshold
polyop.weldvertsbythreshold node weldverts
)
Thank you Jorge !
I will try your code tomorrow.
For now, I had a workaround but I think I can improve it with some parts of your code.
AFAIK, your code contains at least a good way (the fastest way ?) to get an array of the elements of a poly. I have to say that I am surprised that this kind of stuff is not available in an easier way… like (polyop.getElements <poly>) or somethong like that.
I wont claim the first loop, the one that gathers the vertices of the open edges by elements, is the fastest way of doing it, but it is the fastest I know. Perhaps there is an undocumented function or something I dont know that would be faster than that.
The slowdown comes in the second loop, and the more vertices/elements you have, the slower it gets.
like (polyop.getElements <poly>) or somethong like that.
yeah, unfortunately “elements” unlike verts, edges and faces are not an actual base component of a mesh (even though they appear to be the same from the sub-object selection part of mesh & poly gui) Even at an SDK level elements have to be derived from the current “status” of the geometry.
Here is the same algorithm a little bit faster (2-3 times), but I still feel it could be faster than that. It uses more memory but it is fine, nothing to worry about.
Perhaps a different algorithm would be better.
fn WeldElementsEdges node threshold:0.00001 =
(
_getvertsusingface = polyop.getvertsusingface
_getfacesusingvert = polyop.getfacesusingvert
_getelementsusingface = polyop.getelementsusingface
_getvert = polyop.getvert
elements = #()
weldverts = #{}
openverts = polyop.getvertsusingedge node (polyop.getopenedges node)
for j in openverts do
(
face = _getfacesusingvert node j
element = _getelementsusingface node face
elementverts = (_getvertsusingface node element)*openverts
element = for e in elementverts collect
(
deleteitem openverts e
#(e, _getvert node e)
)
append elements element
)
for e1 = 1 to elements.count do
(
for x = elements[e1].count to 1 by -1 do
(
if weldverts[elements[e1][x][1]] do deleteitem elements[e1] x
)
for v1 in elements[e1] do
(
vpos = v1[2]
for e2 = e1+1 to elements.count do
(
for v2 in elements[e2] where (distance vpos v2[2]) <= threshold do
(
append weldverts v1[1]
append weldverts v2[1]
)
)
)
)
polyop.setvertselection node weldverts -- visualize welded vertices
node.weldthreshold = threshold
polyop.weldvertsbythreshold node weldverts
)