Maxscript - Update/Replace trimesh data in Editable Poly and Edit_Poly modifier?


#1

Is it possible to directly change the trimesh in an editable poly and edit_poly modifier?

I want to create faces from verts on an existing model, but the “createFace” command is absurdly slow (seems to update the entire mesh for each individual face created). If a command existed to create many faces at once instead of needing to use loops maybe this could be avoided, but afaik no such command exists. I figured maybe if I can create a trimesh with the needed modifications and just use that to replace the old data this performance issue could be avoided.


#2

have you tried using

MNMesh::setNumVerts
MNMesh::setNumFaces

and then create the face…

MNFace::MakePoly

?

this from my polyextrude mod…

static void BuildMeshFromPolyLine(MNMesh &pmesh, PolyLine& pline, float offset_amount)
{
	int num_polyline_points =  pline.numPts;
	if(!num_polyline_points) return;
	
	int num_segs = num_polyline_points;
	int num_verts = num_polyline_points * 2;
	int num_faces = num_polyline_points;

	pmesh.setNumVerts(num_verts);
	pmesh.setNumFaces(num_faces);

// verts

	int vi = 0;
	MNVert* verts = pmesh.v;
	for(int v = 0; v < num_polyline_points; ++v)
	{
		verts[vi].p = pline.pts[v].p;
		vi++;
	}
	
	for(int v = 0; v < num_polyline_points; ++v)
	{
		verts[vi].p = pline.pts[v].p;
		verts[vi].p.z = offset_amount;
		vi++;
	}

	int fi = 0;
	int fverts[4];
	MNFace* faces = pmesh.f;
	for(int f = 0; f < num_segs; ++f)
	{	
		fverts[0] = f;
		fverts[1] = (f + 1) % num_segs;
		fverts[2] = fverts[1] + num_segs;
		fverts[3] = fverts[0] + num_segs;
		faces[fi].MakePoly(4,fverts);
		fi++;
	}
	pmesh.FillInBorders();



	pmesh.InvalidateGeomCache();
	pmesh.InvalidateTopoCache();
	pmesh.FillInMesh();
}

doesn’t seem to suffer from any performance issues


#3

Oops, should have mentioned I’m doing this in Maxscript.
Is it possible to set the number of faces and verts like that via maxscript for Editable_Poly and Edit_Poly?


#4

You can append some trimesh to poly mesh using c# sdk.



with redraw off
(	
	g = (dotNetClass "Autodesk.Max.GlobalInterface").Instance

	-- make a demo trimesh
	global tmp_trimesh = TriMesh()
	tmp_trimesh.numfaces = 1
	tmp_trimesh.numverts = 3
	setvert tmp_trimesh 1 [0,0,7]
	setvert tmp_trimesh 2 [0,5,7]
	setvert tmp_trimesh 3 [5,5,7]
	
	setface tmp_trimesh 1 [1,2,3]

-- or you can use some built in primitive mesh
--  	tmp_trimesh = (createInstance GeoSphere radius:3).mesh
-- 	mesh mesh:tmp_trimesh wirecolor:yellow

	-- get native trimesh from temporary global mxs value
	fpv = g.fpvalue.create()	
	g.executemaxscriptscript "::tmp_trimesh" true fpv

	-- make a target poly object
	tea = Teapot radius:5 segments:4
	convertToPoly tea

	-- append this trimesh to poly mesh
	inode  = g.COREInterface7.GetINodeByHandle tea.inode.handle asdotnetobject:true
	iobj   = inode.evalworldstate (currenttime as integer) true asdotnetobject:true
	mnmesh = iobj.obj.mesh
		
	mnmesh.addtri fpv.msh

	globalVars.remove #tmp_trimesh

	update tea
)

tmp_trimesh -- should now be undefined

#5

I see you are an active user c# sdk, Serejah … There is a good news for you. In modern versions of MAX (2020, 2021), the optional #asdotnetobject argument defaults to TRUE. :grin:


#6

I’m just too lazy to dive into cpp to prototype something, so yeah turns out I’m a fan of c# sdk. :grin:
I hope AD won’t make c# deprecated too fast.


#7

just whenever I write “asdotnetobject” it drives me crazy - why the hell did they do it by default FALSE … now I won’t


#8

I have to check it again, but in max 2021 this problem is solved:


Swordslayer

Sep '19

This is the problem:

g = (dotNetClass "Autodesk.Max.GlobalInterface").Instance
g.CoreInterface --> this is all that's needed to break everything
g.CoreInterface7.SnapAngle_

Any CoreInterface that’s queried first is the one that gets returned for all the other ones after it. Here this returns true:

g.CoreInterface == g.CoreInterface7

It shouldn’t and I already filed a bugreport but don’t think it will help.

#9

definitely this method must be used to get the latest coreinterface

(dotNetClass "Autodesk.Max.GlobalInterface").Instance.UtilGetCOREInterface***

#10

Thanks for the help Serejah.
Had a follow up question; How would you go about setting edge visibility using this method? It seems that mnmesh discards edge data. I tried setting the edge visibility directly on the the mnmesh directly using setEdgeVis, but it always returns undefined.


#11

DllExport void SetEdgeVis ( int ee, BOOL vis = TRUE )
this method returns nothing so it is ok