Close

Relief for ODA Team in Ukraine

Learn more
ODA Drawings SDK
Creating Extension Modules

You can create dynamically loaded extension modules and custom objects.

Creating an extension module

To create an extension module, the user should create a subclass of the OdRxModule class, as in the following example:


class CustomObjectsModule : public OdRxModule
{
 protected:
   void initApp()
   {
     // register the custom object types defined in this module
     ExCustObject::rxInit();
     ExCustEntity::rxInit();
     ExSphere::rxInit();

     // custom commands can be registered here
   }

   void uninitApp()
   {
     // unregister the custom object types defined in this module
     ExSphere::rxUninit();
     ExCustEntity::rxUninit();
     ExCustObject::rxUninit();

     // remove custom commands here
   }
};

// In case of static module use the following macro that defines the entry point for this library
ODRX_DEFINE_DYNAMIC_MODULE(CustomObjectsModule);

A custom module should contain exactly one subclass of OdRxModule, but can define any number of custom objects.

Naming conventions for extension modules

The shared library containing the subclass of OdRxModule should be named < application name >.tx (or .txv for a vectorization module), where < application name > is the same application name that is used to define the custom object classes in this module. File names of modules that are delivered with an ODA Platform release also contain a suffix indicating the release version. For example: AsdkSmileyDb_3.09_8.tx. You can omit the suffix and ".tx" in the module file name while loading; they are substituted automatically if absent:


OdRxModulePtr pModule = ::odrxDynamicLinker()->loadModule(L"AsdkSmileDb");

This is recommended usage to avoid editing code while moving to the next ODA Platform version or upgrading the compiler.

Automatic loading of extension modules

When the application loads a file containing custom objects or entities, it calls OdRxDynamicLinker::loadApp() to load the application associated with the custom object class. By default, it looks for this module in the same directory as the ODA shared libraries.

Static use of extension modules

Support for an extension module can be linked statically into an application if desired. This can be done for the CustomObjectsModule example defined above, by including the following macros in the program that will be using the custom module:


#ifndef _TOOLKIT_IN_DLL_

// Declare the entry point function for the custom module (one for each module).
ODRX_DECLARE_STATIC_MODULE_ENTRY_POINT(CustomObjectsModule);
ODRX_DECLARE_STATIC_MODULE_ENTRY_POINT(ModelerModule);

ODRX_BEGIN_STATIC_MODULE_MAP()
  ODRX_DEFINE_STATIC_APPLICATION("ExCustObjs",       CustomObjectsModule)
  ODRX_DEFINE_STATIC_APPLICATION("ModelerGeometry",  ModelerModule)
ODRX_END_STATIC_MODULE_MAP()

#endif

After the static module map has been declared, the host application should use the ODRX_INIT_STATIC_MODULE_MAP macro once to initialize the static module map. This should be done before the odInitialize() function, for example:


#ifndef _TOOLKIT_IN_DLL_
    ODRX_INIT_STATIC_MODULE_MAP();
#endif
    odInitialize(this);

Once these calls have been made, the registered custom module will be loaded on demand (for example, when this module is needed to serialize a custom object), or it can be loaded explicitly by calling OdRxDynamicLinker::loadModule() and passing the application name that was registered in the first argument to the ODRX_DEFINE_STATIC_APPLICATION macro.

Creating custom objects

Custom objects are created by subclassing an existing class, for example OdDbEntity or OdDbObject. As an example, consider the following minimal custom object declaration:


class EXCUSTOBJEXPORT ExCustObject : public OdDbObject
{
 public:
   // Declare default functions necessary for all database objects.
   ODDB_DECLARE_MEMBERS(ExCustObject);

   ExCustObject();
   virtual ~ExCustObject();

   // Required overrides
   OdResult dwgInFields(OdDbDwgFiler* pFiler);
   void dwgOutFields(OdDbDwgFiler* pFiler) const;
   OdResult dxfInFields(OdDbDxfFiler* pFiler);
   void dxfOutFields(OdDbDxfFiler* pFiler) const;
};

Note that dwgInFields, dwgOutFields, dxfInFields, and dxfOutFields must be overridden in a custom object in order to provide support for .dwg and .dxf files. Other data members and functions can be added to this class as desired.

The implementation for a custom class must call the ODRX_DXF_DEFINE_MEMBERS macro, which creates implementations for the functions declared by the ODDB_DECLARE_MEMBERS macro used in the class declaration:


ODRX_DXF_DEFINE_MEMBERS(ExCustObject,                                        // class name
                        OdDbObject,                                          // parent class name
                        DBOBJECT_CONSTR,                                     // creation macro
                        OdDb::vAC15,                                         // dwg version
                        OdDb::kMRelease0,                                    // maintenance release version
                        0,                                                   // proxy flags
                        EXCUSTOBJECT,                                        // DXF name
                        ExCustObjs|Description: Run-time Extension Example)  // Application name

Note that the application name here, ExCustObjs, must agree with the name of the shared library that contains the implementation for this object (ExCustObjs.tx in this example).

Creating a custom graphical entity

Creating a custom graphical entity is similar to creating a non-graphical database object, except for the following:

  • OdDbEntity (or a subclass of OdDbEntity) should be used as the parent class for the custom entity.
  • In addition to the dwg/dxf I/O functions that need to be overridden, a custom entity class should override OdDbEntity::subWorldDraw() as well (and optionally OdDbEntity::subViewportDraw()).

See the ExCustObjs sample application for a complete example of a custom database object and a custom entity that can render itself within the rendering framework.

Proxy graphics

Drawings SDK API can optionally save proxy graphics to a file for custom entities, depending on the value of the PROXYGRAPHIS system variable (0 == do not save, 1 == save). The OdDbDatabase::setPROXYGRAPHICS function can be used to control this setting.

Copyright © 2002 – 2022. Open Design Alliance. All rights reserved.