/////////////////////////////////////////////////////////////////////////////// // 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 "RxDynamicModule.h" #include "RxObject.h" #include "StaticRxObject.h" #include "TvFactory.h" #include "TvGeomCollector.h" #include "TvFilerTimer.h" #include "TvModuleNames.h" #include "TvDatabaseCleaner.h" #include "TvDatabaseUtils.h" #include "Inv2Visualize.h" #include "TInvModuleNames.h" #include "RxInit.h" #include "RxVariantValue.h" #include "InvVis/GiGs/InvGsManager.h" #include "ColorMapping.h" #include "IptHostAppServices.h" //SEA #include "DynamicLinker.h" #include "ExVisualizeDeviceExtensions.h" #include "RxModelTreeBaseNode.h" #include "RxModelHierarchyTreeBase.h" #include #include //*************************************************************************************// // Implementation of the methods of the inheritants of 'OdTvVisualizeInvFilerDbSource' //*************************************************************************************// class OdTvVisualizeInvFilerSourceFromDb : public OdTvVisualizeInvFilerDbSource { OdDbBaseDatabase *mDatabase; public: OdTvVisualizeInvFilerSourceFromDb(OdDbBaseDatabase *pDatabase) : mDatabase(pDatabase) {}; virtual OdInvDatabaseGiDrPtr getDb() { return mDatabase; }; virtual bool odWasInitialized() const { return false; } virtual OdString getFilename() { OdInvDatabaseGiDrPtr pDb = mDatabase; if (!pDb.isNull()) { OdString fileName = pDb->getFilename(); if (!fileName.isEmpty()) return fileName; } return OD_T("NoNameInvDatabase"); } }; class OdTvVisualizeInvFilerSourceFromFile : public OdTvVisualizeInvFilerDbSource { //OdStaticRxObject svcs; OdString mFilePath; protected: double m_initTime; public: OdTvVisualizeInvFilerSourceFromFile(const OdString& filePath, OdTvFilerTimeProfiling* pProfileRes, const Inv2Visualize::OdTvVisualizeInvFilerProperties* pProperties) { initialize(filePath, pProfileRes, pProperties); }; virtual OdInvDatabaseGiDrPtr getDb() { OdRxInvInteropModulePtr pModule = odrxDynamicLinker()->loadModule(InvInteropModuleName, false); OdInvDatabaseGiDrPtr pGiDrDb = OdInvDatabaseGiDr::createObject(); pGiDrDb->m_pDb = pModule->readFile(mFilePath); return pGiDrDb; }; virtual double getInitTime() const { return m_initTime; } virtual OdString getFilename() { //generate name for the stream file return OdTvDatabaseUtils::getFileNameFromPath(mFilePath); }; protected: OdTvVisualizeInvFilerSourceFromFile() {}; void initialize(const OdString& filePath, OdTvFilerTimeProfiling* pProfileRes, const Inv2Visualize::OdTvVisualizeInvFilerProperties* pProperties) { mFilePath = filePath; OdTvFilerTimer timing(needTimer(pProfileRes)); timing.startTotal(); timing.endTotal(); m_initTime = timing.getTotalTime(); }; }; //***************************************************************************// // 'OdTvVisualizeInvFilerProperties' methods implementation //***************************************************************************// using namespace Inv2Visualize; OdTvVisualizeInvFilerProperties::OdTvVisualizeInvFilerProperties() : 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 OdTvVisualizeInvFilerProperties::createObject() { return OdRxObjectImpl::createObject(); } OdTvVisualizeInvFilerProperties::~OdTvVisualizeInvFilerProperties() { } namespace Inv2Visualize { 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(OdTvVisualizeInvFilerProperties); 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(OdTvVisualizeInvFilerProperties); ODRX_DEFINE_PROPERTY_METHODS(Palette, OdTvVisualizeInvFilerProperties, getPalette, setPalette, getIntPtr); ODRX_DEFINE_PROPERTY_METHODS(DCRect, OdTvVisualizeInvFilerProperties, getDCRect, setDCRect, getIntPtr); ODRX_DEFINE_PROPERTY_METHODS(ObjectNaming, OdTvVisualizeInvFilerProperties, getObjectNaming, setObjectNaming, getBool); ODRX_DEFINE_PROPERTY_METHODS(StoreSourceObjects, OdTvVisualizeInvFilerProperties, getStoreSourceObjects, setStoreSourceObjects, getBool); ODRX_DEFINE_PROPERTY_METHODS(FeedbackForChooseCallback, OdTvVisualizeInvFilerProperties, getFeedbackForChooseCallback, setFeedbackForChooseCallback, getIntPtr); ODRX_DEFINE_PROPERTY_METHODS(ClearEmptyObjects, OdTvVisualizeInvFilerProperties, getClearEmptyObjects, setClearEmptyObjects, getBool); ODRX_DEFINE_PROPERTY_METHODS(UseIsolinesFor3DObjects, OdTvVisualizeInvFilerProperties, getUseIsolinesFor3DObjects, setUseIsolinesFor3DObjects, getBool); ODRX_DEFINE_PROPERTY_METHODS(AppendTransform, OdTvVisualizeInvFilerProperties, getAppendTransform, setAppendTransform, getIntPtr); ODRX_DEFINE_PROPERTY_METHODS(NeedCDATree, OdTvVisualizeInvFilerProperties, getNeedCDATree, setNeedCDATree, getBool); ODRX_DEFINE_PROPERTY_METHODS(NeedCollectPropertiesInCDA, OdTvVisualizeInvFilerProperties, getNeedCollectPropertiesInCDA, setNeedCollectPropertiesInCDA, getBool); ODRX_DEFINE_PROPERTY_METHODS(DefaultUnits, OdTvVisualizeInvFilerProperties, getDefaultUnits, setDefaultUnits, getIntPtr); } void OdTvVisualizeInvFilerProperties::setPalette(OdIntPtr palette) { const ODCOLORREF* pPalette = (const ODCOLORREF*)(palette); m_pPalette = pPalette; } OdIntPtr OdTvVisualizeInvFilerProperties::getPalette() const { return (OdIntPtr)(m_pPalette); } void OdTvVisualizeInvFilerProperties::setDCRect(OdIntPtr rect) { OdTvDCRect* pRect = (OdTvDCRect*)(rect); if (!pRect) { ODA_ASSERT(false); } m_importRect = *pRect; } OdIntPtr OdTvVisualizeInvFilerProperties::getDCRect() const { return (OdIntPtr)(&m_importRect); } void OdTvVisualizeInvFilerProperties::setFeedbackForChooseCallback(OdIntPtr pCallback) { m_pCallback = (OdTvFeedbackForChooseCallback)pCallback; } OdIntPtr OdTvVisualizeInvFilerProperties::getFeedbackForChooseCallback() const { return (OdIntPtr)m_pCallback; } void OdTvVisualizeInvFilerProperties::setAppendTransform(OdIntPtr pTransform) { const OdTvMatrix* pAppendTransform = (const OdTvMatrix*)(pTransform); if (pAppendTransform) { m_appendTransform = *pAppendTransform; } else { m_appendTransform = OdTvMatrix::kIdentity; } } OdIntPtr OdTvVisualizeInvFilerProperties::getAppendTransform() const { return (OdIntPtr)(&m_appendTransform); } //***************************************************************************// // 'OdTvVisualizeDgnFiler' methods implementation //***************************************************************************// OdTvVisualizeInvFiler::OdTvVisualizeInvFiler() : m_properties(OdTvVisualizeInvFilerProperties::createObject()), m_pDl(NULL) { } OdTvVisualizeInvFiler::~OdTvVisualizeInvFiler() { if (m_pDl) m_pDl = NULL; } OdTvDatabaseId OdTvVisualizeInvFiler::loadFrom(OdDbBaseDatabase *pDatabase, OdTvFilerTimeProfiling* pProfileRes, OdTvResult* rc) const { OdTvVisualizeInvFilerSourceFromDb dl(pDatabase); return loadFrom(&dl, pProfileRes, rc); } OdTvDatabaseId OdTvVisualizeInvFiler::loadFrom(OdStreamBuf* pBuffer, OdTvFilerTimeProfiling* pProfileRes, OdTvResult* rc) const { if (rc) *rc = tvNotSupported; return OdTvDatabaseId(); } OdTvDatabaseId OdTvVisualizeInvFiler::loadFrom(const OdString& filePath, OdTvFilerTimeProfiling* pProfileRes, OdTvResult* rc) const { OdTvVisualizeInvFilerSourceFromFile dl(filePath, pProfileRes, m_properties); return loadFrom(&dl, pProfileRes, rc); } OdTvDatabaseId OdTvVisualizeInvFiler::generate(OdTvFilerTimeProfiling* pProfileRes) const { return OdTvDatabaseId(); } OdTvModelId OdTvVisualizeInvFiler::appendFrom(const OdTvDatabaseId& databaseId, OdDbBaseDatabase *pDatabase, OdTvFilerTimeProfiling* pProfileRes, OdTvResult* rc) const { OdTvVisualizeInvFilerSourceFromDb dl(pDatabase); return appendFrom(databaseId, &dl, pProfileRes, rc); } OdTvModelId OdTvVisualizeInvFiler::appendFrom(const OdTvDatabaseId& databaseId, OdStreamBuf *pBuffer, OdTvFilerTimeProfiling* pProfileRes, OdTvResult* rc) const { if (rc) *rc = tvNotSupported; return OdTvModelId(); } OdTvModelId OdTvVisualizeInvFiler::appendFrom(const OdTvDatabaseId& databaseId, const OdString &filePath, OdTvFilerTimeProfiling* pProfileRes, OdTvResult* rc) const { OdTvVisualizeInvFilerSourceFromFile dl(filePath, pProfileRes, m_properties); return appendFrom(databaseId, &dl, pProfileRes, rc); } OdTvResult OdTvVisualizeInvFiler::startActionsWithNativeProperties(const OdString& sFilePath, bool bPartial) { OdTvResult rc = tvOk; return rc; } bool OdTvVisualizeInvFiler::isActionsWithNativePropertiesStarted(const OdString& sFilePath) { return false; } OdTvResult OdTvVisualizeInvFiler::endActionsWithNativeProperties() { return tvOk; } OdRxMemberIteratorPtr OdTvVisualizeInvFiler::getNativePropertiesIterator(OdUInt64 dbHandle, OdTvResult* rc) { OdRxMemberIteratorPtr pIter; return pIter; } OdRxValue OdTvVisualizeInvFiler::getNativePropertyValue(OdUInt64 dbHandle, const OdRxPropertyPtr& pProperty, bool* bReadOnly, OdTvResult* rc) { OdRxObjectPtr pElement; return pElement; } OdRxValueIteratorPtr OdTvVisualizeInvFiler::getNativeCollectionPropertyIterator(OdUInt64 dbHandle, const OdRxCollectionPropertyPtr& pCollectionProperty, bool* bReadOnly, OdTvResult* rc) { OdRxValueIteratorPtr pValIter; return pValIter; } OdTvResult OdTvVisualizeInvFiler::setNativePropertyValue(OdUInt64 dbHandle, OdRxPropertyPtr& pProperty, const OdRxValue& value) { OdRxObjectPtr pElement; return tvOk; } OdDbBaseDatabase* OdTvVisualizeInvFiler::getNativeDatabase(OdTvResult* rc) const { return NULL; } OdTvDatabaseId OdTvVisualizeInvFiler::loadFrom(OdTvVisualizeInvFilerDbSource* pInvDatabaseSource, 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 { OdInvDatabaseGiDrPtr pDb = pInvDatabaseSource->getDb(); // reading .ipt or .iam file here if (!pDb.isNull()) { timing.endTotal(); dbReadingTime = timing.getTotalTime() /*+ pInvDatabaseSource->getInitTime()*/; OdStaticRxObject services; pDb->m_pDb->setHostAppServices(&services); if (1) { 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 Inv modules (try to emulate the OdUninitialized for Inv) //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(0, 0, 255)); //For the each 'OdInvView' 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, pInvDatabaseSource->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; //run cycle over views in the view group unsigned int idDevice = 0; // Models counter unsigned int iModels = 0; OdInvViewPtr pCurView = pDb->getActiveView(); OdGsDeviceForInvModelPtr pCachedDevice; if (1) { if (1) { //get the background color from the model OdInvDrawingPtr pModel = pDb->getDrawing(); ODCOLORREF background = (ODCOLORREF)(ODRGB(255, 255, 255)); //create device OdGsDevicePtr pDevice = pGs->createDevice(); OdGiContextForInvDatabasePtr pInvContext = OdGiContextForInvDatabaseToPlotStyleSupport::createObject(); pInvContext->setDatabase(pDb); pInvContext->setView(pCurView); pInvContext->enableGsModel(true); pInvContext->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("NeedConvertDgnColorIndexes"))) //pProperties->putAt(OD_T("NeedConvertDgnColorIndexes"), 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 //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(191, 191, 191); // default in inventor pDevice->setLogicalPalette(pPalCpy.asArrayPtr(), 256); pDevice->setBackgroundColor(background); // setup the device and views OdGsDeviceForInvModelPtr pDeviceForInv = OdGsDeviceForInvModel::setupModelView(pModel.get(), pDevice, pInvContext); if (pCachedDevice.isNull()) { pCachedDevice = pDeviceForInv; } pDeviceForInv->activeView()->setMode(OdGsView::kGouraudShaded); //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 pDeviceForInv->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(); } //setup active view and the relation between views timing.startMisc(); if (tvDbId.isValid()) { // Set units to new models OdTvModelsIteratorPtr modelsIterPtr = tvDbId.openObject()->getModelsIterator(); unsigned int curModel = 0; while (!modelsIterPtr->done()) { OdTvModelPtr pTvModel = modelsIterPtr->getModel().openObject(OdTv::kForWrite); if (!pTvModel.isNull()) { curModel++; if (curModel > iModels) { //get units double addUnitCoefToMeters = 0.; } } modelsIterPtr->step(); } iModels = curModel; } timing.endMisc(); externalTiming += timing.getMiscTime(); idDevice++; } } moduleName = pGs->moduleName(); 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(); } //unload Inv modules (try to emulate the OdUninitialized for Inv) //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 OdTvVisualizeInvFiler::appendFrom(const OdTvDatabaseId& databaseId, OdTvVisualizeInvFilerDbSource *pDgnDatabaseSource, OdTvFilerTimeProfiling* pProfileRes, OdTvResult* rc) const { OdTvModelId tvModelId; return tvModelId; } OdTvGsDeviceId OdTvVisualizeInvFiler::getActiveTvDevice(OdTvDatabaseId& tvDbId, int idDevice) const { return OdTvGsDeviceId(); } OdTvGsViewId OdTvVisualizeInvFiler::getActiveTvView(OdTvGsDeviceId& tvDeviceId, int iActViewViewInd) const { return OdTvGsViewId(); } void OdTvVisualizeInvFiler::createCommonDataAccessTree(OdTvDatabasePtr pTvDb, OdDbBaseDatabase *pDatabase, const OdString& strTreeName) const { } //***************************************************************************// // 'OdTvVisualizeInvFilerModule' methods implementation //***************************************************************************// ODRX_DEFINE_DYNAMIC_MODULE(OdTvVisualizeInvFilerModule); void OdTvVisualizeInvFilerModule::initApp() { // initialize the Visualize odTvInitialize(); } void OdTvVisualizeInvFilerModule::uninitApp() { // Uninitialize the Visualize odTvUninitialize(); } OdTvVisualizeFilerPtr OdTvVisualizeInvFilerModule::getVisualizeFiler() const { OdTvVisualizeFilerPtr pAcisFiler = new OdTvVisualizeInvFiler(); return pAcisFiler; }