Notifications
Clear all

[Closed] [SDK] Fast alternative for CombineMesh?

Hi,
I am using CombineMEsh function to combine meshes, but its very slow,
I tried quickly override it by directly copying buffer using memcpy and I notices that this soultion is faster…

But I will probably turn to my own buffers and just copy final result to Mesh structure,
but first I would like to check if there is a faster or better alternative? Thanks.

8 Replies

are just combining 2 meshes say at a time or are you joining say 4000 at a time ?

Just 2 at one time

Here are some tests, the particle flow (not standard particles) emits 2000 particles and all are seen on the screen:

  • when particles are as cubes the fps is almost maximum about 150-200 fps
  • when I use my plugin and Combine Mesh that replaces particles by cubes the performace is slowing to: from 200 fps with 1 particle to 3-4 fps with 2000 particles
  • when I replace Combine Mesh with my function where I use memcpy to copy the vertex and faces buffers I am getting 45 fps with 2000 particles… so it is much faster

But still is slower than cubes generated by particle flow, notice that emmiting that same amout of cubes from standard particles slows to 4-5 fps with 2000 particles…

I wonder why? and I would like to have even more speed while creating my mesh…

PFlow is not combining meshes. It is using GPU instancing for display.

With 2000 cubes, 45 FPS is very good.

Thanks for clarifying

you can write a c++ version of the clusterattach msx function can speed things up a bit when there a lot of meshes to attach but for 2 at a time there no speed benefits. But your right the built in function is pretty slow. Theres other speed consideration does all the mesh need it’s verts transforming first prior to attaching, what mapping channels and specified normals are in the target and source (if they are not in one being attached 2 then you have to create them for example)

heres the clusterattach function by the way

function clusterAttach objArr =
(
	j = 1
	count = objArr.count
		
	undo off
	(
		while objArr.count > 1 do
		(				
			if classof objArr[j] != Editable_Poly then converttopoly objArr[j]
				
			polyop.attach objArr[j] objArr[j+1]
			deleteItem objArr (j+1)
				
			j += 1
			if (j + 1) > objArr.count then j = 1
		)
	)
	return objArr[1]
)

Thanks, yes I have seen it…

I think I will leave it for now, the memory blocks copying is quite fast, but I make some additional tests and find out that getting particle position is consuming lots of performance:

INode *tmp_node;
pblock2->GetValue(pb_source_pick, t, tmp_node, ivalid);
	
ObjectState tos = tmp_node->EvalWorldState(t, TRUE);

IParticleObjectExt* epobj = NULL;
epobj = (IParticleObjectExt*)tos.obj->GetInterface(PARTICLEOBJECTEXT_INTERFACE);

	if (epobj)
	{
		epobj->UpdateParticles(tmp_node, t);
		int part_count = epobj->NumParticles();

		myMesh.FreeAll();
		myMesh.setNumVerts(8 * part_count);
		myMesh.setNumFaces(12 * part_count);

		for (int part_id = 0; part_id < part_count; part_id++)
		{
                    // accesing particle properties is quite time consuming
			part_pos = epobj->GetParticlePositionByIndex(part_id);
		}
	}

Is there other way to acces particles?

Hello, I’m also looking to speed up attaching meshes and have tried just about everything i could find on these forums. Curious about using memcpy. I’ve tried implementing a function using it in a modifier but i’m not really seeing any performance boost. There must be something I’m missing, does anyone have any ideas?

void meshMemCopy(Mesh& dest, Mesh& src)
{
    int vCount{ dest.numVerts };
    int fCount{ dest.numFaces };
    dest.setNumVerts(vCount + src.numVerts, true);
    dest.setNumFaces(fCount + src.numFaces, true);

    memcpy(&(dest.verts[vCount]), src.verts, sizeof(Point3) * src.numVerts);
    memcpy(&(dest.faces[fCount]), src.faces, sizeof(Face) * src.numFaces);

    for (int i{ fCount }; i < dest.numFaces; i++)
    {
        DWORD* v = dest.faces[i].v;
        DWORD vArr[3]{ v[0] + vCount,v[1] + vCount,v[2] + vCount };
        memcpy(v, &vArr, sizeof(vArr));
    }
}