Perl

The first scripting language supported by modo is ./. Perl is commonly found on Unix variants, is available for every platform, and is a standard for automating tasks and writing quick utilities. Due to this ubiquitous presence, there is a wealth of example Perl code, tutorials and documentation available online and in print. In ‘’modo’’, Perl is used for operations that are more complex than can be accomplished with simple macros, allowing for branching, loops, functions and other features.

As with Macros to obtain lower-level information from the various subsystems, including extracting specific mesh information that is not otherwise accessible through commands themselves.

The official Perl documentation can be found at the [http://www.perl.org/ Perl website].

Perl Header

All perl scripts must have the word perl in the first line so that it can be recognized as a Perl script by the system.

  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
 # perl
</syntaxhighlight >

== modo Extensions to Perl ==

A number of new functions have been added to Perl in ''modo''.  The most common batch include ''lx'', ''lxq'', ''lxqt'', ''lxeval'', ''lxok'', ''lxres'', ''lxout'' and ''lxtrace''. Errors are reported to the [[Event Log Viewport]], so it?s useful to have one open while developing Perl scripts.

=== lx() ===

The '''lx''' function is used to execute commands using the standard ''modo'' [[Command System: Basics|command syntax]]. This returns 1 if the command executed successfully, and nothing if it failed for any reason. ''lxres'' can be used to get more specific information about why a command failed. Also be sure to check the Event Log viewport.

<syntaxhighlight lang="perl">
 # perl

 my $ok = lx( "tool.set prim.cube on" );
 if(!$ok){
     # handle errors here
 }
</syntaxhighlight >

=== lxq() ===

The '''lxq''' function queries a command using the standard question mark syntax, returning an array of values. ''foreach'' can be used to easily walk the array. If you are only interested in the first value, you can use a scalar value and Perl will automatically handle it. If there was an error querying the command, nothing is returned.

<syntaxhighlight lang="perl">
 # perl

 # Get an array of names, one for each selected material
 my @selMaterialNames = lxq( "material.name ?" );
 foreach my $matName (@selMaterialNames) {
     # Process the material name
 }

 # Get the maximum number of undos as a single value
 my $maxUndos = lxq( "pref.value application.maxUndo ?"
</syntaxhighlight >

=== lxqt() ===

The '''lxqt''' function queries [[Command System: Basics#ToggleValue Arguments|ToggleValue]] commands like ''tool.set'', returning a simple ''true'' or ''false'' value. ''lxq'' can be used to get the current actual value of a ''ToggleValue'' command, which can be of any datatype and can be one of a number of possible values depending on the command. ''lxqt'' can be used to more easily see if the commands is "on" or not. This example checks to see if the ''Cube'' tool is currently active.

 <syntaxhighlight lang="perl">
 # perl

 my @isActive = lxqt( "tool.set prim.cube on" );
</syntaxhighlight >

=== lxeval() ===

The '''lxeval''' function is a hyrid of ''lx'' and ''lxq''. If the command string contains a question mark, the command will be queried and returned; otherwise, the command is executed and success or failure is returned.

<syntaxhighlight lang="perl">
 # perl

 # Execute
 lxeval( "user.defNew MyValue" );
 lxeval( "user.value MyValue {Test Value}" );

 # Query
 my $value = lxeval( "user.value MyValue ?" );
</syntaxhighlight >

=== lxok() and lxres() ===

The results of ''lx'', ''lxq'', ''lxqt'' and ''lxeval'' can be tested with ''lxok'' and ''lxres''. '''lxok''' returns ''1'' if the last call was successful and ''0'' if not. '''lxres''' returns the LxResult code, which provides more specific details about result of the commands execution. A list of standard result codes and their meanings can be found in the error codes message table, [[msglxresult.cfg|resource:msglxresult.cfg]]

<syntaxhighlight lang="perl">
 # perl

 my $isOK = lxok;
 my $result = lxres;
</syntaxhighlight >

=== lxtrace() ===

The '''lxtrace''' function toggles tracing on and off. When tracing is enabled, all commands executed or queried  by ''lx'', ''lxq'' and the other execute/query functions are output to the ''Scripting'' sub-system of the ''Event Log'' viewport. This can also be used to see if tracing is on or not by not passing in an argument.

<syntaxhighlight lang="perl">
 # perl

 my $tracing = lxtrace;
 lxtrace( 1 );              # Turn on tracing
</syntaxhighlight >

=== lxout() ===

The '''lxout''' function can be used to output debugging information to the ''Scripting'' sub-system of the Event Log viewport, and can be any string.

<syntaxhighlight lang="perl">
 # perl

 lxout( "My Debug Output" );
</syntaxhighlight >

=== lxoption() and lxsetOption() ===
The '''lxoption''' and '''lxsetOption''' functions allow the script to set properties that determine how the other ''lx'' functions operate. Each option is defined by a tag string and an associated value, and the options can be changed at any time.

Currently there is only one tag defined, '''queryAnglesAs''', which determines if angles queried through ''lxq'' are returned in radians or degrees. This defaults to degrees to maintain backwards compatibility with previous versions of ''modo''. While this behavior is helpful for new scripters, it is generally more useful to work in radians. The value can be set to either radians or degrees, and once set all future queries on angles through ''lxq'' will return those units.  The following shows how to change this option and query its current state.

<syntaxhighlight lang="perl">
 # perl

 lxsetOption( "queryAnglesAs", "radians" );
 lxout( lxoption( "queryAnglesAs" ) ) ;

Arguments

Like macros, Perl scripts support arguments. These are provided in the same way that command line arguments are provided to an external Perl script, through the @ARGV variable.

Progress Monitors

Progress bars, or ‘’monitors’’, are also supported in Perl through the ‘lxmonInit’’ and lxmonStep functions.

lxmonInit()

To initialize the progress bar, call lxmonInit with the total number of steps in the bar. lxmonInit should be called only once per script.

 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
 # perl

 lxmonInit( 20 );
</syntaxhighlight >

=== lxmonStep() ===
To step the progress bar, use lxmonStep. By default, this increments the bar one step, but you can also increase the
bar by an arbitrary number steps.

<syntaxhighlight lang="perl">
 # perl

 lxmonInit( 20 );

 lmonStep;        #Increment by one
 lxmonStep( 2 );  #Step the progress bar by two
</syntaxhighlight >

The return value of ''lxmonStep'' is used by the script to determine if the hit the "abort" button in the progress dialog. If ''lxmonStep'' returns false, the script should abort. The following is a common test for a user abort.

<syntaxhighlight lang="perl">
 # perl

 #Initialize the monitor
 lxmonInit( 20 );

 my $count;
 for ($count = 0; $count < 20; $count++) {

    # Do work here

    # Step the monitor and check for an abort
    if( !lxmonStep ) {
        # Do clean-up here
        die( "User Abort" );
    }

 }
</syntaxhighlight >

=== Monitor Example ===

This simple script demonstrates progress bars through the use of monitors. It busy loops so the progress bar will open. If the script executes fast enough, the progress bar will not appear.

<syntaxhighlight lang="perl">
 #! perl

 my ($i, $j);

 # Initialize the monitor with 20 steps
 lxmonInit( 200 );

 # Loop through our 200 steps
 for($i=0;$i<200;$i++){

     # Do work (i.e.: busy loop )
     for( $j=0; $j < 1000000; $j++ ) {
         ;
     }

     # Step the monitor and check for an abort
     if( !lxmonstep ) {
         # Clean up and exit
         die( "User Abort" );
     }
 }

External Modules

There are a large number of publicly-available Perl modules out there. These modules are accessible from within ‘’modo’’, with a little setup. modo comes with a complete standard Perl module distribution. Other modules are included from various sources on the internet. Modules are loaded using the Perl use keyword as normal.

There are two ways to tell modo where your extra modules are: through environment variables or by modifying @INC at runtime.

Environment Variables

The best way to use external modules not found in the standard distribution is to define the environment variable LX_PERLPATH and set it to the paths of your modules. Multiple paths are supported by using a semicolon as a delimiter.

On Windows, this can be setup through the ‘’Environment Variables’’ dialog of the System control panel?s Advanced tab. From there you can add a new User environment variable for ‘’LX_PERLPATH’’.

Once this path is set, restart modo and you?ll be able to to use the use keyword from a Perl script to import the modules and call their functions.

Modifying @INC

An alternate method is to add your paths to @INC in a BEGIN block at the start of your script. Multiple calls to push can be used to add multiple paths.

1
2
3
4
5
 #perl

 BEGIN {
     push( @INC, "C:\PathToModules");
 }

The main disadvantage to modifying @INC is that the module path will be hard-coded into the script, likely requiring the script to be modified before it can be run on a machine with a different configuration. As such, the environment variable method should be used whenever possible.

After adding the module path, the use keyword can be used to load the modules as normal.

Examples

See Perl Examples for example Perl scripts.

Testing Perl Scripts Outside modo

If you have Perl installed on your computer, you can test scripts outside of modo for syntax errors.

On Mac OS X and Linux, Perl is included with the operating system. Windows users will have to download a Perl distribution such as ActivePerl before they can test scripts outside of modo.

To test a script for compile errors, open a Terminal on Mac OS X or an ‘’MS-DOS Prompt’’ on Windows. Then enter the following line:

1
 perl -c MyScript.pl

The Perl interpreter will now compile your script looking for syntax errors, but will not try to run it (the script won?t run outside of modo if you call any of the lx…() functions anyway). This might be easier for basic syntax checking than using the ‘’Event Log Viewport’’, which only shows the first error it encounters..

More Information