/////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2002-2019, 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-2019 by Open Design Alliance. // All rights reserved. // // By use of this software, its documentation or related materials, you // acknowledge and accept the above terms. /////////////////////////////////////////////////////////////////////////////// // // DgnDbModule.cpp // #include "OdaCommon.h" #include "DgnDbModuleImpl.h" #include "DgXmlPropSources.h" #include "DynamicLinker.h" #include "StaticRxObject.h" #include "DbUndoController.h" // fixed compiling error on mac #include "DgDatabase.h" #include "ExDgnServices.h" #include "DgGiContext.h" #include "DgGsManager.h" #include "DgSSet.h" //#include "DbUnitsFormatterImpl.h" #include "Ge/GePlane.h" #include "RxInit.h" #include "DgSysVarPEImpl.h" #include "ExAppServices.h" // for OdDgGsPath //#include "GsMarkerArray.h" #include "DgSubentId.h" #include "Gs/GsModel.h" #include "Gi/GiPathNode.h" #include "DbUserIO.h" #include "PropServices.h" #include "OdBinaryData.h" #include "DgSummaryInfo.h" #include "ExDgCommandContext.h" #include "DgUnitsFormatter.h" #include "DgGripPoints.h" #include "DgnImport.h" // Drawing/Imports/DgnImport #include "RxVariantValue.h" ////////////////////////////////////////////////////////////////////////// //class OdDgnServicesImpl : public OdExDgnSystemServices, public OdExDgnHostAppServices class OdDgnServicesImpl : public OdExDgnHostAppServices { protected: //ODRX_USING_HEAP_OPERATORS(OdExDgnSystemServices); ODRX_USING_HEAP_OPERATORS(OdExDgnHostAppServices); friend class OdDgnDbModuleImpl; OdSmartPtr m_pBaseHostAppServices; // ----- OdExDgnHostAppServices ----- virtual OdString findFile(const OdString& filename, OdDbBaseDatabase* pDb = 0, FindFileHint hint = kDefault) { if (!m_pBaseHostAppServices.isNull()) return m_pBaseHostAppServices->findFile(filename, pDb, hint); return OdExDgnHostAppServices::findFile(filename, pDb, hint); } virtual OdDbHostAppProgressMeter* newProgressMeter() { if (!m_pBaseHostAppServices.isNull()) return m_pBaseHostAppServices->newProgressMeter(); return OdExDgnHostAppServices::newProgressMeter(); } virtual void releaseProgressMeter(OdDbHostAppProgressMeter* pProgressMeter) { if (!m_pBaseHostAppServices.isNull()) { m_pBaseHostAppServices->releaseProgressMeter(pProgressMeter); return; } OdExDgnHostAppServices::releaseProgressMeter(pProgressMeter); } virtual const OdString program() { if (!m_pBaseHostAppServices.isNull()) return m_pBaseHostAppServices->program(); return OdExDgnHostAppServices::program(); } virtual const OdString product() { if (!m_pBaseHostAppServices.isNull()) return m_pBaseHostAppServices->product(); return OdExDgnHostAppServices::product(); } virtual const OdString companyName() { if (!m_pBaseHostAppServices.isNull()) return m_pBaseHostAppServices->companyName(); return OdExDgnHostAppServices::companyName(); } virtual ProdIdCode prodcode() { if (!m_pBaseHostAppServices.isNull()) return m_pBaseHostAppServices->prodcode(); return OdExDgnHostAppServices::prodcode(); } virtual const OdString releaseMajorMinorString() { if (!m_pBaseHostAppServices.isNull()) return m_pBaseHostAppServices->releaseMajorMinorString(); return OdExDgnHostAppServices::releaseMajorMinorString(); } virtual int releaseMajorVersion() { if (!m_pBaseHostAppServices.isNull()) return m_pBaseHostAppServices->releaseMajorVersion(); return OdExDgnHostAppServices::releaseMajorVersion(); } virtual int releaseMinorVersion() { if (!m_pBaseHostAppServices.isNull()) return m_pBaseHostAppServices->releaseMinorVersion(); return OdExDgnHostAppServices::releaseMinorVersion(); } virtual const OdString versionString() { if (!m_pBaseHostAppServices.isNull()) return m_pBaseHostAppServices->versionString(); return OdExDgnHostAppServices::versionString(); } TD_USING(OdExDgnHostAppServices::warning); virtual void warning(const char* warnVisGroup, const OdString& message) { if (!m_pBaseHostAppServices.isNull()) { m_pBaseHostAppServices->warning(warnVisGroup, message); return; } OdExDgnHostAppServices::warning(warnVisGroup, message); } virtual void warning(OdWarning warningOb) { if (!m_pBaseHostAppServices.isNull()) { m_pBaseHostAppServices->warning(warningOb); return; } OdExDgnHostAppServices::warning(warningOb); } virtual OdString getErrorDescription(unsigned int errorCode) { if (!m_pBaseHostAppServices.isNull()) return m_pBaseHostAppServices->getErrorDescription(errorCode); return OdExDgnHostAppServices::getErrorDescription(errorCode); } virtual OdString formatMessage(unsigned int errorCode, va_list* argList) { if (!m_pBaseHostAppServices.isNull()) return m_pBaseHostAppServices->formatMessage(errorCode, argList); return OdExDgnHostAppServices::formatMessage(errorCode, argList); } virtual OdDbUndoControllerPtr newUndoController() { if (!m_pBaseHostAppServices.isNull()) return m_pBaseHostAppServices->newUndoController(); return OdExDgnHostAppServices::newUndoController(); } virtual void auditPrintReport(OdAuditInfo * pAuditInfo, const OdString& strLine, int printDest) const { if (!m_pBaseHostAppServices.isNull()) { m_pBaseHostAppServices->auditPrintReport(pAuditInfo, strLine, printDest); return; } OdExDgnHostAppServices::auditPrintReport(pAuditInfo, strLine, printDest); } virtual bool ttfFileNameByDescriptor(const OdTtfDescriptor& description, OdString& filename) { if (!m_pBaseHostAppServices.isNull()) return m_pBaseHostAppServices->ttfFileNameByDescriptor(description, filename); return OdExDgnHostAppServices::ttfFileNameByDescriptor(description, filename); } virtual OdString getAlternateFontName() const { if (!m_pBaseHostAppServices.isNull()) return m_pBaseHostAppServices->getAlternateFontName(); return OdExDgnHostAppServices::getAlternateFontName(); } virtual OdString getFontMapFileName() const { if (!m_pBaseHostAppServices.isNull()) return m_pBaseHostAppServices->getFontMapFileName(); return OdExDgnHostAppServices::getFontMapFileName(); } virtual OdString getPreferableFont(const OdString& fontName, OdFontType fontType) { if (!m_pBaseHostAppServices.isNull()) return m_pBaseHostAppServices->getPreferableFont(fontName, fontType); return OdExDgnHostAppServices::getPreferableFont(fontName, fontType); } virtual OdString getSubstituteFont(const OdString& fontName, OdFontType fontType) { if (!m_pBaseHostAppServices.isNull()) return m_pBaseHostAppServices->getSubstituteFont(fontName, fontType); return OdExDgnHostAppServices::getSubstituteFont(fontName, fontType); } virtual OdString fileDialog(int flags, const OdString& dialogCaption = OdString::kEmpty, const OdString& defExt = OdString::kEmpty, const OdString& defFilename = OdString::kEmpty, const OdString& filter = OdString::kEmpty) { if (!m_pBaseHostAppServices.isNull()) return m_pBaseHostAppServices->fileDialog(flags, dialogCaption, defExt, defFilename, filter); return OdExDgnHostAppServices::fileDialog(flags, dialogCaption, defExt, defFilename, filter); } virtual OdGsDevicePtr gsBitmapDevice(OdRxObject* pViewObj = NULL, OdDbBaseDatabase* pDb = NULL, OdUInt32 flags = 0) { if (!m_pBaseHostAppServices.isNull()) return m_pBaseHostAppServices->gsBitmapDevice(pViewObj, pDb, flags); return OdExDgnHostAppServices::gsBitmapDevice(pViewObj, pDb, flags); } // ----- OdDgnServicesImpl ----- void restoreRegVariables() { ExAppServicesPtr pExAppServices = ExAppServices::cast(m_pBaseHostAppServices); if (pExAppServices.isNull()) return; OdString sBaseKey = OD_T("vars/tg/"); #define REGVAR_DEF(type, name, def_val, unused4, unused5) \ if (!pExAppServices->readRegistryValue(sBaseKey + OD_T(#name), \ toRbType(m_##name), &m_##name)) \ m_##name = def_val; #define REGVAR_DEF_ARRAY(type, name, unused3, unused4, unused5) \ { \ m_##name.clear(); \ for (int index = 0; true; index++) \ { \ OdString sName; \ sName.format(OD_T("%ls[%d]"), OD_T(#name), index); \ OdString sValue; \ if ( !pExAppServices->readRegistryValue(sBaseKey + sName, \ kRtString, &sValue) \ || sValue.isEmpty()) \ break; \ m_##name.push_back(sValue); \ } \ } #include "DgRegVarDefs.h" #undef REGVAR_DEF #undef REGVAR_DEF_ARRAY } void saveRegVariables() { ExAppServicesPtr pExAppServices = ExAppServices::cast(m_pBaseHostAppServices); if (pExAppServices.isNull()) return; OdString sBaseKey = OD_T("vars/tg/"); #define REGVAR_DEF(type, name, def_val, unused4, unused5) \ pExAppServices->writeRegistryValue(sBaseKey + OD_T(#name), \ toRbType(m_##name), &m_##name); #define REGVAR_DEF_ARRAY(type, name, unused3, unused4, unused5) \ { \ int num = m_##name.size(); \ for (int index = 0; index <= num; index++) \ { \ OdString sName; \ sName.format(OD_T("%ls[%d]"), OD_T(#name), index); \ if (index >= num) \ { \ pExAppServices->writeRegistryValue(sBaseKey + sName, \ kRtString, &OdString::kEmpty); \ continue; \ } \ pExAppServices->writeRegistryValue(sBaseKey + sName, \ toRbType(m_##name.getAt(index)), &m_##name.getAt(index)); \ } \ } #include "DgRegVarDefs.h" #undef REGVAR_DEF #undef REGVAR_DEF_ARRAY } OdStringArray resetRegVariables() // set to default values { OdStringArray vars; #define REGVAR_DEF(type, name, def_val, unused4, unused5) \ if (m_##name != def_val) \ { \ m_##name = def_val; \ vars.push_back(OD_T(#name)); \ } // are empty by default #define REGVAR_DEF_ARRAY(type, name, unused3, unused4, unused5) \ if (m_##name.size()) \ { \ m_##name.clear(); \ vars.push_back(OD_T(#name)); \ } #include "DgRegVarDefs.h" #undef REGVAR_DEF #undef REGVAR_DEF_ARRAY return vars; } }; ////////////////////////////////////////////////////////////////////////// static OdDgnServicesImpl* appDgnServicesImpl() { static OdStaticRxObject g_services; return &g_services; } OdExDgnHostAppServices* appDgnServices() { return appDgnServicesImpl(); } ////////////////////////////////////////////////////////////////////////// class OdDgnDbModuleImpl : public OdExtDbModuleBaseImpl { public: OdDgnDbModuleImpl(); virtual ~OdDgnDbModuleImpl(); // OdRxModule overridden virtual void initApp(); virtual void uninitApp(); // init issues virtual void setBaseHostAppServices(OdDbBaseHostAppServices* pServices); virtual void initOdExtPE(); virtual void uninitOdExtPE(); virtual OdStringArray resetRegVariables(); // set to default values virtual bool getPreviewBitmap(const OdString& fileName, OdBinaryData& dataBmp); // out // load / save issues virtual OdRxObjectPtr readFile(const OdString& fileName, Oda::FileShareMode shareMode = Oda::kShareDenyWrite); virtual OdRxObjectPtr createUninitializedDatabase(); virtual bool loadToUninitializedDatabase(OdRxObjectPtr pRxDb, const OdString& fileName, Oda::FileShareMode shareMode = Oda::kShareDenyWrite); virtual bool writeFile(const OdString& fileName, OdEdCommandContext* ctx); // Cloud command command context issues virtual OdEdBaseIO* baseIO(OdEdCommandContext* ctx); virtual OdEdCommandContextPtr cloneCommandContext(OdEdCommandContext* ctx, OdEdBaseIO* pIOStream = NULL, OdRxObject* pRxDatabase = NULL); // render issues virtual bool getVisibleLayoutViewIds(OdRxObject* pRxDatabase, OdDbStub*& idActiveLayoutView, // out OdDbStubPtrArray& idsLayoutViews, OdGsDCRectArray& rects); virtual bool getLayoutViewNamesAndIds(OdRxObject* pRxDatabase, OdStringArray& namesLayoutView, OdDbStubPtrArray& idsLayoutView, OdString* pActiveLayoutViewName = NULL, bool bOneForModel = true, OdGsDCRectArray* pRects = NULL); virtual OdGsDevicePtr createDevice(OdGsModulePtr pGs, OdRxObjectPtr pRxDatabase); virtual OdGsDevicePtr createBitmapDevice(OdGsModulePtr pGs, OdRxObjectPtr pRxDatabase); virtual OdGsDevicePtr takeUnderlyingDeviceAndViewports(OdGsDevicePtr pGsDevice, OdArray& viewportsToDeleteAfterUpdate); // out virtual void enableGsModel(class OdGiDefaultContext* pCtx, bool bGsCache); virtual bool getModelBackground(OdRxObject* pRxDatabase, ODCOLORREF& clrBackground, ODGSPALETTE* pPalette = NULL); virtual bool setModelBackground(OdRxObject* pRxDatabase, ODCOLORREF clrBackground); // get point, zoom etc issues virtual OdGsView* getActiveGsView(OdGsDevice* pGsDevice); virtual OdGsModel* getGsModel(OdGsDevice* pGsDevice); virtual OdUnitsFormatter* getFormatter(OdRxObject* pRxDatabase); virtual bool isPerspective(OdRxObject* pRxDatabase, OdGsDevice* pGsDevice = NULL); virtual bool setPerspective(OdRxObject* pRxDatabase, bool bVal); // selection issues virtual OdSelectionSetPtr createSelectionSet(OdRxObject* pRxDatabase); virtual OdSelectionSetPtr select(OdGsView* gsView, int nPoints, const OdGePoint3d* wcsPts, OdDbVisualSelection::Mode mode = OdDbVisualSelection::kCrossing, OdDbVisualSelection::SubentSelectionMode sm = OdDbVisualSelection::kDisableSubents, const OdRxObject* pFilter = NULL); virtual void getVisibleAllIds(OdRxObject* pRxDatabase, OdDbStubPtrArray& ids); virtual OdDbStub* getVisibleLastId(OdRxObject* pRxDatabase); virtual void highlight(OdGsView* gsView, bool bValue, OdDbStub* id, const OdDbBaseFullSubentPath* pPath); // virtual OdGiDrawablePtr cloneEntity(OdDbStub* id); virtual OdRxObjectPtr openObject(OdDbStub* id, bool isForWriteMode = false); virtual OdResult getGripPoints(OdRxObject* pRxDb, OdGiDrawable* pEntity, OdDbGripDataPtrArray& grips, double curViewUnitSize, int gripSize, const OdGeVector3d& curViewDir, int bitFlags); virtual OdResult getGripPoints(OdRxObject* pRxDb, OdGiDrawable* pEntity, OdGePoint3dArray& gripPoints); virtual OdResult moveGripPointsAt(OdRxObject* pRxDb, OdGiDrawable* pEntity, const OdDbVoidPtrArray& gripAppData, const OdGeVector3d& offset, int bitFlags); virtual OdResult moveGripPointsAt(OdRxObject* pRxDb, OdGiDrawable* pEntity, const OdIntArray& indices, const OdGeVector3d& offset); // virtual bool isErased(OdDbStub* id); virtual OdDbHandle getElementHandle(OdDbStub* id); virtual OdString getElementClassName(OdDbStub* id); // undo/redo issues virtual bool startUndoRecord(OdRxObject* pRxDb); virtual bool blockUndoRecording(OdRxObject* pRxDb, bool bBegin); virtual bool isUndoBlockStarted(OdRxObject* pRxDb); virtual bool hasUndo(OdRxObject* pRxDb); virtual void undo(OdRxObject* pRxDb); virtual bool hasRedo(OdRxObject* pRxDb); virtual void redo(OdRxObject* pRxDb); // command issues virtual bool cmdErase(OdEdCommandContext* pCmdCtx); // filters issues virtual bool isResponsible(OdRxObject* pRxDatabase); virtual OdStringArray getExtensions(enum OdEd::GetFilePathFlags flg = OdEd::kGfpForOpen, OdRxObject* pRxDatabase = NULL, bool bWithExtSynonyms = false); virtual OdString getFilterByExtension(const OdString& sExt, int index = 0, enum OdEd::GetFilePathFlags flg = OdEd::kGfpForOpen, OdStringArray* pExtSynonyms = NULL); // import / export issues virtual OdStringArray getImportExportExtensions(OdRxObject* pRxDatabase, bool isForImport = true, bool bWithExtSynonyms = false); // TODO virtual OdString getImportExportFilterByExtension(const OdString& sExt, int index = 0, // TODO for such formats as DXF (it may be binary or ascii) bool isForImport = true, OdStringArray* pExtSynonyms = NULL); // TODO virtual bool importFromFile(OdRxObject* pRxDatabase, const OdString& fileName, ODCOLORREF& clrBackground); /////// Commands /////// #define ODRX_CMD_ENTRY(cmdName, name, impl) OdStaticRxObject m_cmd##name; #include "DgnDbCommands.h" private: OdRxModulePtr m_pDbModule; //OdStaticRxObject m_formatter; }; ODRX_DEFINE_DYNAMIC_MODULE(OdDgnDbModuleImpl); OdDgnDbModuleImpl::OdDgnDbModuleImpl() { #define ODRX_CMD_ENTRY(cmdName, name, impl) m_cmd##name.m_pModule = this; #include "DgnDbCommands.h" } OdDgnDbModuleImpl::~OdDgnDbModuleImpl() { } void OdDgnDbModuleImpl::initApp() { m_pDbModule = odrxDynamicLinker()->loadApp(OdDgnDbModuleName); // Implementation of OdDgGripPointsPE is an empty now. // But ExDgnGripPoints.tx module (in DGN examples) is required grip point functionality odrxDynamicLinker()->loadModule(ExDgnGripPointsModuleName); // ...::rxInit(); // register commands OdEdCommandStackPtr pCommands = odedRegCmds(); #define ODRX_CMD_ENTRY(cmdName, name, impl) pCommands->addCommand(&m_cmd##name); #include "DgnDbCommands.h" } void OdDgnDbModuleImpl::uninitApp() { // unregister commands OdEdCommandStackPtr pCommands = odedRegCmds(); #define ODRX_CMD_ENTRY(cmdName, name, impl) pCommands->removeCmd(&m_cmd##name); #include "DgnDbCommands.h" // ...::rxUninit(); m_pDbModule = NULL; } // init issues void OdDgnDbModuleImpl::setBaseHostAppServices(OdDbBaseHostAppServices* pServices) { appDgnServicesImpl()->m_pBaseHostAppServices = pServices; } void OdDgnDbModuleImpl::initOdExtPE() { ::initOdDgSysVarPE(); appDgnServicesImpl()->restoreRegVariables(); OdPropServicesPtr pPropServices = ::odrxSysRegistry()->getAt(OD_PROP_SERVICES).get(); if (pPropServices.get()) registerOdDgXmlPropSources(pPropServices); } void OdDgnDbModuleImpl::uninitOdExtPE() { OdPropServicesPtr pPropServices = ::odrxSysRegistry()->getAt(OD_PROP_SERVICES).get(); if (pPropServices.get()) unregisterOdDgXmlPropSources(pPropServices); appDgnServicesImpl()->saveRegVariables(); ::uninitOdDgSysVarPE(); } OdStringArray OdDgnDbModuleImpl::resetRegVariables() // set to default values { return appDgnServicesImpl()->resetRegVariables(); } bool OdDgnDbModuleImpl::getPreviewBitmap(const OdString& fileName, OdBinaryData& dataBmp) // out { OdDgSummaryInformationPtr pSi = oddgGetSummaryInformation(fileName); if (pSi.isNull()) return false; pSi->getThumbnailBitmap(dataBmp); return dataBmp.size() != 0; } OdRxObjectPtr OdDgnDbModuleImpl::readFile(const OdString& fileName, Oda::FileShareMode shareMode) // = Oda::kShareDenyWrite { OdDgDatabasePtr pDgnDb = appDgnServicesImpl()->readFile(fileName, shareMode); return OdRxObject::cast(pDgnDb); } OdRxObjectPtr OdDgnDbModuleImpl::createUninitializedDatabase() { OdDgDatabasePtr pDgnDb = appDgnServicesImpl()->createDatabase(OdDgHostAppServices::kDbNotInitialized); return OdRxObject::cast(pDgnDb); } bool OdDgnDbModuleImpl::loadToUninitializedDatabase(OdRxObjectPtr pRxDb, const OdString& fileName, Oda::FileShareMode shareMode) // = Oda::kShareDenyWrite { OdDgDatabasePtr pDgnDb = OdDgDatabase::cast(pRxDb.get()); ODA_ASSERT_ONCE(pDgnDb.get()); if (pDgnDb.isNull()) return false; pDgnDb->readFile(fileName, shareMode); return true; } bool OdDgnDbModuleImpl::writeFile(const OdString& fileName, OdEdCommandContext* ctx) { ODA_ASSERT_ONCE(ctx); OdDgDatabasePtr pDgnDb = OdDgDatabase::cast(ctx->baseDatabase()); if (pDgnDb.isNull()) return false; pDgnDb->writeFile(fileName); return true; } // Cloud command command context issues // possible TODO move reset, baseIO & cloneObject into OdEdCommandContext class OdExDgnCmdContext : public ExDgCommandContext { protected: OdEdCommandContext* m_pOwner; // of clone OdExDgnCmdContext() : m_pOwner(NULL) { } public: //~OdExDgnCmdContext() //{ // if(m_pDb) // m_pDb->release(); //} static OdEdCommandContextPtr createObject(OdEdBaseIO* pIOStream, OdRxObject* pRxDb = NULL, OdEdCommandContext* pOwner = NULL) { OdEdCommandContextPtr pRes = OdRxObjectImpl::createObject(); OdExDgnCmdContext* pCmdCtx = static_cast(pRes.get()); pCmdCtx->m_pDb = OdDgDatabase::cast(pRxDb).get(); pCmdCtx->m_pIoStream = pIOStream; pCmdCtx->m_pOwner = pOwner; //m_pDb->addRef(); return pRes; } //void reset(OdEdBaseIO* pIOStream, OdRxObject* pRxDb) //{ // m_pIoStream = pIOStream; // m_pDb = OdDgDatabase::cast(pRxDb).get(); //} OdEdBaseIO* baseIO() { return m_pIoStream.get(); } virtual OdEdCommandContextPtr cloneObject(OdEdBaseIO* pIOStream = NULL, OdRxObject* pRxDb = NULL) { OdEdCommandContextPtr pRes = OdRxObjectImpl::createObject(); //OdExDgnCmdContext* pCmdCtx = static_cast(pRes.get()); return createObject(pIOStream ? pIOStream : m_pIoStream.get(), pRxDb ? pRxDb : m_pDb, this); } }; OdEdBaseIO* OdDgnDbModuleImpl::baseIO(OdEdCommandContext* pCtx) { if (!pCtx || OdDgDatabase::cast(pCtx->baseDatabase()).isNull()) return NULL; OdExDgnCmdContext* pCmdCtx = static_cast(pCtx); return pCmdCtx->baseIO(); } OdEdCommandContextPtr OdDgnDbModuleImpl::cloneCommandContext(OdEdCommandContext* pCtx, OdEdBaseIO* pIOStream, // = NULL OdRxObject* pRxDb) // = NULL { OdDgDatabasePtr pDgnDb = OdDgDatabase::cast(pRxDb); ODA_ASSERT_ONCE(pDgnDb.get()); if (pDgnDb.isNull()) return OdEdCommandContextPtr(); ODA_ASSERT_ONCE(pCtx); // to check with deb next if (!pCtx || OdDgDatabase::cast(pCtx->baseDatabase()).isNull()) return OdExDgnCmdContext::createObject(pIOStream, pRxDb, pCtx); OdExDgnCmdContext* pCmdCtx = static_cast(pCtx); return pCmdCtx->cloneObject(pIOStream, pRxDb); } // bool OdDgnDbModuleImpl::getVisibleLayoutViewIds(OdRxObject* pRxDatabase, OdDbStub*& idActiveLayoutView, // out OdDbStubPtrArray& idsLayoutViews, OdGsDCRectArray& rects) { idActiveLayoutView = NULL; idsLayoutViews.clear(); rects.clear(); OdDgDatabasePtr pDgnDb = OdDgDatabase::cast(pRxDatabase); if (pDgnDb.isNull()) return false; OdDgElementId idModel = pDgnDb->getActiveModelId(); if (idModel.isNull()) { // MKU 24\11\2010 #8852 (case: /dgn/V7_V8legacy/Regression/out/ExLoadToModel_dll/Building/Dgn/BSI300AE9-Atrium.dgn // If Model is invalid let's try to get & use a Default. idModel = pDgnDb->getDefaultModelId(); pDgnDb->setActiveModelId(idModel); ODA_ASSERT_ONCE(!idModel.isNull()); if (idModel.isNull()) return false; } #ifdef _DEBUG OdString sLayoutName = OdDgModelPtr(idModel.openObject())->getName(); #endif OdDgViewGroupTablePtr pVgTable = pDgnDb->getViewGroupTable(); ODA_ASSERT_ONCE(!pVgTable.isNull()); if (pVgTable.isNull()) return false; for (OdDgElementIteratorPtr pVgIter = pVgTable->createIterator(); !pVgIter->done(); pVgIter->step()) { OdDgViewGroupPtr pViewGroup = pVgIter->item().openObject(); if (pViewGroup.isNull() || pViewGroup->getModelId() != idModel) continue; int index = 0; for (OdDgElementIteratorPtr pItr = pViewGroup->createIterator(); !pItr->done(); pItr->step()) { OdDgElementId idElem = pItr->item(); ODA_ASSERT_ONCE(!idElem.isNull()); if (idActiveLayoutView == idElem) continue; OdDgViewPtr pView = OdDgView::cast(idElem.openObject()); if (!pView.get() || !pView->getVisibleFlag()) continue; if (!index++) idActiveLayoutView = idElem; // current DGN solution for active (the last) idsLayoutViews.push_back(idElem); rects.push_back(pView->getViewRectangle()); } } ODA_ASSERT_ONCE(idActiveLayoutView); if (!idActiveLayoutView) return false; idsLayoutViews.reverse(); rects.reverse(); return true; } bool OdDgnDbModuleImpl::getLayoutViewNamesAndIds(OdRxObject* pRxDatabase, OdStringArray& namesLayoutView, OdDbStubPtrArray& idsLayoutView, OdString* pActiveLayoutViewName, // = NULL bool bOneForModel, // = true (only in focus) OdGsDCRectArray* pRects) // = NULL { idsLayoutView.clear(); namesLayoutView.clear(); if (pActiveLayoutViewName) pActiveLayoutViewName->empty(); if (pRects) pRects->clear(); OdDgDatabasePtr pDgnDb = OdDgDatabase::cast(pRxDatabase); if (pDgnDb.isNull()) return false; OdDgElementId idVectorizedModel = pDgnDb->getActiveModelId(); if (idVectorizedModel.isNull()) { // MKU 24\11\2010 #8852 (case: /dgn/V7_V8legacy/Regression/out/ExLoadToModel_dll/Building/Dgn/BSI300AE9-Atrium.dgn // If Model is invalid let's try to get & use a Default. idVectorizedModel = pDgnDb->getDefaultModelId(); pDgnDb->setActiveModelId(idVectorizedModel); } OdDgModelTablePtr pModelTable = pDgnDb->getModelTable(); OdDgViewGroupTablePtr pVgTable = pDgnDb->getViewGroupTable(); ODA_ASSERT_ONCE(!pModelTable.isNull() && !pVgTable.isNull()); if (pModelTable.isNull() || pVgTable.isNull()) return false; for (OdDgElementIteratorPtr pModelIter = pModelTable->createIterator(); !pModelIter->done(); pModelIter->step()) { OdDgElementId idModel = pModelIter->item(); ODA_ASSERT_ONCE(!idModel.isNull()) if (idModel.isNull()) continue; OdDgModelPtr pModel = idModel.openObject(); OdString sLayoutName = pModel->getName(); // if bOneForModel is true for (OdDgElementIteratorPtr pVgIter = pVgTable->createIterator(); !pVgIter->done(); pVgIter->step()) { OdDgViewGroupPtr pViewGroup = pVgIter->item().openObject(); if (pViewGroup.isNull() || pViewGroup->getModelId() != idModel) continue; bool isActive = (idModel == idVectorizedModel); // = (pViewGroup == pActiveViewGroup); OdDgElementId idViewInFocus; int index = 0; for (OdDgElementIteratorPtr pViewIter = pViewGroup->createIterator(); !pViewIter->done(); pViewIter->step()) { OdDgElementId idView = pViewIter->item(); ODA_ASSERT_ONCE(!idView.isNull()); OdDgViewPtr pView = idView.openObject(); if (pView.isNull() || !pView->getVisibleFlag()) continue; if (!index++) // current DGN solution for view in focus(active) is the first { ODA_ASSERT_ONCE(idModel == pView->getModelId()); ODA_ASSERT_ONCE(bOneForModel); // TODO like namesLayoutView.push_back(OdString().format(L"%ls:%d", sLayoutName.c_str(), ++index)); ... idViewInFocus = idView; } // } ODA_ASSERT_ONCE(!idViewInFocus.isNull()); if (idViewInFocus.isNull()) continue; namesLayoutView.push_back(sLayoutName); idsLayoutView.push_back(idViewInFocus); if (isActive && pActiveLayoutViewName) *pActiveLayoutViewName = sLayoutName; } } //idsLayoutViewIds.reverse(); //namesLayoutView.reverse(); //if (pRects) // pRects->reverse(); if (pActiveLayoutViewName && pActiveLayoutViewName->isEmpty()) { ODA_FAIL_ONCE(); return false; } return true; } OdGsDevicePtr OdDgnDbModuleImpl::createDevice(OdGsModulePtr pGs, OdRxObjectPtr pRxDatabase) { OdGsDevicePtr pGsDevice; if (pGs.isNull() || pRxDatabase.isNull()) { ODA_FAIL_ONCE(); return pGsDevice; } OdDgDatabasePtr pDgnDb = OdDgDatabase::cast(pRxDatabase); if (pDgnDb.isNull()) // valid way to prevent linking with DGN return pGsDevice; pGsDevice = pGs->createDevice(); // the next will be done via OdqView::resetDevice() // Prepare database context for device //OdGiContextForDgDatabasePtr pDgnContext = OdGiContextForDgDatabase::createObject(); //pDgnContext->setDatabase(pDgnDb); // Prepare the device to render the active layout in this database. //OdDbBaseDatabasePEPtr pDbPE = OdDbBaseDatabasePE::cast(pRxDatabase); //ODA_ASSERT_ONCE(!pDbPE.isNull()); //pGsDevice = pDbPE->setupActiveLayoutViews(pGsDevice, pDgnContext); // TODO //pDgnDb->getActiveViewGroupId() ... pDgnDb->recommendActiveViewGroupId() return pGsDevice; } OdGsDevicePtr OdDgnDbModuleImpl::takeUnderlyingDeviceAndViewports(OdGsDevicePtr pGsDevice, OdArray& viewportsToDeleteAfterUpdate) // out { OdGsDeviceForDgModelPtr pLayoutHelperPrev = OdGsDeviceForDgModel::cast(pGsDevice); ODA_ASSERT_ONCE(pLayoutHelperPrev.get() && !viewportsToDeleteAfterUpdate.size()); if (pLayoutHelperPrev.isNull()) return OdGsDevicePtr(); OdGsDevicePtr pUnderlying = pLayoutHelperPrev->underlyingDevice(); ODA_ASSERT_ONCE(pUnderlying.get()) int numViewportsToDelete = pLayoutHelperPrev->numViews(); if (numViewportsToDelete && pUnderlying.get()) { for (int idx = 0; idx < numViewportsToDelete; idx++) { OdGsViewPtr pView = pLayoutHelperPrev->viewAt(idx); ODA_ASSERT_ONCE(pView.get()); viewportsToDeleteAfterUpdate.push_back(pView); // store to delete after update } } pLayoutHelperPrev->eraseAllViews(); return pUnderlying; } OdGsDevicePtr OdDgnDbModuleImpl::createBitmapDevice(OdGsModulePtr pGs, OdRxObjectPtr pRxDatabase) { OdGsDevicePtr pGsDevice; if (pGs.isNull() || pRxDatabase.isNull()) { ODA_FAIL_ONCE(); return pGsDevice; } OdDgDatabasePtr pDgnDb = OdDgDatabase::cast(pRxDatabase); if (pDgnDb.isNull()) // valid way to prevent linking with DGN return pGsDevice; pGsDevice = pGs->createBitmapDevice(); return pGsDevice; } void OdDgnDbModuleImpl::enableGsModel(OdGiDefaultContext* pCtx, bool bGsCache) { ODA_ASSERT_ONCE(pCtx); if (!pCtx) return; OdGiContextForDgDatabasePtr pDgCtx = OdGiContextForDgDatabase::cast(pCtx); if (pDgCtx.isNull()) return; pDgCtx->enableGsModel(bGsCache); } bool OdDgnDbModuleImpl::getModelBackground(OdRxObject* pRxDatabase, ODCOLORREF& clrBackground, ODGSPALETTE* pPalette) // = NULL { OdDgDatabasePtr pDgnDb = OdDgDatabase::cast(pRxDatabase); if (pDgnDb.isNull()) return false; OdDgModelPtr pModel = pDgnDb->getActiveModelId().safeOpenObject(); clrBackground = pModel->getBackground(); if (pPalette) { ODGSPALETTE& palette = *pPalette; ODA_ASSERT_ONCE(!palette.size()); const ODCOLORREF* refColors = OdDgColorTable::currentPalette(pDgnDb); palette.insert(palette.begin(), refColors, refColors + 256); // Color with #255 always defines background. // The background of the active model must be considered in the device palette. palette[255] = clrBackground; // Note: This method should be called to resolve "white background issue" before setting device palette OdDgColorTable::correctPaletteForWhiteBackground(palette.asArrayPtr()); } return true; } bool OdDgnDbModuleImpl::setModelBackground(OdRxObject* pRxDatabase, ODCOLORREF clrBackground) { OdDgDatabasePtr pDgnDb = OdDgDatabase::cast(pRxDatabase); if (pDgnDb.isNull()) return false; OdDgModelPtr pModel = pDgnDb->getActiveModelId().safeOpenObject(OdDg::kForWrite); if (clrBackground == pModel->getBackground()) return true; pModel->setUseBackgroundColorFlag(true); pModel->setBackground(clrBackground); return true; } OdGsView* OdDgnDbModuleImpl::getActiveGsView(OdGsDevice* pGsDevice) { OdGsDeviceForDgModelPtr pLayoutHelper = OdGsDeviceForDgModel::cast(pGsDevice); ODA_ASSERT_ONCE(!pLayoutHelper.isNull()); if (pLayoutHelper.isNull()) return NULL; OdGsView* pGsView = pLayoutHelper->activeView(); ODA_ASSERT_ONCE(pGsView); return pGsView; } OdGsModel* OdDgnDbModuleImpl::getGsModel(OdGsDevice* pGsDevice) { OdGsDeviceForDgModelPtr pLayoutHelper = OdGsDeviceForDgModel::cast(pGsDevice); ODA_ASSERT_ONCE(!pLayoutHelper.isNull()); OdGsModel* pGsModel = pLayoutHelper->gsModel(); // it is NULL if GS cache off //ODA_ASSERT_ONCE(pGsModel); return pGsModel; } OdUnitsFormatter* OdDgnDbModuleImpl::getFormatter(OdRxObject* pRxDatabase) { OdDgDatabasePtr pDgnDb = OdDgDatabase::cast(pRxDatabase); if (pDgnDb.isNull()) return NULL; return &pDgnDb->formatter(); // return &m_formatter; // TODO special for each model in view (via active model) } static OdDgElementId getActiveViewId(OdDgDatabase* pDgnDb) { ODA_ASSERT_ONCE(pDgnDb); OdDgElementId idActiveView; OdDgElementId idModel = pDgnDb->getActiveModelId(); if (idModel.isNull()) idModel = pDgnDb->getDefaultModelId(); if (idModel.isNull()) return idActiveView; OdDgViewGroupTablePtr pVgTable = pDgnDb->getViewGroupTable(); ODA_ASSERT_ONCE(!pVgTable.isNull()); if (pVgTable.isNull()) return idActiveView; OdDgViewGroupPtr pActiveViewGroup; OdDgElementId idViewGroup = pDgnDb->getActiveViewGroupId(); if (!idViewGroup.isNull()) { pActiveViewGroup = idViewGroup.openObject(); ODA_ASSERT_ONCE(pActiveViewGroup->getModelId() == idModel); if (pActiveViewGroup->getModelId() != idModel) pActiveViewGroup = NULL; } if (pActiveViewGroup.isNull()) { for (OdDgElementIteratorPtr pVgIter = pVgTable->createIterator(); !pVgIter->done(); pVgIter->step()) { OdDgViewGroupPtr pViewGroup = pVgIter->item().openObject(); if (pViewGroup.isNull() || pViewGroup->getModelId() != idModel) continue; pActiveViewGroup = pViewGroup; break; } } if (pActiveViewGroup.isNull()) return idActiveView; OdDgElementIteratorPtr pViewIter = pActiveViewGroup->createIterator(); for (; !pViewIter->done(); pViewIter->step()) { idActiveView = pViewIter->item(); OdDgViewPtr pView = OdDgView::cast(idActiveView.openObject()); if (pView.isNull() || !pView->getVisibleFlag()) continue; break; // first visible } return idActiveView; } bool OdDgnDbModuleImpl::isPerspective(OdRxObject* pRxDatabase, OdGsDevice* pGsDevice) // = NULL { OdDgDatabasePtr pDgnDb = OdDgDatabase::cast(pRxDatabase); if (pDgnDb.get()) { OdDgElementId idView = getActiveViewId(pDgnDb); OdDgViewPtr pView = OdDgView::cast(idView.openObject()); if (pView.get()) return pView->getUseCameraFlag(); return false; } return OdExtDbModuleBaseImpl::isPerspective(pRxDatabase, pGsDevice); } bool OdDgnDbModuleImpl::setPerspective(OdRxObject* pRxDatabase, bool bVal) { OdDgDatabasePtr pDgnDb = OdDgDatabase::cast(pRxDatabase); if (pDgnDb.get()) { OdDgElementId idView = getActiveViewId(pDgnDb); OdDgViewPtr pView = OdDgView::cast(idView.openObject(OdDg::kForWrite)); if (pView.get() && pView->getUseCameraFlag() != bVal) { OdAbstractViewPEPtr pVp = OdAbstractViewPE::cast(pView); pVp->setView(pView, pVp->target(pView), pVp->direction(pView), pVp->upVector(pView), pVp->fieldWidth(pView), pVp->fieldHeight(pView), bVal); pView->setUseCameraFlag(bVal); return true; } return false; } return OdExtDbModuleBaseImpl::setPerspective(pRxDatabase, bVal); } // selection issues OdSelectionSetPtr OdDgnDbModuleImpl::createSelectionSet(OdRxObject* pRxDatabase) { OdDgDatabasePtr pDgnDb = OdDgDatabase::cast(pRxDatabase); if (pDgnDb.isNull()) return OdSelectionSetPtr(); return OdDgSelectionSet::createObject(pDgnDb); } OdSelectionSetPtr OdDgnDbModuleImpl::select(OdGsView* gsView, int nPoints, const OdGePoint3d* wcsPts, OdDbVisualSelection::Mode mode, // = OdDbVisualSelection::kCrossing OdDbVisualSelection::SubentSelectionMode sm, // = OdDbVisualSelection::kDisableSubents const OdRxObject* pFilter) // = NULL { if (!gsView || !gsView->userGiContext()) { ODA_FAIL_ONCE(); // test return OdSelectionSetPtr(); } OdDgDatabasePtr pDgnDb = OdDgDatabase::cast(gsView->userGiContext()->database()); if (pDgnDb.isNull()) return OdSelectionSetPtr(); return OdDgSelectionSet::select(pDgnDb, gsView, nPoints, wcsPts, mode, sm, pFilter); } static bool isElementLocked(OdDgElementPtr pElem) { if (pElem.isNull()) return false; if (pElem->getLockedFlag()) return true; OdDgGraphicsElementPtr pItem = OdDgGraphicsElement::cast(pElem); if (pItem.isNull()) return false; if (!pItem->getLevelId().isNull()) { OdDgLevelTableRecordPtr pLevel = pItem->getLevelId().safeOpenObject(); if (pLevel->getIsFrozenFlag() || pLevel->getIsReadOnlyFlag()) return true; } OdDgElementIteratorPtr pItr; { OdDgCellHeader2dPtr pHeader2d = OdDgCellHeader2d::cast(pItem); OdDgCellHeader3dPtr pHeader3d = OdDgCellHeader3d::cast(pItem); if (!pHeader2d.isNull()) pItr = pHeader2d->createIterator(); if (pItr.isNull() && !(pHeader3d = OdDgCellHeader3d::cast(pItem)).isNull()) pItr = pHeader3d->createIterator(); } if (pItr.isNull()) return false; for (; !pItr->done(); pItr->step()) { pElem = OdDgElement::cast(pItr->item().safeOpenObject()); if (pElem.isNull() || !isElementLocked(pElem)) continue; return true; } return false; } void OdDgnDbModuleImpl::getVisibleAllIds(OdRxObject* pRxDatabase, OdDbStubPtrArray& ids) { OdDgDatabasePtr pDgnDb = OdDgDatabase::cast(pRxDatabase); if (pDgnDb.isNull()) return; OdDgModelPtr pModel = OdDgModel::cast(pDgnDb->getActiveModelId().openObject()); ODA_ASSERT_ONCE(!pModel.isNull()); if (pModel.isNull()) return; int idx = 0; for (OdDgElementIteratorPtr pItr = pModel->createGraphicsElementsIterator(); idx < 2; pItr = pModel->createControlElementsIterator(), idx++) { for (; !pItr->done(); pItr->step()) { OdDgElementId idElem = pItr->item(); ODA_ASSERT_ONCE(!idElem.isNull()); if (idElem.isNull()) continue; OdDgElementPtr pElem = OdDgElement::cast(idElem.openObject()); ODA_ASSERT_ONCE(!pElem.isNull()); if (pElem.isNull() || isElementLocked(pElem)) continue; if (!pElem->gsNode()) // Cache continue; ids.push_back(idElem); } } } OdDbStub* OdDgnDbModuleImpl::getVisibleLastId(OdRxObject* pRxDatabase) { OdDgDatabasePtr pDgnDb = OdDgDatabase::cast(pRxDatabase); if (pDgnDb.isNull()) return NULL; OdDgModelPtr pModel = OdDgModel::cast(pDgnDb->getActiveModelId().openObject()); ODA_ASSERT_ONCE(!pModel.isNull()); if (pModel.isNull()) return NULL; int idx = 0; for (OdDgElementIteratorPtr pItr = pModel->createGraphicsElementsIterator(false); idx < 2; pItr = pModel->createControlElementsIterator(false), idx++) { for (; !pItr->done(); pItr->step()) { OdDgElementId idElem = pItr->item(); ODA_ASSERT_ONCE(!idElem.isNull()); if (idElem.isNull()) continue; OdDgElementPtr pElem = OdDgElement::cast(idElem.openObject()); ODA_ASSERT_ONCE(!pElem.isNull()); if (pElem.isNull() || isElementLocked(pElem)) continue; if (!pElem->gsNode()) // Cache continue; return idElem; } } return NULL; } class OdDgGsPath { struct Node : OdGiPathNode { const Node* m_pParent; OdDbStub* m_pId; OdGiDrawablePtr m_pDrawable; OdGsMarker m_gsMarker; const OdGiPathNode* parent() const { return m_pParent; } OdDbStub* persistentDrawableId() const { return m_pId; } const OdGiDrawable* transientDrawable() const { return m_pDrawable; } OdGsMarker selectionMarker() const { return m_gsMarker; } }; const Node* m_pLeaf; void add(const OdGiDrawable* pDrawable, const OdDgElementId& drawableId, OdGsMarker gsMarker = -1) { Node* pNode = new Node(); pNode->m_pParent = m_pLeaf; m_pLeaf = pNode; pNode->m_pDrawable = pDrawable; pNode->m_pId = drawableId; pNode->m_gsMarker = gsMarker; } //void addNode(OdDgElementIdArray::const_iterator& iter) //{ // OdDgElementPtr pObj = iter->safeOpenObject(); // addNode(pObj); // OdDgBlockReferencePtr pInsert = OdDgBlockReference::cast(pObj); // if (pInsert.get()) // addNode(pInsert->blockTableRecord()); // ++iter; //} public: OdDgGsPath() : m_pLeaf(0) { } ~OdDgGsPath() { clear(); } OdDgGsPath(const OdDgFullSubentPath& path) : m_pLeaf(0) { set(path); } void clear() { while(m_pLeaf) { const Node* pNode = m_pLeaf; m_pLeaf = pNode->m_pParent; delete pNode; } m_pLeaf = NULL; } void set(const OdDgFullSubentPath& path) { set(path, kNullSubentIndex); } void set(const OdDgFullSubentPath& path, OdGsMarker gsMarker) { clear(); const OdDgElementIdArray& ids = path.objectIds(); OdDgElementIdArray::const_iterator iter = ids.begin(); if (iter==ids.end()) throw OdError(eInvalidInput); OdDgElementPtr pObj = iter->safeOpenObject(); if (!pObj->ownerId().isNull()) addNode(pObj->ownerId()); for (; iter != ids.end()-1; ++iter) addNode(*iter); addNode(*iter, gsMarker); } void addNode(const OdDgElementId& drawableId, OdGsMarker gsMarker = kNullSubentIndex) { add(0, drawableId, gsMarker); } void addNode(const OdGiDrawable* pDrawable, OdGsMarker gsMarker = kNullSubentIndex) { add(pDrawable->isPersistent() ? 0 : pDrawable, pDrawable->id(), gsMarker); } operator const OdGiPathNode&() const { return *m_pLeaf; } }; void OdDgnDbModuleImpl::highlight(OdGsView* gsView, bool bValue, OdDbStub* id, const OdDbBaseFullSubentPath* pPath) { OdRxObject* pRxDatabase = baseDatabaseBy(id); ODA_ASSERT_ONCE(pRxDatabase && id); if (!pRxDatabase || !id) return; OdDgElementId idEnt(id); OdDgElementPtr pEnt = idEnt.openObject(); if (pEnt.isNull()) return; // erased // TODO via pEnt->highlight(bValue, &pPath); // see OdDbEntity::subHighlight // OdGsCache* pCache = pEnt->gsNode(); if (!pCache) { pEnt->downgradeOpen(); pCache = pEnt->gsNode(); ODA_ASSERT_ONCE(pCache); if (!pCache) return; } if (!pPath) { //if (pEnt->ownerId().isNull()) // return; OdDgGsPath gsPath; //OdDbGsPath gsPath; if (!pEnt->ownerId().isNull()) gsPath.addNode(pEnt->ownerId()); #ifdef _DEBUG else gsPath = gsPath; // brk !!!! #endif gsPath.addNode(pEnt); pCache->model()->highlight(gsPath, bValue); return; } ODA_FAIL_ONCE(); // TODO //OdGsMarkerArray gsMarkers; //pEnt->getGsMarkersAtSubentPath(*pPath, gsMarkers); //for (OdGsMarkerArray::iterator sm = gsMarkers.begin(); sm != gsMarkers.end(); ++sm) //{ // OdDgGsPath gsPath; //OdDbGsPath gsPath; // gsPath.set(*pPath, *sm); // pCache->model()->highlight(gsPath, bValue); //} } OdGiDrawablePtr OdDgnDbModuleImpl::cloneEntity(OdDbStub* id) { return openObject(id, true); //TODO? via virtual OdDgElementPtr subDeepClone(OdDgIdMapping& idMap) const; } OdRxObjectPtr OdDgnDbModuleImpl::openObject(OdDbStub* id, bool isForWriteMode) // = false { OdRxObject* pRxDb = baseDatabaseBy(id); OdRxObjectPtr pRes; if (!isResponsible(pRxDb)) return pRes; OdDgElementId idEnt(id); OdDgElementPtr pEnt = idEnt.openObject(isForWriteMode ? OdDg::kForWrite : OdDg::kForRead); if (pEnt.get()) pRes = OdRxObject::cast(pEnt); return pRes; } OdResult OdDgnDbModuleImpl::getGripPoints(OdRxObject* pRxDb, OdGiDrawable* pEntity, OdDbGripDataPtrArray& grips, double curViewUnitSize, int gripSize, const OdGeVector3d& curViewDir, int bitFlags) { //OdDgGripPointsPEPtr pGripPe = OdDgGripPointsPE::cast(pEntity); //if ( pGripPe.get() // && eOk == pGripPe->getGripPoints(OdDgElement::cast(pEntity), // *(OdDgGripDataPtrArray *) &grips, curViewUnitSize, gripSize, curViewDir, bitFlags)) // return eOk; OdDgElementPtr pElem = OdDgElement::cast(pEntity); ODA_ASSERT_ONCE(pElem.get()); if (pElem.isNull()) return eNoDatabase; return pElem->getGripPoints(*(OdDgGripDataPtrArray *) &grips, curViewUnitSize, gripSize, curViewDir, bitFlags); } OdResult OdDgnDbModuleImpl::getGripPoints(OdRxObject* pRxDb, OdGiDrawable* pEntity, OdGePoint3dArray& gripPoints) { //OdDgGripPointsPEPtr pGripPe = OdDgGripPointsPE::cast(pEntity); //if (pGripPe.get() && eOk == pGripPe->getGripPoints(OdDgElement::cast(pEntity), gripPoints)) // return eOk; OdDgElementPtr pElem = OdDgElement::cast(pEntity); ODA_ASSERT_ONCE(pElem.get()); if (pElem.isNull()) return eNoDatabase; return pElem->getGripPoints(gripPoints); } OdResult OdDgnDbModuleImpl::moveGripPointsAt(OdRxObject* pRxDb, OdGiDrawable* pEntity, const OdDbVoidPtrArray& gripAppData, const OdGeVector3d& offset, int bitFlags) { //OdDgGripPointsPEPtr pGripPe = OdDgGripPointsPE::cast(pEntity); //if (pGripPe.get() && eOk == pGripPe->moveGripPointsAt(OdDgElement::cast(pEntity), // *(const OdDgVoidPtrArray*) &gripAppData, offset, bitFlags)) // return eOk; OdDgElementPtr pElem = OdDgElement::cast(pEntity); ODA_ASSERT_ONCE(pElem.get()); if (pElem.isNull()) return eNoDatabase; return pElem->moveGripPointsAt(*(const OdDgVoidPtrArray*) &gripAppData, offset, bitFlags); } OdResult OdDgnDbModuleImpl::moveGripPointsAt(OdRxObject* pRxDb, OdGiDrawable* pEntity, const OdIntArray& indices, const OdGeVector3d& offset) { //OdDgGripPointsPEPtr pGripPe = OdDgGripPointsPE::cast(pEntity); //if (pGripPe.get() && eOk == pGripPe->moveGripPointsAt(OdDgElement::cast(pEntity), indices, offset)) // return eOk; OdDgElementPtr pElem = OdDgElement::cast(pEntity); ODA_ASSERT_ONCE(pElem.get()); if (pElem.isNull()) return eNoDatabase; return pElem->moveGripPointsAt(indices, offset); } bool OdDgnDbModuleImpl::isErased(OdDbStub* id) { OdDgDatabasePtr pDgnDb = OdDgDatabase::cast(baseDatabaseBy(id)); ODA_ASSERT_ONCE(id && !pDgnDb.isNull()); if (pDgnDb.isNull()) return false; OdDgElementId idElem(id); return idElem.isErased(); } OdDbHandle OdDgnDbModuleImpl::getElementHandle(OdDbStub* id) { return OdDgElementId(id).getHandle(); } OdString OdDgnDbModuleImpl::getElementClassName(OdDbStub* id) { if (!id) return OdDgDatabase::desc()->name(); OdDgDatabasePtr pDgnDb = OdDgDatabase::cast(baseDatabaseBy(id)); ODA_ASSERT_ONCE(id && !pDgnDb.isNull()); if (pDgnDb.isNull()) return OdString::kEmpty; OdDgElementId idElem(id); OdDgElementPtr pElem = idElem.openObject(); ODA_ASSERT_ONCE(!pElem.isNull()); if (pElem.isNull()) return OdString::kEmpty; OdString sName = pElem->isA()->name(); return sName; } bool OdDgnDbModuleImpl::startUndoRecord(OdRxObject* pRxDb) { OdDgDatabasePtr pDgnDb = OdDgDatabase::cast(pRxDb); ODA_ASSERT_ONCE(pDgnDb.get()); if (pDgnDb.isNull()) return false; pDgnDb->startUndoRecord(); return true; } bool OdDgnDbModuleImpl::blockUndoRecording(OdRxObject* pRxDb, bool bBegin) { OdDgDatabasePtr pDgnDb = OdDgDatabase::cast(pRxDb); ODA_ASSERT_ONCE(pDgnDb.get()); if (pDgnDb.isNull()) return false; pDgnDb->blockUndoRecording(bBegin); //if (bBegin) // pDgnDb->startTransaction(); //else // pDgnDb->endTransaction(); return bBegin == pDgnDb->isUndoBlockStarted(); } bool OdDgnDbModuleImpl::isUndoBlockStarted(OdRxObject* pRxDb) { OdDgDatabasePtr pDgnDb = OdDgDatabase::cast(pRxDb); ODA_ASSERT_ONCE(pDgnDb.get()); if (pDgnDb.isNull()) return false; return pDgnDb->isUndoBlockStarted(); } bool OdDgnDbModuleImpl::hasUndo(OdRxObject* pRxDb) { OdDgDatabasePtr pDgnDb = OdDgDatabase::cast(pRxDb); ODA_ASSERT_ONCE(pDgnDb.get()); if (pDgnDb.isNull()) return false; return pDgnDb->hasUndo(); } void OdDgnDbModuleImpl::undo(OdRxObject* pRxDb) { OdDgDatabasePtr pDgnDb = OdDgDatabase::cast(pRxDb); ODA_ASSERT_ONCE(pDgnDb.get()); if (pDgnDb.isNull() || !pDgnDb->hasUndo()) return; pDgnDb->undo(); } bool OdDgnDbModuleImpl::hasRedo(OdRxObject* pRxDb) { OdDgDatabasePtr pDgnDb = OdDgDatabase::cast(pRxDb); ODA_ASSERT_ONCE(pDgnDb.get()); if (pDgnDb.isNull()) return false; return pDgnDb->hasRedo(); } void OdDgnDbModuleImpl::redo(OdRxObject* pRxDb) { OdDgDatabasePtr pDgnDb = OdDgDatabase::cast(pRxDb); ODA_ASSERT_ONCE(pDgnDb.get()); if (pDgnDb.isNull() || !pDgnDb->hasRedo()) return; pDgnDb->redo(); } bool OdDgnDbModuleImpl::cmdErase(OdEdCommandContext* pCmdCtx) { OdDgDatabasePtr pDgnDb = OdDgDatabase::cast(pCmdCtx->baseDatabase()); if (pDgnDb.isNull()) return false; OdDbUserIOPtr pIO = pCmdCtx->userIO(); OdSelectionSetPtr pSSet = pIO->select(); int nLockedLayer = 0, nCount = 0; for (OdDgSelectionSetIteratorPtr pItr = pSSet->newIterator(); !pItr->done(); pItr->next()) { OdDgElementId idElem = pItr->objectId(); OdDgElementPtr pElem = OdDgElement::cast(idElem.safeOpenObject(OdDg::kForWrite)); ODA_ASSERT_ONCE(!pElem.isNull()); if (pElem.isNull()) continue; nCount++; if (isElementLocked(pElem)) { nLockedLayer++; continue; } // already contained via OdDgSelectionSet //OdGsCache* pCsh = pElem->gsNode(); //if (pCsh) // pCsh->model()->onErased(pElem, pElem->ownerId()); pElem->erase(); } if (!nCount) return false; ODA_ASSERT_ONCE(OdPropServices::cast(pCmdCtx).get()); OdString sMsg; sMsg.format(OdPropServices::cast(pCmdCtx)->tr(" %d found.").c_str(), nCount); pIO->putString(sMsg); if (nLockedLayer) { sMsg.format(OdPropServices::cast(pCmdCtx)->tr( // msgNWasWereOnALockedLayer (nLockedLayer > 1) ? " %d were on a locked layer." : " %d was on a locked layer.").c_str(), nLockedLayer); pIO->putString(sMsg); } return true; } bool OdDgnDbModuleImpl::isResponsible(OdRxObject* pRxDatabase) { ODA_ASSERT_ONCE(pRxDatabase); // test OdDgDatabasePtr pDgnDb = OdDgDatabase::cast(pRxDatabase); return !pDgnDb.isNull(); } OdStringArray OdDgnDbModuleImpl::getExtensions(enum OdEd::GetFilePathFlags flg, // = OdEd::kGfpForOpen OdRxObject* pRxDatabase, // = NULL bool) // bWithExtSynonyms = false { OdStringArray lst; if (!pRxDatabase || isResponsible(pRxDatabase)) lst.push_back(L"dgn"); return lst; } OdString OdDgnDbModuleImpl::getFilterByExtension(const OdString& sExt, int index, // = 0 enum OdEd::GetFilePathFlags, // flg = OdEd::kGfpForOpen OdStringArray*) // pExtSynonyms = NULL { if (!index && sExt == L"dgn") return L"DGN files (*.dgn)|*.dgn|"; return OdString::kEmpty; } // import / export issues OdStringArray OdDgnDbModuleImpl::getImportExportExtensions(OdRxObject* pRxDatabase, bool isForImport ,// = true bool) // bWithExtSynonyms // = false { OdStringArray lst; if ( pRxDatabase && isForImport && !isResponsible(pRxDatabase)) // better avoid linking with TD_DB here // OdDbDatabase::cast(pRxDatabase)) lst.push_back(L"dgn"); return lst; } OdString OdDgnDbModuleImpl::getImportExportFilterByExtension(const OdString& sExt, int index, // = 0 bool isForImport, // = true OdStringArray*) // pExtSynonyms // = NULL { if (!index && isForImport && sExt == L"dgn") return L"DGN files (*.dgn)|*.dgn|"; return OdString::kEmpty; } using namespace TD_DGN_IMPORT; bool OdDgnDbModuleImpl::importFromFile(OdRxObject* pRxDatabase, const OdString& sFileName, ODCOLORREF&) // clrBackground // in / out { OdDgnImportModulePtr pDgnImport = OdDgnImportModule::cast(::odrxDynamicLinker()->loadApp(OdDgnImportModuleName)); if (pDgnImport.isNull()) { appDgnServicesImpl()->warning(L"TD_DgnImport.tx was not found"); return false; } OdDgnImportPtr importer = pDgnImport->create(); if (importer.isNull()) { appDgnServicesImpl()->warning(L"Could not create dgn importer"); return false; } // Set the conversion parameters importer->properties()->putAt(L"Services", appDgnServicesImpl()->m_pBaseHostAppServices); importer->properties()->putAt(L"DgnPath", OdRxVariantValue(sFileName)); //appDgnServices()->disableProgressMeterOutput(true); importer->properties()->putAt(L"DgnServices", appDgnServices()); importer->properties()->putAt(L"Database", pRxDatabase); //pDwgDb); //importer->properties()->putAt( L"MS_SYMBRSRC", OdRxVariantValue(arrRsrc) ); importer->properties()->putAt(L"XRefImportMode", OdRxVariantValue(OdUInt8(2))); importer->properties()->putAt(L"ImportActiveModelToModelSpace", OdRxVariantValue(true)); importer->properties()->putAt(L"ImportPaperSpaceModels", OdRxVariantValue(true)); importer->properties()->putAt(L"RecomputeDimensionsAfterImport", OdRxVariantValue(false)); importer->properties()->putAt(L"ImportViewIndex", OdRxVariantValue(OdUInt8(0))); importer->properties()->putAt(L"3dShapeImportMode", OdRxVariantValue(OdUInt8(1))); //OdString shxPath = getenv("FONTS"); //importer->properties()->putAt(L"shxFontsPath", OdRxVariantValue(shxPath)); //Import DGN file OdDgnImport::ImportResult res = importer->import(); switch (res) { case OdDgnImport::fail: appDgnServicesImpl()->warning(L"Unknown error."); break; case OdDgnImport::bad_password: appDgnServicesImpl()->warning(OD_T("Invalid password.")); break; case OdDgnImport::bad_file: appDgnServicesImpl()->warning(OD_T("Cannot open file.")); break; case OdDgnImport::bad_database: appDgnServicesImpl()->warning(OD_T("Invalid file.")); break; case OdDgnImport::encrypted_file: appDgnServicesImpl()->warning(OD_T("Decryption error.")); break; case OdDgnImport::success: //ODA_ASSERT_ONCE(pDwgDb == OdDbDatabase::cast(importer->properties()->getAt(L"Database"))); return true; } return false; }