C# SDK: Vertex Colors, how to create them?


#1

I want to colorize vertices using C # code, just like described in this picture:

VertexProperties

There is already an older post where exactly this question for unmanged code was answered by Klvnk (Expert).

The c ++ solution looks like this:

mesh.setNumVertCol (4);
mesh.setNumVCFaces (2);

mesh.setMapVert (0, 0, Point3 (0.5f, 0.5f, 0.5f));
mesh.setMapVert (0, 1, Point3 (0.5f, 0.5f, 0.5f));
mesh.setMapVert (0, 2, Point3 (0.5f, 0.5f, 0.5f));
mesh.setMapVert (0, 3, Point3 (0.5f, 0.5f, 0.5f));

Face * faces = mesh.faces;
TVFace * mapfaces = mesh.mapFaces (0);
mapfaces [0] .t [0] = faces [0] .v [0];
mapfaces [0] .t [1] = faces [0] .v [1];
mapfaces [0] .t [2] = faces [0] .v [2];

mapfaces [1] .t [0] = faces [1] .v [0];
mapfaces [1] .t [1] = faces [1] .v [1];
mapfaces [1] .t [2] = faces [1] .v [2];


My implementation in C # looks like this, but it doesn’t work.
The vertices keep their existing color and are not colored blue.
What am I doing wrong ?

[…]
var mesh = triObject1.Mesh;

mesh.SetMapSupport (0, true);

mesh.SetNumVertCol (mesh.NumVerts, false);
mesh.SetNumVCFaces (mesh.NumFaces, false, 0);

var vertexColorCount = mesh.NumCVerts;

// Blue Color
var vertexColor = Global.Point3.Create (0.0f, 0.0f, 1.0f);

for (var i = 0; i <vertexColorCount; i ++)
{
mesh.VertCol [i] = vertexColor;
}

var mapFaces = mesh.MapFaces (0);
var mapFacesCount = mapFaces.Count;

for (var i = 0; i <mapFacesCount; i ++)
{
mapFaces [i] .T [0] = mesh.Faces [i] .V [0];
mapFaces [i] .T [1] = mesh.Faces [i] .V [1];
mapFaces [i] .T [2] = mesh.Faces [i] .V [2];
}
[…]


#2

how are you checking it’s been set ? the viewport is notoriously poor for updating/showing this shit…

does it show up on the editmesh panel as per your firstimage ?


#3

Here is a long thread with a lot of code and ideas to solve what you need:


#4

I don’t think it’s a refresh problem.
Even after save/reload the vertex color is not set when I check it in the vertex properties (as in the picture above).

A check with Export as 'ASCII Scene Export ’ (ase) also showed that only the old color is present in the vertices and not the one assigned by the code.

  • MESH_NUMCVERTEX 8
  • MESH_CVERTLIST {
  • MESH_VERTCOL 0 1.0000 1.0000 1.0000
  • MESH_VERTCOL 1 1.0000 1.0000 1.0000
  • MESH_VERTCOL 2 1.0000 1.0000 1.0000
  • MESH_VERTCOL 3 1.0000 1.0000 1.0000
  • MESH_VERTCOL 4 0.8471 0.0000 1.0000
  • MESH_VERTCOL 5 0.8471 0.0000 1.0000
  • MESH_VERTCOL 6 0.8471 0.0000 1.0000
  • MESH_VERTCOL 7 0.8471 0.0000 1.0000

#6

my guess is the line…

var mesh = triObject1.Mesh;

is probably the culprit as it’s probably making a copy of the entire mesh
try adding

triObject1.Mesh = mesh;

at the end (asssuming you don’t already). I’m not sure whether c# can be made to use references.


#7

Bingo!
The line at the end does the job.
Thank you!!!

triObject1.Mesh = mesh ;
actually pulls a copy, what a crappy SDK.

(I also have the refresh problems you wrote about in your first post. But the main thing is that it works now)


#8

I’ve found a set of examples from an autodesk blog where
they use… something like…

triObject1.Mesh.SetMapSupport (0, true);
triObject1.Mesh.SetNumVertCol (triObject1.Mesh.NumVerts, false);
triObject1.Mesh.SetNumVCFaces (triObject1.Mesh.NumFaces, false, 0);

to avoid having to copy the whole mesh twice


#9

I’ve already implemented this without the unnecessary copying (see code below)

However, I noticed that the code only colors the vertices when the command is applied to an Editable Mesh. (Although it was previously converted to ITriObject using the TryConvertToTriObject method)

If the command is called on an Editable Poly, the vertices are not colored.

I’m not a hardcore 3ds Max user, but shouldn’t the Editable Mesh and Editable Poly vertices be the same?

protected ITriObject TryConvertToTriObject(IINode node)
{
// Get it’s current object state. If a modifier has been applied, for example,
// it is going to return the OS of the mesh in it’s current form in the timeline.
var os = node.ObjectRef.Eval(Ip14.Time);
// Now grab the object itself.
var objOriginal = os.Obj;
// Let’s make sure it is a TriObject, which is the typical kind of object with a mesh
if (!objOriginal.IsSubClassOf(Global.TriObjectClassID))
{
// If it is NOT, see if we can convert it…
if (objOriginal.CanConvertToType(Global.TriObjectClassID) == 1)
objOriginal = objOriginal.ConvertToType(Ip14.Time, Global.TriObjectClassID);
else
return null;
}
var triOriginal = objOriginal as ITriObject;
return triOriginal;
}

public void TestVerticesToBlue()
{
var node1 = Ip14.GetSelNode(0);
if (node1 == null)
return;
var triObject = TryConvertToTriObject(node1);
if (triObject != null)
{
triObject.Mesh.SetMapSupport(0, true);
triObject.Mesh.SetNumVertCol(triObject.Mesh.NumVerts, false);
triObject.Mesh.SetNumVCFaces(triObject.Mesh.NumFaces, false, 0);
var vertexColorCount = triObject.Mesh.NumCVerts;
//Blue Color
var vertexColor = Global.Point3.Create(0.0f, 0.0f, 1.0f);
for (var i = 0; i < vertexColorCount; i++)
{
triObject.Mesh.VertCol[i] = vertexColor;
}
var mapFaces = triObject.Mesh.MapFaces(0);
var mapFacesCount = mapFaces.Count;
for (var i = 0; i < mapFacesCount; i++)
{
mapFaces[i].T[0] = triObject.Mesh.Faces[i].V[0];
mapFaces[i].T[1] = triObject.Mesh.Faces[i].V[1];
mapFaces[i].T[2] = triObject.Mesh.Faces[i].V[2];
}
}
}


#10

i think what you are getting from the EditablePoly is another copy of it’s mnmesh as a mesh so any changes you make are not changing the original… you need to modify mnmesh directly
ie (a c++ snippet from our vertex tint modifier

if(obj->IsSubClassOf(triObjectClassID))  // Handle any triobject types
	{
		map_utils::modify((TriObject*)obj, p,t);
	}
	else if(obj->IsSubClassOf(polyObjectClassID)) // Handle any PolyObject types
	{
		map_utils::modify((PolyObject*)obj,p, t);
	}
	else if(obj->IsSubClassOf(patchObjectClassID))  // Handle any PatchObject types
	{
		map_utils::modify((PatchObject*)obj, p, t);
	}
	else if(obj->CanConvertToType(triObjectClassID)) // all others should try to convert to a triobject, 
	{
		TriObject  *triOb = (TriObject *)obj->ConvertToType(t, triObjectClassID);
		os->obj = triOb; // Now stuff this into the pipeline!
		map_utils::modify(triOb, p ,t);
	}