Files
2025-09-29 00:52:08 +02:00

161 lines
4.9 KiB
Plaintext
Executable File

--
-- File:: VertexSnap.ms
-- Description:: Given a selection of meshes, snaps vertices on one object to any vertices on another object in the selection
-- which are within the given tolerance.
--
-- Author:: Greg Smith (original)
-- Date:: 9 September 2004
--
-- Author:: Marissa Warner-Wu <marissa.warner-wu@rockstarnorth.com> (Cleanup, moved main function over from GTA3)
-- Date:: 3 August 2009
--
-- somewhere in 2014 and 25/05/2015 : Nico = snap works both in poly and mesh, invert the snaping of "snap to", average snap selected.
-- struct Strct_SnapVerts
-- (
-- IsAverage = false
-- )
-- Strct_SnapVerts = Strct_SnapVerts()
--////////////////////////////////////////////////////////////
-- functions
--////////////////////////////////////////////////////////////
fn RnFilterSnapPick o = (
cursel = #()
cursel = cursel + selection
retval = false
if finditem cursel o == 0 then (
retval = true
)
retval
)
fn SnapVertsByTol snapset tolerance ByAverage:False = (
-- For every object in the selection except the last one
-- (we assume this has been checked by the end)
for i = 1 to (snapset.count - 1)do (
otherObjects = deepCopy snapset
deleteItem otherObjects i
-- Get the number of verts, supporting multiple object types
if (classof snapset[i] == Editable_Mesh) then (
aNum = getNumVerts snapset[i]
) else if (classof snapset[i] == Editable_Poly) then (
aNum = polyOp.getNumVerts snapset[i]
) else (
messagebox ("This class of the object " + snapset[i].name + " is not supported, the object needs to be an editable poly or editable mesh")
return false
)
-- Find a match for each vert
for aVIndex = 1 to aNum do
(
-- Get the current vert position, supporting multiple object types
if (classof snapset[i] == Editable_Mesh) then (
aVert = getVert snapset[i] aVIndex
) else if (classof snapset[i] == Editable_Poly) then (
aVert = polyOp.getVert snapset[i] aVIndex
) else (
messagebox ("This class of the object " + snapset[i].name + " is not supported, the object needs to be an editable poly or editable mesh")
return false
)
-- Check against the verts in other objects
print otherObjects
for bObj in otherObjects do (
-- Get the number of verts, supporting multiple object types
if (classof bObj == Editable_Mesh) then (
bNum = getNumVerts bObj
) else if (classof bObj == Editable_Poly) then (
bNum = polyOp.getNumVerts bObj
) else (
messagebox ("This class of the object " + bObj.name + " is not supported, the object needs to be an editable poly or editable mesh")
return false
)
for bVIndex = 1 to bNum do (
-- Get the current vert position, supporting multiple object types
if (classof bObj == Editable_Mesh) then (
bVert = getVert bObj bVIndex
) else if (classof bObj == Editable_Poly) then (
bVert = polyOp.getVert bObj bVIndex
) else (
messagebox ("This class of the object " + bObj.name + " is not supported, the object needs to be an editable poly or editable mesh")
return false
)
-- Do we have a match?
if (((distance aVert bVert) < tolerance) and (bVert != aVert)) then
(
--if is average = false then snap to
if ByAverage == false do
(
-- Move this vert to the match and skip to the next vert
offset = [0, 0, 0]
offset.x = bVert.x - aVert.x
offset.y = bVert.y - aVert.y
offset.z = bVert.z - aVert.z
if (classof bObj == Editable_Mesh) then (move bObj.verts[bVIndex] -offset)
else if (classof bObj == Editable_Poly) then
(
polyOp.moveVert bObj bVIndex -offset
)
format "Found Match: % in % moved to %\n" bVert snapset[i] bVert
)
--if is average =true then average
if ByAverage == true do
(
-- Move this vert to the match and skip to the next vert
offset = [0, 0, 0]
offset.x = (bVert.x - aVert.x)/2
offset.y = (bVert.y - aVert.y)/2
offset.z = (bVert.z + aVert.z)/2
if (classof bObj == Editable_Mesh) then
(
move bObj.verts[bVIndex] -offset
move snapset[i].verts[aVIndex] offset
)
else if (classof bObj == Editable_Poly) then
(
polyOp.moveVert bObj bVIndex -offset
polyOp.moveVert snapset[i] aVIndex offset
)
format "Found Match: % in % moved to %\n" bVert snapset[i] bVert
)
)
)
)
)
)
)