/////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2002-2025, Open Design Alliance (the "Alliance"). // All rights reserved. // // This software and its documentation and related materials are owned by // the Alliance. The software may only be incorporated into application // programs owned by members of the Alliance, subject to a signed // Membership Agreement and Supplemental Software License Agreement with the // Alliance. The structure and organization of this software are the valuable // trade secrets of the Alliance and its suppliers. The software is also // protected by copyright law and international treaty provisions. Application // programs incorporating this software must include the following statement // with their copyright notices: // // This application incorporates Open Design Alliance software pursuant to a license // agreement with Open Design Alliance. // Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance. // All rights reserved. // // By use of this software, its documentation or related materials, you // acknowledge and accept the above terms. /////////////////////////////////////////////////////////////////////////////// #include "OdaCommon.h" #include "AECAppStaticModules.h" #include "AECCAppStaticModules.h" #include "OdString.h" #include "RxVariantValue.h" #include "ExSystemServices.h" #include "ExHostAppServices.h" #include "IfcExamplesCommon.h" #include "IfcCore.h" #include "StaticRxObject.h" #include "RxDynamicModule.h" #include "OdPerfTimer.h" #include "ExPrintConsole.h" #include "diagnostics.h" #include "DbDatabase.h" #include "DbEntity.h" #include "DbDimAssoc.h" #include "OdCharMapper.h" #include "RxObjectImpl.h" #include "ExProtocolExtension.h" #include "TCExProtocolExtension.h" #include "OdFileBuf.h" #include "FdField.h" #include "TCStringUtils.h" #include "DbDumper.h" #ifdef OD_HAVE_CONSOLE_H_FILE #include #endif /************************************************************************/ /* Compile password support for R18 Drawings */ /************************************************************************/ #include "Common/ModuleNames.h" #include "../Exchange/Exports/Civil2Ifc/Include/Civil2IfcExport.h" using namespace CIVIL_IFC_EXPORT; /************************************************************************/ /* Define a module map for statically linked modules: */ /************************************************************************/ #ifndef _TOOLKIT_IN_DLL_ ODRX_DECLARE_ARCH_STATIC_MODULES_ENTRY_POINTS() ODRX_DECLARE_ARCH_UI_STATIC_MODULES_ENTRY_POINTS() ODRX_DECLARE_RENDERING_STATIC_MODULES_ENTRY_POINTS() ODRX_DECLARE_CIVIL2IFC_STATIC_MODULES_ENTRY_POINTS() // Or ODRX_DECLARE_CIVIL2IFC_STATIC_MODULES_SOLIDMODELER_ENTRY_POINTS() // for ODA SolidModeler ODRX_DECLARE_STATIC_MODULE_ENTRY_POINT(OdRecomputeDimBlockModule); ODRX_DECLARE_CIVIL_STATIC_MODULES_ENTRY_POINTS() ODRX_DECLARE_CIVIL_UI_STATIC_MODULES_ENTRY_POINTS() ODRX_DECLARE_STATIC_MODULE_ENTRY_POINT(OdRxThreadPoolService); ODRX_DECLARE_STATIC_MODULE_ENTRY_POINT(DbCryptModule); ODRX_BEGIN_STATIC_MODULE_MAP() ODRX_DEFINE_ARCH_STATIC_APPMODULES() ODRX_DEFINE_ARCH_UI_STATIC_APPMODULES() ODRX_DEFINE_RENDERING_STATIC_APPMODULES() ODRX_DEFINE_CIVIL_STATIC_APPMODULES() ODRX_DEFINE_CIVIL_UI_STATIC_APPMODULES() ODRX_DEFINE_STATIC_APPMODULE(OdThreadPoolModuleName, OdRxThreadPoolService) ODRX_DEFINE_STATIC_APPMODULE(DbCryptModuleName, DbCryptModule) ODRX_DEFINE_CIVIL2IFC_STATIC_APPMODULES() // Or ODRX_DEFINE_CIVIL2IFC_STATIC_SOLIDMODELER_APPMODULES() // for ODA SolidModeler ODRX_DEFINE_STATIC_APPMODULE(OdRecomputeDimBlockModuleName, OdRecomputeDimBlockModule) ODRX_END_STATIC_MODULE_MAP() #endif class CivilServices : public ExSystemServices, public ExHostAppServices { protected: ODRX_USING_HEAP_OPERATORS(ExSystemServices); private: #ifdef _MSC_VER bool getPassword(const OdString& civilName, OdPassword& password) { odPrintConsoleString(OD_T("Enter password to open drawing: %ls\n"), civilName.c_str()); wchar_t pwdBuff[_MAX_PATH] = { 0 }; STD(wcin).get(pwdBuff, L'\n').get(); ::CharUpperW(pwdBuff); password = pwdBuff; return !password.isEmpty(); } #endif }; static bool MyCheckAssertGroup(const char* pGroup) { return !pGroup || !*pGroup; // asserts of base group are enabled only (default) //return true; // asserts of all groups are enabled } static int Civil2IfcConvert(CivilServices& svcs, OdCivilExportPtr Exporter, const OdStringArray& civilInFileNames) { int nRes = 0; for (auto& civilInFileName : civilInFileNames) { OdDbDatabasePtr pDb = svcs.readFile(civilInFileName); Exporter->properties()->putAt(L"Database", pDb); OdCivilExport::ExportResult res = Exporter->doExport(); if (res == OdCivilExport::ExportResult::success) { odPrintConsoleString(OD_T("\nExCivil2Ifc: %ls successful conversion"), civilInFileName.c_str()); } else { switch (res) { case OdCivilExport::ExportResult::bad_database: nRes++; odPrintConsoleString(OD_T("\nExCivil2Ifc: bad database for file: %ls\n"), civilInFileName.c_str()); break; case OdCivilExport::ExportResult::bad_file: nRes++; odPrintConsoleString(OD_T("\nExCivil2Ifc: bad ifc file for file: %ls\n"), civilInFileName.c_str()); break; case OdCivilExport::ExportResult::fail: nRes++; odPrintConsoleString(OD_T("\nExCivil2Ifc: unknown conversion error for file: %ls\n"), civilInFileName.c_str()); break; case OdCivilExport::ExportResult::bad_password: nRes++; odPrintConsoleString(OD_T("\nExCivil2Ifc: bad password for file: %ls\n"), civilInFileName.c_str()); break; case OdCivilExport::ExportResult::schema_not_supported: nRes++; odPrintConsoleString(OD_T("\nExCivil2Ifc: schema not supported for file: %ls\n"), civilInFileName.c_str()); break; case OdCivilExport::ExportResult::success: break; default: break; } } } return nRes; } #if defined(OD_USE_WMAIN) int wmain(int argc, wchar_t* argv[]) #else int main(int argc, char* argv[]) #endif { /**********************************************************************/ /* Set customized assert function */ /**********************************************************************/ odSetAssertFunc(MyAssert); odSetCheckAssertGroupFunc(MyCheckAssertGroup); setlocale(LC_TIME, ""); // set current user locale (not OD_T("C")), for strftime odPrintConsoleString(OD_T("\nExCivil2IfcExport sample program\n")); #if defined(TARGET_OS_MAC) && !defined(__MACH__) argc = ccommand(&argv); #endif bool bNothingToConvert = argc < 3 ? true : false; int nRes = 0; // bool enablePartialLoading = false; // bool disableSvcsOutput = false; // bool disableRecompute = false; #if !defined(_TOOLKIT_IN_DLL_) ODRX_INIT_STATIC_MODULE_MAP(); #endif if (bNothingToConvert) { odPrintConsoleString(OD_T("Use as: ExCivil2Ifc.exe [paths_to_civil_files.dwg] path_to_ifc_file.ifc [-noWait]\n")); return 0; } /**********************************************************************/ /* Parse Command Line strings */ /**********************************************************************/ int currentArgIndex = 1; OdStringArray sCivilFileNames; OdString sIfcFile; bool noWait = false; for (; currentArgIndex < argc; ++currentArgIndex) { OdString dwgFileName(argv[currentArgIndex]); if (dwgFileName.find(OD_T(".dwg")) == (dwgFileName.getLength() - 4)) { sCivilFileNames.append(dwgFileName); } else { break; } } OdString ifcOutFileName(argv[currentArgIndex]); if (ifcOutFileName.find(OD_T(".ifc")) == (ifcOutFileName.getLength() - 4)) { sIfcFile = ifcOutFileName; ++currentArgIndex; } else { odPrintConsoleString(OD_T("Missing path_to_ifc_file.ifc\n")); return OdResult::eNoFileName; } const OdString noWaitKeyword = OD_T("-noWait"); while (currentArgIndex < argc) { OdString str = argv[currentArgIndex]; if (noWaitKeyword.iCompare(str) == 0) { noWait = true; } ++currentArgIndex; } /********************************************************************/ /* Create a custom Services instance. */ /********************************************************************/ OdStaticRxObject svcs; // svcs.disableOutput(disableSvcsOutput); /* if (disableRecompute) { svcs.setRecomputeDimBlocksRequired(false); } */ /*odrxInitialize(&svcs); ::odrxDynamicLinker()->loadModule(OdCivil2IfcModuleName, false); */ /**********************************************************************/ /* Initialize ODA Civil SDK */ /**********************************************************************/ odInitialize(&svcs); /**********************************************************************/ /* Create a Services object */ /**********************************************************************/ OdStaticRxObject ifcSvcs; OdCivil2IfcModulePtr pCivil2IfcModule = ::odrxDynamicLinker()->loadModule(OdCivil2IfcModuleName, false); /**********************************************************************/ /* Display the Product and Version that created the executable */ /**********************************************************************/ odPrintConsoleString(OD_T("\nExCivil2Ifc example developed using %ls ver %ls"), ifcSvcs.product().c_str(), ifcSvcs.versionString().c_str()); try { if (!pCivil2IfcModule.isNull()) { OdCivilExportPtr Exporter = pCivil2IfcModule->create(); Exporter->properties()->putAt(L"IfcServices", static_cast(&ifcSvcs)); // Optional Exporter->properties()->putAt(L"SchemaVersion", OdRxVariantValue((OdInt16)kScmIfc4x3)); Exporter->properties()->putAt(L"IfcOutFilePath", OdRxVariantValue(ifcOutFileName)); OdPerfTimerWrapper timerWrapper; timerWrapper.getTimer()->start(); nRes = Civil2IfcConvert(svcs, Exporter, sCivilFileNames); if (nRes == 0) // Number of conversion errors { if (Exporter->writeIfcFile(ifcOutFileName) != eOk) { odPrintConsoleString(OD_T("\nExCivil2Ifc: IFC file write error.\n")); } } timerWrapper.getTimer()->stop(); odPrintConsoleString(OD_T("\nExCivil2Ifc: Civil to IFC full working time is %d msec.\n"), timerWrapper.getTimer()->countedMSec()); } } catch (OdError& e) { odPrintConsoleString(OD_T("\n\nError: %ls"), e.description().c_str()); nRes = -1; } catch (...) { odPrintConsoleString(OD_T("\n\nUnexpected error.")); nRes = -1; } if (nRes == 0) // Number of conversion errors odPrintConsoleString(OD_T("\nSUCCESS!\n")); if (!noWait) { odPrintConsoleString(OD_T("\nPress ENTER to continue.\n")); getchar(); } pCivil2IfcModule = nullptr; odrxDynamicLinker()->unloadModule(OdCivil2IfcModuleName); /**********************************************************************/ /* Uninitialize ODA SDK */ /**********************************************************************/ odUninitialize(); return nRes; }