[Closed] Plugin implementing TriMesh?
Hello,
In my plugin, I have a third-party application which generates, and updates, geometry.
My plugin operates by creating a TriMesh and using the API to create and set vertices within it, then the geometry changes, the vertices are updated accordingly. That is, the TriMesh object maintains a copy of the third-party geometry data.
I recall reading some time ago that it was possible for a plugin to create its own TriMesh ‘equivalent’, maintaining the geometric data itself and being able to sit at the bottom of the stack and allow Max modifiers to work with it.
I would like to do this, to reduce the time it takes to update the geometry, but cannot find any reference to this feature.
Does this even exist or am I mis-remembering? Can anyone point me to the documentation on it?
Sorry that would have been helpful! The SDK. (My plugin uses the .NET SDK but this reference was in the C++ documentation.)
EDIT
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[0].Handle.ToPointer();
MaxTVFace* tvfaces = (MaxTVFace*)maxMesh.TvFace[0].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?