Extending Omegalib With Custom Modules

Starting form version 5.0, omegalib features a fully modular design. This new design allows users to start with a very lightweight version of omegalib, and customize it with the modules they need. Modules are kept in separate repositories so each revision history is separate, and development by different users is easier. When needed you can create your own modules in C++ or python, save them into a github repository and make them accessible to other omegalib users. Omegalib does the following to perform module search and installation:
  • During the first cmake configuration, a module list file is downloaded from a specific github repository, called the module hub. The predefined module hub is http://github.com/omega-hub/hub, and it can be customized by setting the OMEGA_HUB_URL CMake variable. Changing the hub repository is useful if you want to maintan your own module list.
  • The module list file is simply a CMakeLists.txt file containing a list of available modules, the url of their github repository and a brief description.
  • CMake populates a list with checkable boxes for each module in the list
  • The user clicks on modules that should be installed, or lists their names in the MODULES CMake variable. The variable is particularly useful for command line configurations: for instance, typing cmake [path-to-omega-source] -DMODULES="cyclops sprite omegaVtk" will setup an omegalib build environment with the cyclops, sprite and omegaVtk modules (and all their dependencies)
  • CMake clones the github repositories of all the selected modules. The repositories get cloned in the /modules directory. CMake then runs the CMakeLists.txt file for each module. This file is used to setup the builds of native C++ modules, specify install commands, and lists module dependencies. The module dependencies are used to install additional required modules.
  • The user does a cmake configure (possibly multiple times), until all the modules are downloaded and all the dependencies have been resolved.
  • the build environment is ready

Creating a module

Omegalib modules can be created in C++ or python. This section will document steps common to both module types. Folowing sections will detail how to develop modules in each language.

Setting up a module development environment

The first step in creating a module is choosing a name for it. Make sure the name is unique (not shared with other modules), and as explanatory as possible.
You should create a directory in /modules with your module name. All your module code and data will be in this directory.
Each module directory should contain at least a file: CMakeLists.txt. For very simple modules with no dependencies, this file can be empty. This file can also contain a list of dependencies, modules needed my this module to work. Dependencies are specified using therequest_dependency() command. Note thas this makes it possible to create bundle modules: empty modules that contain only a CMakeLists file enumerating other modules. When users install a bundle module, all modules listed as dependencies will be installed automatically. This makes it practical to create pre-packaged distributions. See the vr-bundle module for an example of this (https://github.com/omega-hub/vr-bundle)

Python Modules

In addition to the CMakeLists file, python modules should contain at least an __init__.py file. This file will be executed when users import the module using an import moduleName pyton statement. For simple modules, all you code can be placed in init.py. For more complex modules with multiple classes or scripts, init.py should in turn import each one of those modules.

example

This is an example of a python module called sphereMaker, containing a single function makeSphere that can be used to, you guessed, create sphere objects. We assume this module depends on the cyclop module. The module directory (which should be/modules/sphereMaker) will contain the following three files:
CMakeLists.txt
# Tell omegalib this module depends on another module (cyclops). Cyclops will
# be automatically installed when this module is enabled.
request_dependency(cyclops)
init.py
# Just import the sphereMakerFunctions file, it will contain our actual function
from sphereMakerFunctions import *
sphereMakerFunctions.py
from cyclops import *
from omega import *
from euclid import *
def makeSphere(x, y, z, color):
 sp = SphereShape.create(1, 2)
 sp.setPosition(x, y, z)
 sp.setEffect("colored -e " + color) 
 return sp
...and that's it!
Now, in an omegalib application script or interactive console you can type the following to create a red sphere:
from sphereMaker import *
makeSphere(0, 2, -2, 'red')

C++ Modules

The following is an example of a CMakeLists.txt file that creates an omegalib C++ module:
request_dependency(cyclops)

# The following line makes sure the cyclops module is installed.
if(TARGET cyclops)
        # Set the module name here
        SET(MODULE_NAME templateModule)

        # Set module name and source files here
        add_library(${MODULE_NAME} MODULE 
                templateModule.cpp)

        # Set the module library dependencies here
        target_link_libraries(${MODULE_NAME}
                omega 
                omegaToolkit 
                cyclops)

        #------------------------------------------------------------------------------
        # DO NOT MODIFY ANYTHING BELOW AFTER THIS LINE
        set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "")
        if(WIN32)
                set_target_properties(${MODULE_NAME} PROPERTIES FOLDER modules SUFFIX ".pyd")
        endif()
endif()

Python Interface Declaration

C++ classes and methods are exposed using a module declaration section in your source file. The module declaration lists all the classes and methods you want to expose, together with some minimal information about how they work. Here is an example of a module declaration:
BOOST_PYTHON_MODULE(templateModule)
{
 // SceneLoader
 PYAPI_REF_BASE_CLASS(HelloModule)
  PYAPI_STATIC_REF_GETTER(HelloModule, createAndInitialize)
  PYAPI_METHOD(HelloModule, setObjectColor)
  ;
}
The module declaration uses a set of macros that internally use Boost::python to interface python and C++. The previous declaration creates a module named templateModule, containing a class HelloModule with a static and nonstatic method.
For a full reference on the Python Interface Declaration see this section
Publishing your module
To make your module accessible to other developers you need to do two things: commit it to a new git repository (we suggest using GitHub to host your repository), and add it to the master module list. The default master module list is hosted in the https://github.com/omega-hub/hub repository (see https://github.com/omega-hub/hub/blob/master/CMakeLists.txt). You should fork this repository and modify its CMakeLists file to add your module. In your installation, you can tell CMake to use your fork of the master module list: 
If you want to share your module with others, send a pull request on the omega-hub repository.

Comments

Popular posts from this blog

Parallel Beam Tracing and Visualization of 200 Million Sonar Points

Parallel Gaussian Elimination Using MPI

Flickering 2D transform elements in Chrome: a simple fix