Close

Relief for ODA Team in Ukraine

Learn more
ODA IFC SDK
Export IFC Model Geometry to the OBJ Format

Geometry data from an IFC file can be exported to OBJ format.

OBJ is an open format for storing geometry data in a simple textual data format that describes 3D geometry:

  • Vertices and their coordinates
  • Normal vectors
  • Triangles and polygons that are represented with three or more vertices
  • Textures

Data about materials is stored in supplementary MTL (Material Library) files. OBJ files can refer to an MTL file by using a special directive (mtllib) followed by the full name of the MTL file.

Export Prerequisites

To export an IFC model geometry representation to an OBJ format file, within your IFC SDK-based applications, load the OBJToolkit.tx module. Source code for this module is available in the Components/OBJToolkit folder.

Check that the following prerequisites are met before exporting IFC content to the OBJ format:

  1. Include the necessary header files and declare initialization/de-initialization functions in your application source code:
              
    #include "OdaCommon.h"
    #include "OdString.h"
    #include "IfcExamplesCommon.h"
    #include "ExPrintConsole.h"
    #include "OBJToolkit.h"
              
            
  2. For static configurations, use the set of DECLARE/DEFINE_STATIC macro instances:
              
    #if !defined(_TOOLKIT_IN_DLL_)
      ODRX_DECLARE_STATIC_MODULE_ENTRY_POINT(OdSDAIModule);
      ODRX_DECLARE_STATIC_MODULE_ENTRY_POINT(OdIfcCoreModule);
      ODRX_DECLARE_STATIC_MODULE_ENTRY_POINT(OdIfc2x3Module);
      ODRX_DECLARE_STATIC_MODULE_ENTRY_POINT(OdIfc4Module);
      ODRX_DECLARE_STATIC_MODULE_ENTRY_POINT(OdIfcGeomModuleImpl);
      ODRX_DECLARE_STATIC_MODULE_ENTRY_POINT(OdIfcBrepBuilderModule);
      ODRX_DECLARE_STATIC_MODULE_ENTRY_POINT(OdIfcFacetModelerModule);
      ODRX_DECLARE_STATIC_MODULE_ENTRY_POINT(OdRxThreadPoolService);
      ODRX_DECLARE_STATIC_MODULE_ENTRY_POINT(OdDbRootModuleObject);
      ODRX_DECLARE_STATIC_MODULE_ENTRY_POINT(OdGsModuleObject);
      ODRX_DECLARE_STATIC_MODULE_ENTRY_POINT(OdGiModuleObject);
      ODRX_DECLARE_STATIC_MODULE_ENTRY_POINT(OdObjToolkitModuleImpl);
      ODRX_BEGIN_STATIC_MODULE_MAP()
        ODRX_DEFINE_STATIC_APPMODULE(OdSDAIModuleName, OdSDAIModule)
        ODRX_DEFINE_STATIC_APPMODULE(OdIfcCoreModuleName, OdIfcCoreModule)
        ODRX_DEFINE_STATIC_APPMODULE(OdIfc2x3ModuleName, OdIfc2x3Module)
        ODRX_DEFINE_STATIC_APPMODULE(OdIfc4ModuleName, OdIfc4Module)
        ODRX_DEFINE_STATIC_APPMODULE(OdIfcGeomModuleName, OdIfcGeomModuleImpl)
        ODRX_DEFINE_STATIC_APPMODULE(OdIfcBrepBuilderModuleName, OdIfcBrepBuilderModule)
        ODRX_DEFINE_STATIC_APPMODULE(OdIfcFacetModelerModuleName, OdIfcFacetModelerModule)
        ODRX_DEFINE_STATIC_APPMODULE(OdThreadPoolModuleName, OdRxThreadPoolService)
        ODRX_DEFINE_STATIC_APPMODULE(OdDbRootModuleName, OdDbRootModuleObject)
        ODRX_DEFINE_STATIC_APPMODULE(OdGsModuleName, OdGsModuleObject)
        ODRX_DEFINE_STATIC_APPMODULE(OdGiModuleName, OdGiModuleObject)
        ODRX_DEFINE_STATIC_APPMODULE(OdObjToolkitModuleName, OdObjToolkitModuleImpl)
      ODRX_END_STATIC_MODULE_MAP()
    #endif
              
            
  3. It is assumed that the following classes are declared and defined:
    • OdExIfcHostAppServices class implements platform-dependent operations and progress metering for IFC SDK-based applications. See the declaration and definition of this class in the ExIfcHostAppServices.h and ExIfcHostAppServices.cpp files located in the Ifc/Extensions/ExServices subfolder of the IFC SDK installation folder. This class is inherited from the OdIfcHostAppServices class.
                    
      class OdExIfcHostAppServices : public OdIfcHostAppServices
      {
      public:
        OdExIfcHostAppServices();
      };
                    
                  
    • MyServices custom class combines platform-dependent functionality of the OdRxSystemServices and OdDbBaseHostAppServices classes. This class is inherited from the ExSystemServices and OdExIfcHostAppServices classes.
                    
      class MyServices : public ExSystemServices, public OdExIfcHostAppServices
      {
      ...
      }
                    
                  
  4. There are two variables that store the necessary information for the export process:
    • ifcInFileName — Contains the full path to the input IFC file.
    • objOutFileName — Contains the full path to the output OBJ file.
              
    OdString ifcInFileName;
    OdString objOutFileName;      
              
            

Import Properties

