Hey Polycount! I got a (newbie) Maxscript question. The task seems fairly simplistic but I keep running into technical issues. Here's what I wanna do:
-make a cycle that takes every UV vertex, calculates its' distance to every other UV of the model;
-for every pair of UV vertices check distance between them;
-if some of the UV vertices are too close to each other (distance less than a certain amount), select them.
After some experimenting here's what I ended up with:
theobj = selection[1]
addModifier theobj (Unwrap_UVW())
uv = theobj.modifiers[#Unwrap_UVW]
closeuvs = #()
closeuvs.count = theobj.numtverts
texVertIndices = #{1 .. theobj.numtverts}
texVerts = for texVertIndex in texVertIndices collect (getTVert theobj texVertIndex) --collecting all the vertices
for i = 1 to theobj.numtverts do
(
-- take UV coordinates of every vertex
ivertX = texVerts[i].x
ivertY = texVerts[i].y
-- and compare them to coords of every other vertex
for j = 1 to theobj.numtverts do
(
if j != i do
(
jvertX = texVerts[j].x
jvertY = texVerts[j].y
--calculate the shortest distance between the i vertex and the j vertex
resX = jvertX - ivertX
resY = jvertY - ivertY
finX = resX^2
finY = resY^2
resdist = finX + finY
findist = sqrt resdist
--distance calculated
if findist <= 0.25 then closeuvs[i] = 0
else closeuvs[i] = 1 --vertices that should be selected are marked with 0
)
)
)
resultuvs = for m in closeuvs where closeuvs[m] == 0 collect (getTVert theobj m) --collect close vertices into an array
uv.selectVerticesByNode resultuvs theobj --and select it
This code seems to check the UV distance just fine but if it finds any close uvs I'm still getting an error: "Runtime error: Mesh TVertex index out of range: 0"
I know I'm probably missing something super obvious but I can't seem to figure it out, maybe you tech-wizards can help me
Thank you!
Replies
The error I see is that you are trying to select an array of Point3 values (resultsuvs). The select commands only work on bitArrays.
There are several workflow improvements you can make to this script faster.
1. I know it seems reasonable to store lots of information and then process that data. But memory is slow and the processor is fast. So it's always faster to check data as you loop through it instead of storing it and checking it later.
2. Use the "Distance" function instead of doing the math manually.
3. Use the UnwrapUVW functions for getting vertex counts and UV positions so that your script can run on EPoly or EMesh objects.
4. When using an index loop use a saved variable instead of constantly accessing a property or function. Fast (for i = 1 to var) Slow (for i = 1 to array.count)
5. Use the Where context instead of doing an if check when starting a loop.
6. 0.25 is actually a pretty large threshold. It's about 1/4 the size of the 0-1 UV space. So in my example I have it set to 0.01.
0.25 is obviously just a value for this example, for the same reason I didn't bother fixing all the various optimization problems. Oh, I see, that was the main problem. I totally used the wrong data type. Thanks for clarifying it.
Well that's embarrassing lol. I did not even know that function was a thing