Getting vertex colors from a VertexSelection object?


#1

Autodesk tech support (for which my employer pays) is as fast as usual (i.e.: molasses), so I figured I’d ask my question here…

          I need to determine the color(s) of a mesh vertex, given a VertexSelection.
          
          I've looked at "Understanding Texture Coordinates and Vertex Colors"in the (horrible) MaxScript help file, but the relevant section is poorly worded (and has even retained a significant typo over the course of many years, despite a [promise that it would be corrected](http://forums.cgsociety.org/showpost.php?p=3599504&postcount=5)).
         
         What I'm looking at is this:

[ol]
[li]Take the index of the mesh vertex.[/li][li]Find out which faces reference the index of the face.[/li][li]Note the number of the vertex (1st, 2nd or 3rd - .x, .y or .z) inside each face.[/li][li]For each face referencing the vertex, get the texture face with the same index.[/li][li]Get the index of the respective texture vertex from the face - 1st, 2nd or 3rd / .x, .y or .z[/li][li]The vertex you got corresonds (sic) to the mesh vertex we started with.[/li][/ol]Steps 1 through 3 make enough sense for me to write code and get predictable results (once the typo in step 2 is corrected).

         I'm not sure about step 4, though.  "For each face referencing the vertex, get the texture face with the same index."  Since it has been apparently too much for Autodesk to simply provide a code example these ten years or so, I've had to assume that they meant something like this:
texVertArrays = for face in faces collect (getTVFace m face)

… Where faces is derived from meshop.getFacesUsingVert, and m is obviously a Mesh object.

   Assuming that is correct, step 5 is even more vague.  "Get the index of the respective texture vertex from the face - 1st, 2nd or 3rd / .x, .y or .z"  That's not an explanation, that's a hint.  What do they mean by "respective"?  With respect to [i]what[/i]?  And why am I being directed to get an index of a value between 1 and 3, when I am looking for indeces of texture vertices?

I had to assume that they meant to say that I should use the values derived in step 3 (i.e. the “corner” of each face – 1, 2, or 3 – to which the relevant vertex is assigned) to determine which value in each of my texVertArrays values corresponds to my original vertex:

texVerts = for i = 1 to texVertArrays.count collect (texVertArrays[i])[corners[i]] as Integer

Anyway, assuming I got steps 4 and 5 right, I’m still not getting the proper color values by calling getVertColor $‘mesh’ texVerts[i].

Has anyone successfully pulled this off, or something like it, using MaxScript? (i.e. I’m not interested in a C++ solution.)

        P.S. Sorry if I sound peevish in this post (which I am), but after a few years of hell working with 3DS Max, followed by a few years of bliss working with Maya, I'm back on 3DS Max, and I'm consistently rediscovering why I hated it so much  (although the MaxScript .NET compatability, which Max didn't have last time I coded for it, is damn nice).

#2

every mesh has same number of geo faces and map faces if map channel is supported. Vertex color is one of texture channels. It’s number is 0.

every geo face of a mesh has to have 3 verts. Every map face of a mesh has also 3 verts but their indexes can be different then geo indexes. To get correspondent map vert index you have to:

  1. geo_verts = getFace mesh f_id – point3 of geo verts indexes
  2. map_verts = meshop.getMapFace mesh channel f_id – point3 of map verts indexes
    (or getVCFace mesh f_id)

geo_verts[n] index corresponds to map_verts[n]

to get color of geo vert you have to collect all correspondent map verts and their colors

meshop.getmapvert mesh channel map_vert_index --where channel is 0

getVertColor works for map vertex index.
getVertColor mesh mvert works same as meshop.getmapvert mesh 0 mvert


#3

it makes sense to create a buffer with all geo verts and their correspondent map verts


vert_buffer = #()
for f in mesh.faces as bitarray do
(
 gverts = getFace mesh f
 mverts = getVCFace mesh f
 for k=1 to 3 do
 (
  if vert_buffer[gverts[k]] == undefined do vert_buffer[gverts[k]] = #()
  appendifunique vert_buffer[gverts[k]] mverts[k]  
 )
)

and use this buffer later to get correspondent map vert indexes…


#4

with SDK you can do it faster and memory “cheaper” but the interface is very similar.


#5

Not always. I have gotten bad color values using channel 0, and good values using channel 1. It depends how the artist applied the colors.

OK, so what I did was right, yes?

Here is exactly what I did (m = Mesh object, v = VertexSelection index):

-- 1. Take the index of the mesh vertex.
  vIdx = m.verts[v].index
  
  -- 2. Find out which faces reference the index of the vertex.
  faces = (meshop.getFacesUsingVert m vIdx) as Array
  
  -- 3. Note the number of the vertex (1st, 2nd or 3rd - .x, .y or .z) inside each face.
  corners = for face in faces collect (findItem ((meshop.getVertsUsingFace m face) as Array) vIdx)
  
  -- 4. For each face referencing the vertex, get the texture face with the same index.
  texVertArrays = for face in faces collect (getTVFace m face)
  
  -- 5. Get the index of the respective texture vertex from the face - 1st, 2nd or 3rd / .x, .y or .z 
  texVerts = for i = 1 to texVertArrays.count collect (texVertArrays[i])[corners[i]] as Integer

What does meshop.getMapVert have to do with my problem? That simply returns UV coordinates. I don’t need UV coordinates, I need vertex colors.

Huh? One returns UV coordinates, the other returns a color value.

Anyone else, please?


#6

– 3. Note the number of the vertex (1st, 2nd or 3rd - .x, .y or .z) inside each face.
corners = for face in faces collect (findItem ((meshop.getVertsUsingFace m face) as Array) vIdx)

this part is not right
meshop.getVertsUsingFace returns bitarray and it doesn’t keep the right order…
you have to use getFace function…

about meshop.getmapvert and getVertColor …
yes, only difference is what they return. First one returns point3, second one returns color.
I’m usually using meshop.getmapvert because in my cases vert color channel usually is not 0


#7

Thanks, Denis! That was my problem, using meshop.getVertsUsingFace.

I’ve switched to getFace and now it works.

That’s one thing I hate about MaxScript and the C++ SDK, too many similar but subtly different ways to get specific values.

Thanks, again!


#8

This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.