class lxu.service.AudioAnim

Empty AudioAnim service Python user class.


Return the audio object.

Audio object = Audio()


Return the end time to play audio.

float = End()


Audio for animation can be accessed through the SDK using a global service interface. Return the audio clip item for animation.

Item object = Item()


Return the audio object.

Unknown object = ItemAudio(object obj)

ItemSample(loop, time, type, value)

ItemSample(object obj,integer loop,float time,integer type,pointer value)


Return true if the audio for animation is loop mode.

integer = Loop()


Return true if the audio for animation is in mute.

integer = Mute()


Return true if the audio for animation is playing.

integer = Playing()


This also return the audio object between start and end times, but this is resampled with the current animation settings like Start time and Loop. The audio object must be release on user side.

Audio object = Preview(float startTime,float endTime)

Sample(type, value)

Sample(float time,integer type,data[] value)


Return true if the scurb is enabled.

integer = Scrub()


Return the start time to play audio.

float = Start()


class lxu.service.Cache

Empty CacheData Python user class.


Unknown object = GetData(string name,integer key)


PurgeData(string name)


Register(string name)


Release(string name)


The Cache Service provides methods for modifying and accessing named caches.

Unknown object = ScriptQuery()

SetData(key, data)

SetData(string name,integer key,object data)


class lxu.service.ChannelUI

Empty ChannelUI service Python user class.


string desc = ChannelDescription(object item,integer channel)


string tip = ChannelToolTip(object item,integer channel)


Get the username, description and toolitp of a channel given an item (not an item type) and the channel index.

string = ChannelUserName(object item,integer channel)


string name = ItemTypeDesc(integer typeID,integer useSuper)


This returns the name of the icon for this item type, optionally falling back to its supertype.

string = ItemTypeIconText(integer typeID,integer useSuper)


Given an item type, these returns the type’s username (not the internal name) and description, as defined in the ItemHelp configs. If useSuper is true, the supertye’s information will be used if no information can be found for the specific type.

string name = ItemTypeName(integer typeID,integer useSuper)


Get the username of a mesh map given its internal name. If addIcon is true, the icon will be encoded into the buffer as a rich text string.

string = MeshMapUserName(string name,integer addIcon)


Unknown object = ScriptQuery()


class lxu.service.ColorMapping

integer = ConfigCount()


string configPath = ConfigFullPath(integer index)


string configName = ConfigName(integer index)


Get the color mapping used for displaying colors in the interface.

ColorMapping object = GetDisplayColorMapping()


Get the color mapping used for numeric values in the interface.

ColorMapping object = GetNumericColorMapping()


ColorMapping object = MakeColorMapping(string colorspaceName,integer toLinear)


RegisterColorspaceForConfig(string configName,string colorspaceName)


class lxu.service.Command

Empty Command service Python user class.

AliasCreate(targetCmd, targetTag, targetName, args)

Commands can be aliased. This allows one command to replace another, and to create shortcut commands that have arguments preset. Aliases themselves cannot be aliased. When creating or deleting aliases, any one of cmd, tag or name may be set. The argument string used during creation will be used to provide default values for the command. The arguments set in the cmd (if provided) are ignored. Note that using aliased arguments is only completely supported for commands that do not use dynamic datatypes. The issue is that if the user changes the the REQFORVARIABLE argument, the other arguments will need to be reset, thus overriding the aliased defaults. This shouldn’t pose any issues in most situations.

AliasCreate(string name,object targetCmd,integer targetTag,string targetName,string args)

AliasDelete(tag, name)

AliasDelete(object alias,integer tag,string name)


This allocates an

UIHints object = AllocateUIHintsFromCommand(object cmd,integer argIndex)


This function returns the argument list as a string which would result in the same arguments for the command if parsed. This is mainly used for recording the command in an executable history. If includeCmd is true, the internal command name will prefix the argument portion.

string = ArgsAsString(object cmd,integer includeCmd)


This is identical to ArgsAsString, but is a safer function that takes a buffer length to reduce the chance of a buffer overflow. ArgAsString() was updated a long time ago to include a len argument, making it identical to this function. Before nexus 12, there was a bug in ArgAsString() that kept it from working properly, but as of 12 both are identical.

string = ArgsAsStringLen(object cmd,integer includeCmd)


It is sometimes desirable to have multiple commands executed as a single undoable event. This can be done by creating command blocks. Blocks can be nested as needed. Each block can be given a name that will be sent in the block create event and undo data and be displayed in the command history. Block names should be localized, and can take the form of “@table@message@”

BlockBegin(string name,integer flags)




CancelDoAtEndOfRootLevelUndoableCommand(object visitor)


Command object = CommandByIndex(integer index)


The command list can be walked with these functions, returning the prototype. Commands are sorted by internal name. Note that commands will be loaded from plug-ins if necessary as the list is walked.

integer count = CommandCount()


This creates a new

ValueArray object = CreateQueryObject(string typeName)


This returns the current command execution depth. -1 means no commands are currently executing. This information is useful in rare situations. Note that this count includes both commands and command blocks.

integer depth = CurrentExecDepth()


Sometimes a large undoable operation occurs that causes a lot of events to come in, and you want to do one undoable operation once everything else is done. You could use ScriptService::DoWhenUserIsIdle(), which is general useful for deferred and lazy operations, but if you want to perform an undoable operation you’ll have have to fire a command, and that means the user will have to do an extra undo to go back, which isn’t ideal and makes the undos feel broken. This method can only be called while an undoable command is being fired, and will fail otherwise. It registers a visitor that will be called after the root-level undoable command or block is about to return, but the undo block is still open. Calling this method twice with the same object pointer does nothing; the object is only registered once. The cancel method can be used to remove the registration, but the object passed in must be exactly the same as the one passed for registration, as this does a pointer compare. When doing this from Python, this means that you must pass the exact same visitor COM object (not Python object). This is also necessary when removing listeners and canceling timers, as discussed here:

DoAtEndOfRootLevelUndoableCommand(object visitor)


For commands, an argument string suitable for executing it can be read with this function.

string = ExecEntryAsArgString(integer index)


string name = ExecEntryName(integer index)


integer type = ExecEntryType(integer index)


The username can be obtained for both commands and blocks.

string userName = ExecEntryUserName(integer index)


This inverse function takes the exec flags and converts them back into a prefix string.

string = ExecFlagsAsPrefixString(integer flags)

ExecuteArgString(tag, args)

This is a high-level function that parses arguments and fires the command all in one go. If the tag is CTAG_NULL, it is assumed that the command name begins the argument string. If the tag is CTAG_NULL, then there are some special characters that can be used to modify the execution state. These flags are insereted at the very beginning of the arugment string, before the command name. A single exclamation point “!” can be used to turn off the SHOWERR and GETARGS flags for this command only. An opposite effect can be achieved by using a single leading plus “+”. This adds SHOWERR and GETARGS to the command. Note that the above only affect this specific command. All sub-commands can be affected be using double exclamation points “!!” or double pluses “++” where appropriate. These will add SHOWERR_FORCESUB_OFF and GETARGS_FORCESUB_OFF or SHOWERR_FORCESUB and GETARGS_FORCESUB to the execFlags. This function also handles special UI-level behaviors. For example, if a required argument is missing, the command dialog will open. Similarly, if a query operator is specified for an argument, it will be applied. This includes using a question mark by itself on an argument that can be represented by a popup, thereby forcing it to open a menu at the current mouse position, or in the case of a boolean argument, causing it toggle it on or off.

ExecuteArgString(integer execFlags,integer tag,string args)

ExecuteArgString2(tag, args)

These functions are identical to their non-‘2’ counterparts, but will indirectly return a COM object representing the command object. This allows you to read post-execution flags and messages from the executed command, without having to manually spawn the command, set the argumetns, and do everything else you have to do to set up and execute a command manually. It’s important to note that this object may be NULL if the command could not be spawned. If the object returned is non-NULL, it must be released by the caller when no longer needed.

Command object = ExecuteArgString2(integer execFlags,integer tag,string args)

ExecuteAttribObject(tag, cmdName, attribArgs)

Finally, we support using an

ExecuteAttribObject(integer execFlags,integer tag,string cmdName,object attribArgs)

ExecuteAttribObject2(tag, cmdName, attribArgs)

Command object = ExecuteAttribObject2(integer execFlags,integer tag,string cmdName,object attribArgs)

ExecuteBooleanArgString(tag, args)

This allows the boolean argument’s value to be easily changed to an alternate state. As above, the boolean argument is expected to be marked with a query operator, and the argument’s value will be toggled based on the argument’s currently queried value before being executed..

ExecuteBooleanArgString(integer execFlags,integer tag,string args)

ExecuteBooleanArgString2(tag, args)

Command object = ExecuteBooleanArgString2(integer execFlags,integer tag,string args)


Execute an implicit script directly.

ExecuteImplicitScript(string definition,integer execFlags)


Command object = ExecuteImplicitScript2(string definition,integer execFlags)

ExecuteSpecial(cmd, specialArgIndex)

This executes a command object, but also takes a special argument index. If the index is not -1, then special behaviors specific to that argument may be taken (i.e., opening a popup), or the command may be executed normal or a command dialog may appear as normal. This same behavior is taken automatically when executing a command from a string using

ExecuteSpecial(integer execFlags,object cmd,integer specialArgIndex)

ExecuteToggleArgString(tag, args, newState)

Similar, but also allows a toggle arg to be flipped. -1 can be used to invert the current state.

ExecuteToggleArgString(integer execFlags,integer tag,string args,integer newState)

ExecuteToggleArgString2(tag, args, newState)

Command object = ExecuteToggleArgString2(integer execFlags,integer tag,string args,integer newState)


integer sep = GetNameSep()


When getting the value, both a simple on/off state and the current value of the arg can be provided, or either can be NULL.

(integer state,Value object) = GetToggleArgState(object cmd)


This succeeds if the command is aliased. Note that a command can be both a container and aliased.

boolean = IsAliased(object cmd)


Commands with queried boolean arguments can also be somewhat tedious to test, toggle and execute, especially considering the multiple ways that a boolean argument can be specified. This function takes a command string, and if the boolean argument contains any query operators (including a question mark alone), this returns true.

boolean = IsBooleanArgString(string string)


There are currently three types of commands: normal commands, containers and aliases. This functions can be used to tell if the command is a container.

boolean = IsContainer(object cmd)


This returns LXe_TRUE if a command is executing and the interaction flags are set. This means that if this returns LXe_FALSE, the client should not open any dialogs and instead should perform its default behavior. The interaction flags are often unset when running from a script or when in headless mode, during which time modo’s own dialogs (such as ILxMessage-based dialogs) will be automatically suppressed, acting as though the user had hit cancel/abort/no. By testing

boolean = IsGlobalInteractionOK()


Scripts can be more easily executed using this function. Before looking up any commands, this should be called to see if it starts with the script marker (the @ symbol). Note that the definition string should include entire command like, not just the @ and script name; if If it does, the next function will create the implicit script command and and set the script name and arg string arguments automatically. Scripts cannot be queried, so the command returned is only useful for execution. The command can otherwise be treated a a normal command object after it is created. See if the command is an implicit script execution.

