/////////////////////////////////////////////////////////////////////////////// // 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 "DynamicLinker.h" #include "RxDynamicModule.h" #include "DynamicLinker.h" #include "RxObject.h" #include "StaticRxObject.h" #include #include #include #include "TvFactory.h" #include "TvGeomCollector.h" #include "TvFilerTimer.h" #include "TvModuleNames.h" #include "TvDatabaseCleaner.h" #include "TvDatabaseUtils.h" #include "Jt2Visualize.h" #include "RxInit.h" #include "RxVariantValue.h" #include "ColorMapping.h" //SEA #include "ExVisualizeDeviceExtensions.h" #include "ThreadsCounter.h" #include "RxModelTreeBaseNode.h" #include "RxModelHierarchyTreeBase.h" #include "GiContextForJtDatabase.h" #include "JtPartitionNodeElement.h" #include "JtGsLayoutHelper.h" //*************************************************************************************// // Implementation of the methods of the inheritants of 'OdTvVisualizeJtFilerDbSource' //*************************************************************************************// class OdTvVisualizeJtFilerSourceFromDb : public OdTvVisualizeJtFilerDbSource { OdDbBaseDatabase* m_pDatabase; public: OdTvVisualizeJtFilerSourceFromDb(OdDbBaseDatabase *pDatabase) : m_pDatabase(pDatabase) {}; virtual OdJtDatabasePtr getDb() { return m_pDatabase; }; virtual bool odWasInitialized() const { return false; } virtual OdString getFullFileName() { return OdString(); } virtual OdString getFilename() { OdJtDatabasePtr pDb = m_pDatabase; if (!pDb.isNull()) { OdString fileName = pDb->rootPartition()->filename(); if (!fileName.isEmpty()) { return fileName; } } return OD_T("NoNameJtDatabase"); } }; class OdTvVisualizeJtFilerSourceFromFile : public OdTvVisualizeJtFilerDbSource { // OdStaticRxObject svcs; OdString m_FilePath; protected: double m_initTime; public: OdTvVisualizeJtFilerSourceFromFile(const OdString& filePath, OdTvFilerTimeProfiling* pProfileRes, const JT2Visualize::OdTvVisualizeJtFilerPropertiesPtr pProperties) { initialize(filePath, pProfileRes, pProperties); } virtual OdJtDatabasePtr getDb() { OdStreamBufPtr pStream = ::odrxSystemServices()->createFile(m_FilePath); OdJtDatabasePtr pDb = OdJtDatabase::createObject(); pDb->read(pStream); return pDb; }; virtual double getInitTime() const { return m_initTime; } virtual OdString getFilename() { return OdTvDatabaseUtils::getFileNameFromPath(m_FilePath); // Generate name for the stream file. } virtual OdString getFullFileName() { return m_FilePath; } protected: OdTvVisualizeJtFilerSourceFromFile() {} void initialize(const OdString& filePath, OdTvFilerTimeProfiling* pProfileRes, const JT2Visualize::OdTvVisualizeJtFilerPropertiesPtr pProperties) { m_FilePath = filePath; OdTvFilerTimer timing(needTimer(pProfileRes)); timing.startTotal(); ::odrxDynamicLinker()->loadModule(OdJtModuleName, false); timing.endTotal(); m_initTime = timing.getTotalTime(); } }; //***************************************************************************// // 'OdTvVisualizeJtFilerProperties' methods implementation //***************************************************************************// using namespace JT2Visualize; OdTvVisualizeJtFilerProperties::OdTvVisualizeJtFilerProperties() : m_flags(kClearEmptyObjects | kUseIsolinesFor3DObjects), m_pCallback(0) { m_importRect.xmax = 1; m_importRect.xmin = 0; m_importRect.ymax = 0; m_importRect.ymin = 1; m_defaultUnits = OdTv::kMillimeters; } OdRxDictionaryPtr OdTvVisualizeJtFilerProperties::createObject() { return OdRxObjectImpl::createObject(); } OdTvVisualizeJtFilerProperties::~OdTvVisualizeJtFilerProperties() { } namespace JT2Visualize { ODRX_DECLARE_PROPERTY(Palette) ODRX_DECLARE_PROPERTY(DCRect) ODRX_DECLARE_PROPERTY(ObjectNaming) ODRX_DECLARE_PROPERTY(StoreSourceObjects) ODRX_DECLARE_PROPERTY(FeedbackForChooseCallback) ODRX_DECLARE_PROPERTY(ClearEmptyObjects) ODRX_DECLARE_PROPERTY(UseIsolinesFor3DObjects) ODRX_DECLARE_PROPERTY(AppendTransform) ODRX_DECLARE_PROPERTY(NeedCDATree) ODRX_DECLARE_PROPERTY(NeedCollectPropertiesInCDA) ODRX_DECLARE_PROPERTY(DefaultUnits) ODRX_BEGIN_DYNAMIC_PROPERTY_MAP(OdTvVisualizeJtFilerProperties); ODRX_GENERATE_PROPERTY(Palette) ODRX_GENERATE_PROPERTY(DCRect) ODRX_GENERATE_PROPERTY(ObjectNaming) ODRX_GENERATE_PROPERTY(StoreSourceObjects) ODRX_GENERATE_PROPERTY(FeedbackForChooseCallback) ODRX_GENERATE_PROPERTY(ClearEmptyObjects) ODRX_GENERATE_PROPERTY(UseIsolinesFor3DObjects) ODRX_GENERATE_PROPERTY(AppendTransform) ODRX_GENERATE_PROPERTY(NeedCDATree) ODRX_GENERATE_PROPERTY(NeedCollectPropertiesInCDA) ODRX_GENERATE_PROPERTY(DefaultUnits) ODRX_END_DYNAMIC_PROPERTY_MAP(OdTvVisualizeJtFilerProperties); ODRX_DEFINE_PROPERTY_METHODS(Palette, OdTvVisualizeJtFilerProperties, getPalette, setPalette, getIntPtr); ODRX_DEFINE_PROPERTY_METHODS(DCRect, OdTvVisualizeJtFilerProperties, getDCRect, setDCRect, getIntPtr); ODRX_DEFINE_PROPERTY_METHODS(ObjectNaming, OdTvVisualizeJtFilerProperties, getObjectNaming, setObjectNaming, getBool); ODRX_DEFINE_PROPERTY_METHODS(StoreSourceObjects, OdTvVisualizeJtFilerProperties, getStoreSourceObjects, setStoreSourceObjects, getBool); ODRX_DEFINE_PROPERTY_METHODS(FeedbackForChooseCallback, OdTvVisualizeJtFilerProperties, getFeedbackForChooseCallback, setFeedbackForChooseCallback, getIntPtr); ODRX_DEFINE_PROPERTY_METHODS(ClearEmptyObjects, OdTvVisualizeJtFilerProperties, getClearEmptyObjects, setClearEmptyObjects, getBool); ODRX_DEFINE_PROPERTY_METHODS(UseIsolinesFor3DObjects, OdTvVisualizeJtFilerProperties, getUseIsolinesFor3DObjects, setUseIsolinesFor3DObjects, getBool); ODRX_DEFINE_PROPERTY_METHODS(AppendTransform, OdTvVisualizeJtFilerProperties, getAppendTransform, setAppendTransform, getIntPtr); ODRX_DEFINE_PROPERTY_METHODS(NeedCDATree, OdTvVisualizeJtFilerProperties, getNeedCDATree, setNeedCDATree, getBool); ODRX_DEFINE_PROPERTY_METHODS(NeedCollectPropertiesInCDA, OdTvVisualizeJtFilerProperties, getNeedCollectPropertiesInCDA, setNeedCollectPropertiesInCDA, getBool); ODRX_DEFINE_PROPERTY_METHODS(DefaultUnits, OdTvVisualizeJtFilerProperties, getDefaultUnits, setDefaultUnits, getIntPtr); } void OdTvVisualizeJtFilerProperties::setPalette(OdIntPtr palette) { const ODCOLORREF* pPalette = (const ODCOLORREF*)(palette); m_pPalette = pPalette; } OdIntPtr OdTvVisualizeJtFilerProperties::getPalette() const { return (OdIntPtr)(m_pPalette); } void OdTvVisualizeJtFilerProperties::setDCRect(OdIntPtr rect) { OdTvDCRect* pRect = (OdTvDCRect*)(rect); if (!pRect) { ODA_ASSERT(false); } m_importRect = *pRect; } OdIntPtr OdTvVisualizeJtFilerProperties::getDCRect() const { return (OdIntPtr)(&m_importRect); } void OdTvVisualizeJtFilerProperties::setFeedbackForChooseCallback(OdIntPtr pCallback) { m_pCallback = (OdTvFeedbackForChooseCallback)pCallback; } OdIntPtr OdTvVisualizeJtFilerProperties::getFeedbackForChooseCallback() const { return (OdIntPtr)m_pCallback; } void OdTvVisualizeJtFilerProperties::setAppendTransform(OdIntPtr pTransform) { const OdTvMatrix* pAppendTransform = (const OdTvMatrix*)(pTransform); if (pAppendTransform) { m_appendTransform = *pAppendTransform; } else { m_appendTransform = OdTvMatrix::kIdentity; } } OdIntPtr OdTvVisualizeJtFilerProperties::getAppendTransform() const { return (OdIntPtr)(&m_appendTransform); } //***************************************************************************// // 'OdTvVisualizeDgnFiler' methods implementation //***************************************************************************// OdTvVisualizeJtFiler::OdTvVisualizeJtFiler() : m_properties(OdTvVisualizeJtFilerProperties::createObject()), m_pDl(NULL) { } OdTvVisualizeJtFiler::~OdTvVisualizeJtFiler() { if (m_pDl) m_pDl = NULL; } OdTvDatabaseId OdTvVisualizeJtFiler::loadFrom(OdDbBaseDatabase *pDatabase, OdTvFilerTimeProfiling* pProfileRes, OdTvResult* rc) const { OdTvVisualizeJtFilerSourceFromDb dl(pDatabase); return loadFrom(&dl, pProfileRes, rc); } OdTvDatabaseId OdTvVisualizeJtFiler::loadFrom(OdStreamBuf* pBuffer, OdTvFilerTimeProfiling* pProfileRes, OdTvResult* rc) const { if (rc) *rc = tvNotSupported; return OdTvDatabaseId(); } OdTvDatabaseId OdTvVisualizeJtFiler::loadFrom(const OdString& filePath, OdTvFilerTimeProfiling* pProfileRes, OdTvResult* rc) const { OdTvVisualizeJtFilerSourceFromFile dl(filePath, pProfileRes, m_properties); return loadFrom(&dl, pProfileRes, rc); } OdTvDatabaseId OdTvVisualizeJtFiler::generate(OdTvFilerTimeProfiling* pProfileRes) const { return OdTvDatabaseId(); } OdTvModelId OdTvVisualizeJtFiler::appendFrom(const OdTvDatabaseId& databaseId, OdDbBaseDatabase *pDatabase, OdTvFilerTimeProfiling* pProfileRes, OdTvResult* rc) const { OdTvVisualizeJtFilerSourceFromDb dl(pDatabase); return appendFrom(databaseId, &dl, pProfileRes, rc); } OdTvModelId OdTvVisualizeJtFiler::appendFrom(const OdTvDatabaseId& databaseId, OdStreamBuf *pBuffer, OdTvFilerTimeProfiling* pProfileRes, OdTvResult* rc) const { if (rc) *rc = tvNotSupported; return OdTvModelId(); } OdTvModelId OdTvVisualizeJtFiler::appendFrom(const OdTvDatabaseId& databaseId, const OdString &filePath, OdTvFilerTimeProfiling* pProfileRes, OdTvResult* rc) const { OdTvVisualizeJtFilerSourceFromFile dl(filePath, pProfileRes, m_properties); return appendFrom(databaseId, &dl, pProfileRes, rc); } OdTvResult OdTvVisualizeJtFiler::startActionsWithNativeProperties(const OdString& sFilePath, bool bPartial) { OdTvResult rc = tvOk; return rc; } bool OdTvVisualizeJtFiler::isActionsWithNativePropertiesStarted(const OdString& sFilePath) { return false; } OdTvResult OdTvVisualizeJtFiler::endActionsWithNativeProperties() { return tvOk; } OdRxMemberIteratorPtr OdTvVisualizeJtFiler::getNativePropertiesIterator(OdUInt64 dbHandle, OdTvResult* rc) { OdRxMemberIteratorPtr pIter; return pIter; } OdRxValue OdTvVisualizeJtFiler::getNativePropertyValue(OdUInt64 dbHandle, const OdRxPropertyPtr& pProperty, bool* bReadOnly, OdTvResult* rc) { OdRxObjectPtr pElement; return pElement; } OdRxValueIteratorPtr OdTvVisualizeJtFiler::getNativeCollectionPropertyIterator(OdUInt64 dbHandle, const OdRxCollectionPropertyPtr& pCollectionProperty, bool* bReadOnly, OdTvResult* rc) { OdRxValueIteratorPtr pValIter; return pValIter; } OdTvResult OdTvVisualizeJtFiler::setNativePropertyValue(OdUInt64 dbHandle, OdRxPropertyPtr& pProperty, const OdRxValue& value) { OdRxObjectPtr pElement; return tvOk; } OdDbBaseDatabase* OdTvVisualizeJtFiler::getNativeDatabase(OdTvResult* rc) const { return NULL; } void disableBackFaceCulling(OdTvGeometryDataId geometryId) { if (geometryId.getType() == OdTv::kSubEntity) { for (auto pGeometryIt = geometryId.openAsSubEntity()->getGeometryDataIterator(); !pGeometryIt->done(); pGeometryIt->step()) { disableBackFaceCulling(pGeometryIt->getGeometryData()); } } else if (geometryId.getType() == OdTv::kShell) { geometryId.openAsShell()->setBackFaceCulling(OdTvShellData::kOff); } } OdTvDatabaseId OdTvVisualizeJtFiler::loadFrom(OdTvVisualizeJtFilerDbSource* pJtDatabaseSource, OdTvFilerTimeProfiling* pProfileRes, OdTvResult* rc) const { OdTvDatabaseId tvDbId; if (rc) *rc = tvOk; //check that time profiling is need bool bUseTimeProfiling = needTimer(pProfileRes); double internalTiming = 0.; double externalTiming = 0.; //prepare timing object OdTvFilerTimer timing(bUseTimeProfiling); timing.startTotal(); double dbReadingTime = 0.; //store visualize device module name OdString moduleName; try { OdJtDatabasePtr pDb = pJtDatabaseSource->getDb(); // reading SW file here if (!pDb.isNull()) { timing.endTotal(); dbReadingTime = timing.getTotalTime() /*+ pJtDatabaseSource->getInitTime()*/; OdTvFilerFeedbackForChooseObject filerFeedbackForChooseObject(OD_T("Choose views for import")); bool bCanceled = false; OdTvFilerFeedbackItemForChooseArray* pFilerFeedbackForChooseArray = filerFeedbackForChooseObject.getFilerFeedbackItemForChooseArrayPtr(); OdString strIndex; strIndex.format(OD_T("%d"), 0); OdTvFilerFeedbackItemForChoose filerFeedbackForChoose(strIndex); pFilerFeedbackForChooseArray->append(filerFeedbackForChoose); if (bCanceled) { if (rc) *rc = tvFilerEmptyInternalDatabase; pDb = NULL; //unload Jt modules (try to emulate the OdUninitialized for SW) //here we will unload all including Visualize device odrxDynamicLinker()->unloadUnreferenced(); return tvDbId; } timing.startTotal(); timing.startVectorizing(); OdGsModulePtr pGs = ::odrxDynamicLinker()->loadModule(OdTvVisualizeDeviceModuleName, false); if (pGs.isNull()) { if (rc) *rc = tvMissingVisualizeDeviceModule; return tvDbId; } //get the palette from the database const ODCOLORREF* refColors = (ODCOLORREF*)(ODRGB(195, 200, 210)); //For the each 'OdJtView' will be created a separate device with a separate model. //More of it, for each view it will used a new Visualize device. At the same time the //TV database will be the same. That's why we will create the tv database outside of the //visualize device. //create empty tv database. OdTvFactoryId tvFactoryId = odTvGetFactory(); tvDbId = tvFactoryId.createDatabase(); OdTvDatabasePtr pTvDb = tvDbId.openObject(OdTv::kForWrite); // save filename to database user data OdTvDatabaseUtils::writeFileNameToTvDatabase(tvDbId, pJtDatabaseSource->getFilename()); //Also there are some objects like material which should be the same for all models. For this //purpose we will use special Visualize device cache //initialize cache and switch it to the "write only" mode ExGsVisualizeDeviceCache deviceCache; deviceCache.m_bApplyCacheData = false; //OdJtViewPtr pCurView = pDb->getActiveView(); OdGsDevicePtr pCachedDevice; //get the background color from the model //dJtuiModelDoc_cPtr pModel = pDb->getModelDoc(); ODCOLORREF background = (ODCOLORREF)(ODRGB(195, 200, 210)); //create device OdGsDevicePtr pDevice = pGs->createDevice(); OdGiContextForJtDatabasePtr pJtContext = OdRxObjectImpl::createObject(); pJtContext->setDatabase(pDb); //pJtContext->setView(pCurView); pJtContext->enableGsModel(true); pJtContext->setPaletteBackground(background); OdRxDictionaryPtr pProperties = pDevice->properties(); if (pProperties.get()) { if (pProperties->has(OD_T("DisplayViaGLES2"))) pProperties->putAt(OD_T("DisplayViaGLES2"), OdRxVariantValue(false)); if (pProperties->has(OD_T("AllowNonPersistentObjects"))) pProperties->putAt(OD_T("AllowNonPersistentObjects"), OdRxVariantValue(false)); #if !defined(__APPLE__) if (pProperties->has(OD_T("EnableTiming"))) pProperties->putAt(OD_T("EnableTiming"), OdRxVariantValue(bUseTimeProfiling)); #endif if (pProperties->has(OD_T("TvDatabaseID"))) pProperties->putAt(OD_T("TvDatabaseID"), OdRxVariantValue((OdIntPtr)(&tvDbId))); if (pProperties->has(OD_T("WriteUserData"))) pProperties->putAt(OD_T("WriteUserData"), OdRxVariantValue(m_properties->getStoreSourceObjects())); if (pProperties->has(OD_T("GenerateEntityNames"))) pProperties->putAt(OD_T("GenerateEntityNames"), OdRxVariantValue(m_properties->getObjectNaming())); if (pProperties->has(OD_T("DeviceCache"))) pProperties->putAt(OD_T("DeviceCache"), OdRxVariantValue((OdIntPtr)(&deviceCache))); if (pProperties->has(OD_T("CompareUnnamedImages"))) pProperties->putAt(OD_T("CompareUnnamedImages"), OdRxVariantValue(true)); if (pProperties->has(OD_T("EnableViewDependentEntities"))) pProperties->putAt(OD_T("EnableViewDependentEntities"), OdRxVariantValue(true)); if (pProperties->has(OD_T("ModelName"))) { OdString strModelName; pProperties->putAt(OD_T("ModelName"), OdRxVariantValue(strModelName)); } //Write font file path as user data if (pProperties->has(OD_T("WriteFontFilePath"))) pProperties->putAt(OD_T("WriteFontFilePath"), OdRxVariantValue(true)); //Do not transform layer lineweight if (pProperties->has(OD_T("DisableNonEntityLineweightTransformation"))) pProperties->putAt(OD_T("DisableNonEntityLineweightTransformation"), OdRxVariantValue(true)); } //set the palette and background to the device const ODCOLORREF* palette = (const ODCOLORREF*)m_properties->getPalette(); palette = odcmAcadPalette(background); // black background //set the palette and background to the device OdArray > pPalCpy; pPalCpy.insert(pPalCpy.begin(), palette, palette + 256); pPalCpy[7] = ODRGB(149, 155, 176); // model color pDevice->setLogicalPalette(pPalCpy.asArrayPtr(), 256); pDevice->setBackgroundColor(ODRGB(255, 255, 255)); // setup the device and views OdGsDevicePtr pDeviceForJt = OdJtGsLayoutHelper::setupLayoutView(pDevice, pJtContext); if (pCachedDevice.isNull()) { pCachedDevice = pDeviceForJt; } //call onsize OdTvDCRect* pRect = (OdTvDCRect*)m_properties->getDCRect(); if (pRect && (pRect->xmax > 0 || pRect->xmin > 0 || pRect->ymax > 0 || pRect->ymin > 0)) { OdGsDCRect gsRect(pRect->xmin, pRect->xmax, pRect->ymin, pRect->ymax); pDevice->onSize(gsRect); } //call draw to the Visualize database pDeviceForJt->update(); if (bUseTimeProfiling) { #if !defined(__APPLE__) if (pProperties->has(OD_T("TvElapsedTime"))) { internalTiming += OdRxVariantValue(pProperties->getAt(OD_T("TvElapsedTime")).get())->getDouble(); } #endif } //we should update the state of the device cache marked it to use the cached data during next vectorizing if (pProperties->has(OD_T("DeviceCache"))) { deviceCache.m_bApplyCacheData = true; OdIntPtr ptr = OdRxVariantValue(pProperties->getAt(OD_T("DeviceCache")).get())->getIntPtr(); } externalTiming += timing.getMiscTime(); timing.startMisc(); if (tvDbId.isValid() && m_properties->getClearEmptyObjects()) OdTvDatabaseCleaner::cleanTvDatabase(tvDbId); timing.endMisc(); externalTiming += timing.getMiscTime(); timing.endVectorizing(); } else { if (rc) *rc = tvFilerEmptyInternalDatabase; } } catch (...) { if (rc) *rc = tvInternal; timing.endVectorizing(); } if (tvDbId.isValid()) { auto db = tvDbId.openObject(OdTv::kForWrite); auto device = db->getDevicesIterator()->getDevice().openObject(OdTv::kForWrite); auto view = device->viewAt(0).openObject(OdTv::kForWrite); view->setVisualStyle(db->findVisualStyle("Gouraud")); view->setDefaultLightingIntensity(0.7); auto model = db->getModelsIterator()->getModel().openObject(OdTv::kForWrite); for (auto entityIt = model->getEntitiesIterator(); !entityIt->done(); entityIt->step()) { auto entity = entityIt->getEntity().openObject(OdTv::kForWrite); for (auto geometryIt = entity->getGeometryDataIterator(); !geometryIt->done(); geometryIt->step()) { disableBackFaceCulling(geometryIt->getGeometryData()); } } } // Unload Jt modules (try to emulate the OdUninitialized for SW). // Here we will unload all including Visualize device. odrxDynamicLinker()->unloadUnreferenced(); timing.endTotal(); if (pProfileRes) { pProfileRes->setImportTime(OdInt64(dbReadingTime * 1000.)); pProfileRes->setVectorizingTime(OdInt64(timing.getVectorizingTime() * 1000.)); #if !defined(__APPLE__) pProfileRes->setTvTime(OdInt64((internalTiming + externalTiming) * 1000.)); #endif } return tvDbId; } OdTvModelId OdTvVisualizeJtFiler::appendFrom(const OdTvDatabaseId& databaseId, OdTvVisualizeJtFilerDbSource *pDgnDatabaseSource, OdTvFilerTimeProfiling* pProfileRes, OdTvResult* rc) const { OdTvModelId tvModelId; return tvModelId; } OdTvGsDeviceId OdTvVisualizeJtFiler::getActiveTvDevice(OdTvDatabaseId& tvDbId, int idDevice) const { return OdTvGsDeviceId(); } OdTvGsViewId OdTvVisualizeJtFiler::getActiveTvView(OdTvGsDeviceId& tvDeviceId, int iActViewViewInd) const { return OdTvGsViewId(); } void OdTvVisualizeJtFiler::createCommonDataAccessTree(OdTvDatabasePtr pTvDb, OdDbBaseDatabase *pDatabase, const OdString& strTreeName) const { } //***************************************************************************// // 'OdTvVisualizeJtFilerModule' methods implementation //***************************************************************************// ODRX_DEFINE_DYNAMIC_MODULE(OdTvVisualizeJtFilerModule); void OdTvVisualizeJtFilerModule::initApp() { // initialize the Visualize odTvInitialize(); } void OdTvVisualizeJtFilerModule::uninitApp() { // Uninitialize the Visualize odTvUninitialize(); } OdTvVisualizeFilerPtr OdTvVisualizeJtFilerModule::getVisualizeFiler() const { OdTvVisualizeFilerPtr pAcisFiler = new OdTvVisualizeJtFiler(); return pAcisFiler; }