Notifications
Clear all

[Closed] Sdk attach mesh

Can some one give me some pointers on how to attach objects in the sdk? I have been looking trough the samples but I haven’t find a solution.

Lets say I get a plane from max or I create it in the sdk then I copy this plane trough the scene, I want to end up with just one mesh not the hundreds of copies.

Appreciate any help.
Guillermo

7 Replies

in simplest terms

amesh = amesh + bmesh;

for an example see the mesher object in the sdk

or you can use the MeshDelta::AttachMesh function as used by meshop_attach routine in mxsagni project

Check this:

Thanks for the replay, Both are good examples but I have another related question before I actually do the attaching.

If I do it the way I initially thought I would have to physically create hundreds of objects then attached them, like this…

  • create a plane node
  • create lets say 200 copies and scatter them on a surface
  • change the position and rotation on each plane
  • attach all of them into a single mesh or poly

Is there a way to create them virtually with out actually creating a node so it does not show up and slows max until I have a single mesh of all attached planes.

I need a node if I want to change the transformations of each plane right ?

no need to create nodes, you only need recreate the transform that would be for the nodes position. And if they are all clones the just grab one version of it’s mesh and keep attaching it in the new positions… again look at the mesher example in sdk it does exactly that.

void AttachMesh(Mesh& mesh, Mesh& amesh, Tab<Matrix3>& xforms)
{
	for(int i = 0; i < xforms.Count(); ++i)
	{
		Matrix3& tm = xforms[i];
		Mesh tmesh;

#if __LOOKING_FOR_A_BIT_MORE_PERFORMANCE
		tmesh.CopyBasics(amesh); // simplified version
#else
		tmesh = amesh;
#endif
		tm.TransformPoints(tmesh.verts, tmesh.numVerts);
		mesh = mesh + tmesh;
	}
}

or possibly something like…

void AttachMesh(Mesh& mesh, Mesh& amesh, Tab<Matrix3>& xforms)
{
	for(int i = 0; i < xforms.Count(); ++i)
	{
		int old_vert_count = mesh.numVerts;
		mesh = mesh + amesh;
		xforms[i].TransformPoints(&mesh.verts[old_vert_count], amesh.numVerts);
	}
}

not tested btw

Thanks Klvnk

I did the following test before I saw you replay and it seems to be working but I’m not sure if its the right way to do it.

One thing is that when I tried by writing mesh = mesh + tmesh; like you have it, I lost the uv’s of the original plane.

I used CombineMeshes which I saw used on particalmesher.cpp, collapse.cpp and Parray.cpp and it seems to work fine, Why should I use mesh = mesh +tmesh ?

I have a few questions on the code below.

  • On creating the plane: How do you find out what the id’s for setting the parameters for the plane? I used the code you posted here. Creating plane with 3dsMax SDK and guessed about the uv’s but the realscale does not seems to be doing anything.
  • On the loop where I create 6 copies how do I delete the copyMesh ? if I delete it max crashes.
  • Also it seems I need to delete the tempMesh too but it also crashes max.
Interface *ip = GetCOREInterface();

int planeWsegs = 1;
int planeLsegs = 1;
bool planeUV = true;
bool planeWorldScale = false;
float planeSize = 5.0f;

SimpleObject2* planeObj = (SimpleObject2*)GetCOREInterface()->CreateInstance(GEOMOBJECT_CLASS_ID, PLANE_CLASS_ID);

IParamBlock2* pb = (IParamBlock2*)planeObj->GetReference(0);
if (pb)
{
pb->SetValue(1, 0, planeSize*2.0f);
pb->SetValue(0, 0, planeSize);
pb->SetValue(2, 0, planeWsegs);
pb->SetValue(3, 0, planeLsegs);
pb->SetValue(6, 0, planeUV);
pb->SetValue(7, 0, planeWorldScale);
}

Object *obj = planeObj->CollapseObject();

int t = 0;
TriObject *tri = NULL;

if (obj->CanConvertToType(Class_ID(POLYOBJ_CLASS_ID, 0)))
{
PolyObject *pTri = (PolyObject *)obj->ConvertToType(t, Class_ID(POLYOBJ_CLASS_ID, 0));

  if (pTri->CanConvertToType(Class_ID(TRIOBJ_CLASS_ID, 0))) {

  	tri = (TriObject *)pTri->ConvertToType(t, Class_ID(TRIOBJ_CLASS_ID, 0));
  }

}

Mesh& planeMesh = tri->GetMesh();

Mesh tempMesh;
tempMesh.DeepCopy(&tri->GetMesh(), GEOM_CHANNEL | TOPO_CHANNEL | TEXMAP_CHANNEL | MTL_CHANNEL | DISP_ATTRIB_CHANNEL | TM_CHANNEL);

for (int m = 0; m < 5; m++)
{
Matrix3 tm(1.0);
Matrix3 rotate;
Mesh copyMesh = tri->GetMesh();

  tm.Translate(Point3((planeSize*2) + m, 0.0f, 0.0f));

  // Move the new plane around
  for (int v = 0; v < copyMesh.numVerts; v++)
  {
  	copyMesh.verts[v] = copyMesh.verts[v] * tm;
  }

  CombineMeshes(planeMesh, tempMesh, copyMesh);

}

planeMesh.InvalidateGeomCache();

INode* planeNode = GetCOREInterface()->CreateObjectNode(tri);

TSTR name(T(“superPlane“));
ip->MakeNameUnique(name);
planeNode->SetName(name);

Point3 pt(5.0, 5.0, 0.0);
Matrix3 tm;
tm.SetTranslate(pt);
planeNode->SetNodeTM(TimeValue(0), tm);

Guillermo

you find them in gridobj.cpp (prim project)

  enum { grid_length,
    	   grid_width,
    	   grid_wsegs,
    	   grid_lsegs,
    	   grid_rsegs,
    	   grid_rscale,
    	   grid_genuvs,
    	   grid_leftover,
    	   grid_leftover1,
    	 };

and copymesh looks like a local variable thats deleted when it goes out of scope.

Thanks for all the help.