boolean = IsImplicitScript(string definition)


This processes a command string (name and args) and returns LXe_TRUE if it is a toggle arg command, and LXe_FALSE if not. If true, this means the command can be executed with

boolean = IsToggleArgString(string string)


Should you want to, this returns a command’s tag, which can be used to create an instance of a command instead of using its name.

integer tag = Lookup(string name)


integer status = MasterStatus()

ParseArgString(alertFlags, args)

This is similar to CmdEntryFireTag(), and takes a string representing the arguments.

ParseArgString(object cmd,integer alertFlags,string args)

ParseAttribObject(alertFlags, attribArgs)

This function uses an ILxAttributesID to fill in the arguments. See ExecuteAttribObj() for more information about how this works.

ParseAttribObject(object cmd,integer alertFlags,object attribArgs)

PostModeBegin(tag, name, args, postEndObj)

The being and end functions. In begin, any of cmd, tag or args can be provided. If all are NULL, it is assumed that the command name prefixes the arguments.Otherwise, the argument list is optional.

PostModeBegin(object cmd,integer tag,string name,string args,object postEndObj)




This resets all undoable states since the



This fetches the current post-mode state (i.e., on or off).



This function can be used to parse the special prefix characters mentioned above out the string, and combine them with other execution flags. This is useful when you are directly creating an

(integer newFlags,string afterFlags) = ProcessStringFlags(integer flags,string string)


This returns the

Command object = Proto(integer tag,string name)


This returns the prototype of a command from an alreadly instanced one.

Command object = ProtoFromCommand(object cmd)


This queries a command for its values, providing a new

ValueArray object = Query(object cmd,integer index)

QueryArgString(alertFlags, args, includesCmdName)

This is similar, but takes an argument string instead of an index. One argument may be marked with a ?, and that one will be queried. The index of that argument can be obtained through the queryIndex argument, or NULL can be passed NULL if you don’t want it back. Similarly, the ILxValueArrayID argument can be NULL if only the queryIndex itself is desired but not the actual queried values. If includesCmdName is true, the first part of the argument string is assumed to be the command name and will be skipped. The alertFlags (LXfCMD_ALERT_ defines) are used to decide how to present errors to the user during parsing; passing 0 will suppress any error dialogs. If successful parsed, the command object provided will be populated with the arguments present in the args string.

(ValueArray object,integer queryIndex) = QueryArgString(object cmd,integer alertFlags,string args,integer includesCmdName)


Some commands are fired many times over and over again as the user changes a value. An example of this is the the Move Tool; each time the users drags the mouse, the Move Tool fires a new AddPosition (or whatever) command. This clutters up the command histroy quite a bit. Instead, the Move Tool should fire the AddPosition command effectively once with the final value, thus resulting in a single entry in the command history. This process has been dubbed “Refiring”. On mouse down, a tool calls CmdRefireBegin(), and on mouse up calls CmdRefireEnd(). In between it fires commands using CmdEntryFireArgs() or CmdEntryFireTag() to fire a command. When a command is refired, the previous execution is undone just before the command is re-executed. Each successive time CmdEntryFire…() is called within a refire block, the previously fired command is undone. IT IS REQUIRED THAT THE COMMAND BEING FIRED IS UNDOABLE! Large annoying requesters will pop up if you try to use any non-undoable commands. Only a single command can be executed inside a refire block, although that command may execute others. Attempting to execute more than one will cause those later commands to fail. If you need to fire multiple commands, you can wrap them in a command block via



string name = RefireBlock()


These can be used to get the prototype of the command or the name of the block being refired. NOTE: this is returned without being add-refed! That needs to be fixed.

Command object = RefireCmd()




integer state = RefireState()


This method adds an object to a sandbox. The object is AddRef()’ed when added, and released when the sandbox is destroyed.

SandboxAddObject(object object)


Command sandboxes can be started through this method. Flags are any combination of LXfCMDSANDBOX_ flags, and cannot be changed once the sandbox is created.

SandboxBegin(integer flags)


When the sandbox is no longer needed, it must be popped off the stack with this method.



integer flags = SandboxFlags()


More commonly, this method would be used to get the object associated with the command’s SandboxGUID() method.

Unknown object = SandboxObjectByCommand(object cmd)


Unknown object = SandboxObjectByIndex(integer index)


A list of objects can be read with these functions.

integer count = SandboxObjectCount()


An object can be looked up by the interfaces it supports. The first object with the GUID will be returned, or the method fails. Since this method caches interface queries, it is recommended instead of walking the object list directly.

Unknown object = SandboxObjectLookup(string guid)


This method returns LXe_CMD_SANDBOX_GLOBAL if there are no sandboxes on the stack, and LXe_CMD_SANDBOXED if there is at least one. Any other return code is a failure.



As with all globals, the first method gets the ILxScriptQueryID interface for the system.

Unknown object = ScriptQuery()


It is sometimes useful to be able to lock out interaction on a global level. A common case is Slave mode, where we don’t want any dialogs opening as these machines are usually unattended. This state can only be set from within a command, and is automatically cleared when the stack is emptied. It cannot be manually cleared if it was not set by the client.

SetIsGlobalInteractionOK(integer isOK)


SetNameSep(integer sep)


These functions makes it easy to flip the toggle of a Toggle Argument command, and to tell if the state is on or off. 1 is on, 0 is off, and -1 inverts the current state.

SetToggleArgState(object cmd,integer state)


This spawns a new command object given its name or tag, which means it creates a fully functional command object whose args can be set for firing and querying. The object needs to be released with XObjectRelease() when no longer needed.

Command object = Spawn(integer tag,string name)


This spawns a new command object given another command object. Note that the spawned command will include any aliasing that was applied, even if the original command was create with

Command object = SpawnFromCommand(object cmd)


This super-wrapper spawns a command from an argument string and sets all the arguments found. It will also return the index of the query argument, if one was set in the argument string; the query argument will be -1 if no query argument is set. Also, execution flags passed in will be modified based on the leading characters of the command string (!, +, ?, etc). Note that the execFlags should be iniitalized to some useful execution flags, such as LXfCMD_EXEC_DEFAULT, as this will also be used to present parsing errors. Once the command has been spawned in this way, it is ready for execution or querying.

(integer execFlags,integer queryArgIndex,Command object) = SpawnFromString(string args)


Spawn a command to launch the script. This “definition” string should include any arguments to pass to the script.

Command object = SpawnImplicitScript(string definition)


Commands can be aliased such that they replace an existing command. This is useful when you want an alias to be able to completely replace built-in functionality. This method can be used to spawn an instance of the original, unaliased command, thus allowing the alias to call the original command’s methods.

Command object = SpawnUnaliased(integer tag,string name)


This function composes and returns a string describing the arguments of the command in a user-readable format. This string is dynamically generated from the command’s own argument list, and includes the command name.

string buffer = Usage(object cmd)


class lxu.service.Deformer

Empty Deformer service Python user class.


object = DeformEltToItem(id elt)


integer index = DeformerChannel(object item)


Given a deformer, this returns the deformation item. If this is a locator deformer then it returns LXe_TRUE, otherwise FALSE.

item object = DeformerDeformationItem(object defItem)



integer flags = DeformerFlags(object item)


Given a group deformer item and a channel read object (for evaluation, not action) this returns the group deformer interface.

GroupDeformer object = GroupDeformer(object dgroup,object chanRead)


Some events can cause the set of items that are targets for deformations to change implicitly. If that happens, a client can call this method to cause the deformation system to update.

InvalidateTargets(object scene)


The LXtDeformElt type can represent a point or an item (so far). For points the value is the same as the LXtPointID for the point. For items it’s a special pointer that can be converted to and from an item ILxUnknownID using these functions.

id = ItemToDeformElt(object item)


Compute the merge of two change states.

MergeChangeState(integer c1,integer c2)


Item object = MeshByIndex(object defItem,integer index)


Given a deformer, get the set of meshes that it influences. The

integer count = MeshCount(object defItem)


Unknown object = ScriptQuery()


class lxu.service.DirCache

While it operates as a low-priority thread, dir cache background isn’t always desirable. A preference determines if the cache should always upgrade in the background or only when a client is actively using it. Clients declare that they’re using it by calling this method to increment the use count. This keeps the cahce thread running and makes sure that everything is up to date. If a client attempts to access the cache without increasing the use count, they may have stale cache data or no cache data at all.



This returns if two paths are equal. Synthetic paths are considered to be case insensitive.

ArePathsEqual(string path1,string path2)

AttributesChanged(which, attribute)

AttributesChanged(object dirCacheEntry,integer which,string attribute)


This aborts any pending async operations given an identifier string. This is tested against that returned by all of the pending async objects’ Ident() methods, and all that match are canceled.

CachedThumbnailAsyncCancel(string ident)


This returns true if a path can be renamed with the file.rename and dircache.rename commands.

CanBeRenamed(string path)

IsChildOfPath(parentToTestAgainsts, orIsSame)

Test to see if a path is a child of another path, returning LXe_TRUE if it is and LXe_FALSE if it’s not. This works on both real and synthetic paths.

IsChildOfPath(string possibleChild,string parentToTestAgainsts,integer orIsSame)


Lookup a cache entry by its path anywhere in the hierarchy. The path is expected to be in local platform format. This is thread-safe.

DirCacheEntry object = Lookup(string path)


This ensures that the path provided exists on disk, creating the directories along the path if they don’t. At leaast the first component of the path must exist, and the user must have approriate permissions to modify the path. If any part of the path can’t be created, this will fail. If skipLastPart is true, we assume that part is the file component and will not try to create a directory there, but will create them for all components up to that point. This works only on local paths, and will fail on synthetics and merged entries.

MakeDirHierarchy(string path,integer skipLastPart)


This generates a new path that has a guaranteed unique filename relative in the directory represented by the entry provided (more on that below). The name is a base filename that is appended to the entry’s path, and should include an extension, such as “color.lxc”. A unique name is generated by insering “_1”, “_2”, etc just before the extension until a file cannot be found at that location. The following objects can be passed to this method:

string = MakeUniqueIn(object object,string filename)

ParseName(baseName, baseNameLen, path, pathLen)

With the introduction of synthetic paths, we need a way to parse those paths. This will automatically handle both file system paths and synthetic paths, with the caveat that the paths must be absolute (ie: a synthetic path starts with “[servername]:”) so that it can be properly identified.

ParseName(string filename,byte[] baseName,integer baseNameLen,byte[] path,integer pathLen)

PathCompose(filenameLen, baseName, path)

Similarly, this will compose a path, inserting the appropriate seperators for synthatic vs. local paths. The filename buffer will be a combination of the path, a separator, and the basename, although if the basename is absolute it will be the only thing in the filename buffer.

PathCompose(byte[] filename,integer filenameLen,string baseName,string path)


When a client no longer needs to access the cache, it should remove itself. This just keeps the cache from doing any further updates, but it will first finish writing any changes to disk as needed.



DirCacheEntry object = RootByIndex(integer index)


Entries within a cache are represented by objects with an

integer count = RootCount()


