Sorry that would have been helpful! The SDK. (My plugin uses the .NET SDK but this reference was in the C++ documentation.)
I think what I was referring to was this page here:
When you develop a geometric object that inherits from SimpleObject2 you will have to construct and initialize the SimpleObject::mesh member variable which is of type Mesh.
This isn’t really what I want though, I am happy to use TriObject, which itself is a GeomObject. What I want is a way to update the common mesh member as quickly as possible. According to the documentation on mesh and documentation on PerData, the mesh class contains the vertex data in a set of PerData instances, from which I can get pointers to the actual data, although mesh has a number of helper methods to address these correctly.
I have managed to set mesh data directly using these in .NET, in the following way if anyone else is interested.
For example, to set the vertex positions or texture coordinates, the GetVertPtr() or GetTVertPtr() can be used like so:
IPoint3 p3 = maxMesh.GetVertPtr(0);
Marshal.Copy(myMesh.Vertices.ToArray(), 0, p3.Handle, myMesh.NumVertices * 3);
Where myMesh.Vertices is a float array of (x,y,z) coordinates. In the C++ SDK these methods return pointers to the vertex data, which can be accessed using the Handle member of the IPoint3 object returned by the .NET counterpart.
And for the faces:
unsafe struct Indices3
public UInt32 v1;
public UInt32 v2;
public UInt32 v3;
unsafe struct MaxFace
public Indices3 v;
public UInt32 smGroup;
public UInt32 flags;
/* Get the default flags value */
IFace referenceFace = globalInterface.Face.Create();
referenceFace.SetEdgeVisFlags(EdgeVisibility.Vis, EdgeVisibility.Vis, EdgeVisibility.Vis);
MaxFace referenceMaxFace = *(MaxFace*)referenceFace.Handle.ToPointer();
UInt32 referenceFlags = referenceMaxFace.flags;
/* Create the faces that define the surface of the mesh */
MaxFace* faces = (MaxFace*)maxMesh.Faces.Handle.ToPointer();
MaxTVFace* tvfaces = (MaxTVFace*)maxMesh.TvFace.Handle.ToPointer();
for (int i = 0; i < myMesh.TriangulatedFaces.Length; i++)
Face myFace = myMesh.TriangulatedFaces[i];
faces[i].v.v1 = (UInt32)myFace.PositionVertex1;
faces[i].v.v2 = (UInt32)myFace.PositionVertex2;
faces[i].v.v3 = (UInt32)myFace.PositionVertex3;
faces[i].flags = (UInt32)((ushort)myFace.MaterialId << 16) | (ushort)referenceFlags;
tvfaces[i].v1 = (UInt32)myFace.TextureVertex1;
tvfaces[i].v2 = (UInt32)myFace.TextureVertex2;
tvfaces[i].v3 = (UInt32)myFace.TextureVertex3;
Obviously the source data structures are not optimised for this yet.
This also assumes that the memory allocated for each channel is continguous, can anyone confirm this?