Command Execution Environment
neuray Services provides a number of features to facilitate the execution of commands beyond simply providing access to the Neuray API. This includes scope, transaction and scene management, type conversion facilities and a virtual file system for scene data. Access to all these is via the command context passed into every command on execution. Other API implementations will have access to a reduced set of these facilities, depending on their requirements.
The Neuray API
Commands have complete access to the Neuray API via the mi::neuraylib::IPlugin_api interface. The only restriction is that commands will only ever be executed while neuray is running and so cannot access any functionality that is only available before startup. Whilst access to the complete API is available it is highly recommend that you use the neuray Services abstractions or conventions that wrap or replace native functionality whenever offered. This will allow for greater interoperability between commands.
Scopes
neuray Services makes exclusive use of the named scope feature of the Neuray Library. Wherever the API needs a scope it will use the name of a scope rather then a scope id. Therefore when creating scopes you should ensure that you use mi::neuraylib::IDatabase::create_or_get_named_scope() . Note that scope names must be unique within the database, not just within a hierarchy. If you have a scope "B" that is a child of scope "A" and you try to create another scope "B" as a child of "AA" then create_or_get_named_scope() will return the first scope "B" and not create a new one.
Use the empty scope name, "", to specify the global scope.
The Execution Transaction
To perform any operation on the neuray database a transaction is required. Given that this is such a common operation neuray Services provides the concept of an execution transaction. The scope that this transaction is created in is controlled by the calling application. This frees you from having to work out which scope a transaction should be created in (and having to provide the scope details via an argument) and allows for a single transaction to be used across multiple commands.
The execution transaction can be obtained with mi::nservices::ICommand_context::get_transaction. The command should typically not commit or abort this transaction unless absolutely necessary. If it is necessary then mi::nservices::ICommand_context::create_new_transaction should be used. A command may also change the scope of the current transaction by using mi::nservices::ICommand_context::change_scope which will create a new transaction at the supplied scope. All remaining commands in the current service request (or sub commands executed by this command) will use this new transaction.
Scene Abstraction
- access to an enhanced render context.
- removal of the scene and all it's contents.
- automatic scene expiry and removal from the database after a period of inactivity.
- an associated attribute container to store custom information along side the scene.
- named render contexts that persist between command calls and expire after a period of inactivity.
- retrieval of information about what the context is rendering.
- access to the results of the last render performed.
- storage of arbitrary canvases within the context which persist between command calls.
Path Mapping
Many commands have need to access the file system. For example to load scenes off disk or specify the name of texture files. The paths to these files typically come in as command arguments however it cannot be expected (nor is it desirable) for the user to know the absolute paths to these files. neuray Services provides a path mapper which can be used to map any incoming relative paths to absolute ones. Typically, the parent application will configure a 'content root' directory and it is expected that all scene resources will be stored under that directory. It will then provide an mi::nservices::IPath_remapper path mapper as a global attachment to the command called "path_remapper". Commands may then take any incoming path argument and pass it through the mapper. This will return an absolute path within the content root directory which can be passed to importers, textures etc. The mapper provides a 'chrooted' environment, if the incoming path maps outside the content root then NULL is returned. For example:
mi::base::Handle<mi::IString> path(context->get_argument<mi::IString>("path"); mi::base::Handle<mi::IMap> attachments(context->get_attachments()); mi::base::Handle<mi::nservices::IPath_remapper> mapper(attachments->get_value<mi::nservices::IPath_remapper>("path_remapper")); mi::base::Handle<mi::IString> abs_path(mapper->get_absolute_path(path->get_c_str()); if (abs_path.is_valid_interface()) { // import file }
User State
In addition to the execution transaction neuray Services provides a user state transaction. The scope for this transaction is provided by the calling application and is expected to be a scope that is specific to the end user calling the commands. This scope is used to persist arbitrary information related to the user and their session. In general commands will not require access to this transaction unless they are commands specifically designed to manipulate session related data. You should not assume that a user state has been provided nor that any specific data exists within it.