When using the above two methods, it is important to lock the list so that it doesn’t change out from under you. This is accomplished with the locking methods. Lock calls are renetrant within a thread, and can be nested. It is usually wise to make a copy of the root list and then unlock it. This avoids any possible deadlocks that may arise from a lock being held on the root list while one of the dir cache threads attempts to lock it while already having a lock on one of its entries. The deadlock arises from each thread waiting for the other to release its lock so that it can obtain the next lock. This isn’t a problem if you always walk up the list (from base to child), but it will be an issue if you walk up the list (say, checking to see if a specific entry is a root entry by locking the entry and then locking the root). As long as the root is locked before any entries are locked in the thread, this issue can be avoided





The dir cache needs to be told when a file or directory changes. On app activation it will automatically rescan all directories looking for changes, and update as appropriate. If the files or dirs are added or removed while the app is running, this function should be called by the client that did that modification so that the cache will be refreshed. If the path provided points to a directory, that directory and its children will be scanned for changes. If the path is a file, the directory that contains the file and its children will be scanned. If the path is NULL, the entire cache is rescanned. Rescanning involves hitting the disk, testing each file and its sidecar files for changes. Scanning the entire standard content directory hierarchy in a development build on a spinning disk hard drive takes about four seconds, which isn’t too bad for 4000 or so files and dirs. Targetting a specific directory should be nearly instant from the user’s point of view.

ScanForChanges(string path)


As with all services, we start with the ScriptQuery method, although it is not implemented.

Unknown object = ScriptQuery()


It is not uncommon to create a new file by D&D’ing some content into a Preset Browser. If the view supports manual ordering or grid mode, it is often desirable to respect that and place the newly-created file in the appropraite location. This method handles all of that for you. You just need to provide an LXtObjectID from the drop destination and the path of the file you created, and this will update the manual order and grid position as appropraite. Note that the file’s path must match that of the directory provided by the destination object, or this will do nothing. It is important to note that this is only realy good for updating a single file; calling this multiple times may result in the paths being shuffled around oddly, as you really want to take into account the previosuly positioned file instead of just the information present in the destination object. With the introduction of merged base paths, the new SetPosOnDropForCLlent() should be used instead

SetPosOnDrop(string path,object dest)


This retuns the local version of a path. Synthetic paths are simply returned as the original path, while non-synethic paths are returned as though

string = ToLocalAlias(byte[] path)


class lxu.service.Drop

During a drop, this returns the name of the drop server and the action code of the server. Scripts associated with the drop server can use knowledge of that server’s action codes to perform specific drop actions (add vs. replace, say).

(string serverName,integer actionCode) = Action()


This returns the current destination object, failing if there is none. The object must be released when no longer needed.

Unknown object = Destination()


As with all globals, the first method gets the ILxScriptQueryID interface for the system. However, it is not implemented for

Unknown object = ScriptQuery()


This returns the current source type and source object. While a source can expose multiple source types and objects, this is the specific source type (as an LXsDROPSOURCE_ define) and object representing the drop in progress. The object must be released when no longer needed.

(string sourceType,Unknown object) = Source()


class lxu.service.File

Empty File service Python user class.


Allocate a redirection object from the service. When created it has no history so no redirections are done.

FileRedirect object = AllocRedirect()


FileReference object = AllocReference(string path)


This compares two paths and returns true if they are equal. This respects case-sensitivity and other quirks specific to the operating system. It doesn’t follow symbolic links or other directory traversal.

boolean = ArePathsEqual(string path1,string path2)


This adds the base filename onto a path with the path separator defined by the OS. If the basename is absolute it returns LXe_INVALIDARG.

string = ComposePath(string basename,string path)


This deletes a dir from disk.

DirDelete(string filename)


This executes an arbitrary program given an argv-style array of arguments. If “show” is true, the application will be visible when launched; if false, it will be hidden. If force32 is true, the 32 bit version of the application will be launched on a 64 bit system if available supports fat/universal binaries (such as OS X); otherwise, the native version of the application will launch.

string argv = Execute(integer show,integer force32)

FileCopy(dstFilePath, overwrite)

This copies a file from one path to another. If a file already exists at the destination path and overwrite is true, it will be overwritten with no warning given. If overwrite is false, then the method will fail if a file already exists at the destination.

FileCopy(string srcFilePath,string dstFilePath,integer overwrite)


It is often useful to know the modification time of a file in a platform-agnostic format. This method returns that as a string of “YYYY:MM:DD HH:MM:SS”. This assures that sorting date strings using strcmp()-like functions puts the dates in chronological order.

string = FileDateString(string filename)


This deletes a file from disk, if possible. In general, this must be a file (not a directory).

FileDelete(string filename)


string = FileFromURL(string url)


string path = FileSystemPath(string name)


These two utilities convert between local paths and URLs. These paths begin with the “file://” URL prefix.

string = FileToURL(string filename)


(integer first,integer last) = FindSequenceBounds(string pattern)


string = FindSequencePattern(string filename)


Local file and path names can be converted to and from neutral format with these interfaces. The value returned is the result of the conversion. These conversions are raw, performing a simple conversion without validity checks. Aliases are not used in the first two methods, they are in ‘ToLocalAlias’.

string = FromLocal(string local)


string = GenerateSequenceName(string pattern,integer frame)


This returns LXe_TRUE if a path is absolute, and LXe_FALSE if it is not.

boolean = IsAbsolutePath(string path)


Given a path to a directory, this creates the directories, if possible.

MakeDirectory(string path)


This in-place modifies a C string, replacing characters with special meaning in the OS (like slashes and colons) with underscores. If replacedDot is true, periods will also be replaced. This should only be called on filenmaes, as it will remove the slashes and colons from full paths. This returns LXe_TRUE if the path was already legal, and LXe_FALSE if any characters were replaced with underscores.

MakeLegalFilename(byte[] filename,integer replaceDot)


This makes a filename relative to a path, if possible. This fails if the filename could not be made relative.

string = MakeRelative(string filename,string path)


This computes a unique filename given a base pattern by adding digits. For example, if the path is “c:myfile.ext”, this will first see if “c:myfile.ext” exists. If it does not, it will be returned. If it does exist, then the path will be changed to “c:myfile_1.ext” and tested again, and so on until the path is unique. This method fails if the path portion doesn’t exist.

string = MakeUnique(string filename)


This opens a file in the application associated with it by the operating system.

OpenFileWithDefaultApp(string filename)


This parses a filename path, extracting the last portion of the path into the basename buffer and the path into the path buffer.

string = ParsePath(string filename,integer component)


This renames a file on disk, if possible. This will also work on directories. This can also be used to move files.

RenameFile(string from_str,string to_str)


This finds the file/folder and selects it in Explorer/Finder. Calling this with a folder will open the parent in Explorer/Finder and select it, while using

RevealInFileViewer(string filename)


This takes a filename and extension, and returns the same filename but with the new extension. The extension string is just the part after the period.

string = SetExtension(string filename,string extension)


This returns a combination of flags indicating if a file can be read and/or written. This method always succeeds, even if the file doesn’t exist.

integer mode = TestFileMode(string filename)


NONE indicates that the file does not exist or cannot be accessed for some reason. UNKNOWN indicates that the file exists but is some unusual type.

(boolean,integer type) = TestFileType(string filename)


string = ToLocal(byte[] neutral)


string = ToLocalAlias(string neutral)


Takes a product name and version number and returns LXe_OK if there is a valid license.

ValidateLicense(string product,integer versionNum)


class lxu.service.GUID

Empty GUID service Python user class.


string = Class(string guid)


string = ClassName(string guid)


integer = Compare(string guid1,string guid2)


string = Fixed(string guid)


string = GetName(string guid)


A service interface for converting between GUID strings and LXtGUID structs is exported as part of the application global.

string = Translate(string guidStr)


class lxu.service.Host

Empty Host service Python user class.


Application hosts can add servers as factories. This should not be done by plug-ins becuase they can add servers through the module method.

AddServer(object factory)


This returns the path to the plug-in directory.

string path = DefaultPath()

LookupServer(name, allowLoad)

This method can be used to lookup a factory it’s class and server name. If allowLoad is true it will prompt the user to find a module if the server is not known. The factory must be released when no longer needed.

Factory object = LookupServer(string className,string name,integer allowLoad)


These methods allow the server database to be scanned. These first two allow the server list to walked by class. The factory returned must be released when no longer needed.

integer = NumServers(string className)

SaverSave(format, object, monitor)

This will perform a save using the filename, format and data object. The monitor is optional.

SaverSave(string filename,string format,object object,object monitor)

SaverVerify(object, msg)

Saver verification can be triggered directly for a given format and data object.

SaverVerify(string format,object object,object msg)


As with all globals, the first method gets the ILxScriptQueryID interface for the system.

Unknown object = ScriptQuery()


Factory object = ServerByIndex(string className,integer index)


Servers can also be looked up by name to get their index.

integer index = ServerGetIndex(string className,string name)


We can also query things specific to our module. This return LXe_TRUE if the server is being spawned only to read tags.



This simply tests to see if a server exists, and skips the error reporting.

boolean = TestServer(string className,string name)


Dynamic modules can update - well, dynamically. Calling this method will force the server database to update the contents of the dynamic module.

UpdateModule(string name)


class lxu.service.IO

Empty IO service Python user class.

OpenBlockStore(format, flags)

Open a block store. Each store has a format given by a string up to 8 charaters in length. Depending on the flags the file may be created if it doesn’t exist, in which case this method returns FALSE instead of OK.

(boolean,BlockStore object) = OpenBlockStore(string filename,string format,integer flags)


object = PeekOptions()


Unknown object = ScriptQuery()


These methods are used to access the global load-options object. This is an object set by the loader’s options command which can then be read by the loader during the actual load. It will also be stored in the case of sub-object loads.

SetOptions(object options)


class lxu.service.Image

Empty Image service Python user class.

Composite(source, pos)

Composite(object dest,object source,vector pos)

Create(height, type, maxIndex)

Image object = Create(integer width,integer height,integer type,integer maxIndex)

CreateCrop(x, y, w, h)

Image object = CreateCrop(object sourceImage,float x,float y,float w,float h)

CreateLayered(height, layerNum)

Unknown object = CreateLayered(integer width,integer height,integer layerNum)

DrawLine(p0, p1, color)

DrawLine(object image,vector p0,vector p1,vector color)


Image object = Duplicate(object source,integer type)

ImageGetBuffer(type, buf)

This reads the entire image into a single buffer given the pixel format. This is just like Image::GetLine() except that it does all the lines at once.

ImageGetBuffer(object sourceImage,integer type,data[] buf)


vector rgbColor = Kelvin2RGB(float kelvin)


Image object = Load(string filePath)


LaodNoCache() is the same as

Image object = LoadNoCache(string filePath)


float kelvin = RGB2Kelvin(vector rgbColor)

Resample(source, hint)

Resample(object dest,object source,integer hint)

Save(filePath, format, monitor)

Save(object image,string filePath,string format,object monitor)

SaveLayered(filePath, format, monitor)

SaveLayered(object layeredImage,string filePath,string format,object monitor)


