Notifications
Clear all

[Closed] Get Mesh or MNMesh of Editable Poly after NURMS subdiv

You know that an editable poly has the option to tessellate mesh using NURMS subdivision.
How can I get the MNMesh after subdivision?

The current mesh is before subdivision. The sample from SDK (polyedit.h) says the subdivided mesh is in mPreviewMesh or subdivResult. But both of them are private properties.

Any ideas?

6 Replies

grab a copy of the mnmesh and run SmoothByCreases on it ?

This is an auto-smooth algorithm that allows the developer to specify exactly which edges should be creases and which should be smoothed across. All face smoothing groups are rewritten by this algorithm. This algorithm is used, for example, in MeshSmooth, NURMS style, when the user turns on “smooth result” and applies crease values to some edges.

see

void EditPolyObject::UpdateSubdivResult (TimeValue t)  

in polyedit.cpp

I want to get it. Not to make.

The idea is to find a way to get a MNMesh that already made and prepared for preview.
For high poly models it takes a time to do tessellation. The result is stored in the poly object but there is no easy access to it.

PolyObject::GetRenderMesh will return the subdivision mesh

1 Reply
(@denist)
Joined: 2 years ago

Posts: 0

this is true i do it. but it takes a time to convert mesh to MNMesh

Object *EditPolyObject::ConvertToType (TimeValue t, Class_ID obtype)

sets it’s mnmesh to subdivResult if subdiv is set
then calls


Object *ret = pobj->ConvertToType (t, obtype);

which should default to (return this)

so a call of
pobj->ConvertToType (t, polyObjectClassID)

should return a polyobject with the mnmesh set to subdivResult of pobj

Just run a test and it works btw.

def_struct_primitive(polyop_OutToMesh, polyop, "OutToMesh");


Value* polyop_OutToMesh_cf(Value** arg_list, int count)
{
	check_arg_count(OutToMesh, 1, count);
	if (arg_list[0]->is_kind_of(class_tag(MAXNode))) 
	{
		get_valid_node(arg_list[0], OutToMesh);
		Object* obj = ((MAXNode*)arg_list[0])->to_node()->GetObjectRef();
		Object* base_obj = Get_Object_Or_XRef_BaseObject(obj);
		if (base_obj->ClassID() != EPOLYOBJ_CLASS_ID)
			throw RuntimeError (GetString(IDS_POLY_OPERATION_ON_NONPOLY), obj->GetObjectName());

		PolyObject* pobj = (PolyObject*)((PolyObject*)base_obj)->ConvertToType(0,polyObjectClassID);
		MNMesh& pmesh = pobj->GetMesh();
		TriObject* tobj = CreateNewTriObject();
		if(tobj)
		{
			INode* node = NULL;
			node = MAXScript_interface->CreateObjectNode(tobj);
			if(!node)
				tobj->DeleteThis();
			else
				pmesh.OutToTri(tobj->GetMesh());
			if(pobj != base_obj) // if no subdiv then no delete
				pobj->DeleteThis();
			if(node)
				return MAXNode::intern(node);
		}
		return &undefined;
	}
	
	return &undefined;
}
1 Reply
(@denist)
Joined: 2 years ago

Posts: 0

This’s the solution. Thank you! I can’t understand how I could miss it