/////////////////////////////////////////////////////////////////////////////// // 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 "OdString.h" #include "RxVariantValue.h" #include "ExSystemServices.h" #include "ExHostAppServices.h" #include "Core/IgesInit.h" #include "Core/IgesFile.h" #include "Core/IgesModuleNames.h" #include "IgesExamplesCommon.h" #include "StaticRxObject.h" #include "RxDynamicModule.h" #include "OdPerfTimer.h" #include "ExPrintConsole.h" #include "IgesImport.h" using namespace DWG_IGES_IMPORT; struct FileData { OdString name; OdGeMatrix3d transformation; OdString rootProductName; }; using FileList = OdArray; class DbServices : public ExSystemServices, public ExHostAppServices { protected: ODRX_USING_HEAP_OPERATORS(ExSystemServices); virtual void warning(const char*, const OdString& msg) ODRX_OVERRIDE { odPrintConsoleString(OD_T("Exception: %s\n"), msg.c_str()); } }; OdString getModuleWorkDir(OdString moduleDir) { int pos = moduleDir.reverseFind('\\'); if (pos < 0) { pos = moduleDir.reverseFind('/'); } if (pos > 0) { moduleDir = moduleDir.mid(0, pos + 1); } return moduleDir; } bool checkFileDir(OdString& fileName, const OdString& parentFile) { if (odrxSystemServices()->accessFile(fileName, 0)) return true; OdString fullPath = getModuleWorkDir(OdString(parentFile)) + fileName; if (odrxSystemServices()->accessFile(fullPath, 0)) { fileName = fullPath; return true; } odPrintConsoleString(OD_T("\nCan not find %s file.\n"), fileName.c_str()); return false; } OdGeMatrix3d getMatrixFromDoubleArray(const OdDoubleArray& doubleArray) { switch (doubleArray.size()) { case 0: return OdGeMatrix3d::kIdentity; case 1: return OdGeMatrix3d::scaling(doubleArray[0]); case 3: return OdGeMatrix3d::translation(OdGeVector3d(doubleArray[0], doubleArray[1], doubleArray[2])); case 9: case 12: { OdGeMatrix3d matrix; int c = doubleArray.size() / 3; for (unsigned int i = 0; i < doubleArray.size(); ++i) { matrix[i / c][i % c] = doubleArray[i]; } return matrix; } default: break; } odPrintConsoleString(OD_T("Error: wrong size of file matrix array. Matrix array size should be equal 1, 3, 9 or 12.")); return OdGeMatrix3d::kIdentity; } bool getLine(OdStreamBuf* pStreamBuf, OdString& fileLine) { if (pStreamBuf->isEof()) return false; OdUInt64 start = pStreamBuf->tell(); OdUInt8 b; OdUInt32 len = 0; OdUInt32 startLine = 0; while (!pStreamBuf->isEof()) { b = pStreamBuf->getByte(); ++len; if (b == '\n' || b == '\r') { if (startLine + 1 == len) { ++startLine; len = 0; } else break; } } if (len == startLine) return false; #ifdef _DEBUG ODA_ASSERT_ONCE(len); if (len == 0) return false; #endif pStreamBuf->seek(start + startLine, OdDb::kSeekFromStart); char* buf = new char[len]; pStreamBuf->getBytes(buf, len); fileLine = OdString(buf, pStreamBuf->isEof() ? len : len-1); delete[] buf; return true; } FileList getFileList(const OdString& txtFileName) { if (!odrxSystemServices()->accessFile(txtFileName, 0)) { odPrintConsoleString(OD_T("Can not find .txt file.\n")); return FileList(); } OdStreamBufPtr pFileBuf = odSystemServices()->createFile(txtFileName); FileList fileList; FileData fileData; OdString lineData; OdDoubleArray doubleArray; while (!pFileBuf->isEof()) { if (!getLine(pFileBuf, lineData)) continue; if (lineData.find('\"') == 0 && lineData.reverseFind('\"') == lineData.getLength() - 1) { fileData.rootProductName = lineData.mid(1, lineData.getLength() - 2); continue; } int pos = lineData.find(' '); auto c_str = lineData.c_str(); OdChar* end; for (double f = std::wcstod(c_str, &end); c_str != end; f = std::wcstod(c_str, &end)) { if (errno == ERANGE) { break; } c_str = end; doubleArray.append(f); } if (wcslen(end)) { errno = 0; if (!fileData.name.isEmpty()) { if (checkFileDir(fileData.name, txtFileName)) { fileData.transformation = getMatrixFromDoubleArray(doubleArray); fileList.append(fileData); } doubleArray.clear(); } fileData = FileData(); fileData.name = lineData; } } if (!fileData.name.isEmpty()) { if (checkFileDir(fileData.name, txtFileName)) { fileData.transformation = getMatrixFromDoubleArray(doubleArray); fileList.append(fileData); } } return fileList; } // // Define module map for statically linked modules: // #if !defined(_TOOLKIT_IN_DLL_) ODRX_DECLARE_DWG2IGES_STATIC_MODULES_ENTRY_POINTS() ODRX_DECLARE_STATIC_MODULE_ENTRY_POINT(OdRecomputeDimBlockModule); ODRX_DECLARE_STATIC_MODULE_ENTRY_POINT(OdRxThreadPoolService); ODRX_DECLARE_STATIC_MODULE_ENTRY_POINT(ModelerModule); ODRX_BEGIN_STATIC_MODULE_MAP() ODRX_DEFINE_DWG2IGES_STATIC_APPMODULES() ODRX_DEFINE_STATIC_APPMODULE(OdRecomputeDimBlockModuleName, OdRecomputeDimBlockModule) ODRX_DEFINE_STATIC_APPMODULE(OdThreadPoolModuleName, OdRxThreadPoolService) ODRX_DEFINE_STATIC_APPMODULE(OdModelerGeometryModuleName, ModelerModule) ODRX_END_STATIC_MODULE_MAP() #endif #include #include /************************************************************************/ /* Main */ /************************************************************************/ #if defined(OD_USE_WMAIN) int wmain(int argc, wchar_t* argv[]) #else int main(int argc, char* argv[]) #endif { ::odSetAssertFunc(MyAssert); int nRes = 0; // Return value for main #if defined(TARGET_OS_MAC) && !defined(__MACH__) argc = ccommand(&argv); #endif setlocale(LC_TIME, ""); // set current user locale (not OD_T("C")), for strftime /**********************************************************************/ /* Create a Services object */ /**********************************************************************/ OdStaticRxObject dbSvcs; OdStaticRxObject igesSvcs; /**********************************************************************/ /* Display the Product and Version that created the executable */ /**********************************************************************/ odPrintConsoleString(OD_T("\nExDwg2Iges example developed using %ls ver %ls"), dbSvcs.product().c_str(), dbSvcs.versionString().c_str()); /**********************************************************************/ /* Parse Command Line inputs */ /**********************************************************************/ bool bInvalidArgs = (argc < 2); if (bInvalidArgs) { nRes = 1; } if (bInvalidArgs) { odPrintConsoleString(OD_T("\n\nusage: ExDwg2Iges ")); odPrintConsoleString(OD_T("\n... - input .dwg file.")); odPrintConsoleString(OD_T("\n - output .igs/.iges file.")); return nRes; } #if !defined(_TOOLKIT_IN_DLL_) ODRX_INIT_STATIC_MODULE_MAP(); #endif /**********************************************************************/ /* Initialize ODA SDK */ /**********************************************************************/ odrxInitialize(&dbSvcs); /**********************************************************************/ /* Initialize Drawings SDK */ /**********************************************************************/ odInitialize(&dbSvcs); /**********************************************************************/ /* Initialize IGES SDK */ /**********************************************************************/ // 1. Conversion can be done using just abstract OdIgesExportPtr interface, // so IGES SDK initialization can be skipped here. In this case it is // performed inside Dwg2Iges module. ::odrxDynamicLinker()->loadModule(L"sdai.tx", false); odIgesInitialize(false /* No CDA */); try { FileList dwgInFilesData; bool needMatrixTransform = false; int currentArgIndex{ 1 }; for (; currentArgIndex < argc; ++currentArgIndex) { OdString dwgInFileName(argv[currentArgIndex]); dwgInFileName.makeLower(); if (dwgInFileName.find(OD_T(".dwg")) == (dwgInFileName.getLength() - 4) || dwgInFileName.find(OD_T(".dxf")) == (dwgInFileName.getLength() - 4)) { dwgInFilesData.append({ OdString(argv[currentArgIndex]), OdGeMatrix3d::kIdentity }); } else if (dwgInFileName.find(OD_T(".txt")) == (dwgInFileName.getLength() - 4)) { dwgInFilesData = getFileList(OdString(argv[currentArgIndex])); needMatrixTransform = true; } else { break; } } if (dwgInFilesData.size() == 0) { odPrintConsoleString(OD_T("\nNo .dwg files defined for conversion into IGES.\n")); return nRes; } OdString igesOutFileName; OdUInt16 conversionModeFlag = 0; OdString logFilePath; if (argc > currentArgIndex) { igesOutFileName = argv[currentArgIndex]; ++currentArgIndex; } if (argc > currentArgIndex) for (int i = currentArgIndex; i < argc; ++i) { OdString argvi(argv[i]); argvi.makeLower(); if (odStrICmp(argvi, OD_T("-logtoconsole")) == 0) conversionModeFlag |= DWG_IGES_IMPORT::kEnableConsoleLog; else if (odStrICmp(argvi.left(10), OD_T("-logtofile")) == 0) { conversionModeFlag |= DWG_IGES_IMPORT::kEnableFileLog; logFilePath = OdString(argv[i]).right(argvi.getLength() - 11); } else ODA_ASSERT(!"Unknown argument!"); } igesSvcs.setFilesDir(getModuleWorkDir(argv[0])); if (OdDwg2IgesModulePtr pDwg2IgesModule = ::odrxDynamicLinker()->loadApp(OdDwg2IgesModuleName, false)) { OdIgesImportPtr Importer = pDwg2IgesModule->create(); Importer->properties()->putAt(OD_T("IgesServices"), static_cast(&igesSvcs)); // Optional Importer->properties()->putAt(OD_T("ConversionMode"), OdRxVariantValue(conversionModeFlag)); Importer->properties()->putAt(OD_T("LogFilePath"), OdRxVariantValue(logFilePath)); for (const auto& dwgInFileData : dwgInFilesData) { odPrintConsoleString(OD_T("\nStart conversion: %s\n"), dwgInFileData.name.c_str()); OdDbDatabasePtr pDwgDatabase = dbSvcs.readFile(dwgInFileData.name); Importer->properties()->putAt(OD_T("DwgDatabase"), pDwgDatabase); if (needMatrixTransform) // If sets FileMatrix property, than will be created root product for full dwg file with the transformation matrix { Importer->properties()->putAt(OD_T("FileMatrix"), OdRxVariantValue((OdIntPtr)&dwgInFileData.transformation)); Importer->properties()->putAt(OD_T("RootProductName"), OdRxVariantValue(dwgInFileData.rootProductName)); } OdPerfTimerWrapper timerWrapper; timerWrapper.getTimer()->start(); // Start conversion OdIgesImport::ImportResult res = Importer->import(); timerWrapper.getTimer()->stop(); odPrintConsoleString(OD_T("\nDwg2Iges: IGES reading time is %d msec"), timerWrapper.getTimer()->countedMSec()); OdDbDatabasePtr pDb; if (res == OdIgesImport::success) { odPrintConsoleString(OD_T("\nDwg2Iges: successful conversion")); } else { switch (res) { case OdIgesImport::bad_database: odPrintConsoleString(OD_T("\nDwg2Iges: bad database\n")); break; case OdIgesImport::bad_file: odPrintConsoleString(OD_T("\nDwg2Iges: bad dwg file\n")); break; // case OdIgesImport::fail: default: odPrintConsoleString(OD_T("\nDwg2Iges: unknown conversion error\n")); break; } } } if (OdResult resWrite = Importer->writeIgesFile(igesOutFileName)) { odPrintConsoleString(OD_T("\nDwg2Iges: IGES file write error.\n")); } } } catch(OdError& e) { odPrintConsoleString(OD_T("\n\nError: %ls"), e.description().c_str()); nRes = -1; } catch(...) { odPrintConsoleString(OD_T("\n\nUnexpected error.")); nRes = -1; } /**********************************************************************/ /* Uninitialize IGES SDK */ /**********************************************************************/ odrxDynamicLinker()->unloadModule(OdDwg2IgesModuleName); odIgesUninitialize(); /**********************************************************************/ /* Uninitialize Drawings SDK */ /**********************************************************************/ odUninitialize(); /**********************************************************************/ /* Uninitialize ODA SDK */ /**********************************************************************/ odrxUninitialize(); return nRes; }