Mesh Operation - Automatic implementation¶
__TOC__
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.
1 | #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.
C++¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | class MeshOperation : public CLxImpl_MeshOperation, public CLxDynamicAttributes
{
public:
MeshOperation ()
{
dyna_Add ("size", LXsTYPE_DISTANCE);
attr_SetFlt (0, 0.5);
}
LxResult
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);
}
|
Python¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | #!/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 = lx.object.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)
|