[Closed] Problems getting MapVert
Hi, many times when I try to get the corresponding mapvert for a vertex I get the position for a completly different vertex on the uvwlayout. I’m guessing this has to do with the fact that often the mapverts numbers are not the same as the normal vertsnumbers. Is there a simple way to get the corresponding mapvert index for a vert, or at least the correct position in the uvwlayout?
Thanks,
CML
Sure there is, and it is well-documented
Instead of writing 10 pages of description, I would recommend reading through the “Understanding Texture Coordinates and Vertex Colors” topic in the MAXScript Reference.
In short, the only things that are indexed identically in the mesh and the texture coordinates are the face arrays.
So if face 10 references vertices 101, 203 and 404, whilte Texture face 10 references Map Vertices 12, 15, and 142, you can say for sure that mesh vertex 101 is using map vertex 12, mesh vertex 15 corresponds to map vertex 203 and 142 uses map vertex 404.
You can never assume that map vertices are indexed the same as the mesh vertices in Max, you always have to go through their corresponding faces.
(In 3D Studio DOS and the .3DS file format though, you CAN assume that they are indexed identically.)
Cheers,
Bobo
Bobo- Thanks, hmm that’s a way I have tried already. I get the faces a vertex is using, pick one of those faces and check wich vertnumber the initial vert has on that face. Then I get the vertex with the vertexnumber on that face in the uvw’s. Having some problems to get it to work properly though. I will read up on it.
I’m trying to convert selections between the uvw’s and the polymesh. The main probem I’m having is going from the uvw’s verts to getting a specific vert. Maybe it’s not possible.
I should say also that I’m on max5 now, so that part might not be in my help, at least I can’t find it.
CML
It must be there, at least in my 5.1 the topic “Understanding…” appears in the Index.
The main problem is that a single mesh vertex can have ANY number of corresponding map vertices, and the other way round.
So you should always make sure that you have checked ALL faces that share the vertex and “follow all leads”…
I am pretty sure I have posted a script to this forum that worked along these lines…
alright, found these:
polyop.getMapFace $.baseobject 1 …
[size=2]polyop.getFaceVerts $.baseobject …[/size]
[size=2][/size]
[size=2]Those two should do the trick to finding it, thanks for pushing me into the help:) [/size]
[size=2][/size]
[size=2]CML
[/size]
Bobo- Oh yes, of course I need to check all faces. I didn’t think about that. It works ok now both ways, but it’s terribly slow to go from the uvw’s to the polymesh. I was thinking I would implement many of my SelectionMaster tools for the UVW Unwrap but it’s just too slow to work with it like that. I have at least added VertexLoop and VertexRing. It would be easier if there were a function for getting a mapverts mapfaces directly. Thanks for the help.
CML
HOW slow is it?
I tested with a 64 segments Teapot (131300 vertices).
Without any selection, the script took 266 ms.
With ALL vertices selected, it took 9266 ms
So the typical selection time would be way below 9 seconds.
With a teapot with 3000 vertices (all selected), it took 31 ms to select all corresponding map vertices.
With a sphere with 100 segments, 4900 vertices – 62 ms.
With a sphere with 200 segments, 19802 vertices – 1111 ms.
Same 200 seg. sphere, just 10000 vertices selected – 141 ms. (hmmm – half of the vertices, 1/10 of the time?)
I collapsed the object to EMesh and added Unwrap_UVW manually. Flatten mapping or default mapping coordinates – no difference in speed. It depends on the number of faces sharing the selected vertices, that’s the loop that costs time.
Here is the test code I used:
(
st = timestamp()
theObj = $
theMesh = snapshotAsMesh theObj
theVSelection = getVertSelection theObj
theFacesToCheck = (meshop.getFacesUsingVert theMesh theVSelection ) as array
theMapVSelection = #{}
count = theFacesToCheck.count
for f = 1 to count do
(
theFace = getFace theMesh f
theTFace = meshop.getMapFace theMesh 1 f
if theVSelection[theFace.x] do theMapVSelection[theTFace.x] = true
if theVSelection[theFace.y] do theMapVSelection[theTFace.y] = true
if theVSelection[theFace.z] do theMapVSelection[theTFace.z] = true
)
theObj.unwrap_UVW.selectVertices theMapVSelection
et = timestamp()
format "% ms.
" (et-st)
)
YMMV.
Bobo- Thanks, but it’s not so much the getting of the mapverts that’s taking time, it’s when I want to select verts in the $.baseobject based on the selected verts in the unwrap-editor. The reason it’s taking time is mostly beacuse I have to(I think) check all of the mapfaces for each mapvert to get wich of them has the selected vert in them.
Here’s the code I’m using to go from uvw-verts to polymesh-verts. Not sure if you can make out what I’m doing, heh. I would very much like to optimize this code if it is possible.
uv = modpanel.getcurrentobject()
dog = uv.getSelectedVertices()
nog = dog as array
sog = polyop.getNumMapFaces $.baseobject 1
uv.selectFaces #{1..sog}
pog = uv.getSelectedFaces()
hog = pog as array
cog = #()
for i = 1 to nog.count do
(
dom = #()
for u in hog do
(
gog = uv.numberPointsInFace u
kog = #()
for t = 1 to gog do
(
bog = uv.getVertexIndexFromFace u t
append kog bog
)
mog = finditem kog nog[i]
if mog != 0 do append dom u
)
tog = uv.numberPointsInFace dom[1]
rog = 0
for t = 1 to tog do
(
qog = uv.getVertexIndexFromFace dom[1] t
if qog == nog[i] do rog += t
)
yog = uv.getVertexGeomIndexFromFace dom[1] rog
append cog yog
)
polyop.setVertSelection $.baseobject cog
CML
Just an idea – how about using the vertToFaceSelect() method in Unwrap_UVW to convert the vertex selection to face selection, grab the selected faces only, check their vertices and so on. The selection conversion does NOT update the Editor – if you are in Vertex mode, the Faces will be selected “in the background” and not take up time to redraw the Editor if it is open. You could grab the existing face selection, do the vertex to face conversion, grab the new selection, then apply the original face selection back as if nothing has changed…
Unless all map vertices are selected, this should speed up the loop alot – the fewer the vertices, the fewer the faces to go through!
Bobo- Thanks, I don’t know how it is in later versions of max but in my max5, for such a conversion to work, all of the mapfaces verts must be selected. So no deal there I guess.
But, I have another idea to do it that should be much faster. I will simply get the selected mapverts in an array. Then I cycle through all the baseobject verts and get their mapverts. If that mapvert exsitst in the initial mapvert-array I select those verts. I’’l try if this is faster.
cheers,
CML
Alright, I tried the other way of doing it and it’s blazing fast:)
Here’s the code I use if anybody is interested:
uv = modpanel.getcurrentobject()
mapch = uv.getmapchannel()
if mapch == 0 do mapch = 1
dog = uv.getSelectedVertices()
nog = dog as array
polyop.setVertSelection $.baseobject #all
pom = polyop.getVertSelection $.baseobject as array
jog = #()
for i in pom do
(
dud = #()
lom = polyop.getFacesusingVert $.baseobject i
for f in lom do
(
pud = polyop.getMapFace $.baseobject mapch f
bud = polyop.getFaceVerts $.baseobject f
fud = finditem bud i
append dud pud[fud]
)
lud = finditem nog dud[1]
if lud != 0 do append jog i
)
polyop.setVertSelection $.baseobject jog
CML