Could you post an example of the scene you usually work with? (preferably MAX 2020 version). I need to see the type of data you have. How best to optimize depends on it.
Align UV script optimizations
It’s easy not to use a snapshot for a mesh, as well as any conversion to mesh geometry at all. I do this in order to use the methods of meshop mapfaces to elements that are not part of polyop.
I assume that after improving the code and algorithms, we can increase the performance up to 4 times continuing to use only pure maxscript.
Here is an example file.
Katwijk.max (25.9 MB)
You can ignore the roofs, only the walls are relevant.
@Serejah I did a quick test and it seems fast, but I’m not sure how fast. I only tried a small portion of the example file. It was faster than my original script anyway.
I did a test in Blender, which is the source app for the buildings, and it did it in about 4 min 45 sec. I first clicked left, and then bottom. Maybe it could do it twice as fast if there was a button for bottom left align, but there’s not.
I’ve made the test - do all using c++ :
roofs :
CPP SDK elements:22610 time:205
walls:
CPP SDK elements:137464 time:4315
the time in msec…
it definitely beats the Blender
Very nice 
I guess I will have to learn a bit more to progress further 
@denisT What’s your opinion on python in Max?
Most likely your number is more correct. I just copy pasted uvs to mesh and used MNMeshElements to check the count. And maybe it isn’t a valid method at all.
I think that is possible to make pure MXS version which can do the job for about 40-60 sec
Serejah,
do you remember that MXS algorithm to find all mesh geom elements? You already found it once on this forum…
I posted above my updated version of Jorge’s code. If I remember correctly it was working bit faster, but I didn’t do muchs tests to see if it doesn;t break on some corner case scenarios
Thanks! 
I will try to make this UV shift thing based on fast element search using only MXS… the same I do in my cpp code
and finally:
fn shiftPolyMapAllElements node ch:1 =
(
local faces = #{1..node.numfaces}
local numtverts = polyop.getnummapverts node ch
local verts = for v = 1 to numtverts collect #()
local undone = #{1..numtverts}
local elements = #()
getmapface = polyop.getmapface
getmapvert = polyop.getmapvert
setmapvert = polyop.setmapvert
for f in faces do
(
tvv = getmapface node ch f
for tv in tvv do append verts[tv] f
)
for i in faces do
(
element = #(i)
tverts = #()
for j in element where faces[j] do
(
faces[j] = off
f = getmapface node ch j
for k=1 to f.count do
(
v = f[k]
if undone[v] do
(
join element verts[v]
append tverts v
undone[v] = off
)
)
)
u = 1e9
v = 1e9
pp = for tv in tverts collect
(
p = getmapvert node ch tv
if p.x < u do u = p.x
if p.y < v do v = p.y
p
)
shift = [u,v,0]
k = 1
--format ">> % = %\n" tverts.count tverts
for tv in tverts do
(
setmapvert node ch tv (pp[k] - shift)
k += 1
)
append elements tverts.count
)
update node
elements
)
undo "Shift POLY Elements" on
(
gc()
node = $
converttopoly node -- for undo!!!
t1 = timestamp()
m1 = heapfree
elements = shiftPolyMapAllElements node
format "MXS POLY elements:% time:% memory:% >> %\n" (try(elements.count) catch(-1)) (timestamp() - t1) (m1 - heapfree) elements
)
WALLS:
MXS POLY elements:137464 time:4237 memory:268027116L >> #(5, 4, 5, 4, 5, 4, 5, 4, 13, 12, 11, 12, 7, 4, 4, 8, 4, 19, 4, 4, …)
pure MXS is ~4 sec on my machine (!)
Blender sucks! 
Thank you for restoring my faith, oh wise one 
Seriously though, that’s pretty awesome 
I’ll try it out tomorrow!
Thanks for the help! I hope others find it useful too!
If anyone needs to bottom left align 100k+ UV islands, they will find this thread 
Tried it and it works great. Very fast! I can now do this step in Max 
Out of interest, what are the main differences from the first script I made, that result in such an improvement?
do you see any sign of an unwrap in the code?
the rest is just a very clever algorithm to lookup for uv elements
moving verts is simple, knowing which ones to move is not 
Yea, the lack of Unwrap modifier was no surprise 
OK, I suspected finding the UV elements was a big part, but I didn’t think it would be this major. I was looking into alternative methods, but I had just begun to scratch the surface 