Image facilities can be accessed through the SDK using a global service interface.

Unknown object = ScriptQuery()


class lxu.service.ImageMonitor

Empty ImageMonitor service Python user class.


Sometimes image analysis can take a while. This utility can be used to tell all views with a particular image source to ask their server to redraw their view. If immediate is true, the view will be redrawn immediately. This is useful for interaction operations using the mousing methods of the monitor. If false, the view will be updated during at the normal redrawing time.

RefreshViews(string imageSource,integer immediate)


As with all globals, the first method gets the ILxScriptQueryID interface for the system. This is not currently implemented.

Unknown object = ScriptQuery()


ImageMonitor object = ServerByIndex(integer index)


These methods allow the server list to be walked, and allow a server to be looked up by name. When a COM object is returned, the client is responsible for releasing it as usual.

integer count = ServerCount()


ImageMonitor object = ServerLookup(string name)


These methods return the name and username of a server given an index.

string name = ServerNameByIndex(integer index)


string name = ServerUserNameByIndex(integer index)

SetImage(image, frameBuffer, bufferIndex, x1, y1, x2, y2, imageProc, processedThumbnail)

Clients can use this to change the current image in an image source. This in turn will ask associated views to analyze the new image. Either the image (ILxImageID) or frameBuffer (ILxFrameBufferID) and bufferIndex should be set; if they’re NULL, then no image is to be analyzed. x1/y1 and x2/y2 define a window into the image to the analyzed; if 0,0 and 1,1, the entire image is analyzed. Images are set for a specific image source, and thus only affects views monitoring that source. Note that imageProc is an object with an

SetImage(string imageSource,object image,object frameBuffer,integer bufferIndex,float x1,float y1,float x2,float y2,object imageProc,object processedThumbnail)


These can be used to get a list of image sources names, as defined through the config system.

integer count = SourceCount()


string name = SourceNameByIndex(integer index)


string username = SourceUserNameByIndex(integer index)


class lxu.service.ImageProcessing

Empty ImageProcessing service Python user class.


This is the important methods, which returns a new image processing object.

ImageProcessing object = Create()


As with all globals, the first method gets the ILxScriptQueryID interface for the system. Since there is currently no ScriptQuery interface, this method will always fail.

Unknown object = ScriptQuery()


class lxu.service.InputMap

Empty Command service Python user class.

CanEventsCoexist(event1, event2)

This checks to see if two events (by event type) conflict with each other. This returns LXe_TRUE if two events with mutually exclusive flags cover different regions of the mouser, and thus can both use the same key combo.

CanEventsCoexist(id im,integer event1,integer event2)


These allow the context list to be walked. For convenience, contexts are sorted alphabetically, with the global context listed first.

integer count = ContextCount()


This adds the client test object (InputMapClientTest interface) to the input map.

DefineClientTests(object tester)

DefineCustomEvent(name, flags)

DefineCustomEvent(integer event,string name,integer flags)


The remaining definition methods all operate on the most recently created input map. Once defined, an input map cannot be edited dynamically. Each input map can belong to one group for user interface purposes. Common groups are Viewports, Controls and Components, etc. Groups are specified as a path, such as “viewports/3d”. Each path and each component of the path (i.e., “viewport” and “viewport/3d” in the above example) are looked up as message ID 1 in their own message tables using the form “{inputmapgroup} grouppath”. Don’t forget to make message tables for each part of the path.

DefineGroup(string group)


Input maps can specify regions for triggering context menus. Each region’s type and internal name are defined using this function. Region types can be anything but 0, and can overlap with the event codes.

DefineRegion(integer event,string name)


Standard events can be added to an input map with this method. These inputs can then be assigned to specific mouse/key combinations by the user. Standard events have set names and flags, and may be mapped globally or only for specific clients.

DefineStandardEvent(integer event,integer flags)


string desc = Desc(id im)


The following define should be used when calling a function that takes a region index, but you are doing a lookup based on name or type. The list of available events can be walked using these methods.

integer count = EventCount(id im)

EventDesc(stateName, name, index)

string desc = EventDesc(id im,string stateName,string name,integer index)


integer flags = EventFlags(id im,integer index)

EventHelpURL(stateName, name, index)

string helpURL = EventHelpURL(id im,string stateName,string name,integer index)


These methods return the event name, type and flags for a specific event given its index in the input map. LXiINMAPINDEX_NOEVENT can be used as a NULL for functions that can take a type if a name or index is provided instead.

string name = EventName(id im,integer index)


integer type = EventType(id im,integer index)

EventUserName(stateName, name, index)

For the event and region functions, either the name of the event/region or its index must be provided. If name is NULL, the index is used. LXe_NOTFOUND or LXe_OUTOFBOUNDS are the common error codes; LXe_FAILED may be returned if there is string of this type in the help. As usual, the username functions will fall back to the internal name as long as the event exists in the input map. User strings are looked up first by checking the input map and state name combination, falling back to the input map, and finally to the global map for global events. The state name can be LXsINMAPSTATE_GLOBAL if no state test is desired.

string username = EventUserName(id im,string stateName,string name,integer index)

FindEvent(name, type)

These methods can be used to lookup an event or region by name or type, returning its index. If the name is NULL, the type will be used for the lookup. LXiINMAPINDEX_NOEVENT can be used as the type when looking up by name.

integer index = FindEvent(id im,string name,integer type)

FindRegion(name, type)

For regions, a NULL name or an LXsINMAPREGION_ANYWHERE name and a type of LXiINMAPTYPE_NULL will return -1 (LXiINMAPINDEX_ANYWHERE), representing the “entire map” key assignment region. A name of LXsINMAPREGION_NOOP and a type of LXiINMAPTYPE_NULL will returnt he “noop” region. This returns LXiINMAPINDEX_NOREGION if it cannot be found.

integer index = FindRegion(id im,string name,integer type)


The MouseMapID is owned by the input map, and is automatic destroyed on shutdown; you should NOT free the mouse map yourself. This will be more useful once we have an SDK for mousers. Until then, we have to deal with a void *. The same mouse map may be attached to multiple mousers. TODO: Replace void * with COM MouserID when available

Unknown object = GetMouseMap(id im)


The name of a group can be obtained with this method. The string is a group in the form of “path/group”, while depth is what part of the path to return. -1 can be used to get the username for the entire path. Paths can be from read input maps using the

string username = GroupUserName(string path,integer depth)


string helpURL = HelpURL(id im)


These methods provide access to the raw input map properties, such as obtaining the internal name and listing events and regions.

string name = Name(id im)


When the context has changed, the client owning the context should call this function. This will force all mouse maps to update for the context change.



RefreshStates(integer flags)


integer count = RegionCount(id im)

RegionDesc(stateName, name, index)

string desc = RegionDesc(id im,string stateName,string name,integer index)

RegionHelpURL(stateName, name, index)

string helpURL = RegionHelpURL(id im,string stateName,string name,integer index)


These methods return the region name and type. An index of LXiINMAPINDEX_ANYWHERE will return the special “entire map” region with the name of LXsINMAPREGION_ANYWHERE and a type of LXiINMAPTYPE_NULL. Similarly, an index of LXiINMAPINDEX_NOOP will return the the “noop” region with the name LXsINMAPREGION_NOOP and type of LXiINMAPTYPE_NULL.

string name = RegionName(id im,integer i)


integer type = RegionType(id im,integer i)

RegionUserName(stateName, name, index)

string username = RegionUserName(id im,string stateName,string name,integer index)


As with all globals, the first method gets the ILxScriptQueryID interface for the system.

Unknown object = ScriptQuery()


integer flags = StandardEventFlags(integer event)


If you just want the event name/flags irrespective of the input map (these are standardized, after all), you can use these methods.

string name = StandardEventName(integer event)


This returns the username for a state category given an internal name.

string name = StateCatUserName(string cat)


These functions can be used to walk the list of states with assignments in an input map. Only states containing assignments are stored.

integer count = StateCount(id im)


These walk the list of fallback states for a given state, such as having unmapped Tool Preset events “fall through” to the specific Tool assignments within.

integer count = StateUIFallbacksCount(string stateName)


string name = StateUIFallbacksName(string stateName,integer index)


These can be used to walk the list of category states as provided by the clients. These are only used in things like the Input Editor, and while they should contain an all-inclusive list of states, that may not be true.

integer count = StateUIListCatCount()


string name = StateUIListCatName(integer index)


These can be used to get an alpha-sorted list of all known states within a specific category as provided by the input maps.

integer count = StateUIListCount(string cat)


string name = StateUIListName(string cat,integer index)

StateUITestEvent(stateName, eventID)

It is also possible to test to see if an event or region is supported by a state. For example, some tools may not use all of the available events in the input map, so there’s no need to show them in the UI.

StateUITestEvent(id im,string stateName,integer eventID)

StateUITestRegion(stateName, regionID)

StateUITestRegion(id im,string stateName,integer regionID)


The username for states is also available. If the state is NULL, then the global stateless name is returned. If a username cannot be found, the internal name passed in is returned. This method will always return a valid string.

string name = StateUserName(string state)


This checks to see if a current state is active. This can be used to decide which assignments should be applied to the mouse map defined by the input map, returning LXe_TRUE if the state is active. Note that multiple states may be active at once, which is where the priority comes in; the higher priority state assignments will take input first, falling through to the lower priority state assignments. The global “stateless” state will always return true with a priority of 0.

integer priority = TestState(id im,string state)


This tells inmap that a device’s state has changed, such as due to a button being pushed. The device will be polled for new values for all of its buttons and analog inputs.

UpdateDeviceInstance(string name)


InputMapService provides two methods to tell inmap that something has changed with regards to input devices. This should be called when the list of available devices has changed. All InputDevices servers will be scanned, with new devices added and old ones removed from the list.



These get the usernames for the input map itself and its specific events and regions. If a username cannot be found, the internal name is returned. For events and regions, NULL is returned if the event/region does not exist (out of bounds, etc).

string username = UserName(id im)


class lxu.service.Layer

Empty layer service Python user class.


(vector min,vector max) = Bounds(integer index)


ClearMark(object item)


The following functions operate on these lists, with indices based, naturally, on the position within the given list.

integer count = Count()


This function returns the name of the user’s currently selected deformer for the mesh item passed in, allowing the expected mesh to be retrieved through

string name = CurrentDeformer(object meshItem)


string name = CurrentMap(integer type)


float angle = CurveSmoothAngle(integer index)


integer flags = Flags(integer index)


The IsProcedural function determines if a layer is procedural or not. However, this function also takes the UI state into account, so if ghosting is enabled in the mesh operation stack and the base mesh is selected, the function will return false, even if the mesh is procedural. This is useful for setting the enable and disable state of tools or commands that operate on procedural layers.

IsProcedural(integer index)


Item object = Item(integer index)


These methods find an item’s position in one of the lists based on the item itself, or on its name. They will return an error AND set the index to -1 if the item is not found in the specified list. To use this index in layer commands, use LXi_LAYER_ALL mode.

integer index = ItemLookup(integer mode,object item)


integer childIndex = LayerChild(integer index,integer childNumber)


