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)