Chapter 4. Implementing Object Formats

This document explains how to implement new object formats, such as Iges, VRML, DXF and Wawefront OBJ, to name a few.

In order to add a new object format to Realsoft 3D, one has to implement the following classes:

Some file formats don't need import or export options, in which case only the first class needs to be implemented.

Importing

When the user specifies a file name and clicks Load, the program scans through the registered file format classes and attemps to instance them by calling their R3RM_CREATE method. The parameter R3IEMODE_READ indicates that the object should be created for reading.

If the class in question doesn't recognize the format in the given file, R3RM_CREATE returns NULL and the system will try to instance the next registered format.

If the class do reconize the format, R3RM_CREATE will succeed and the created object will be called with the following methods:

The method R3IEM_READOBJECTS is the actual work horse. This method scans through the file and creates corresponding Realsoft 3D objects into the current project. The R3IEM_READ method may look something like below:


    while(read_entity_from_file(&entityid, ...)) {
        switch(entityid) {
            case entity_sphere:
                /* create Realsoft 3D object */
                sphere = R3New(R3CLID_SPHERE,
                               R3SPHA_Center, &center,
                               R3SPHA_Radius, &rad,
                               R3RA_Name, name,
                               ....,
                               R3TAG_END);
                /* and insert it into the current project */
                R3DoA(self->prim_layer, R3PLAYM_RAWINSERT, prim);
                break;

Exporting

When the user saves the current project, the filer object instances the selected file format class (specified in 'File Format' field of 'File/Save As' window).

The filer then calls the R3IEM_BEGINWRITE method from which the file format object can save, for example, header data to the file. Then the system calls the following methods with the objects to be exported:


    R3IEM_BEGINWRITE
    R3IEM_WRITEOBJECTS
    R3IEM_WRITEOBJECTSBEGINLEVEL
    R3IEM_WRITEOBJECTSENDLEVEL
    R3IEM_ENDWRITE

The R3IEM_WRITEOBJECTS exports the given object. The method may look something like below:


    /* fetch attributes common to all geometric objects */
    R3GetAttrs(prim,
               R3RA_ClassID, clid,
               ...,
               R3TAG_END);

    /* see if we recognize the object to be exported */
    switch (clid) {
        case R3CLID_SPHERE:
            /* yes, fetch sphere specific attributes */
            R3GetAttrs(prim,
                       R3SPHA_Center, &center,
                        ...,
                       R3TAG_END);
            /* and write them into the opened file */
            ...
            break;

The two methods R3IEM_WRITEOBJECTSBEGINLEVEL and R3IEM_WRITEOBJECTSENDLEVEL are called once for each level object to describe the hierarchical structure of Realsoft 3D scene. You need to catch these if the export format supports hierarchy.

Once all the objects are exported, the R3IEM_ENDWRITE metod is called. Here you can, for example, free all the data allocated in BEGINWRITE method, write some final information to the file (total size perhaps) etc.

Implementing Import/Export Options

Some Object File Formats may provide the user with set of export options, such as 'quality' or 'compression on/off'. You may also want to show the user what's in the selected file. In this case one has to implement two or three new classes:

The user interface classes must be derived from the 'inc/real/windows/r3fifoga.h' base class.

To plug-in export options for 'File/Save As' window. call:


    #include <real/code/r3fsave.h>

    R3SendClassMsgA3(R3CLID_FILESAVE, R3CSAVE_REGISTERGADGET, (void *)R3CLID_MYFORMAT, (void *)R3CLID_MYMODEL, (void *)R3CLID_MYGADGET);

where:

The model and user interface communicate with each other via standard model-view concept, as usual. The actual file format class gets the model object in R3IEA_Model attribute.

When the user opens the File/Load window and selects 'My Format', the following steps are accomplished:

The user can then specify desired export options and when the user clicks 'Save', the actual file format class (R3CLID_MYFORMAT) is instanced and the model is passed to it.

To plug-in read options for a file format, call:


    #include <real/code/r3fload.h>
    R3DoClassA3(R3CLID_FILELOAD, R3FLOADCM_REGISTEROPTION, R3CLID_MYFORMAT, R3CLID_MYMODEL, R3CLID_MYGADGET);

When the user selects R3CLID_MYFORMAT file using the File/Open window, the following operations are executed:

To plug-in new file format class into Realsoft 3D, call:


    #include <real/code/r3filer.h>

    R3DoClassA3(R3CLID_FILER, R3FIRCM_REGISTERSAVER, "My Format", NULL, (void*)R3CLID_MYFORMAT);
    R3DoClassA3(R3CLID_FILER, R3FIRCM_REGISTERLOADER, "My Format", NULL, (void*)R3CLID_MYFORMAT);
where:

    p1 - (char *) name of the file format 
    p2 - unused 
    p3 - (R3CLID) class identifier of your file format class. 

Note: a file format class may only implement read methods or write methods, in which case you should only call one of the above registration methods. However, it is strongly suggested that you implement both read and write methods.

Examples

The folder samples/plugins/objectformat contains several import export examples. The minimalio.c demonstrates a minimal object format class. It doesn't implement any import nor export options so only one class is needed.