Notifications
Clear all

[Closed] Align to vertex?

I have to meshes with an equal number of vertices.

Mesh1 is a deforming mesh. All of the vertices in Mesh2 are offset from Mesh1 by an arbitrary position.

I want to be able to deform Mesh1, then run a script and have all the vertices of Mesh2 re-align themselves to the vertices of Mesh1, maintaining their original position offset.

So far I have two scripts. This script saves the original offset of the vertices of Mesh2:

    verts = #()
    
    for g in 1 to mesh2.numverts do
    (	
    	v =  (getvert mesh2 g) - (getvert mesh1 g)
    	append verts v	
    )
    
Then, after deforming Mesh1, I run this script to re-align the verts of Mesh2 to Mesh1:

    for g in 1 to mesh2.numverts do
    (
    	mesh1V = (getvert mesh1 g)
    	mesh1N = (getnormal mesh1 g)
    	mesh1M = (matrixfromnormal mesh1N)
    
    	setvert mesh2 g ( mesh1V +(verts[g]*mesh1M))
    )
    update mesh2
    
This seems to work when the deformations are small. But when the deformations are large, the align no longer works and the mesh2 vertices do not end up in the right place.

Anyone have any ideas how I can achieve correct deformations? [b]I'm basically trying to recreate what the SkinWrap modifier does.[/b]
13 Replies

I don’t know what is causing your problem, but could you do some ghetto macro of making a morpher modifier and pulling the new target, dialing it up to 100% and then collapsing it back to mesh?

That probably wouldn’t work for animation however.

Hey Aaron,

Well I need to do this on a few thousand verts per frame…it’s part of a modifier I’m making, so a hacky solution won’t work unfortunately

you are storing the offset of these two meshes in world space (difference of correspondent vertex positions). i see another way that can work better.
try to store the difference in “deformed vertex” space. the rule of making the space might be different but lets say do it as (pseudocode):


vertoffset = (getvert mesh1 vertIndex) * (inverse (matrixfromnormal ((getvert mesh2 vertIndex) - mesh.center)))
vert_repos = vertoffset * (matrixfromnormal ((getvert mesh2 vertIndex) - mesh.center))

of course the method is not perfect but I hope it makes sense.

In don’t think it’s needed to convert between spaces Denis. But who knows, you are always right in the end…

Here is my try:

for g in 1 to mesh2.numverts do
(
	mesh1V = (getvert mesh1 g)
	mesh1N = (getnormal mesh1 g)
	offset = mesh1V - (mesh1N * length(verts[g]))

	setvert mesh2 g offset
)
update mesh2

As you can see I’m not even using matrices because the positions are directly set in world space anyway…

Hope this helps,
Eugenio

I got it working.

The key was to transform the vertices relative to a matrix for each target point constructed in the following way:


t = getvert mesh1 vertexIndex
zvec = getnormal mesh1 vertexIndex

--the following code gets a vert connected to our target vert by a shared edge
edgeList = (meshop.getEdgesUsingVert mesh1 vertexIndex) as array
edge1 = (meshop.getVertsUsingEdge mesh1 edgeList[1]) as array
vInx = edge1[1]
if (vInx == g) then vInx = edge1[2]

pole = getVert mesh1 vInx
pole = normalize (pole - t)
xvec = normalize (cross zvec pole)
yvec = normalize (cross zvec xvec)

m3 = matrix3 xvec yvec zvec [0,0,0]

3 Replies
(@denist)
Joined: 11 months ago

Posts: 0

that’s exactly what i said… find a space of the relative position. it might be any. just it has to be relative, not absolute.

(@ivanisavich)
Joined: 11 months ago

Posts: 0

Yea, your tip pointed me in the right direction. Only reason why your example didn’t work on the first try, is because the surface of the mesh is deforming (it’s a skinned mesh with bones), so pointing it to the center won’t work. Pointing it to an adjacent vertex solves the problem.

(@denist)
Joined: 11 months ago

Posts: 0

i was absolutely sure that my point has been wrong.

 3ak

why do you need vertex normal at all?
store (obj2.vertex.pos – obj1.vertex.pos) and then just add it to new obj1.vertex.pos
am i missing something?

1 Reply
(@ivanisavich)
Joined: 11 months ago

Posts: 0

Yes, what you’re forgetting is that if the target mesh mesh rotates, the position offset will not be correct unless multiplied by a proper transform matrix…and the transform matrix we want must be relative to each target vert if the surface of the target object is deforming.

the only thing what i tried to do was push you to a relative coordinates. it worked.

Oh boy, somehow I completely overlooked this part at the very beggining. And this changes everything. Shame on me…

And that’s a shame twice because some days ago I had problems to stick particles to a deforming volume, since Lock/Bond leaves empty spaces if the deformations are too strong. Then I got thinking about how to stick the particles, and I was somewhat on your lines but never tried anything because I figured out I would probably end up with something similar to Lock/Bond result. Anyway in the end we got thinking particles and there it worked very well, evenly distributed particles all the time. I wonder how they do that.

And just out of curiosity, your meshes have the same number of vertices and topology, right? And why did you have to do it through maxscript and not skinwrap?

1 Reply
(@ivanisavich)
Joined: 11 months ago

Posts: 0

Yup…the mesh has the same number of vertices.

I need to do it through code because it’s part of a plugin that deforms a mesh over time…there’s actually not two meshes…just one being deformed over a series of frames. I only explained my example with two meshes to make it easier to understand

Basically I calculate a deformation on a mesh, and then I want to apply that deformation to the mesh as it animates…while maintaining the deforming mesh underneath as the base. In order to properly apply the deformation to the deforming mesh, I needed to know how to calculate a proper vertex offset between the base verts and the deformed verts.