Property Name Description
IFC File An input IFC file to be exported. Represented with a smart pointer to an IFC database.
OBJ File An output OBJ file to store IFC geometry in.
OBJ Export Options A list of options that determines how the IFC geometry should be exported to OBJ format. Options are stored and handled with the OdObjExportOptions structure defined in the Components/OBJToolkit/Include/OBJToolkit.h header file.

The OdObjExportOptions structure consists of the following attributes:

  • Application Comment — Text that is added to the OBJ header. The text can contain any information (application name, author, date and time of last modification, etc.).
    To get access to the application comment, use the m_applicationComment field of the structure instance.
  • Save Textures with OBJ File Flag — A flag that determines whether texture data is saved in the same folder where the output OBJ file is located. When the flag value equals true, texture files are saved in the OBJ file's folder. When the flag value equals false, paths to texture files are stored in compliant MTL file. By default, this option is equal to true.
    To get access to the flag value, use the m_keepTexturesNearObj field of the structure instance.
  • View Index — An index of a view that should be exported to the output OBJ file.
    To get access to the view index, use the m_nView field of the structure instance.
  • OBJ Database — A smart pointer to a database object that contains OBJ data in memory. OBJ data is appended to an OBJ database if the OBJ database flag value equals true.
    To get access to the OBJ database smart pointer, use the m_pObjDb field of the structure instance.
    If the smart pointer is NULL, the OBJ database object is created.
    The OdObjDb class that represents an OBJ database is declared in the Components/OBJToolkit/Include/OBJToolkit.h header file.
  • OBJ Database Flag — A flag that determines whether an OBJ database should be filled with the data stored in the output OBJ file. If the flag value equals true, the OBJ database is filled with the exported data; otherwise (when the flag equals false) data is written directly in the output OBJ file.
    To get access to the OBJ database flag value, use the m_bFillDb field of the structure instance.

Export Routine

To use the export functionality in your IFC SDK-based application:

  1. Create an instance of a previously declared custom services class:
              
    OdStaticRxObject <MyServices> ifcSvcs;
              
            
  2. If you use the static configuration, initialize the module map:
              
    #if !defined(_TOOLKIT_IN_DLL_) 
      ODRX_INIT_STATIC_MODULE_MAP();
    #endif
              
            
  3. Initialize ODA Platform and IFC SDK:
              
    odrxInitialize(&ifcSvcs);
    odIfcInitialize(false, true);
              
            
  4. Add a try ... catch() section for handling errors:
              
    try
    {
    …
    }
    catch (OdError& e)
    {
      odPrintConsoleString(L"\n\nIfc2Obj: Error: %ls", e.description().c_str());
      nRes = 1;
    }
    catch (...)
    {
      odPrintConsoleString(L"\n\nIfc2Obj: Unexpected error.");
      nRes = 1;
    }
              
            
    All of the following code fragments are added to the try{} section.
  5. Load the OBJToolkit module and create a converter object:
              
    OBJToolkit::OdObjToolkitModulePtr pObjModule = 
    odrxDynamicLinker()->loadApp(OdObjToolkitModuleName);
    if (pObjModule.isNull())
    {
       odPrintConsoleString(L"\n\nIfc2Obj: loading OBJToolkit module is failed.\n");
       nRes = 1;
       return nRes;
    }
    odPrintConsoleString(L"\n\nIfc2Obj: OBJToolkit module is successfully loaded.\n");
              
            
  6. Read the input IFC file:
              
    OdIfcFilePtr pIfcFile = ifcSvcs.readFile(ifcInFileName);
    if (pIfcFile.isNull())
    {
       odPrintConsoleString(L"\n\nIfc2Obj: reading file %s is failed.\n", ifcInFileName.c_str());
       nRes = 1;
       return nRes;
    }
              
            
  7. Get a representation context that contains the geometric information to be converted to the output OBJ file:
              
    {
       OdDAIObjectIds contextsSelection =     OdIfc::Utils::getDefaultRepresentationContextsSelection(pIfcFile, false);
       if (contextsSelection.isEmpty())
       {
          contextsSelection = OdIfc::Utils::getAllRepresentationContexts(pIfcFile);
       }
       pIfcFile->setContextSelection(contextsSelection);
    	  
       odPrintConsoleString(L"\nIfc2Obj: composing entities.\n");
       pIfcFile->composeEntities();
    }
              
            
  8. Initialize a pointer to the IFC database and define export parameters:
              
    OdDbBaseDatabase* pDatabase = static_cast <OdDbBaseDatabase*>(pIfcFile);
    OBJToolkit::OdObjExportOptions options;
    options.m_applicationComment = ifcSvcs.product() + L" example ExIfc2Obj version " + ifcSvcs.versionString();
    odPrintConsoleString(L"\nIfc2Obj: exporting .obj file %s",objOutFileName.c_str());
              
            
  9. Run the export process:
              
    OdResult res = pObjModule->exportObj(pDatabase, objOutFileName, &options);
              
            
  10. Unload the OBJ Toolkit module and de-initialize IFC SDK and ODA Platform:
              
    pObjModule.release();
    odrxDynamicLinker()->unloadModule(OdObjToolkitModuleName);
    
    odIfcUninitialize();
    odrxInitialize();
              
            
    De-initialization calls must be done in reverse order compared with initialization calls and should be placed outside the try{} ... catch() section.

Result of IFC-to-OBJ Export

The illustrations below show an original IFC file and the resulting OBJ file that was created while using the OdVisualizeViewer sample application to export from IFC to OBJ.

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