integer num = LayerChildCount(integer index)


Item object = LayerClip(integer index)


integer num = LayerClipCount()


Unknown object = LayerEdge(integer mode,integer index)


integer num = LayerEdgeCount(integer mode)


Item object = LayerMaterial(integer index)


integer num = LayerMaterialCount()


These methods access the parent-child relationships among layers. They return an index into the LXi_LAYER_ALL list, or -1.

integer parentIndex = LayerParent(integer index)


string part = LayerPart(integer index)


integer num = LayerPartCount()


Unknown object = LayerPoly(integer mode,integer index)


integer num = LayerPolyCount(integer mode)


string selSet = LayerSelSet(integer type,integer index)


integer num = LayerSelSetCount(integer type)

LayerTagTexture(type, tag, index)

Item object = LayerTagTexture(integer layer,integer type,string tag,integer index)

LayerTagTextureCount(type, tag)

integer num = LayerTagTextureCount(integer layer,integer type,string tag)


Item object = LayerTexture(integer layer,integer index)


The set of texture items applied to an item, or a part thereof are accessed with these functions.

integer num = LayerTextureCount(integer layer)


Unknown object = LayerVMap(integer index)


The meshes in the layer list have a number of associated entities like vertex maps, image clips, and textures. APIs are provided to access these entities, presumable as the appropriate COM objects. The list of vert. maps present in the active and background layers can be accessed using these methods. Multiple VMaps with the same name and type are represented as a single entry.

integer num = LayerVMapCount()


Unknown object = LayerVertex(integer mode,integer index)


Mesh elements (vertices, polygons, edges) can also retrieved, hopefully based on the layer list mode as well as a marking system yet to be described…

integer num = LayerVertexCount(integer mode)


Mesh object = Mesh(integer index)


string name = Name(integer index)


integer index = NameLookup(integer mode,string name)


integer level = PatchSubdivision(integer index)


float pivot = Pivot(integer index)


LayerScan object = ScanAllocate(integer flags)


You can also allocate a layer scan object for one mesh layer.

LayerScan object = ScanAllocateItem(object item,integer flags)


Scene object = Scene()


As with all globals, the first method gets the ILxScriptQueryID interface for the system.

Unknown object = ScriptQuery()


These functions set, clear and test for the mark used .

SetMark(object item)


The layer service functions operate with to a certain scene. This scene should be specified by the client BEFORE any other methods are used, as an initialization step. The scene can also be reset at any time, either to a new scene, or to force a refresh of the layer data.

SetScene(object scene)


integer slot = Slot(integer index)


integer level = SplinePatchSubdivision(integer index)


integer = TestMark(object item)


A transform scan object is allocated using the layer service. The client must also pass the tool vector object which contains info about weights and axes.

TransformScan object = XfrmAllocate(object toolVec)


class lxu.service.Listener

Empty listener service Python user class.


AddListener(object object)


RemoveListener(object object)


A listener service allows a client to submit itself as a global listener. The client object is queried for all global listener interfaces and any that are found will subsequently receive notifications as events occur.

Unknown object = ScriptQuery()


class lxu.service.Log

Empty log service Python user class.


This method can be used by any low-level client to acquire the global monitor for use. The acquire method returns a “peek” of the global monitor, so it is not add-refed, and the method may return null if there is none or it has already been acquired previously.

object = AcquireMonitor()


Info blocks can be used to provide formatted messages. The first step is to get a new ILxLogEntryID with this method. The block arguments are the name of a previously registered info block. Once created, the ILxLogEntryID can be filled in with the the appropriate methods.

LogEntry object = CreateEntryInfoBlock(integer type,string blockName)


Debug messages are used only for internal purposes, and follow the same visibility rules as DBprintf(), as well as being output to the console through DBprintf() when added.

LogEntry object = CreateEntryMessage(integer type,string message)


This allows yout create a new entry from an ILxMessageID. The message itself and the type code are read from the ILxMessageID

LogEntry object = CreateEntryMessageFromMsgObj(object msgObj)


A second way to add complex formatted messages is through name/value pairs. The returned ILxLogEntryID will need to be populated with the appropriate methods.

LogEntry object = CreateEntryPaired(integer type)


This function lets plug-ins dump data to the normal debug log. The level indicates the severity of the information, allowing debug trace output to be hidden during normal usage.

DebugLogOutput(integer level,string line)

DebugLogOutputSys(logSystem, line)

DebugLogOutputSys(integer level,string logSystem,string line)


Logging can be enabled and disabled on a per-subsystem basis. When disabled, logged events will still go to that subsystem, but they will not show up in the master log or the console output. This does not affect rolling log entries.

EnableLogging(string systemName,integer state)


Message object = ExceptionBlockCollect()


Exception messages are handled by a client system high enough to be able to display an error message, but general enough that any type of exception might be possible. The start method assures that past exceptions have been handled and clears the state. The collect method reads out any exception message. This generally only needs to be called when an error has happened, and if there is no error it will return NOTFOUND.



The exception message is a single, global message object that holds a description of the cause of an unexpected failure. This can be set at the site of an initial error with a description of the cause of the error, and it will be displayed to the user by the controlling code higher up the stack.

object = ExceptionMessage(integer error,integer flags)


LogInfoBlock object = InfoBlockByIndex(integer index)


Like subsystems, the list of info blocks can be walked and looked up by name.

integer count = InfoBlockCount()


This returns the group and/or sub parts of the field name. Either can be NULL if you only want the one. Note that *sub may be NULL if there is no sub. Also note that this function is NOT thread safe, and that the strings returned are only good until the next call to this function.

(string group,string sub) = InfoBlockFieldGetParts(string name)


These helpers check to see if two field names are in the same group (i.e., have the same name up to the first period), and return the names of the group and sub. The group test returns LXe_TRUE if the two field names are in the same group and LXe_FALSE if not. Any other code is an error.

boolean = InfoBlockFieldsAreSameGroup(string name1,string name2)


This looks up a subsystem by name.

LogInfoBlock object = InfoBlockLookup(string name)


This returns LXe_TRUE if loggin is enabled for a system, and LXe_FALSE if it is disabled.

boolean = IsLoggingEnabled(string systemName)


Log object = MasterSubSystem()

ReplaceEntryMessage(type, msg)

This low-level utility provides a way to change the string and type code associated with a message-class log entry. This is rarely used, but can be useful when you need to add some summary information to a parent entry. This only works on log entries created with

ReplaceEntryMessage(object logEntry,integer type,string msg)


As with all globals, the first method gets the ILxScriptQueryID interface for the system.

Unknown object = ScriptQuery()


There are times when high-level operations trigger low-level operations that may take a while. In that case we should have a monitor, but there is no way to pass the monitor down from the UI command to the actual code that needs it. The log service allows us to prepare a monitor and deliver it to a lower-level function. This method sets the global monitor. If called with null the monitor is cleared.

SetMonitor(object monitor)


Log object = SubSystemByIndex(integer index)


The list of subsystems can be walked with these functions. As of 901, an entry can only belong to one subsystem, or zero if it hasn’t been added to any yet.

integer count = SubSystemCount()


This looks up a subsystem by name or, if NULL, by ID.

Log object = SubSystemLookup(string name)


class lxu.service.Mesh

Empty mesh service Python user class.


This converts a private mesh to a static mesh.

ConvertMesh(object triGroupObj,object meshObj)


Clients can create their own private mesh objects, not affiliated with any item.

Mesh object = CreateMesh()


Creates a

PolygonSlice object = CreateSlice()


Creates a

SolidDrill object = CreateSolidDrill()


Returns a curve group for the provided mesh, allowing the polygonal curves to be enumerated and evaluated.

Unknown object = CurveGroupFromMesh(object mesh,matrix xfrm)


This returns LXe_TRUE if the specified mesh item is procedural and LXe_FALSE if it isn’t.

boolean = IsMeshProcedural(object item)


Returns an Item object that a mesh belongs to. For private meshes, the function fails.

Item object = ItemFromMesh(object mesh)

MeshFromSurface(surfItem, surfObj)

Returns a mesh from a surface interface.

MeshFromSurface(object meshObj,object surfItem,object surfObj)


This converts a static mesh to an editable mesh.

MeshFromTriGroup(object meshObj,object triGroupObj)


This method allows multiple mode bits to be marked as “must be set” or “must be cleared”. The two arguments take a space-delimited list of modes to set or clear, failing with LXe_NOTFOUND if the mode is unknown. Either argument can be NULL.

integer mode = ModeCompose(string set,string clear)


Unknown object = ScriptQuery()


Returns a surface from a mesh. In the majority of cases, the mesh item can be evaluated directly for a surface. However if you have a private mesh, this function can be used.

Surface object = SurfaceFromMesh(object mesh,object meshItem)


This converts any surface to a static mesh.

SurfaceToTriGroup(object triGroupObj,object surfObj)

Tessellate(meshSource, xfrm, flags)

Returns a tessellated mesh from source mesh. ‘xfrm’ transform new vertex position as option. if COPYFACE is set then it copies raw face polygons without subdivision, otherwise FACE polygons are tessellated to triangles. Subdivision surface polygons are tessellated to quadrangles. if TRIPLE is set, subdivision surface are tesselated to triangles instead of quadrangles.

Tessellate(object meshTess,object meshSource,matrix xfrm,integer flags)


Static meshes can be rigidly transformed.

matrix xfrm = TriGroupTransform(object triGroupObj)


It can also be useful to find the features of a vertex map type without requiring an actual instance. These functions are equivalent to the same-named functions in the mesh map interface.

integer dimension = VMapDimension(integer type)


boolean = VMapIsContinuous(integer type)


boolean = VMapIsEdgeMap(integer type)


string name = VMapLookupName(integer type)


Vertex map types have names and codes which can be translated with these functions.

integer type = VMapLookupType(string name)


boolean = VMapZeroDefault(integer type)


Validates and returns the named mesh meta for the provided mesh.

Unknown object = ValidateMetaData(object mesh,string name)


class lxu.service.Message

Empty message service Python user class.


This allocate a new

Message object = Allocate()


string = ArgTypeDesc(string argType)


string = ArgTypeOptionDesc(string argType,string option)


These get a specific user string given an internal option name and an argument type name.

string = ArgTypeOptionUserName(string argType,string option)


These methods return the username and description of a given argument type.

string = ArgTypeUserName(string argType)


An existing

Message object = Duplicate(object msg)


This return a human-readable string from the given message object. This fails if there is no message text, but will also set the buffer to an empty string. Note that messages returned in this way will not have any rich text encodings from modo markup in them. If you want the encodings, see

string = MessageText(object msg)


For backwards compatibility, message strings have any modo markup removed before they are returned. This makes them suitable for use in non-modo UIs, like web pages or Qt widgets. These functions return the string without stripping the decoded markup, allowing them to be displayed as rich text in modo.

string = MessageTextRich(object msg)


Finally it’s possible to get the raw message pattern directly from the message table, without substitution and without using an

string text = RawText(string table,string msg)


string text = RawTextRich(string table,string msg)


As usual, the service starts with a ScriptQuery method.

