Notifications
Clear all

[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 ?

9 Replies

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.

1 Reply
(@polytools3d)
Joined: 11 months ago

Posts: 0

I won’t 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 don’t 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
 )

@Jorge: I will definitely study your last piece of code, Jorge, thanks.
@Klunk-1: Thanks for the information.