[Closed] Vertex color sanity check
Hi all,
Im trying to simply retreive the vertex color per vertex (not per mapvertex!!).
In the manual there is a pseudo code example
In order to find out which texture vertex corresponds to a mesh vertex, you have to do the following:
- Take the index of the mesh vertex.
- Find out which faces reference the index of the face.
- Note the number of the vertex (1st, 2nd or 3rd – .x, .y or .z) inside each face.
- For each face referencing the vertex, get the texture face with the same index.
- Get the index of the respective texture vertex from the face – 1st, 2nd or 3rd / .x, .y or .z
- The vertex you got corresonds to the mesh vertex we started with.
- Repeat steps 3 to 6 for all faces found.
Same applies to color vertices.
From that I came up with this:
o = $.mesh
vchannel = 0
vert = 145
[I]-- Get all faces using the vert as array[/I]
fArray = (meshop.getFacesUsingVert o vert) as array
[I]-- Get back vert order from face[/I]
vArray = (meshop.getVertsUsingFace o fArray[1]) as array
[I]-- Find the order of the vert in the face[/I]
f = findItem vArray vert
[I]-- Retreive verts from map face (map face corresponds with normal face[/I]
mV = (meshop.getMapVertsUsingMapFace o vchannel fArray[1]) as array
[I]-- Vert order should be the same[/I]
v = mV[f]
[I]--getVertColor o v[/I]
255.*(meshop.getMapVert o vchannel v)
Is this ok, it does work, but I don’t do this vertex color thing alot, maybe someone can confirm…
Thanks,
-Johan
Not quite.
(
theMesh = snapshotasmesh $ --get the TriMesh into memory
vchannel = 0 --define vcolor channel index
vert = 1 --this is the vertex we are looking at
-- Get all faces using the vert as array
fArray = (meshop.getFacesUsingVert theMesh vert) as array
for f in fArray do -- for each face,
(
--Get geometry face - vertex is either its first, second or third component
gF = getFace theMesh f
-- Get map face (index corresponds with geometry face)
mF = meshop.getMapFace theMesh vchannel f
-- Find order inside the mesh face - vertex (component) order will be the same in both
mV = case of
(
(gF.x == vert): mF.x
(gF.y == vert): mF.y
(gF.z == vert): mF.z
)
--show the value
format "Face: %, MapVertex: %, Color: %
" f mV (255.*(meshop.getMapVert theMesh vchannel mV))
)--end f loop
delete theMesh --release the mesh from memory
)--end script
For example, every mesh vertex of a geosphere with some vertex colors painted will have either 5 or 6 corresponding map vertices, each with its own value (usually the same, but sometimes not).
Here are the results from the first 4 vertices of a geosphere I painted some red on the north pole of:
Face: 1, MapVertex: 1.0, Color: [255,0,0]
Face: 2, MapVertex: 4.0, Color: [255,0,0]
Face: 3, MapVertex: 7.0, Color: [255,0,0]
Face: 4, MapVertex: 10.0, Color: [255,0,0]
Face: 5, MapVertex: 13.0, Color: [255,0,0]
0
Face: 1, MapVertex: 2.0, Color: [255,234.729,234.729]
Face: 5, MapVertex: 15.0, Color: [255,234.729,234.729]
Face: 6, MapVertex: 18.0, Color: [255,234.729,234.729]
Face: 10, MapVertex: 29.0, Color: [255,234.729,234.729]
Face: 11, MapVertex: 31.0, Color: [255,234.729,234.729]
Face: 12, MapVertex: 34.0, Color: [255,234.729,234.729]
0
Face: 1, MapVertex: 3.0, Color: [255,219.35,219.35]
Face: 2, MapVertex: 5.0, Color: [255,219.35,219.35]
Face: 6, MapVertex: 17.0, Color: [255,219.35,219.35]
Face: 7, MapVertex: 21.0, Color: [255,219.35,219.35]
Face: 13, MapVertex: 37.0, Color: [255,219.35,219.35]
Face: 14, MapVertex: 40.0, Color: [255,219.35,219.35]
0
Face: 2, MapVertex: 6.0, Color: [255,239.686,239.686]
Face: 3, MapVertex: 8.0, Color: [255,239.686,239.686]
Face: 7, MapVertex: 20.0, Color: [255,239.686,239.686]
Face: 8, MapVertex: 24.0, Color: [255,239.686,239.686]
Face: 15, MapVertex: 43.0, Color: [255,239.686,239.686]
Face: 16, MapVertex: 46.0, Color: [255,239.686,239.686]
0
If you take a box and paint a different color on each side of it, its corner vertices would need different map vertices to accomodate the color of each side. So you cannot assume there is ONE map vertex there giving the mesh vertex its color, there can be ANY number of map vertices, one per each face sharing that vertex. In some cases, these faces might reference the SAME map vertex, but in many cases they don't.
Another example, the pole of a Sphere has as many map vertices as there are segments in the sphere. Unwrap it and you will see a row of map faces at the poles, each with its own map vertex.
I see the pseudo code in the Reference is not clear, will try to add a real code example next time around.
Bobo, thanks so much for your example, it does make sense… only…
I need to export a vert color per vertex, it’s like exporting a weightmap, which can have only 1 value per vertex. I use vertex paint to paint the weights (since max obviously hasn’t got weight maps, like maya/xsi)… So with that in mind, I only sample 1 face per vertex, since I’m assuming from the start that the painted vertex colors are going to be continous. I could also sample all the mapverts corresponding with the right faces and get back the avarage of that, but I think it’s overkill.
With that in mind (which I should have stated in my first post offcourse) is my method still sound, cause I only need 1 color per vertex back…
Thanks,
-Johan
prepares for some more testing
Nope, your method is not sound. It uses findItem to find something that has no relevance to what you are trying to do, and would work just by accident but not because it is correct.
To get just one value, remove my FOR loop and just set F=1 instead. The rest can remain the same as you need to check the .x, .y and .z components of the Face and MapFace definitions to see which vertex corresponds to which mapVertex.
Hello,
Thank you very much for this post. This code really helps me.
However, I’d like to ask about the vchannel variable. I saw in the manual, and it’s an Integer which stands for the mapChannel of the face, but I really don’t understand this. Could someone explain me or tell me where to get this information?
I tried writing this same function, but I got an error:
– Runtime error: Map support not enabled for specified map channel: 0
As I said, I don’t understand this. I then set vchannel to 1 and it worked, but I’d like to understand a bit more about what I’m writing.
Thank you again.
By default an object has no vertex colors and so no information in map channel 0. So if you haven’t assigned them explicitly this failure will occur. Collapse the object to mesh/poly and assign vtx colors by hand. Do you still have the problem then?
-Johan
I can’t find out how to assign by hand.
I tried using setNumCPVVerts $ (getNumVerts $) true and I still get the same error after I execute the function I want.
Then I tried meshop.setNumCPVVerts (getNumVerts $) 162, and it doesn’t work, I get the same error after executing this one.
How then can I “assign vtx colors by hand”. (I have already converted it to Mesh).
Thank you.
NOTE: if a leave vchannel = 1, the function does work. However, if after that I assign a material, I still get the same values. So it is like the material assignment is not being registered, or the function is not working…
Okay, I think that assigning vertex colors by hand means to apply the VertexPaint modifier, am I right? By doing this, I can execute the Bobo-function with vchannel = 0 and get no errors.
The question that still remains is the color itself. The first time I execute the function I get that every vertex is white, and after I assign more materials, I still get the same answer.
How can I fix this?
Hi,
Try this code
b = box heightSegs:10 widthSegs:10 lengthSegs:10
convertToPoly b
-- enable viewport shading
b.showVertexColors = true
b.vertexColorsShaded = false
b.VertexColorType = #color
-- Only works in 2008 and higher
polyOp.setMapSupport b 0 true
-- Get vertColor vert count
vc = polyOp.getNumMapVerts b 0
-- Create color as point3 value
c = (orange as point3) / 255
-- Loop over all verts and assign a vertex color
for i in 1 to vc do
polyOp.setMapVert b 0 i c
-- redraw views
completeRedraw()
Goodluck,
-Johan
Thank you for your answer, JHN.
I didn’t try the code because I don’t have 3DS 2008. But I found out how to fix what I was trying to do.
I have another question, though. I modified a bit the Bob-function so instead of telling me the colour of a given vertex, it applies another colour. I just used meshop.setMapVert, and it works. But only for the viewport. There I can see the changes the functions applies, but then it doesn’t render. The object rendered appears with the initial colour it had when it was first created; as ignoring the changes applied by the function.
What do I need to add after I set the vertex colout in order to get the object propperly rendered?
Thank you again
So have you an vertex color map applied to your material… vertex colors don’t render without the special vertex color map applied to the diffuse slot of a material. You have to tell the renderer which color to render, just like max when an material is applied to a object it doesn’t render the object(wireframe) color anymore.
-Johan