### CommandSequence Availability LightWave® 6.0 Component Modeler Header lwcmdseq.h Command sequence plug-ins issue commands to create and manipulate geometry in Modeler. They also have access to the same mesh editing functions as the MeshDataEdit class. Activation Function
       XCALL_( int ) MyCmdSeq( int version, GlobalFunc *global,
          LWModCommand *local, void *serverData );
The `local` argument to a command sequence's activation function is an LWModCommand.
       typedef struct st_LWModCommand {
          void          *data;
          const char    *argument;
          LWCommandCode (*lookup)   (void *, const char *cmdName);
          int           (*execute)  (void *, LWCommandCode cmd, int argc,
                                       const DynaValue *argv,
                                       EltOpSelect, DynaValue *result);
          MeshEditBegin *editBegin;
          int           (*evaluate) (void *, const char *command);
          void          (*undoGroupBegin) (void);
          void          (*undoGroupEnd) (void);

       } LWModCommand;
`data` An opaque pointer to data used internally by Modeler. Pass this as the first argument to the `lookup`, `execute` and `evaluate` functions. `argument` Users and other plug-ins can invoke your plug-in with arguments, which are stored here as a string. `cmdcode = lookup( data, cmdname )` Returns an integer code corresponding to the command name. The command is issued by passing the command code to the `execute` function. Command codes are constant for a given Modeler session, so this only needs to be called once per command, after which the codes can be cached and then used in any number of calls to `execute`. `result = execute( data, cmdcode, argc, argv, selection, cmdresult )` Issue the command given by the command code argument. `argv` is an array of DynaValue arguments. `argc` is the number of arguments in the `argv` array. The selection determines which geometry will be affected by the command and can be any one of the EltOpSelect codes except `OPSEL_MODIFY`. The result of the command is written in `cmdresult`. The function returns `CSERR_NONE` (0) if it succeeds or one of the following non-zero error codes. `CSERR_MEMORY CSERR_IO CSERR_USERABORT CSERR_ARGCOUNT CSERR_ARGTYPE CSERR_ARGVALUE CSERR_OPFAILURE CSERR_BADSEL` `edit = editBegin( pnt_bufsize, pol_bufsize, opsel )` Begin a mesh edit. The buffer sizes are used to create temporary buffers associated with each point and polygon. Modeler allocates and frees this memory for you, and you can use it for any per-point or per-polygon data you might need during the edit. Points and polygons are flagged as selected according to the code you pass in `opsel`. The `editBegin` function is identical to the function passed as the local data to mesh edit plug-ins. See that page for complete documentation of the MeshEditOp structure it returns. Command sequence plug-ins can perform multiple mesh edits. Each edit begins by calling this function to get a MeshEditOp and ends when the MeshEditOp's `done` function is called. No commands can be issued during a mesh edit. `result = evaluate( data, cmdstring )` Issue the command with the name and arguments in the command string. This is an alternative to using `lookup` and `execute`. The command and its arguments are written to a single string and delimited by spaces. undoGroupBegin() This allows for multiple actions to be classified under a single undo operation. Call this before the first action. undoGroupEnd)() Call this to complete a series of actions that are part of a single undo group. See the Commands pages for a complete list of the commands that can be issued in Modeler, as well as a detailed explanation of the formatting of command arguments for both the `execute` and `evaluate` methods. Example The DNA sample is a CommandSequence plug-in that builds classic Watson-Crick DNA molecules. It uses the ModLib static-link library, which greatly simplifies command execution by translating commands into function calls. The library currently contains about 170 functions that cover Modeler commands, mesh edit functions, and globals. This ModLib function executes the `MAKEBALL` command, building the DynaValue argument list and calling the `lookup` and `execute` functions. (ModData is a ModLib structure that caches the LWModCommand pointer and the data returned from a number of globals.)
       int csMakeBall( double *radius, int nsides, int nsegments,
          double *center )
       {
          static LWCommandCode ccode;
          ModData *md = getModData();
          DynaValue argv[ 4 ];

          assert( md->edit == NULL );

          argv[ 0 ].type = DY_VFLOAT;
          argv[ 0 ].fvec.val[ 0 ] = radius[ 0 ];
          argv[ 0 ].fvec.val[ 1 ] = radius[ 1 ];
          argv[ 0 ].fvec.val[ 2 ] = radius[ 2 ];

          argv[ 1 ].type = DY_INTEGER;
          argv[ 1 ].intv.value = nsides;

          argv[ 2 ].type = DY_INTEGER;
          argv[ 2 ].intv.value = nsegments;

          if ( center ) {
             argv[ 3 ].type = DY_VFLOAT;
             argv[ 3 ].fvec.val[ 0 ] = center[ 0 ];
             argv[ 3 ].fvec.val[ 1 ] = center[ 1 ];
             argv[ 3 ].fvec.val[ 2 ] = center[ 2 ];
          }
          else argv[ 3 ].type = DY_NULL;

          if ( !ccode )
             ccode = md->local->lookup( md->local->data, "MAKEBALL" );

          md->cmderror = md->local->execute( md->local->data, ccode,
             4, argv, md->opsel, &md->result );

          return md->cmderror == CSERR_NONE;
       }
Using ModLib makes DNA's command processing almost as simple as scripting. Below is a code fragment from the function in the DNA plug-in that creates the cylinders representing atomic bonds.
       csSetLayer( layer2 );
       csSetDefaultSurface( surface_name( snum ));
       csMakeDisc( r, h, 0, "Y", bond_nsides, bond_nsegments, c );
       csRotate( xrot, "X", NULL );
       csRotate( yrot, "Y", NULL );
       csMove( pt );
       rot = 36 * j;
       csRotate( rot, "Y", NULL );
       csCut();
       csSetLayer( layer1 );
       csPaste();