Home Technical Talk

Maxscript, color per vertex -> ascii output

polycounter lvl 13
Offline / Send Message
Harry polycounter lvl 13
I've been messing around with this piece of code for two days trying to figure out a different way to tackle it.

My objective is just to output RGB vertex coloration values eith each line being an index for each vertex in the mesh.

The problem is relatively known and documented, and this is probably mostly a case of me being relatively terrible with numbers and programming as a whole.
Basically max, for whatever reason, stores vert coloration in a completely different set of indices than that of the actual vert array of the geometry, so there's no 1:1 method to take a vertex in the geometry and just find its color values as you would expect.

The geometric face indices are, however, apparently the same as the mesh coloration per-face. I've tried a few things on converting the indices to match one another but something seems to always ruin things for me.

A document i read specified that if you access color-per-face data's vertices by their x y and z, they would correspond to the x y z vertex indices of geometric faces you accessed. this seems simple enough but firstly, the vertices referenced by any given face is stored as a bitarray which, forgive my noob'dom, i can't figure out how to get the specific values for. Once that's sorted, my problem is figuring out the most efficient way to reorder the colours of the vertices to match the indexing of the geometric vertices.

Even writing about this is causing me to lose my shit, though this might be something i've just looked at too long and have built up to be more complicated than it is.

Having googled around a bit, I can't actually find an example of the script i'm trying to make, which is awfully strange because I would have thought it'd be a very common thing for people to want to do. Perhaps i'm just not feeding the right words to google.

Ugh, i'm sure this is all very unclear but anything to make some sense of this for me, or examples of such a script already implemented, would be great.

Replies

  • Buzzy
    Options
    Offline / Send Message
    I just tackled this problem myself recently. Its kind of a pain in the ass.

    There is a very good reason that vertex color is not stored in the same place as vertex geometry. This is because a single vertex can have multiple colors, the same way that a single vertex can have multiple UV map coordinates. For example, in your UV layout, if a vert is on a seam, then that vert has 2 different UV coordinates. Similarly, if you paint one face red, and another face blue, you can end up with a color "seam" and verts on that seam will have multiple colors. Therefore, for every geometry vert, it is possible to have multiple mapping verts and color verts....still with me?

    Now, in any realtime engine (max's viewport included), if a vert ever has multiple data sets (such as multiple UVs or multiple colors), it is NOT actually a single vert, it is in fact multiple verts that just happen to be on top of one another. Max still treats them as a single vert for editing purposes, but it is really and truly multiple verts.

    Faces, however, are always the same (and by 'faces' I mean 'triangles'). So that is our starting point to find the verts you need. Basically, we need to loop through every face and export the 3 color verts in each face as a color and position.

    So, here is a basic script that will grab the vertex positions and colors and put them into a arrays. You can write these to a file however you choose to.
    obj = $
    vertPosList = #()
    vertColList = #()
    
    for f in 1 to (getNumCPVVerts obj) do
    (
      mp = getFace obj f
      mc = getVCFace obj f
      for m in 1 to 3 do
      (
        a = mc[m]
        b = mp[m]
        mPos = getVert obj b
        mCol = getVertColor obj a
        vertPosList[a] = mPos
        vertColList[a] = mCol
      )
    )
    

    EDIT: Note that this script only works on Editable Meshes.
  • Harry
    Options
    Offline / Send Message
    Harry polycounter lvl 13
    Buzzy wrote: »
    Therefore, for every geometry vert, it is possible to have multiple mapping verts and color verts....still with me?
    I read that article, and I understand it would be useful to, for example, have "sharp" edges in the colour mapping... But, how is that actually done using the painting tools? idk.
    Buzzy wrote: »
    for m in 1 to 3 do
    did *not* know that was valid syntax. Thanks!
  • Harry
    Options
    Offline / Send Message
    Harry polycounter lvl 13
    ok so, having had a proper look at that, basically my next step is to eliminate duplicates, get the GEOMETRIC verts by their position, looping through the vertPosList, and assume for each vert found, the vertPosList colour is equal to the vertColList

    thats really pretty stupidly complicated, youd think autodesk would have made a more direct approach rather than have everyone who wants to do this basically write the same program
  • Buzzy
    Options
    Offline / Send Message
    With the painting tool, you can paint by faces instead of verts. This will paint faces solid with sharp color 'seams.'

    No, you do not want to remove duplicates. The script automatically removes duplicates because it writes directly to array indices. For example, if face #12 uses vert #43, it will write to vertPosList[43]. If face #15 also uses vert #43, it too will write to vertPosList[43], and simply overwrite what was there with the exact same data.

    Each vert in vertPosList will correspond with the same vert in vertColList.

    It should be noted that I've never used this to export vert colors, only UVs.



    Looking back, i noticed an error in that script.
    The line that says
    for f in 1 to (getNumCPVVerts obj) do
    
    should read
    for f in 1 to (meshop.getNumMapFaces obj 0) do
    
  • Buzzy
    Options
    Offline / Send Message
    I've been doing some testing with this, and I had assumed it worked the same as UVs, but I'm running into some anomalies. I will mess around and see if i can figure it out.

    But good luck! This is a pain!
Sign In or Register to comment.