Notifications
Clear all

[Closed] Getting the verts between two vertices

Thanks everyone!

denisT, your script worked perfectly! :keenly:

global connectPointsDialogPos = if  connectPointsDialogPos == undefined then unsupplied else connectPointsDialogPos
try(destroydialog connectPointsDialog) catch()
rollout connectPointsDialog "Connect Verts by denisT" width:200
(
	fn getVertEdges node vert = 
	(
		edges = #{}
		for k=1 to node.GetVertexEdgeCount vert do append edges (node.GetVertexEdge vert k)
		edges
	)
	fn as_point4 point index = 
	(
		point = point as point4
		point.w = index
		point
	)
	fn getEdgeSecondVert node edge first asPoint:on = 
	(
		vv = polyop.getEdgeVerts node edge 
		if (k = finditem vv first) != 0 do deleteitem vv k
		v = vv[1]
		if asPoint then as_point4 (polyop.getvert node v) v else v 
	)
	fn getEdgeBestByDistance node first target value: = 
	(
		edges = getVertEdges node first
		if value == unsupplied do value = 1e9
		best = undefined
		for edge in edges do
		(
			p = getEdgeSecondVert node edge first
			d = distance (p as point3) target
			if d < value do
			(
				value = d
				best = #(edge, p, value)
			)
		)
		best
	)
	fn getEdgeDirection node edge first source: normalized:on = 
	(
		if source == unsupplied do source = polyop.getvert node first 
		p = getEdgeSecondVert node edge first
		v = p as point3 - source
		if normalized do v = normalize v
		as_point4 v p.w
	)
	fn getEdgeBestByDirection node first target value: = 
	(
		edges = getVertEdges node first
		if value == unsupplied do value = 1e9
		best = undefined
		for edge in edges do
		(
			source = polyop.getvert node first 
			p = getEdgeDirection node edge first source:source
			d = abs (1 - dot (p as point3) (normalize (target - source)))
			if d < value do
			(
				value = d
				best = #(edge, p, value)
			)
		)
		best
	)
	/*
	fn getEdgeBestByLoop node first target value: = 
	(
		edges = getVertEdges node first
		edges[target.w] = off 
		if value == unsupplied do value = 1e9
		best = undefined
		for edge in edges do
		(
			p = getEdgeDirection node edge first
			d = abs (1 - dot (p as point3) (target as point3))
			if d < value do
			(
				value = d
				best = #(edge, p, value)
			)
		)
		best
	)
	*/
	fn searchConnection node first second method: = 
	(
		verts = #(first)
		edges = #{}
		out = off
		source = polyop.getvert node first
		target = polyop.getvert node second
		
		value = distance source target
		while not (out or keyboard.escpressed) do
		(
			best = method node first target --value:value
			if best != undefined then
			(
				v = best[2].w as integer
				if finditem verts v > 0 then out = on
				else
				(
					append verts v 
					append edges best[1]
					first = v
					value = best[3]
					out = (v == second)
				)
			)
			else out = on
		)
		node.selectededges = edges
		--format "best:%
" best
		verts
	)

	fn searchLoopConnection node first second = 
	(
		first_edges = getVertEdges node first
		
		__verts = #()
		__edges = #()
		
		for edge in first_edges while not first_edges.isempty do
		(
			node.selectededges = #{edge}
			node.SelectEdgeLoop()
			edges = node.selectededges as bitarray
			verts = polyop.getvertsusingedge node edges
			if verts[second] do
			(
				for edge in (first_edges * edges) do
				(
					_verts = #(first)
					_edges = #{e}
					
					out = off
					vert = first
					while not (out or keyboard.escpressed) do
					(
						vert = getEdgeSecondVert node edge vert asPoint:off
						append _verts vert						
						append _edges edge
						if vert == second then out = on
						else
						(
							edge = (getVertEdges node vert - _edges) * edges
							edge = (edge as array)[1]
						)
					)
					append __verts _verts
					append __edges _edges
					first_edges -= _edges
				)
			)
		)
		if __edges.count == 0 then
		(
			node.selectededges = #{}
			undefined
		)
		else
		(
			len = __verts[1].count
			best = 1
			for k=2 to __verts.count where __verts[k].count < len do
			(
				len = __verts[k].count
				best = k
			)
			node.selectededges = __edges[best]
			__verts[best]
		)
	)
	
	fn getNode = 
	(
		if iskindof (node = selection[1]) Editable_Poly and node.selectedverts.count == 2 do node
	)
	
	radiobuttons method_rb "Method:" labels:#("Distance", "Direction", "Loop") default:1 align:#center offset:[0,0]

	button search_bt "Find Connection" width:192 align:#right offset:[9,0]
	
	on search_bt pressed do undo "Find Connection" on if (node = getNode()) != undefined do
	(
		first = node.selectedverts[1].index
		second = node.selectedverts[2].index
		
		if method_rb.state == 3 then
		(
			verts = searchLoopConnection node first second
		)
		else
		(
			method = #(getEdgeBestByDistance, getEdgeBestByDirection)[method_rb.state]
			verts = searchConnection node first second method:method
		)
		
		format "% <-> % = %
" first second verts
	)
	
	on connectPointsDialog close do
	(
		connectPointsDialogPos = getdialogpos connectPointsDialog
	)
)
createdialog connectPointsDialog pos:connectPointsDialogPos

added method by loop.
similar to what i described some post above but uses mxs function do check loop shift

Another algorithm for a loop of vertices which might be simpler in concept could be:

Given two vertices indexes v1 and v2:

Get the sorted vertices loop

If it is an open loop start the sorting from one end

Find the offset of v1 and v2

Get the vertices in between

If it is an open loop measure their distance and the distance of the inverted vertices

Pick up either the longest or the shortest one

Page 4 / 4