MAX - Multi Object Vertex Snap

Hello,
I am currently working on a large scale terrain for simulation and I need a 3dsmax 2009 tool that would allow me to snap the vertex of multiple objects (>1000) within a certain threshold. The engine we are using doesn’t allow texture blending so we have to apply a second layer of geometry with alpha textures to get decals. As long as the geometry has the same triangulation and vertex snapped, there is no flickering. Right now we go through Multigen Creator (simulation tool) to do that but since we do all the content in 3dsmax i was looking for a tool to do that with max.

Thanks in advance,
David

edit: I forgot to mention that merging all meshes into one object and weld verts is not an acceptable solution!

I wrote something for a buddy who wanted to do what sounds to be roughly the same thing a while back… Give this a try.

The script allows you to snap all the verts of the selected object to a grid intersection with the spacing selected in the dropdown; 1, 2, 4, 8, 16, 32, 64, 128, 256.

Then again, I may be misunderstanding what it is you’re trying to accomplish.

(Works on poly’s only.)

(
	fn round x = 
	(
		if x < 0 then
		newX = (x - .5) as integer
		else
		newX = (x + .5) as integer
	)
	
	rollout vertSnap "Vertex Snapper" width:80 height:90
	(
		dropDownList ddlGrid "Grid" pos:[8,9] width:56 height:40 items:#("1", "2", "4", "8", "16", "32", "64", "128", "256")
		button btnSnap "Snap" pos:[8,56] width:64 height:24
		
		on btnSnap pressed do
		(
			if ((classOf selection[1]) == Editable_Poly) then
			(
				scale = ddlGrid.selected as integer
				polyOp.setVertSelection selection[1] #all
				for v = 1 to (polyOp.getNumVerts selection[1]) do
				(
					currentVertPos = (polyOp.getVert selection[1] v)
					n = [0,0,0]
					n.X = (round (currentVertPos.x / scale)) * scale
					n.Y = (round (currentVertPos.y / scale)) * scale
					n.Z = (round (currentVertPos.z / scale)) * scale
					
					newVertPos = n
					format "vert: % 	 pos: % moved to % 
" v (polyOp.getVert selection[1] v) n
					polyOp.setVert selection[1] v newVertPos
				)
				piv = [0,0,0]
				piv.X = (round (selection[1].pivot.x / scale)) * scale
				piv.Y = (round (selection[1].pivot.y / scale)) * scale
				piv.Z = (round (selection[1].pivot.z / scale)) * scale
				format "Pivot pos: % moved to % 
" selection[1].pivot piv
				selection[1].pivot = piv
			)
		)
	)
	createDialog vertSnap
)

I may not be explaining well because English isn’t my first language. What I am trying to accomplish is to snap the vertices of multiple objects not to a grid but between all the objects. Lets say i have a building with a simple tileable texture. If i want to have an ambient occlusion or decals to break the pattern, we have fake it by cloning the building and have these textures on the second building with alphas. The problem is with all the manipulations we do, we often end up with a macroscopic displacement between the 2 objects and that causes flickering in the Simulation engine we work with. At the moment we use a tool in Multigen called “match vertices”. Basically, you input a threshold, and for all objects selected, it will match the vertices position that are under this threshold. Its just like “collapse” from editable poly but it works on multiple objects at the same time and it doesnt weld the vertices but simply match the vertices position. I hope it is clearer.

Thanks again

Correct me if I’m wrong, but won’t snapping the vertices in these cases (decals, cloned geometry with ambient occlusion) actually make the flickering (z-fighting) worse?

Surely what you want to do is actually just use a Push modifier with a fairly low value to make sure that the surfaces are not touching at all?

Certainly that’s the case in the game engines I’ve used, maybe yours is different, but it still sounds strange?

[QUOTE=davidm;2243]I may not be explaining well because English isn’t my first language. What I am trying to accomplish is to snap the vertices of multiple objects not to a grid but between all the objects. Lets say i have a building with a simple tileable texture. If i want to have an ambient occlusion or decals to break the pattern, we have fake it by cloning the building and have these textures on the second building with alphas. The problem is with all the manipulations we do, we often end up with a macroscopic displacement between the 2 objects and that causes flickering in the Simulation engine we work with. At the moment we use a tool in Multigen called “match vertices”. Basically, you input a threshold, and for all objects selected, it will match the vertices position that are under this threshold. Its just like “collapse” from editable poly but it works on multiple objects at the same time and it doesnt weld the vertices but simply match the vertices position. I hope it is clearer.

Thanks again[/QUOTE]

I’d try looking around scriptspot, and CGTalk. I know what you’re describing, but I don’t know if anyone has a good script for it.

Do the two objects have the same vert indices? If so, you could just run (select the good mesh, then the bad mesh):


(
	local op = (if classOf selection[2] == Editable_Poly then polyop else meshop)
	for i = 1 to selection[1].mesh.numverts do
	(
		op.setVert selection[2] i (getVert selection[1].mesh i)
	)
)

That should be generic enough, you can specialize and optimize it for whatever it needs to do (it is also in local space, not world space).

If the two object’s vert ID’s aren’t the same, it wouldn’t be too difficult if you know about the steps involved (which are simple but have somewhat of a learning curve).
[ol]
[li]Get the closest face on good mesh to vert i on bad mesh[/li][li]Get the closest vert on the closest face (distance test on each vert)[/li][li]Move vert i on bad mesh to the position of the closest vert.[/li][/ol]
There is a function for finding the closest point on a surface here: [w]Common_functions#Closest_Point_on_Surface[/w] You should be able to do what you need based on that. If you need more help, just ask.

Srry for this noob question. But i search every word I do not know and I can’t find an explanation for vert indices. Can someone explain me?

Perhaps try Rico Holmes’ Vertex Placer 3 script.

Link

It’s a vertex quantiser.

Not sure if it’d work at the object level.

I think for this I’d get whoever was writing the data puller to put a little bit of tollerance into the vertex positions when attempting to match them up, then it wouldn’t matter if they were out a little bit.

[QUOTE=MoP;2244]Correct me if I’m wrong, but won’t snapping the vertices in these cases (decals, cloned geometry with ambient occlusion) actually make the flickering (z-fighting) worse?

Surely what you want to do is actually just use a Push modifier with a fairly low value to make sure that the surfaces are not touching at all?

Certainly that’s the case in the game engines I’ve used, maybe yours is different, but it still sounds strange?[/QUOTE]

Surprisingly it doesn’t affect performance all that much in the engine we are using as long as the triangulation between both layer is identical. It is a simulation engine and the shaders are so basic thus light on performance that we can afford such “cheats” to get better looking environments.

I’ll try the solutions proposed and keep you updated. Thanks a lot for your time

Each vertex has a number, usually determined from the order each vertex was created. This number is called a vertex index, so in English multiple vertex numbers are called vertex indices.