Selection Operation - Automatic implementation

__TOC__

Selection Operations integrate into the procedural system by writing an ILxSelectionOperation server to a channel, which is evaluated by the procedural modelling system. This ILxSelectionOperation has functions for testing individual elements on the mesh to determine whether they should be selected or not.

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

Applying the following server tag to an ILxSelectionOperation interface, will automatically create a selection operation item and a modifier. The modifier will write the ILxSelectionOperation server into a channel, so that it can be evaluated as part of the procedural system. The ILxSelectionOperation 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 selection operation item. The name of the selection operation item, will be the name of selection operation server, with “.item” appended at the end.

1
#define LXsSELOP_PMODEL                "pmodel.selectionop"

Sample Code

The following sample code implements a very basic selection operation that selects all elements within a particular index range. The start and end attributes are converted into channels that can be manipulated or animated by the user.

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
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
class SelectionOperation : public CLxImpl_SelectionOperation, public CLxDynamicAttributes
{
        public:
                SelectionOperation ()
                {
                        dyna_Add ("start", LXsTYPE_INTEGER);
                        attr_SetInt (0, 0);

                        dyna_Add ("end", LXsTYPE_INTEGER);
                        attr_SetInt (1, 100);
                }

                        LxResult
                selop_SetMesh (
                        ILxUnknownID             mesh)          LXx_OVERRIDE
                {
                        /*
                         *      Cache the mesh COM object. This is need to spawn the accessors
                         *      in the Test functions.
                         */

                        if (_mesh.set (mesh))
                                return LXe_OK;

                        return LXe_FAILED;
                }

                        bool
                IsIndexInRange (
                        unsigned int             index)
                {
                        int                      start = 0, end = 100;

                        /*
                         *      Get the start and end attributes and ensure that start < end.
                         */

                        start = dyna_Int (0, 0);
                        end = dyna_Int (0, 100);

                        if (start > end)
                                std::swap (start, end);

                        /*
                         *      Test if the provided index is within range.
                         */

                        return (index <= end && index >= start);
                }

                        LxResult
                selop_TestPoint (
                        LXtPointID               point)         LXx_OVERRIDE
                {
                        CLxUser_Point            accessor;
                        unsigned int             index = 0;

                        /*
                         *      Select the provided point in the accessor and test it's index
                         *      against the range.
                         */

                        if (_mesh.test () && accessor.fromMesh (_mesh))
                        {
                                if (LXx_OK (accessor.Select (point)))
                                {
                                        accessor.Index (&index);
                                        if (IsIndexInRange (index))
                                                return LXe_TRUE;
                                }
                        }

                        return LXe_FALSE;
                }

                        LxResult
                selop_TestEdge (
                        LXtEdgeID                edge)          LXx_OVERRIDE
                {
                        CLxUser_Edge             accessor;
                        unsigned int             index = 0;

                        /*
                         *      Select the provided point in the accessor and test it's index
                         *      against the range.
                         */

                        if (_mesh.test () && accessor.fromMesh (_mesh))
                        {
                                if (LXx_OK (accessor.Select (edge)))
                                {
                                        accessor.Index (&index);
                                        if (IsIndexInRange (index))
                                                return LXe_TRUE;
                                }
                        }

                        return LXe_FALSE;
                }

                        LxResult
                selop_TestPolygon (
                        LXtPolygonID             polygon)       LXx_OVERRIDE
                {
                        CLxUser_Polygon          accessor;
                        unsigned int             index = 0;

                        /*
                         *      Select the provided point in the accessor and test it's index
                         *      against the range.
                         */

                        if (_mesh.test () && accessor.fromMesh (_mesh))
                        {
                                if (LXx_OK (accessor.Select (polygon)))
                                {
                                        accessor.Index (&index);
                                        if (IsIndexInRange (index))
                                                return LXe_TRUE;
                                }
                        }

                        return LXe_FALSE;
                }

                CLxUser_Mesh             _mesh;

                static LXtTagInfoDesc    descInfo[];
};

LXtTagInfoDesc SelectionOperation::descInfo[] =
{
        { LXsSELOP_PMODEL,              "." },
        { 0 }
};

void initialize ()
{
        CLxGenericPolymorph     *srv = NULL;

        srv = new CLxPolymorph                                          <SelectionOperation>;
        srv->AddInterface               (new CLxIfc_SelectionOperation  <SelectionOperation>);
        srv->AddInterface               (new CLxIfc_Attributes          <SelectionOperation>);
        srv->AddInterface               (new CLxIfc_StaticDesc          <SelectionOperation>);

        lx::AddServer ("select.inRange", srv);
}