Mesh Operation - Automatic implementation

From The Foundry MODO SDK wiki
Revision as of 16:28, 28 June 2016 by Mattcox (Talk | contribs) (C++)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Mesh Operations can be integrated directly into the procedural modelling system, allowing them to be evaluated as part of the procedural stack. A modifier should spawn the ILxMeshOperation server and store it in the MeshOpObj channel on the Mesh Operation Item. This channel is then evaluated by the procedural modelling system, and it's functions are called to perform the mesh edit.

For the majority of Mesh Operations, this modifier code is boiler plate and completely generic. Therefore, we provide a simplified path that automatically generates an Mesh Operation item from an ILxMeshOperation server.

Applying the following server tag to an ILxMeshOperation interface, will automatically create a mesh operation item and a modifier. The modifier will write the ILxMeshOperation server into a channel, so that it can be evaluated as part of the procedural system. The ILxMeshOperation should also implement an Attributes interface, that will allow attributes to converted into channels on the newly created item. The value of this tag doesn't matter, as the presence of the server tag alone is enough to automatically create a mesh operation item. The name of the mesh operation item, will be the name of mesh operation server, with ".item" appended at the end.

#define LXsMESHOP_PMODEL                "pmodel.meshop"

Sample Code

The following sample code implements a very basic mesh operation that creates a grid at the centre of the world. The size attribute is converted into a channel that can be manipulated or animated by the user. For simplicity, this example does not perform re-evaluation, but simply evaluates from scratch every time the size channel changes.

class MeshOperation : public CLxImpl_MeshOperation, public CLxDynamicAttributes
		MeshOperation ()
			dyna_Add ("size", LXsTYPE_DISTANCE);
			attr_SetFlt (0, 0.5);
		mop_Evaluate (
			ILxUnknownID		 mesh_obj,
			LXtID4			 type,
			LXtMarkMode		 mode)			LXx_OVERRIDE
			CLxUser_Mesh		 mesh (mesh_obj);
			CLxUser_Polygon		 polygon;
			CLxUser_Point		 point;
			LXtPolygonID		 poly_id = NULL;
			LXtPointID		 point_id[4];
			LxResult		 result = LXe_FAILED;
			LXtVector		 pos;
			double			 size = 0.5;
			static double		 positions[4][3] = {{-0.5, 0.0, -0.5},
								    { 0.5, 0.0, -0.5},
								    { 0.5, 0.0,  0.5},
								    {-0.5, 0.0,  0.5}};
			size = dyna_Float (0, 0.5);
			if (size < 0.0)
				size = 0.0;
			size *= 2.0;
			if (mesh.test ())
				polygon.fromMesh (mesh);
				point.fromMesh (mesh);
				if (polygon.test () && point.test ())
					for (unsigned i = 0; i < 4; i++)
						LXx_VSCL3 (pos, positions[i], size);
						point.New (pos, &point_id[i]);
					polygon.New (LXiPTYP_FACE, point_id, 4, 1, &poly_id);
					mesh.SetMeshEdits (LXf_MESHEDIT_GEOMETRY);
					result = LXe_OK;
			return result;
		static LXtTagInfoDesc	 descInfo[];
LXtTagInfoDesc MeshOperation::descInfo[] =
	{ LXsMESHOP_PMODEL,		"." },
	{ 0 }
void initialize ()
	CLxGenericPolymorph	*srv = NULL;
	srv = new CLxPolymorph						<MeshOperation>;
	srv->AddInterface		(new CLxIfc_MeshOperation	<MeshOperation>);
	srv->AddInterface		(new CLxIfc_Attributes		<MeshOperation>);
	srv->AddInterface		(new CLxIfc_StaticDesc		<MeshOperation>);
	lx::AddServer ("prim.plane", srv);
#!/usr/bin/env python
import lx
import lxifc
import lxu.attributes
import lxu.vector
class MeshOperation (lxifc.MeshOperation, lxu.attributes.DynamicAttributes):
    def __init__ (self):
        lxu.attributes.DynamicAttributes.__init__ (self)
        self.dyna_Add ('size', lx.symbol.sTYPE_DISTANCE)
        self.attr_SetFlt (0, 0.5)
    def mop_Evaluate (self, mesh_obj, type, mode):
        mesh = lx.object.Mesh (mesh_obj)
        positions = ((-0.5, 0.0, -0.5),
                     ( 0.5, 0.0, -0.5),
                     ( 0.5, 0.0,  0.5),
                     (-0.5, 0.0,  0.5))
        size = self.attr_GetFlt (0)
        if size < 0.0:
            size = 0.0;
        size = size * 2.0
        polygon = lx.object.Polygon (mesh.PolygonAccessor ())
        point = lx.object.Point (mesh.PointAccessor ())
        point_ids = []
        for pos in positions:
            point_ids.append (point.New (lxu.vector.scale (pos, size)))
        points_storage = ()
        points_storage.setType ('p')
        points_storage.setSize (4)
        points_storage.set (point_ids)
        polygon.New (lx.symbol.iPTYP_FACE, points_storage, 4, 1)
        mesh.SetMeshEdits (lx.symbol.f_MESHEDIT_GEOMETRY)
tags = {lx.symbol.sMESHOP_PMODEL: "."}
lx.bless (MeshOperation, "prim.plane", tags)