/////////////////////////////////////////////////////////////////////////////// // 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. /////////////////////////////////////////////////////////////////////////////// // ODA Platform #include "OdaCommon.h" #include "BimRv2Dwg2DExportTool.h" #include "TvVisualizeFiler.h" #include "TvModuleNames.h" #include "DynamicLinker.h" #include "ExPrintConsole.h" #include "TvFactory.h" #include "TvModel.h" #include "TvGsDevice.h" #include "RxInit.h" #include "BitmapRender.h" //***************************************************************************// // Some help functions //***************************************************************************// // Method for the ODA SDK activation void ODASdkActivate() { static const char* ActInfo[] = { #ifdef TEIGHA_TRIAL "", "" #else //"UserInfo", "UserSignature" // Before compiling, a ODA SDK activation file should be placed in a location that a compiler can access, // otherwise you get a compiler error such as "Kernel/Extensions/ExServices/ExSystemServices.h:43:10: fatal error: 'OdActivationInfo' file not found". // To learn about ODA SDK activation, see the activation guide at https://docs.opendesign.com/tkernel/oda_activation.html #include "OdActivationInfo" #endif }; odActivate(ActInfo[0], ActInfo[1]); } // Method for the ODA SDK deactivation void ODASdkDeactivate() { odCleanUpStaticData(); } static OdUInt32 g_devicesNumber = 0; static OdString s_strViewName; void viewsChooseCallback(OdTvFilerFeedbackForChooseObject& feedbackForChooseObject) { s_strViewName = OdString(); OdTvFilerFeedbackItemForChooseArray* pFilerFeedbackForChooseArray = feedbackForChooseObject.getFilerFeedbackItemForChooseArrayPtr(); for (unsigned int i = 0; i < pFilerFeedbackForChooseArray->size(); i++) { if (i == g_devicesNumber) { pFilerFeedbackForChooseArray->at(i).m_bChosen = true; s_strViewName = pFilerFeedbackForChooseArray->at(i).m_strName; int slashPos = s_strViewName.reverseFind('\\'); s_strViewName = s_strViewName.right(s_strViewName.getLength() - slashPos - 1); } else pFilerFeedbackForChooseArray->at(i).m_bChosen = false; } } OdString getFileNameFromFullPath(const OdString& sFilePath) { OdString sFileName = sFilePath; sFileName.replace('\\', '/'); int slashPos = sFileName.reverseFind('/'); if (slashPos != -1) sFileName = sFileName.right(sFileName.getLength() - slashPos - 1); int dotPos = sFileName.reverseFind(L'.'); if (dotPos != -1) sFileName = sFileName.left(dotPos); if (!s_strViewName.isEmpty()) sFileName = sFileName + "_" + s_strViewName; return sFileName; } //***************************************************************************// // BimRv2Dwg2DExportTool implementation //***************************************************************************// BimRv2Dwg2DExportTool::BimRv2Dwg2DExportTool() { //activate ODA SDK ODASdkActivate(); // initialize the Visualize SDK odTvInitialize(); } BimRv2Dwg2DExportTool::~BimRv2Dwg2DExportTool() { try { ODASdkDeactivate(); // Uninitialize the ODA Visualize SDK odTvUninitialize(); } catch (OdError& e) { odPrintConsoleString(L"Uninitialization failed.\n"); odPrintConsoleString(L"OdError description:\n%ls\n", e.description().c_str()); } catch (...) { odPrintConsoleString(L"Uninitialization failed.\n"); } } OdTvResult BimRv2Dwg2DExportTool::execute(const OdString& sFilePath, int viewNum, bool bNeedBitmapFlag, const OdString& sOutputDirectory) const { // 1. Load BimRv file g_devicesNumber = viewNum; OdString strBim2VisualizeModuleName; OdTvResult rc = tvOk; OdTvDatabaseId dbId; { OdTvVisualizeFilerModulePtr pBimRv2VisualizeModule = odrxDynamicLinker()->loadApp(OdTvBim2VisualizeModuleName, true); if (pBimRv2VisualizeModule.isNull()) return tvMissingFiler; { const OdUInt32 nWidth = 1024, nHeight = 768; OdTvVisualizeFilerPtr pFiler = pBimRv2VisualizeModule->getVisualizeFiler(); OdString msg; msg = OD_T("BimRv2Dwg2DExportTool: load ") + sFilePath + OD_T("\n"); odPrintConsoleString(msg); OdRxDictionaryPtr pProperties = pFiler->properties(); OdTvDCRect dcRect(0, nWidth, nHeight, 0); if (pProperties->has(OD_T("DCRect"))) pProperties->putAt(OD_T("DCRect"), OdRxVariantValue((OdIntPtr)&dcRect)); if (pProperties->has(OD_T("FeedbackForChooseCallback"))) pProperties->putAt(OD_T("FeedbackForChooseCallback"), OdRxVariantValue((OdIntPtr)&viewsChooseCallback)); if (pProperties->has(OD_T("StoreSourceObjects"))) pProperties->putAt(OD_T("StoreSourceObjects"), OdRxVariantValue((bool)true)); if (pProperties->has(OD_T("StoreCategoryId"))) pProperties->putAt(OD_T("StoreCategoryId"), OdRxVariantValue((bool)true)); if (pProperties->has(OD_T("ObjectNaming"))) pProperties->putAt(OD_T("ObjectNaming"), OdRxVariantValue((bool)true)); if (pProperties->has(OD_T("ThinLines"))) pProperties->putAt(OD_T("ThinLines"), OdRxVariantValue((bool)true)); if (pProperties->has(OD_T("IgnoreEdgesColors"))) pProperties->putAt(OD_T("IgnoreEdgesColors"), OdRxVariantValue((bool)true)); if (pProperties->has(OD_T("ClearEmptyObjects"))) pProperties->putAt(OD_T("ClearEmptyObjects"), OdRxVariantValue((bool)true)); dbId = pFiler->loadFrom(sFilePath, NULL, &rc); if (!dbId.isValid()) return tvInternal; } strBim2VisualizeModuleName = pBimRv2VisualizeModule->moduleName(); } if (!strBim2VisualizeModuleName.isEmpty()) odrxDynamicLinker()->unloadModule(strBim2VisualizeModuleName); // Change path for platform OdString sDwgFileName = sOutputDirectory; #if defined(ODA_WINDOWS) sDwgFileName.replace('/', '\\'); #else sDwgFileName.replace('\\', '/'); #endif OdString sFileName = getFileNameFromFullPath(sFilePath); OdString sSlash = OD_T("/"); #if defined(ODA_WINDOWS) sSlash = OD_T("\\"); #endif OdString sOutputDwgFileName = sDwgFileName + sSlash + sFileName + OD_T(".dwg"); // 2. Export to DWG in 2D mode { OdTvDatabasePtr pDatabase = dbId.openObject(); OdTvGsDeviceId deviceId; OdTvDevicesIteratorPtr pDeviceIter = pDatabase->getDevicesIterator(&rc); if (pDeviceIter->done()) return tvDevicesIsEmpty; deviceId = pDeviceIter->getDevice(); OdTvGsDevicePtr pDevice = deviceId.openObject(); if (!pDevice->isBitmap()) pDevice->switchBitmapState(); pDevice->setupGsBitmap(1024, 768, OdTvGsDevice::kOpenGLES2); pDevice->update(); OdTvDwgExportParams exportParams; exportParams.setDevice(deviceId); exportParams.setFilePath(sOutputDwgFileName); exportParams.setExportIn2d(true); exportParams.setSaveNativeEntityHandles(true); exportParams.setExportBlackAsIndex(true); rc = pDatabase->exportTo(&exportParams); } OdTvFactoryId tvFactory = odTvGetFactory(); tvFactory.removeDatabase(dbId); // 3. Draw result to bitmap image OdString strDwg2VisualizeModuleName; if (bNeedBitmapFlag) { OdTvVisualizeFilerModulePtr pDWGFilerModule = odrxDynamicLinker()->loadApp(OdTvDwg2VisualizeModuleName, false); if (pDWGFilerModule.isNull()) return tvMissingFiler; // define output image size const OdUInt32 nWidth = 1024, nHeight = 768; OdTvDatabaseId db1Id; // Import first DWG file { // generate database OdTvVisualizeFilerPtr pFiler = pDWGFilerModule->getVisualizeFiler(); if (pFiler.isNull()) return tvMissingFiler; OdRxDictionaryPtr pProperties = pFiler->properties(); OdTvDCRect dcRect(0, nWidth, nHeight, 0); ODCOLORREF color = 0XFFFFFF; //white if (pProperties->has(OD_T("BackgroundColor"))) pProperties->putAt(OD_T("BackgroundColor"), OdRxVariantValue((OdIntPtr)&color)); if (pProperties->has(OD_T("DCRect"))) pProperties->putAt(OD_T("DCRect"), OdRxVariantValue((OdIntPtr)&dcRect)); if (pProperties->has(OD_T("ClearEmptyObjects"))) pProperties->putAt(OD_T("ClearEmptyObjects"), OdRxVariantValue((bool)true)); db1Id = pFiler->loadFrom(sOutputDwgFileName); } if (!db1Id.isValid()) return tvInternal; TvBitmapRender _tb(db1Id); _tb.prepareDevice(OdTvGsDevice::kOpenGLES2, (long)nWidth, (long)nHeight); // render to file OdString sOutputBmpFileName = sDwgFileName + sSlash + sFileName + OD_T(".png"); _tb.renderImageToFile(sOutputBmpFileName, false); tvFactory.removeDatabase(db1Id); strDwg2VisualizeModuleName = pDWGFilerModule->moduleName(); } if (!strDwg2VisualizeModuleName.isEmpty()) odrxDynamicLinker()->unloadModule(strDwg2VisualizeModuleName); return tvOk; }