Unknown object = ScriptQuery()


Strings tables are like message tables, but aren’t localized. They can be useful if you want to store an internal string in a config so that ti can be easily changed. This looks up a string given a table/ident pair and returns it.

string text = StringLookup(string table,string ident)


If you do have a srting with rich text codes in it, they can be stripped with this function. The string returned should be considered volatile, and used or copied as soon as possible.

string stripped = StripRichText(string string)


class lxu.service.Network
OneOffHostListAdd(ip, port)

OneOffHostListAdd(string hostname,integer ip,integer port)

OneOffHostListRemove(ip, port)

It is also possible to remove a one-off connection. This is really just a clean-up phase; it doesn’t disconnect from the host. It’s usually useful to remove it when you want to try to reconnect to it as calling

OneOffHostListRemove(string hostname,integer ip,integer port)


As with all globals, the first method gets the ILxScriptQueryID interface for the system. However, it is not implemented for

Unknown object = ScriptQuery()


class lxu.service.Nodal

Empty nodal service Python user class.

AddSampleChan(item, chanIndex, type)

The nodal service is used to establish and evaluate channels as part of the Nodal Shading system. The service is used by textures & shaders in two ways: as part of the Shader Tree, their inputs can be evaluated on a per-sample basis, and their outputs can also be requested as part of the Nodal Modifier system. The Nodal Service will transparently handle both of these cases. AddSampleChan & AddSampleChanName are used to add a channel of an item to the nodal evaluation system. When processed as part of the Shader Tree, the evaluator index will be stored in the ‘idxArray’ passed, and when processed as a nodal modifier, the evaluator index will be stored internally within the nodal evaluator (and ‘idxArray’ may be NULL). Additionally, within the Shader Tree, if the channel is not actually driven on a per-sample basis for the current pass, the evaluator index is stored as LXiNODAL_NOT_DRIVEN. This value speeds up the evaluations by letting the Get* methods know that the value does not have to be read from the evaluator. When adding channels for texture locators, LXfECHAN_LOCATOR should be ORed with the LXfECHAN_READ and/or LXfECHAN_WRITE flags. GetFloat, GetInt & GetValue are used to get the current sample values from a nodal evaluator. ‘index’ is the index of channel in the item. For evaluations in Shader Tree, the values will be read from the evaluator using the ‘idxArray’ passed, unless the stored index is LXiNODAL_NOT_DRIVEN, in which case the ‘orig’ value will be returned. When evaluated as a nodal modifier, the internal index array will be used. IsDriven & IsDrivenName are used to determine if a channel is driven per-sample, and therefore needs to be read at every sample. If not, the value can be read once per layer. AnyDrivenChans is used for optimization of the evaluation. It is passed a contiguous array of evaluator indexes, and will return LXe_TRUE for the first sample-driven channel, and LXe_FALSE if none are found.

(integer,integer idxArray) = AddSampleChan(object eval,object item,integer chanIndex,integer type)

AddSampleChanName(item, chanName, type)

(integer,integer idxArray) = AddSampleChanName(object eval,object item,string chanName,integer type)


(integer,integer chans) = AnyDrivenChans(integer count)

GetFloat(index, orig)

(float,integer idxArray) = GetFloat(object etor,integer index,float orig)

GetInt(index, orig)

(integer,integer idxArray) = GetInt(object etor,integer index,integer orig)

GetValue(index, orig)

(pointer,integer idxArray) = GetValue(object etor,integer index,pointer orig)


integer = IsDriven(object item,integer chanIndex)


integer = IsDrivenName(object item,string chanName)


class lxu.service.NotifySys

Empty notifysys service Python user class.


Notifier object = ByIndex(integer index)


These functions can be used to walk the list of instanced notifiers. As usual, the client must release any objects returned by

integer count = Count()


Notifiers that have been instanced can be looked up with this function. This will fail if the notifier has not been instanced, and the returned notifier must be released when no longer needed.

Notifier object = Lookup(string name,string args)


string name = NameByIndex(integer index)



Unknown object = ScriptQuery()


A new notifier can be instanced with this function. The plug-in class name and argument string are provided. If the notifier with these arguments already exists, that notifier is used instead. IF a notifier with this name and exact arguments is already instanced, it will be returned instead of spawning a new one. In both cases the returned object must be released when no longer needed.

Notifier object = Spawn(string name,string args)


class lxu.service.Packet

Empty packet service Python user class.

AddPacket(name, flags)

AddPacket(object vtype,string name,integer flags)


These two methods allow clients to create simple vector types. The first method allocates an empty vector type, and the second method allows packets to be added to the definition.

VectorType object = CreateVectorType(string category)


pointer = FastPacket(object vector,integer offset)


integer offset = Lookup(string category,string name)


string name = Name(string category,integer offset)


The lookup is available to plug-in clients as a global service with a

Unknown object = ScriptQuery()


class lxu.service.Particle

Empty particle service Python user class.


Enumerate the particle features added to an item. Any item can set the USEFEATURES server tag to allow features to be added. For each feature the visitor can read the ident string and channel offset.

EnumParticleFeatures(object item,object visitor)


ReplicatorEnumerator object = EnumeratorEvaluate(object attr,integer index)


These methods are provided for accessing a replicator enumerator as part of a modifier. The channel-read object in this case should be NULL.

integer index = EnumeratorPrepare(object eval,object replItem)


string ident = FeatureIdent()


integer offset = FeatureOffset()


Get an enumerator for a replicator. This requires a valid replicator item, and will need an evaluated channel-read object to enumerate.

ReplicatorEnumerator object = GetReplicatorEnumerator(object replicatorItem)


Get a particle object from any particle item. Takes an eval channel read object.

Unknown object = ItemToParticle(object item,object chanRead)


Unknown object = ScriptQuery()

TriGroupBlend(triGroup1, blend)

You can also blend two tri-groups representing particle state. Group 0 will be changed based on the amount, with 0.0 being no change and 1.0 being complete replacement.

TriGroupBlend(object triGroup0,object triGroup1,float blend)


If you have a triGroup object with positional data and other particle features, you can convert it to a particle object with this function.

Unknown object = TriGroupToParticle(object triGroup)


class lxu.service.Persistence

Empty persistence service Python user class.


While in an entry definition, values can be added. Currently only one value per entry is allowed. The type name is any of the value types.

AddValue(string typeName)


Clients call this method to define a set of persistent attributes. The name will define a top-level atom in the config file which should be unique. The object can be a visitor which, when evaluated, should add entries and values. It should be noted that this function should only be called once for any top-level name during the lifetime of the application. Attempting to call it again will return an error.

Configure(string name,object obj)


PersistentEntry object = End()


Unknown object = ScriptQuery()


During configuration, these calls define the nested hierarchy of entries. Each entry has a name and a type

Start(string name,integer type)


class lxu.service.Platform

Empty platform service Python user class.


integer build = AppBuild()


Get the application name.

string name = AppName()


string name = AppUsername()


Get the version and build numbers of the application.

integer version = AppVersion()


integer version = AppVersionMajor()


Get the minor and service back version numbers.

integer version = AppVersionMinor()


integer version = AppVersionSP()


This can be used to remove a pending user idle action. It will do nothing if the idle action isn’t armed. Note that flags and the vistor pointer must be exactly the same as the one passed to

CancelDoWhenUserIsIdle(object visitor,integer flags)


This arms a user idle action, preferably only once until it has been fired, after which you can arm it again if necessary.

DoWhenUserIsIdle(object visitor,integer flags)


Get the number of days left until the key expires, or -1 if the key is permanent.

integer daysLeft = ExpiresIn()


string path = ImportPathByIndex(integer index)


Walk the list of imported resource paths.

integer index = ImportPathCount()


This returns true if the application (but not necessarily the platform) is 64 bit, and false if it’s 32 bit.

boolean = IsApp64Bit()


Another useful feature is to be able to know when the app has become active or inactive. This returns LXe_TRUE if the app is currently active.

boolean = IsAppActive()


This returns LXe_TRUE if the app is running in headless mode, and LXe_FALSE if not.

boolean = IsHeadless()


This will return true if the app was started in safe mode.

boolean = IsSafeMode()


This simply returns if the user is currently idle. It can be useful at times, but generally you always want to perform your idle actions from

boolean = IsUserIdle()


Get the user the app is licensed to. If not licensed, this fails.

string licensee = LicensedTo()


Get the number of licenses this key works with.

integer licenses = NumLicenses()


string name = OSName()


integer type = OSType()


string version = OSVersion()


string path = PathByIndex(integer index)


Walk the list of paths.

integer count = PathCount()


This returns the internal name of the path, or NULL if the path doesn’t have one.

string name = PathNameByIndex(integer index)


Unknown object = ScriptQuery()


Get the serial number of this key.

string serial = SerialNumber()


The current session stage can be read with this method, indicating the status of the application.

integer stage = SessionStage()


A currently-running timer can be canceled with this function. The visitor and flags must match what the timer was armed with. Note that when doing this from Python, you must pass the exact same visitor COM object (not Python object). This is also necessary when removing listeners and canceling user idle actions, as discussed here:

TimerCancel(object visitor,integer idleFlags)

TimerStart(milliseconds, idleFlags)

Timers execute after a pre-determiend number of milliseconds. A timer executes only once, but you can re-arm it when it expires if you want. The most common use of timers is to check files for changes or trigger periodic refreshes of part of the UI. Note that timers can trigger at arbitrary and unsafe times, such as in the middle of rendering or while saving a file. You should never execute a command from a timer, for exmaple, but rather arm a user idle action (and even then executing commands is a bit iffy, since now you’re adding something to the command history or undo list that the user didn’t do directly, but sometimes it is necessary).

TimerStart(object visitor,integer milliseconds,integer idleFlags)


class lxu.service.PresetBrowser

Empty PresetBrowser service Python user class.


Normally, preset selection is done through the selection system. However, this requires executing commands, which can limit how the browser is used (such as using the Preset Browser as a clipChoice component). To handle this, the Preset Browser can be set to a special selection mode that allows only one path to be selected at a time. This path (given an identifier) can set and read with these methods. Toggling the special selection mode is done with viewport arguments when embedded in a form, or through the viewport preset when in a layout. Note that when in this mode, the “do” (double-click) behavior and the preset region in general are disabled, as those require executing commands and the selection system. These functions will always work, even if the a viewport with the identifier doesn’t exist or isn’t in special selection mode. This allows the path to be set and read at any time. When setting, if asInteractive is true, the “do” action associated with browser is executed for the path as though the user had double-clicked it.

string = GetSpecialSelModePath(string identifier)


boolean = IsViewportVisible(string identifier,string hash)


(string serverName,string category) = RecognizeFile(string path,integer flags)


This is identical to

(string serverName,string category) = RecognizeFileForce(string path,integer flags)


The rescan method is a wrapper for

Rescan(string path)


As with all globals, the first method gets the ILxScriptQueryID interface for the system.

Unknown object = ScriptQuery()


PresetType object = ServerByIndex(integer index)


These methods allow the server list to be walked, and allow a server to be looked up by name. When a COM object is returned, the client is responsible for freeing it as usual.

