Collect Border Edges of mesh

I'm trying to collect the edges of all borders (open edges) in my mesh and store these edges in an array. More specifically I would like to seperate the edges into as many arrays as there are borders in the mesh. Example: we have a mesh with 2 holes in it (see attached files for an image of the mesh), therefore it has 2 borders, I'd like the script to produce an array with 2 subarrays, 1 subarray for each hole/'open edge loop'.

If anyone could tell me what the proper way to collect the edges into an array is that'd be very much appreciated. If you know/can think of a good way of separating the edges into their respective sub arrays (corresponding to the holes/border in the mesh) please let me know.

What I've tried:
I've tried selecting the open edges using the command

polyOp.getOpenEdges $

.
I did get this working for selecting the open edges, unfortunately I was not able to 'get' the edge numbers of said open edges using this command since the result of the getOpenEdges command is a bitarray(http://forums.cgsociety.org/archive/index.php?t-478659.html and https://help.autodesk.com/view/3DSMAX/2016/ENU/?guid=__files_GUID_B40F84...).

I've written some pseudocode which should work for seperating the edges into their respective subarrays after all open edges have been stored in an array:

--NOTE: open_edges is the array in which all open/border edges of the mesh are stored
i = 0; edge_found = true
while open_edges.count > 0 do(
current_loop = #()
while edge_found == true do(
    i += 1
    if i==1 do( append current_loop open_edges[1]; Deleteitem open_edges 1 )
 
    -- Select 2nd vertex of current_loop[-1]
    -- Find edge in 'open_edges' which has this vertex
        -- Append the found edge to 'current_loop'
        -- Remove the found edge from 'open_edges'
    --if(no edge is found)do( edge_found = false )
 
		) --end while edge_found == true do(
	) --end while open_edges.count > 0 do(

If you spot a mistake in my code/approach for separating the edges into their respective sub arrays (corresponding to the holes/border in the mesh) or can think of a better/more efficient method of performing this process please let me know.

Thank you!

Note: in the attached image: 'edge_and_vertex_nums.png' I've indicated the edge numbers in red and the vertex numbers in blue/purple.

AttachmentSize
desired_ouput.png69.48 KB
edge_and_vertex_nums.png53.79 KB
open_edge_loop_numbers.png61.92 KB
testmesh.max960 KB

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
miauu's picture

.

(
	local poGetOpenEdges = polyop.getOpenEdges
	local poGetVertsUsingEdge = polyop.getVertsUsingEdge
	local poGetEdgesUsingVert = polyop.getEdgesUsingVert
 
	function GetFirstBit arr = 
	(
		if arr.isEmpty then #{} else #{(arr as array)[1]}
	)
 
	local curO = selection[1]
 
	if classOf curO == Editable_Poly do
	(
		local openEdgesBA = poGetOpenEdges curO
 
		local separatedLoopsArr = #()
		local eIdxBABA
		local edgesBA
		local tmpEdgesBA
 
		eIdxBA = GetFirstBit openEdgesBA
		tmpEdgesBA = openEdgesBA
		while not eIdxBA.isEmpty do
		(
			edgesBA = poGetEdgesUsingVert curO (poGetVertsUsingEdge curO eIdxBA)
			edgesBA *= openEdgesBA
			tmpEdgesBA -= edgesBA
 
			eIdxBA = if not (edgesBA - eIdxBA).isEmpty then edgesBA else
			(
				append separatedLoopsArr edgesBA
				GetFirstBit (openEdgesBA = tmpEdgesBA)
			)
		)
		separatedLoopsArr
	)
)
jahman's picture

.

for some reason when poly border has shared vert my function returns two separate edge groups for each part. But when you select this border in viewport manually it will contain both of them.

fn getPolyBorders obj = (
 
	local opendEdges = polyop.getOpenEdges obj
	local borders = #()
	local polyopGetBorderFromEdge = polyop.getBorderFromEdge
 
	for i in opendEdges where opendEdges[i] do (
 
		local border = polyopGetBorderFromEdge obj i
		append borders border
		opendEdges -= border
 
	)
 
	borders 
 
)
miauu's picture

.

Because 3ds Max uses more inaccurate method than yours. :)

jahman's picture

.

you're almost there
1. polyOp.getOpenEdges
2. polyop.getBorderFromEdge

;)

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.