Selected vertex attracts it's nearest neighbor to weld into it.

Hello guys,

I am in need of a script:

Selected vertex attracts it's nearest neighbor to weld into it.

If more than one vertex is selected, each selected vertex should attract to it the nearest neighbor. Only one vertex to be welded to the original vertex.

Would appreciate if anybody could help on this :)

Comments

Comment viewing options

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

Select nearest object based on selected object

Hi can anyone help me i need to write a maxscript for this
I need to give concrete texture to a floor-object mentioned in the image attached to this comment
based on the availability of the railing-object which sits exactly on top of the floor-object as u can see
but almost every floor-object has same name except their last number in order
so i need to give concrete texture everytime to one particular floor-object only as shown

any help ?

AttachmentSize
f.jpg 69.29 KB

Sharath pawar

rvidal's picture

Seletive weld (target weld script)

Hello
I need to complete my script and this topic is related to my problem, so I hope somebody help me out.

The problem:
I need to weld some verteces that I already know one by one.
Exemple:
$.EditablePoly.SetSelection #Vertex #{4326}
$.EditablePoly.SetSelection #Vertex #{4322}

to the closest vertex located in a selected border at the same object (see the attached pictures)

AttachmentSize
seletive_weld.png 695.05 KB
miauu's picture

.

Try this:

(
	global rol_weldVerts
	try(destroyDialog rol_weldVerts)catch()
	rollout rol_weldVerts "miauu"
	(
		local curO = undefined
		local vertsToWeldBA = #{}
 
		button btn_getVerts "Get Verts" width:140
		button btn_weld "WELD" width:140
 
		on btn_getVerts pressed do
		(
			curO = modPanel.getCurrentObject()
			if classOf curO == Editable_Poly do
			(
				vertsToWeldBA = polyop.getVertSelection curO
			)
		)
 
		on btn_weld pressed do
		(
			if vertsToWeldBA.isEmpty == false do
			(
				selEdgesBA = polyop.getEdgeSelection curO
				selEdgesVertsBA = polyop.getVertsUsingEdge curO selEdgesBA
				closestVertsArr = #()
				for v in vertsToWeldBA do
				(
					vPos = polyop.getVert curO v
					minDist = 1e9
					tmpArr = #(v, vv, undefined)
					for vv in selEdgesVertsBA do
					(
						vvPos = polyop.getVert curO vv
						if (dist = distance vPos vvPos) < minDist do
						(
							minDist = dist
							tmpArr[2] = vv
							tmpArr[3] = vvPos
						)
					)
					append closestVertsArr tmpArr
				)
				if closestVertsArr.count != 0 do with undo "Weld verts" on
				(
					vertsIdxToWeldBA = #{}
					for arr in closestVertsArr do
					(
						polyop.setVert curO arr[1] arr[3]
						vertsIdxToWeldBA += #{arr[1], arr[2]}
					)					
					curO.weldThreshold = 0.0001
					polyop.weldVertsByThreshold curO vertsIdxToWeldBA
				)
			)
		)
	)
	createdialog rol_weldVerts
)

Select the verts that you want to weld.
Select the edges.
Press the [Get Verts] button.
Press the [Weld] button.

rvidal's picture

Great. Thank you Miauu. I

OMG... Thank you Miauu. I will look the code and try to learn. I think it will solve my problem

barigazy's picture

...#2 distance comparation method

(
	if selection.count == 1 and isKindOf (obj = selection[1]) Editable_poly then
	(
		selVertsBA = obj.selectedverts as bitarray
		if selVertsBA.isEmpty then (messagebox "Select some vertices" title:"Invalid Selection" beep:off) else
		(
			local vertsToWeldBA = #{}, vertsToSelBA = #{}, vertsPos = #()
			local getVuE = polyop.getVertsUsingEdge
			local getEuV = polyop.getEdgesUsingVert
			local weldThresh = obj.weldThreshold = 0.001
			local weldVerts = polyop.weldVertsByThreshold
			for v in selVertsBA do
			(
				vPos = obj.verts[v].pos
				neighborVertsBA = (getVuE obj (getEuV obj v)) - #{v}
				minDist = 1e9 ; nearestVert = undefined
				for nv in neighborVertsBA do (if (dist = distance (obj.verts[nv].pos) vPos) < minDist do (minDist = dist ; nearestVert = nv))
				join vertsToWeldBA  #{v, nearestVert}
				append vertsPos (obj.verts[nearestVert].pos = vPos)
			)
			weldVerts obj vertsToWeldBA
			for v in 1 to obj.numverts do
			(
				for p in vertsPos where distance obj.verts[v].pos p <= weldThresh do append vertsToSelBA v
			)
			obj.selectedverts = vertsToSelBA
		)
	) else (messagebox "Select only one editable poly object" title:"Invalid Selection" beep:off)
)

bga

barigazy's picture

...

So the point here is to reduce usage of polyOp struct to minimum.
Hope you agree with me Kostadin. I have not had time to to compare speed and memory.

bga

miauu's picture

I think that for object with

I think that for object with small amount of verts the speed using polyop and not using polyop will be too small. But when I have time I will compare both methods.
The most important I think is to stop the last for loop when all verts, that have to be selected, are found. So we have to use something like this:

cnt = 0
			for v in 1 to obj.numverts while cnt  < selVertsBA.numberset do
			(
				for p in vertsPos where distance obj.verts[v].pos p <= weldThresh do
				(
					append vertsToSelBA v
					cnt += 1
				)
			)
barigazy's picture

Nice one i like it. Maybe

Nice one i like it. Maybe there is a better finding method because what if we used few last verts that need to be selected after welding.

bga

miauu's picture
barigazy's picture

...#1 string comparation method

Sorry for double post and untested version.
I have a new aproch without using getset Vert Data.

(
	if selection.count == 1 and isKindOf (obj = selection[1]) Editable_poly then
	(
		selVertsBA = obj.selectedverts as bitarray
		if selVertsBA.isEmpty then (messagebox "Select some vertices" title:"Invalid Selection" beep:off) else
		(
			local vertsToWeldBA = #{}, vertsPos = #()
			local getVuE = polyop.getVertsUsingEdge
			local getEuV = polyop.getEdgesUsingVert
			local weldVerts = polyop.weldVertsByThreshold
			for v in selVertsBA do
			(
				vPos = obj.verts[v].pos
				neighborVertsBA = (getVuE obj (getEuV obj v)) - #{v}
				minDist = 1e9 ; nearestVert = undefined
				for nv in neighborVertsBA do (if (dist = distance (obj.verts[nv].pos) vPos) < minDist do (minDist = dist ; nearestVert = nv))
				join vertsToWeldBA  #{v, nearestVert}
				append vertsPos ((obj.verts[nearestVert].pos = vPos) as string)
			)
			weldVerts obj vertsToWeldBA
			obj.selectedverts = (for v in 1 to obj.numverts where findItem vertsPos (obj.verts[v].pos as string) != 0 collect v)
		)
	) else (messagebox "Select only one editable poly object" title:"Invalid Selection" beep:off)
)

bga

Comment viewing options

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