General¶
How do I write to the log?¶
Writing to the event log viewport can be done by deriving from the CLxLogMessage utility class (or the CLxLuxologyLogMessage class, which just adds a Lux copyright). This is done by objio.cpp to report load warnings and errors. See Writing to the Event Log for more detail.
The spikey tool sample uses a log block to display tool feedback. The current value is formatted into the block and displayed as part of the tool info viewport.
Writing to the debug output on stdout is possible using one of the variants of LogService::DebugOut(), as shown in the Hello World sample. You have to specify a level, and the default level for release builds is ‘error’ I think. Lower-level messages are filtered out. If you want to see all the debug output, start modo with the “-debug:verbose” command line switch.
How do I find the local path represented by an alias?¶
Through the file service. The “ToLocalAlias” function will return the absolute pathspec in local OS specific format. If the alias could not be found the original string will be returned.
You can also pass a string that contains a path alias and additional sub-folder content or filespec content and the alias portion will be resolved in place. If the Alias is not translated the original input string is returned unaltered.
C++
CLxUser_File Service FileService;
char buf[1024];
string localAliasDir, fullLocalPath;
localAliasDir = FileService.ToLocalAlias(buf, "ArtisticGlassMaterials:");
fullLocalPath = FileService.ToLocalAlias(buf, "ArtisticGlassMaterials:scr\test.py");
Python
FileService = lx.service.File()
localAliasDir = FileService.ToLocalAlias("ArtisticGlassMaterials:")
fullLocalPath = FileService.ToLocalAlias("ArtisticGlassMaterials:scr\test.py")
How do I read server tags on a package?¶
Packages are servers, so you can access them through the HostService Interface as a Factory Object. This function returns the value for any server tag given the server class, the name of the server, and the tag key.
C++
const char *
ServerTag (
const char *className,
const char *serverName,
const char *tagKey)
{
CLxUser_HostService hostSrv;
CLxUser_Factory factory;
const char *value;
hostSrv.Lookup (fac, className, serverName);
if (LXx_OK (fac.InfoTag (tagKey, &value))
return value;
return 0;
}
In order to use this function to read server tag for item types (packages), you just need to find the package name from the item type.
C++
bool
IsMask (
CLxUser_Item &item)
{
CLxUser_SceneService scnSrv;
const char *pkgName;
scnSrv.ItemTypeName (item.Type (), &pkgName);
return (ServerTag (LXa_PACKAGE, pkgName, LXsPKG_IS_MASK) != 0);
}
When is it safe to make changes to the scene from inside a listener?¶
Listeners allow you to respond to events within Modo, such as selection changes, channel edits, time changes, etc…
However, making changes to the scene in response to those events can cause potential issues depending on the current undo state (e.g. the event might be part of the user undoing something and generally you don’t want to make changes to the scene in response to that).
To find out the undo state, you can query it from the Undo Service and take appropriate steps depending on the result.
C++
CLxUser_UndoService undo_svc;
unsigned int undoState = undo_svc.State();
// undoState will be one of:
// LXiUNDO_INVALID
// LXiUNDO_ACTIVE
// LXiUNDO_SUSPEND
Python
undoState = lx.service.Undo().State()
# undoState will be one of:
# lx.symbol.iUNDO_INVALID
# lx.symbol.iUNDO_ACTIVE
# lx.symbol.iUNDO_SUSPEND
*INVALID - The undo state is invalid. It is not safe to make changes to the scene. *ACTIVE - The undo system is recording undo steps for the changes being made. It is safe to make changes to the scene and they will be undoable. *SUSPEND - The undo system is not recording undo steps for the changes being made. Generally this happens during events like scene loading. It is safe to make changes to the scene, however they will not be undoable.
Why are my Kit’s Python files ignored when running under linux?¶
Linux is case sensitive. Ensure the names and extensions of the config files in your kit are lowercase.
How can I access image layers?¶
C++
CLxUser_ChannelRead read;
read.from (item, 0.0);
// Read object from channel and cast it to a ImageFilter inteface
CLxUser_ImageFilter filter;
read.Object (item, LXsICHAN_VIDEOCLIP_IMAGESTACK, filter);
CLxUser_ImageFilterMetrics myMetrics;
read.Object (item, LXsICHAN_VIDEOCLIP_IMAGESTACK, myMetrics);
// This will fill the metrics structure so that we can read the image dimensions from it
LXtImageMetrics metrics;
CLxUser_ImageFilterMetrics myMetrics (filter);
myMetrics.Generate (&metrics);
// This returns the image from the filter
CLxUser_Image image;
filter.Generate (metrics.maxRes[0], metrics.maxRes[1], 0, image);
// Read an RGBA pixel
LXtPixelFormat format = image.Format();
if (format == LXiIMV_RGBA)
{
unsigned char pixel[4];
LxResult result = image.GetPixel (0, 0, format, pixel);
}
Python
if item.type == lx.symbol.sITYPE_IMAGELAYER:
imgFilter = lx.object.ImageFilter( item.channel('imageStack').get() )
image = imgFilter.Generate(64,64, None)
if image.Format() == lx.symbol.iIMV_RGBA:
storage = lx.object.storage('b', 4)
image.GetPixel( 0,0, lx.symbol.iIMV_RGBA, storage)
print 'RGBA values: ', [storage[i] for i in xrange(4)]