integer count = ServerCount()


PresetType object = ServerLookup(string name)


These methods return the name and username of a server given an index.

string name = ServerNameByIndex(integer index)


string name = ServerUserNameByIndex(integer index)

SetSpecialSelModePath(path, asInteractive)

SetSpecialSelModePath(string identifier,string path,integer asInteractive)


The packets in a particular subtype can then be walked with the SelClient…() series of functions defined in sel.qq. The selection client and index together are used to walk a particular list of packets. There is also a function to listen for events for a specific subtype. Selection should also be done with the select.preset command, and dropped with select.presetDrop. This ensures that only one subtype is affected. There is also a special “global” subtype that can be obtained by passing NULL to

integer subtype = SubtypeFromIdentifier(string identifier)


On the flip side, the client needs to notify the browser when its state changes externally. This method will update the preset selection if necessary, as well as updating the current path of any preset browser with that identifier so that the current selection is visible there. The identifier must be non-NULL. Note that this works by executing commands for the normal selection mode. If in special selection mode,

UpdateIdentifierState(string identifier,string path)


class lxu.service.PresetDestination

Empty Python user class


ApplyMeshPresetToMeshPD(object predest,string filepath)

ApplyProfilePDToMesh(tolerance, freeze, axis, mesh)

Some Preset Destination items can be applied programmatically as well. This function makes mesh elements from the preset. If ‘freeze’ is on, it converts the preset to face polygons. If ‘center’ is NULL, the shape center will be located in the raw position of the file. ‘tol’ is the tolerance to subdive curve. If ‘tol’ is zero, this subdivide curves based on curve display level. “metrics” stores optional data to transform the profile.

ApplyProfilePDToMesh(object predest,float tolerance,integer freeze,integer axis,object mesh)


Unknown object = CreateMeshLayerPD(object mesh,object shadeItem)


Unknown object = Profile1DPDFromPath(string filepath)


Unknown object = Profile2DPDFromPath(string filepath)


Various preset destination objects can be allocated through the SDK.

Unknown object = ShaderPDFromItem(object item)


class lxu.service.Preview

Empty preview service Python user class.


Preview object = CreatePreview()

GetMeshPreview(width, height)

Unknown object = GetMeshPreview(object item,integer width,integer height)


class lxu.service.Render

Empty render service Python user class.


Delete the frame buffer file at the given slot index. This also deletes associated data, such as stats files and thumbnails.

FrameDelete(integer slotIndex)

FrameRecall(passIndex, monitor)

Loads a previously saved frame buffer from disk at the “slot” and “render pass” indices provided and returns an object with an ILxFrameBufferID interface.

FrameBuffer object = FrameRecall(integer slotIndex,integer passIndex,object monitor)


RenderStats object = FrameRecallStats(integer slotIndex)


Image object = FrameRecallThumbnail(integer slotIndex)


