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:
The actual import/export class. This class is responsible for reading and writing the format in question.
Model class, for defining import and/or export options. This class is optional and needs to be defined only if the format supports import and/or export options.
User interface class for the File/Save As window. Needed only if the class supports export options.
User interface class for the File/Load window. Allows the user to specify import options.
Some file formats don't need import or export options, in which case only the first class needs to be implemented.
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:
R3IEM_BEGINREAD
R3IEM_READOBJECTS
R3IEM_ENDREAD
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, ¢er, R3SPHA_Radius, &rad, R3RA_Name, name, ...., R3TAG_END); /* and insert it into the current project */ R3DoA(self->prim_layer, R3PLAYM_RAWINSERT, prim); break;
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, ¢er, ..., 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.
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:
one model class defines necessary file format specific import and export options. To be very pedantic, two new models could actually be implemented: one for export options and one for import options. But the same model class can define the both options. This class must be derived from the 'inc/real/code/r3fifomo.h' base class.
user interface class for import options (File/Load window).
user interface class for export options (File/Save window)
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:
p1 - (R3CLID) specifies the actual format class
p2 - (R3CLID) specifies the class defining file format specific options (model)
p3 - (R3CLID) specifies the user inteface (view) class which is shown in the 'File/Save As' window when the file format in question is selected.
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:
File/Load window creates R3CLID_MYMODEL object.
File/Load window creates R3CLID_MYGADGET object and shows it to the user. The created model object is set to the gadget using R3WGA_Model attribute, as usual.
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:
R3CLID_MYGADGET is instanced and shown in the File/Open window.
R3CLID_MYMODEL is instanced and passed as a model to the gadget.
The actual file format class (R3CLID_MYFORMAT) is called with R3IEM_READOPTIONS method and the model is passed to it so that the the file format object can read data from the opened file and initialize the model object attributes accordingly. For example, if the file is compressed, the format object sets the corresponding compressed model option, and the user sees the Compressed check box checked in the File/Load window.
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.
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.