This convenience method returns the number of render passes. (The implementation calls

integer numPasses = FrameRenderPassCount(integer slotIndex)

FrameRenderPassInfo(passIndex, name)

Return the render pass name, size, and number of render outputs of the frame buffer at the given slot and pass indices. If the slot or pass is not found, FrameRenderPassInfo returns LXe_NOTFOUND.

(integer width,integer height,integer outputCount,integer isStereo,integer eyeDisplay,integer stereoComposite) = FrameRenderPassInfo(integer slotIndex,integer passIndex,byte[] name)

FrameSaveImage(bufferIndex, filename, format, message, monitor)

Save a frame buffer to disk as a simple image or a layered image.

FrameSaveImage(object framebuffer,integer bufferIndex,string filename,string format,object message,object monitor)

FrameSaveLayered(filename, format, message, monitor)

FrameSaveLayered(object framebuffer,string filename,string format,object message,object monitor)

FrameSavePassLayered(filename, format, message, monitor)

Save a frame buffer to disk as a layered image, only for its own pass.

FrameSavePassLayered(object framebuffer,string filename,string format,object message,object monitor)

FrameSavePassesAsImages(filename, format, message, monitor)

Save a frame buffer to disk as a simple image or a layered image, for each render pass at the given slot index.

FrameSavePassesAsImages(integer slotIndex,string filename,string format,object message,object monitor)

FrameSavePassesAsLayeredImages(filename, format, message, monitor)

FrameSavePassesAsLayeredImages(integer slotIndex,string filename,string format,object message,object monitor)


Writes the framebuffer to disk in a proprietary format. The frame buffer can be recalled later on for display to the user. FrameStore and FrameRecall are commonly used in a system to enable reloading previous renders. FrameStore is called internally before a job’s ProgressFrameEnd() method, but can also be called after baking operations that modify the frame buffer pixel colors, to make those changes permanent. This function should still be called even if Write Buckets To Disk is used, in which case the frame buffer pixels are written to disk separately, and this call will simply write the meta-data that is required to re-load the frame buffer later on. Once a frame and its pixels has been written to disk, the header can be re-written without affecting the pixels by passing in zero for the writePixels parameter.

FrameStore(object frameBuffer,integer writePixels)


These methods are used to save and load the stats for a frame buffer. The stats are reprresented by an object with an

FrameStoreStats(integer slotIndex,object stats)


Clients can also save a thumbnail image for each slot. This image may be any size, but something like 256x256 is commonly used. The thumbnail is indented to be used to populate a browser without needing to load the entire frame buffer into memory. The thumbnail is saved as a sidecar file to the frame buffer. These methods are thread safe. Note that the renderer does not save a thumbnail itself; it is up to the client if they want to save a thumbnail. These methods just provide an easy way to assocaite a thumbnail with a frame buffer.

FrameStoreThumbnail(integer slotIndex,object image)


Tests if a frame buffer is present on disk at the given slot and pass indices. FrameTestRecall can be called in a loop to get a count of the number of passes by incrementing passIndex until LXe_NOTFOUND is returned.

boolean = FrameTestRecall(integer slotIndex,integer passIndex)


This aborts a currently running render job. It will fail if no jobs are currently rendering. Note that although this function returns immediately, it may take some time before the render has finished aborting.



This utility can be used to reclaim memory after a render has completed. If clearJob is true, this also clears out the current job by implicitly calling JobSetCurrent(NULL);

JobCleanup(integer clearJob)


This returns the current render job, failing if there is no current job. The returned object must be released by the caller if the method returns success.

RenderJob object = JobCurrent()


Return whether or not the current job is running in slave mode.

integer = JobIsSlave()


These are used to get the number of outputs and their username strings while a render is in progress. This information can be used to populate a render outputs popup that the user can change while rendering via the job’s ProgressImageMetrics() method. These methods are only valid while rendering, and will return Lx_ when not.

integer count = JobRenderOutputCount()


string name = JobRenderOutputName(integer index)


This related function returns the type of a render output as an LXiRENDEROUTPUT_ define.

integer type = JobRenderOutputType(integer index)


The client provides information about how to render a scene with a render job. This is a COM object with an

JobSetCurrent(object job)


This method can be used to start rendering the current job, using the properties of the job to render the scene. This function does not block, and will return immediately. Status updates are sent to various methods on the job object itself.



This returns an

object = JobStats()


This returns the current status of a render job as an LxResult code.



This is used to indicate that the metrics of the progress image need to be refreshed by the client. The client should then call



This function returns the Effect name from a given render type value. e.g LXiRENDEROUTPUT_FINALCOLOR to “shader.color”

string effectName = RenderEffectFromRenderType(integer type)


This function returns type for a given effect name and the number of components. For instance, “alpha” will have one component, whereas “shade.color” will have 3.

(integer type,integer size) = RenderEffectToType(string effect)


As with all globals, the first method gets the ILxScriptQueryID interface for the system. Since there is currently no ScriptQuery interface, this method will always fail.

Unknown object = ScriptQuery()


This causes the render service to call the current job’s ProgressImage method with the progress image from the current.



class lxu.service.Scene

In python the entire list can be read at once.


Call this service method to allocate an empty collection.

ItemCollection object = AllocEmptyCollection()


This function returns the number of components in the given one of the LXiCHANMODE_* defines.

integer size = ChannelVectorSize(integer mode)


Useful for UIs and configs, this function returns the text hints array for the vector modes.

hints hints = ChannelVectorTextHints()


A collection can be closed given a closure mode. All items matching the mode are added to the collection. NONE can be used just to merge the recently added items so they can be tested.

CloseCollection(object collection,integer mode)


Create an empty scene. This is parented to the root scene, and is truely empty not a default new scene.

Scene object = CreateScene()


Destroy a scene. Effectively the same as closing it. All references to the contents of the scene must have been released.

DestroyScene(object scene)


Support for finding source items for mesh instance items and the instances of mesh items takes the following form: Given an

Item object = GetMeshInstSourceItem(object inst)


The GetReplicatorEnumerator interface allows you to get an enumerator for a replicator item to enumerate the positions & orientations of replicants generated by its particle source.

ReplicatorEnumerator object = GetReplicatorEnumerator(object replicatorItem)

ItemGraphCollection(type, graph, fwd)

It is often useful to collect associated items in a particular graph, and populate an

ItemGraphCollection(object collection,integer type,string graph,integer fwd)


This return the the name of each subtype by index.

string subtype = ItemSubTypeByIndex(integer type,integer index)


This returns the number of subtypes for a given item type.

integer count = ItemSubTypeCount(integer type)


list of sub-types = ItemSubTypeList(type)


This returns each item type by index into the global list.

integer type = ItemTypeByIndex(integer index)


This method returns the number of channels shared by two items. This is the number of channels defined by their common ancestor type, if any. If they do not share any channels, this returns LXe_NOTFOUND;

integer count = ItemTypeCommonChannels(object item1,object item2)


This returns the total number of item types.

integer = ItemTypeCount()

ItemTypeGetTag(tag, super)

Read the value of a tag for an item type, if any. If super is true the supertypes will also be checked.

string value = ItemTypeGetTag(integer type,string tag,integer super)


list of types = ItemTypeList()


Given a type name, this returns the type ID.

integer type = ItemTypeLookup(string name)


This method returns the internal name of a type given it’s type ID.

string name = ItemTypeName(integer type)


It is also possible to look up the super-type code from a type code. This returns LXe_NOTFOUND if the item type has no super-type.

integer super = ItemTypeSuper(integer type)


Returns LXe_TRUE or LXe_FALSE if the item type supports the provided COM interface.

boolean = ItemTypeSupportsInterface(integer type,string guid)


Type codes can be tested for relationship. This returns LXe_TRUE if ‘what’ is the same type as, or a sub-type of, ‘isA.’

boolean = ItemTypeTest(integer what,integer isA)

LoadImage(path, monitor)

Images are loaded with the following method. The path is absolute and the object returned is the new clip item. The function can return LXe_FILE_REMAP if the path needed to be altered to find an image.

Item object = LoadImage(object scene,string path,object monitor)


This method returns the mesh instance using the given mesh item as source by index.

Item object = MeshInstanceByIndex(object mesh,integer index)


This method returns the number of mesh instances using the given mesh item as source.

integer = MeshInstanceCount(object mesh)


The root scene acts as a container for all loaded scenes. It is not visible to the user. Newly added scenes are created as sub-scenes of the root. This method returns the global root scene, and can be used to walk all of the sub-scenes.

Scene object = Root()


Get the script query object for the service.

Unknown object = ScriptQuery()

SubSceneAdd(other, refItems)

This method adds a sub-scene to another scene. The refItems flag can be set to have all items in the sub-cinema referenced in the parent.

SubSceneAdd(object scene,object other,integer refItems)

SubSceneLoad(path, monitor)

This loads a scene as a sub-scene. If the parent scene is null this will be a root scene.

Scene object = SubSceneLoad(object scene,string path,object monitor)


class lxu.service.ScriptSys

Empty scriptsys service Python user class.


ScriptManager object = ByIndex(integer index)


integer count = Count()


string name = Desc(object manager)


Managers can also be looked up by name.

ScriptManager object = Lookup(string name)


string name = NameByIndex(integer index)


To simplify the use of scripts in kits, we support script aliases. This allows a script hash (aka the path to a script on disk) to be aliased to an arbitrary string. Script aliases are defined solely from within configs, usually by the script’s developer. The alias may include path aliases, and may included any ASCII characters, although it is important to note that it is not a translatable string. When used in kits, the simple form can be used when the script is in the kit’s directory: <hash type=”ScriptAlias” key=”aliasedScriptName”>

string path = ResolveAlias(string alias)


Unknown object = ScriptQuery()


Some user interface information about a manager can be read with these functions. User strings are looked up in the message table matching the manager’s name with “{scriptservice} ” prefixed.

string name = UserName(object manager)


UserValue object = UserValueByIndex(integer index)


The list of user values can be walked directly, or a specific user value can be looked up by name. The object returned has an ILxUIserValueDef interface. This includes all config, temporary and momentary user values. These methods are implemented as of nexus 801. User values can only be created with user.defNew, edited with user.def, the value set with user.value. None of these functions or those commands are thread-safe, and care should be taken to not call these from a thread.

integer count = UserValueCount()


UserValue object = UserValueLookup(string name)


class lxu.service.Selection

Empty selection service Python user class.




SelectionType object = Allocate(string name)


pointer = ByIndex(integer type,integer idx)


This is like

Clear(integer type)


integer = Count(integer type)

CurrentSubTypes(sub, len)

This returns the list of current subtypes into the client’s array. If the number of current subtypes is laarger than the length of the buffer then SHORTBUFFER is returned.

integer num = CurrentSubTypes(integer type,unsigned[] sub,integer len)


This returns the most recent selection type

integer = CurrentType(unsigned[] types)


Deselect(integer type,pointer packet)


Drop(integer type)




These methods allow clients to read and set the current time.

float = GetTime()


These methods allow clients to look up name-type associations and to allocate our own instances of the packet interface.

string = LookupName(integer type)


integer = LookupType(string name)


pointer = Recent(integer type)


Remove(integer type,pointer packet)


The selection system is wrapped by a selection service interface for reading and altering the selection state. The

Unknown object = ScriptQuery()


Editing the selection can be done selecting or deselecting, removing packets from all selections, and manipulating the batch state.

Select(integer type,pointer packet)


SetTime(float time)




This is similar to

integer = State(integer type,pointer packet)


boolean = Test(integer type,pointer packet)


Toggle(integer type,pointer packet)


class lxu.service.Shader

Empty shader service Python user class.


Given a collection, add items needed for shading.

CollectMaterials(object collection)

ColorBlendValue(c2, opa, mode)

vector c = ColorBlendValue(vector c1,vector c2,float opa,integer mode)

ComputeFresnel(normalRay, normReflAmt)

This function is essentially an SDK wrapper for SchlickFresnel.

float = ComputeFresnel(vector inRay,vector normalRay,float normReflAmt)


Shader object = MeshShaderAccessor(object meshItem)


This method allows a shader to make a thread-safe request for a random float, distributed from 0.0 to 1.0.

float = NextRandom(object vector)


PoissonOffset returns a 2D offset in the unit disc with a nice poisson distribution.

(float u,float v) = PoissonOffset(object vector)


Shader object = PolyShaderAccessor(object meshItem,id polyID)


These shader service methods allow a custom shader to perform Russian Roulette, to stochastically and unbiasedly terminate rays. It returns the importance multiplier used to compensate for the termination of some rays.

float = RussianRoulette(object vector,float importance)


This returns an

SampleCloud object = SampleCloud(object sample)

ScalarBlendValue(v2, opa, mode)

These functions are used for packet blending (like blending two materials in the shader tree).

float = ScalarBlendValue(float v1,float v2,float opa,integer mode)


This function will convert a sample drawn from asquare 2D sampling distribution in the (-1, -1) to (1, 1) range to a circular distribution.

SquareToCircle(float[] x,float[] y)


class lxu.service.StdDialog

Empty StdDialog service Python user class.


Calling the

AsyncMonitor object = AsyncMonitorAllocate(string system,string title)


In some cases async monitors are not abortable, and should not draw an abort widget in the activity view. This is purely cosmetic, and does not affect the operation of the moonitor, and thus is only available for root-level monitors, which are the ones that determine how the montior is displayed.

Unknown object = AsyncMonitorAllocateWithoutAbort(string system,string title)


This can be used to look up an async monitor by its unique identifier string. As always, the returned object must be released when no longer needed.

Monitor object = AsyncMonitorLookup(string ident)


AsyncMonitorRelease(object monitor)


AsyncMonitor object = AsyncMonitorSubAllocate(object parent,string title)


AsyncMonitorSystem object = AsyncMonitorSystemByIndex(integer index)


These can be used to walk the list of async monitor systems or look them up by name. Objects returned by these methods sport an

integer count = AsyncMonitorSystemCount()


AsyncMonitorSystem object = AsyncMonitorSystemLookup(string name)


This service method will display any of several types of file dialogs to allow the user to browse to a location, file or list of files. The configuration of the dilaog is defined by the client’s dialog object.

FileDialog(object dlgObj)


Clients can request an

Message object = MessageAllocate()

MessageOpen(title, helpURL, cookie)

MessageOpen(object message,string title,string helpURL,string cookie)


Clients can request an

Monitor object = MonitorAllocate(string title)




Clients are supposed to call AllocateMonitor() /

MonitorReleaseObj(object monitor)


Unknown object = ScriptQuery()


class lxu.service.Tableau

Empty tableau service Python user class.


TableauVertex object = AllocVertex()


Unknown object = ScriptQuery()


This utility method will populate a vertex description with all the known features of the tableau surface object. It puts the four required features at the front as normal.

VertexFromFeatures(object surfObj,object vertex)


class lxu.service.TextEncoding

Empty textencoding service Python user class.


TextEncoding object = Allocate()


class lxu.service.Undo

Empty undo service Python user class.


Undo objects are added to the system using these next two methods. The undo object passed in will be queried for it’s

Apply(object undo)


Record(object undo)


The global undo service provides the

Unknown object = ScriptQuery()


The global undo service allows clients to add their actions to the undo state. The state can be queried at any time and may have one of three values.

integer = State()


class lxu.service.Value

Empty value service Python user class.


Given two different value type names, returns an

ValueConversion object = ConvertValues(string from_str,string to_str)


This method creates a new value object of the given type.

Value object = CreateValue(string type)


Check a float for NaN or infinity. A zero return value is OK.

integer = FloatType(float val)


Given a frame and using the global Frames Per Second, returns an equivalent time.

float = FrameToTime(float frame)


Given a frame and a Frames Per Second, returns an equivalent time.

float = FrameToTimeFPS(float frame,float fps)


Returns the global Frames Per Second.

float = GetFPS()


As with all globals, the first method gets the ILxScriptQueryID interface for the system.

Unknown object = ScriptQuery()


This method decodes a string using the hint array. If the string is a number it will be returned directly after being clamped to min or max limits. If nothing is recognized then the function end-of-list will be returned. This will return LXe_NOTFOUND when the string does not exactly match any text hints and cannot be converted into an integer (i.e., it doesn’t start with a number). LXe_OK_NO_CHOICES is returned when the string was sucessfully converted from a number into an integer and may have been constrained to any min/max hints present, but the hints contain no actual choices. This may occur in the case of a hints array that is used only for min/max or similar properties, and is not meant to have a list of choices.

integer value = TextHintDecode(string buf,hints hint)


This encodes a numeric value as a string. If the ‘buf’ pointer is null, then a rolling buffer will be allocated and returned. If the hint pointer is null then the value is written as a plain signed integer. This will return LXe_OK_INEXACT_MATCH when an integer is provided that does not exactly map to one of the choices. This is only returned if there are choices. LXe_OK_NO_CHOICES is returned if there are no choices at all. In both cases, the raw integer is encoded into the string buffer. Both codes are “OK” codes, and do not signify an error, but rather provide hints about the content of the encoded string, and may help instruct an code path if you do need an exact match or were expecting choices.

string = TextHintEncode(integer value,hints hint)


Given a time and using the global Frames Per Second, returns an equivalent frame.

float = TimeToFrame(float time)


Given a time and a Frames Per Second, returns an equivalent frame.

float = TimeToFrameFPS(float time,float fps)


This gets the intrinsic type for a given value type, as one of the LXi_TYPE_* choices.

integer valType = ValueType(string type)


class lxu.service.Variation

Empty Variation Service Python user class.


Items are tested to see if they support specific variations. The test result may vary depending on the state of the item. If an item state changes, the following function can be used to invalidate the cached test results for a specific item, and cause it be retested against all variation servers.

InvalidateItem(object item)


Unknown object = ScriptQuery()


class lxu.service.VertexFeature

Empty vertes service Python user class.


Get a new, empty TableauVertex object.

TableauVertex object = AllocVertex()


string typeName = DataType(string ident)


integer dimension = Dimension(string ident)


This gets the ident string for a vertex feature given the type and (optional) name.

string ident = Lookup(integer type,string name)


string name = Name(string ident)


Unknown object = ScriptQuery()


boolean = TestCategory(string ident,string category)


Given the ident the various attributes of the feature can be read.

integer type = Type(string ident)


string vecType = VectorType(string ident)


class lxu.service.View3Dport

Adds an

AddVirtualModel(object vmodel)


Allocate a GLViewport.

Unknown object = AllocGLViewport()


The viewport service will provide access to a list of 3d and UV viewports referenced by index.

integer = Count()


integer = Current()

GLMaterial(item, view)

This function allocates a GL material object (

Unknown object = GLMaterial(object bin,object item,object view)


Converts an

Unknown object = ImageToGLImage(object image)


integer = InvalidateOverrider(object scene,string pkgName)


(integer,integer x,integer y) = Mouse()


Removes an

RemoveVirtualModel(object vmodel)


As with all globals, the first method gets the ILxScriptQueryID interface for the system.

Unknown object = ScriptQuery()


SetHitUVMap(string name)


Converts a

Unknown object = TriGroupToViewObject(integer type,object triGroup)


Updates drawing for the provided virtual model.

UpdateVirtualModel(object vmodel)


Unknown object = View(integer index)