//-------------------------------------------------------------------------------------------------------+ // Copyright (C), 1998-2007, Beijing Tangent Software Co. Ltd. // = FileName : TArchPerDocData 类 // = Version : ver2.0 // = Author : wlw // = CreateDate : 2002-09-09 // = Description: TArchPerDocData 定义 // = Maintainers: // //-------------------------------------------------------------------------------------------------------+ #include "StdAfx.h" #include "TArchPerDocData.h" #include "TPushMemVar.h" #include "TAcDbObjectPtr.h" #include "TDbWall.h" #include "Symdef.h" #include "dbDimension.h" #include "DbCornerWin.h" #include "TDbRegion.h" #include "TDbColumn.h" #include "TArchDbReactor.h" #include "lngtrans.h" #include #ifdef TASD #include "TArchAppDocGlobals.h" #include "TDbExtentsZoneTable.h" #endif extern int g_nMaxAutoScale; #ifdef TASD extern CMapPtrToPtr g_mapDb2ZoneTable; extern void OpenZoneTbl(AcDbDatabase* pDb, TDbExtentsZoneTable* pZoneTbl); extern void SaveZoneTbl(AcDbDatabase* pDb, TDbExtentsZoneTable* pZoneTbl); #endif TArchPerDocData::TArchPerDocData(AcApDocument *pDoc) : m_ssPickGrip(SS_FREE) { m_pDoc = pDoc; m_pDbReactor = NULL; m_nMinLenWall = _AS_SYS_UNIT(20); // Global variable #if (TAR_LANGUAGE == TAR_CHBIG5) m_lWallWidth = _AS_SYS_UNIT(60.0); m_rWallWidth = _AS_SYS_UNIT(60.0); #else m_lWallWidth = _AS_SYS_UNIT(120.0); m_rWallWidth = _AS_SYS_UNIT(120.0); #endif m_bDwgBegin = FALSE; m_bAcadIdle = TRUE; m_nDrawWall = 0; m_nOsnapType = 1; m_bModelNumber = FALSE; m_szLastCommand[0] = EOS; m_bUpdateDisp = FALSE; m_bLispCommand = FALSE; m_szCommandStr[0] = EOS; m_nPos = 0; m_bUpdating = false; m_pCommandSender = NULL; } TArchPerDocData::~TArchPerDocData() { if (m_pCommandSender != NULL) { delete m_pCommandSender; } } TArchPerBlockData* TArchPerDocData::GetBlockData(const AcDbEntity*pEnt) { return FindOrAddBlockData(pEnt->blockId()); } // 提取键盘的输入, AutoCAD可再处理 BOOL TArchPerDocData::OnAcadChar(UINT nChar, UINT nRepCnt, UINT nFlags) { unsigned char cChar = LOBYTE(nChar); int nOldPos = m_nPos; int nCmdActive = 0; TGGetVar(_T("CMDACTIVE"), &nCmdActive); if (!m_bAcadIdle && nCmdActive) { return FALSE; } if (IsKeyPressed(VK_CONTROL) || IsKeyPressed(VK_MENU)) { return FALSE; } //为了防止键盘缓冲区溢出 if (cChar == 8) { //退格键 if (m_nPos < nRepCnt) { return FALSE; } } else if (cChar < 33 || cChar > 126) {//控制字符 return FALSE; } else { //正常字符 if (m_nPos + nRepCnt >= 1020) { return FALSE; } } for (UINT i = 0U; i < nRepCnt; i++) { ASSERT(m_nPos >= 0 && m_nPos < 1023); if (cChar == 8) {//退格键 m_szCommandStr[m_nPos] = EOS; m_nPos--; } else { m_szCommandStr[m_nPos] = cChar; m_nPos++; } } ASSERT(m_nPos >= 0 && m_nPos < 1023); m_szCommandStr[m_nPos] = EOS; if (g_bEnableShortCut) { CString sCommand = m_szCommandStr; if (m_nPos == 1 && nOldPos == 0 && //命令行输入第一个字符时 sCommand[0] != _T('(') && //不是lisp命令 g_pKeyMapTable != NULL && g_pKeyMapTable->Key2Command(sCommand))//并且定义有快捷键 { if (m_pCommandSender != NULL) { delete m_pCommandSender; } m_pCommandSender = new TSendCommandEdit; m_pCommandSender->Create(sCommand); m_nPos = 0; m_szCommandStr[0] = EOS; } } return FALSE; } void TArchPerDocData::ResetDocCmdGlobals() { for (long i = 0; i < m_lstBlock.GetLength(); i++) { m_lstBlock[i]->Reset(); } //替换集合 modify on 100609 m_setModifiedOpeningId.clear(); m_setModifiedWallId.clear(); m_setClipChanged.clear(); m_setClippedChanged.clear(); m_setRegionChanged.clear(); } TArchPerBlockData* TArchPerDocData::FindOrAddBlockData(AcDbObjectId idBlock) { TArchPerBlockData* pNew = new TArchPerBlockData(idBlock); if (m_lstBlock.SortIn(pNew)) { pNew->Initialize(); return pNew; } else { delete pNew; return m_lstBlock.GetCurData(); } } void TArchPerDocData::FindAndDelBlockData(AcDbObjectId idBlock) { if (m_lstBlock.BFindDataTo(TArchPerBlockData(idBlock))) { m_lstBlock.DelCur(); } } void TArchPerDocData::AddWallCorners(const TDbWall *pWall) { if (IsDocLocked() || m_bUpdating) { return; } TArchPerBlockData* pBD = GetBlockData(pWall); if (pBD != NULL) { pBD->AddWallCorners(pWall); } } void TArchPerDocData::AddChangedColumn(const TDbColumn *pColumn) { if (IsDocLocked() || m_bUpdating) { return; } TArchPerBlockData* pBD = GetBlockData(pColumn); if (pBD != NULL) { pBD->AddChangedColumn(pColumn); } } void TArchPerDocData::AddModifiedOpening(const AcDbObjectId &id) { if (IsDocLocked() || m_bUpdating) { return; } m_setModifiedOpeningId.insert(id); } void TArchPerDocData::AddModifiedWall(const AcDbObjectId &id) { if (IsDocLocked() || m_bUpdating) { return; } m_setModifiedWallId.insert(id); } void TArchPerDocData::AddModifiedClip(const AcDbObjectId &id) { if (IsDocLocked() || m_bUpdating) { return; } m_setClipChanged.insert(id); } void TArchPerDocData::AddModifiedClipped(const AcDbObjectId &id) { if (IsDocLocked() || m_bUpdating) { return; } m_setClippedChanged.insert(id); } void TArchPerDocData::AddModifiedRegion(const AcDbObjectId &id) { if (IsDocLocked() || m_bUpdating) { return; } m_setRegionChanged.insert(id); } void TArchPerDocData::OnOpenedForModify(const AcDbObject *dbObj) { } void TArchPerDocData::OnModified(const AcDbObject *dbObj) { } void TArchPerDocData::UpdateExtend(bool bRefreshBlock) { } void TArchPerDocData::UpdateCorners(bool bFormatCor) { TPushMemVar vTemp(m_bUpdating,true); if (IsDocLocked()) { return; } m_mapIdToCorner.RemoveAll(); //add by xlc 100610 清空范围映射 if (acdbCurDwg() != NULL) { //add by xlc on 100531 提速优化 if (bFormatCor) { m_mapIdToCorner.SetAt(100,AcDbExtents()); } for (long i = 0;i < m_lstBlock.GetLength(); i++) { m_lstBlock[i]->UpdateCorners(&m_mapIdToCorner); } //测试corner 的范围 /* AcDbExtents ext; long lKey = 0l; for (POSITION ps = m_mapIdToCorner.GetStartPosition();ps != NULL;) { m_mapIdToCorner.GetNextAssoc(ps,lKey,ext); AcDbLine* pLine = new AcDbLine; pLine->setStartPoint(ext.minPoint()); pLine->setEndPoint(ext.maxPoint()); pLine->setColorIndex(1); AddToModelSpace(pLine); }*/ } } //考虑了转角窗的特殊性TDbCornerWin void TArchPerDocData::UpdateOpenings() { TPushMemVar vTemp(m_bUpdating,true); if (IsDocLocked()) { return; } if (m_setModifiedOpeningId.size() < 1) { return; } TDPtrList* plstAllWall = NULL;//块内所有墙 TDPtrList* plstAllDim = NULL;//块内所有尺寸 AcDbObjectId idBlock = AcDbObjectId::kNull; bool bShowProgress = m_setModifiedOpeningId.size() >= 200; if (bShowProgress) { acedSetStatusBarProgressMeter(_T("正在更新门窗数据,请稍候..."),1,m_setModifiedOpeningId.size()); } CMap mapIdToIdWalls,mapIdToDims; int i = 0; //先统一更新整体修改范围 lfy 2010-7-9 for (IT it = m_setModifiedOpeningId.begin();it != m_setModifiedOpeningId.end();it++) { AcDbObjectId &id = (AcDbObjectId &)*it; if (!id) { continue; } //modify by xlc on 100531 提速优化,只读打开,修改时再升级 TAcDbObjectPtr obj(id, AcDb::kForRead,Adesk::kTrue); if (!obj) { continue; } AcDbEntity *pEntityObj = AcDbEntity::cast(obj.m_pObject); if (pEntityObj != NULL ) { idBlock = pEntityObj->blockId(); //modify by xlc on 100531 提速优化 AcDbExtents extT,extT2; pEntityObj->getGeomExtents(extT); if ( m_mapIdToCorner.Lookup(idBlock.asOldId(),extT2) ) { extT2.addExt(extT); m_mapIdToCorner.SetAt(idBlock.asOldId(),extT2); } else { m_mapIdToCorner.SetAt(idBlock.asOldId(),extT); } } } idBlock.setNull(); for ( it = m_setModifiedOpeningId.begin();it != m_setModifiedOpeningId.end();it++) { if (bShowProgress) { acedSetStatusBarProgressMeterPos(i); i++; } AcDbObjectId &id = (AcDbObjectId &)*it; if (!id) { continue; } //modify by xlc on 100531 提速优化,只读打开,修改时再升级 TAcDbObjectPtr obj(id, AcDb::kForRead,Adesk::kTrue); if (!obj) { continue; } AcDbEntity *pEntityObj = AcDbEntity::cast(obj.m_pObject); if (pEntityObj != NULL && pEntityObj->blockId() != idBlock) { idBlock = pEntityObj->blockId(); //modify by xlc on 100531 提速优化 plstAllWall = NULL; if (mapIdToIdWalls.Lookup(idBlock.asOldId(),(PVOID&)plstAllWall)) { } else { plstAllWall = new TDPtrList; GetEntFromBlockByClass2(*plstAllWall, TDbWall::desc(), 1,idBlock,&m_mapIdToCorner); mapIdToIdWalls.SetAt(idBlock.asOldId(),(PVOID)plstAllWall); } plstAllDim = NULL; if (mapIdToDims.Lookup(idBlock.asOldId(),(PVOID&)plstAllDim)) { } else { plstAllDim = new TDPtrList; GetEntFromBlockByClass2(*plstAllDim, TDbDimension2::desc(), 1, idBlock,&m_mapIdToCorner); mapIdToDims.SetAt(idBlock.asOldId(),(PVOID)plstAllDim); } } TDbOpening *pOpening = TDbOpening::cast(obj.m_pObject); if (!pOpening) { TDbCornerWin *pWin = TDbCornerWin::cast(obj.m_pObject); if (pWin) { if (!pWin->isErased()) { if(plstAllWall != NULL) { //modify by xlc on 100625 有时会出现升级打开不成功的情况 //pWin->upgradeOpen(); Acad::ErrorStatus es = pWin->upgradeOpen(); if (!(es == Acad::eOk || es == Acad::eWasOpenForWrite)) { continue; } pWin->ValidateContainership(*plstAllWall); pWin->downgradeOpen(); } } } continue; } else { if (!pOpening->isErased()) { if (plstAllWall != NULL) { //modify by xlc on 100625 有时会出现升级打开不成功的情况 //pOpening->upgradeOpen(); Acad::ErrorStatus es = pOpening->upgradeOpen(); if (!(es == Acad::eOk || es == Acad::eWasOpenForWrite)) { continue; } pOpening->ValidateContainership(*plstAllWall); //验证和墙的配属关系 pOpening->downgradeOpen(); } } extern BOOL SkipSubErase(const TCHAR *szCmd); TCString &sCmd = m_sCurCommand; CString sTemp(sCmd); sTemp.MakeUpper(); bool bPaste = sTemp.Find(_T("PASTECLIP")) >= 0; bool bCopy = sTemp.Find(_T("COPY")) >= 0; //add by by xlc on 100630 图形切割时忽略标注更新 bool bCut = sTemp.Find(_T("CUTDRAWING")) >= 0; if (!bPaste && !bCopy && !bCut && _tcsicmp(sCmd,_T("MIRROR")) != 0 && _tcsicmp(sCmd,_T("ARRAY")) != 0 && (!(pOpening->isErased() && TchPrivate::SkipSubErase(sCmd)))) { if (plstAllDim != NULL) { //modify by xlc on 100625 有时会出现升级打开不成功的情况 //pOpening->upgradeOpen(); Acad::ErrorStatus es = pOpening->upgradeOpen(); if (!(es == Acad::eOk || es == Acad::eWasOpenForWrite)) { continue; } pOpening->ValidateDim(*plstAllDim); pOpening->downgradeOpen(); } } } } if (bShowProgress) { acedRestoreStatusBar(); } //add by xlc on 100531 提速优化,只读打开,修改时再升级 LONG_PTR lKey = 0; for (POSITION ps = mapIdToIdWalls.GetStartPosition();ps != NULL;) { mapIdToIdWalls.GetNextAssoc(ps,lKey,(PVOID&)plstAllWall); if (plstAllWall != NULL) { delete plstAllWall; } } for (ps = mapIdToDims.GetStartPosition();ps != NULL;) { mapIdToDims.GetNextAssoc(ps,lKey,(PVOID&)plstAllDim); if (plstAllDim != NULL) { delete plstAllDim; } } m_setModifiedOpeningId.clear(); } void TArchPerDocData::UpdateRegion() { TPushMemVar vTemp(m_bUpdating,true); if (IsDocLocked()) { return; } for (IT it = m_setRegionChanged.begin();it != m_setRegionChanged.end();it++) { AcDbObjectId &id = (AcDbObjectId &)*it; TDbRegion *pEnt = NULL; acdbOpenObject(pEnt,id,AcDb::kForWrite,Adesk::kTrue); if (pEnt != NULL) { pEnt->ResetRegionShip(); pEnt->SetErrorFlag(); pEnt->close(); } } bool bShowProgress = m_setRegionChanged.size() >= 200; if (bShowProgress) { acedSetStatusBarProgressMeter(_T("正在更新地块数据,请稍候..."),1,m_setRegionChanged.size()); } int i = 0; for (it = m_setRegionChanged.begin();it != m_setRegionChanged.end();it++) { if (bShowProgress) { ::acedSetStatusBarProgressMeterPos(i); i++; } AcDbObjectId &id = (AcDbObjectId &)*it; if (id.isNull() || !id.isValid()) { continue; } TDbRegion *pEnt = NULL; acdbOpenObject(pEnt,id,AcDb::kForWrite); if (pEnt != NULL) { pEnt->ValidateRegionShip(); pEnt->close(); } } if (bShowProgress) { acedRestoreStatusBar(); } m_setRegionChanged.clear(); } void TArchPerDocData::UpdateWalls() { TPushMemVar vTemp(m_bUpdating,true); if (IsDocLocked()) { return; } bool bShowProgress = m_setModifiedWallId.size() >= 200; if (bShowProgress) { acedSetStatusBarProgressMeter(_T("正在更新墙体数据,请稍候..."),1,m_setModifiedWallId.size()); } int i = 0; for (IT it = m_setModifiedWallId.begin();it != m_setModifiedWallId.end();it++) { if (bShowProgress) { acedSetStatusBarProgressMeterPos(i); i++; } AcDbObjectId &id = (AcDbObjectId &)*it; if (!id) { continue; } OPENOBJ_BEGIN(id, AcDb::kForWrite, TDbWall, pWall); if (pWall) { pWall->ValidateContainership(); //验证和门窗的配属关系 //add by xlc on 101119 解决图块在位编辑丢失参照的问题(解除墙之间连接关系) pWall->ReLinkWithOwner(); } OPENOBJ_END(); } if (bShowProgress) { acedRestoreStatusBar(); } m_setModifiedWallId.clear(); } //add by xlc on 100531 提速优化,只读打开,修改时再升级 static void EraseMapPair(const std::pair& pairEl) { if (pairEl.second != NULL) { delete (AcDbObjectIdArray*)pairEl.second; } } void TArchPerDocData::UpdateClip()//更新裁剪关系 { TPushMemVar vTemp(m_bUpdating,true); if (IsDocLocked()) { return; } bool bShowProgress = (m_setClipChanged.size() + m_setClippedChanged.size()) >= 300; long count = 0; if (bShowProgress) { acedSetStatusBarProgressMeter(_T("正在更新自动裁剪数据,请稍候..."),1,m_setClipChanged.size() + m_setClippedChanged.size()); } AcDbEntity *pEnt = NULL; TEntityBase* pEntBase = NULL; std::map mapRecIdToEnts; AcDbObjectIdArray arIds; for(IT it = m_setClipChanged.begin();it != m_setClipChanged.end();it++) { count++; if (bShowProgress && (count%10) == 0) { acedSetStatusBarProgressMeterPos(count); } const AcDbObjectId &id = *it; if (id.isNull() || !id.isValid()) { continue; } //modfy by xlc on 100531 提速优化,只读打开,修改时再升级 acdbOpenObject(pEnt,id,AcDb::kForRead,Adesk::kTrue); if (pEnt != NULL) { pEntBase = TEntityBase::Cast(pEnt); if (pEntBase != NULL) { Acad::ErrorStatus es = pEnt->upgradeOpen(); if (!(es == Acad::eOk || es == Acad::eWasOpenForWrite)) //modify by xlc on 100625 有时会出现升级不成功的情况 { pEnt->close(); continue; } if (pEnt->isErased()) { pEntBase->ResetClippedShip(); } else { pEntBase->ValidateClipShip(&mapRecIdToEnts,&m_mapIdToCorner); } pEnt->downgradeOpen(); } pEnt->close(); } arIds.append(id); } m_setClipChanged.clear(); int nFind = -1; for(it = m_setClippedChanged.begin();it != m_setClippedChanged.end();it++) { count++; if (bShowProgress && (count%10) == 0) { acedSetStatusBarProgressMeterPos(count); } const AcDbObjectId &id = *it; /*if (arIds.find(id,nFind)) { continue; }*/ if (id.isNull() || !id.isValid()) { continue; } //modify by xlc on 100531 提速优化,只读打开,修改时再升级 acdbOpenObject(pEnt,id,AcDb::kForRead,Adesk::kTrue); if (pEnt != NULL) { pEntBase = TEntityBase::Cast(pEnt); if (pEntBase != NULL) { Acad::ErrorStatus es = pEnt->upgradeOpen(); if (!(es == Acad::eOk || es == Acad::eWasOpenForWrite)) //modify by xlc on 100625 有时会出现升级不成功的情况 { pEnt->close(); continue; } if (pEnt->isErased()) { pEntBase->ResetClipShip(); } else { pEntBase->ValidateClippedShip(&mapRecIdToEnts,&m_mapIdToCorner); } pEnt->downgradeOpen(); } pEnt->close(); } } if (bShowProgress) { acedRestoreStatusBar(); } m_setClippedChanged.clear(); //释放 std::for_each(mapRecIdToEnts.begin(),mapRecIdToEnts.end(),EraseMapPair); } //由pDb初始化数据 void TArchPerDocData::Initialize(AcDbDatabase*pDb) { m_lstBlock.Clear(); AcDbBlockTable *pRecTable = NULL; pDb->getBlockTable(pRecTable,AcDb::kForRead); if (pRecTable != NULL) { AcDbBlockTableIterator *pIter = NULL; pRecTable->newIterator(pIter); if (pIter != NULL) { for (pIter->start();!pIter->done();pIter->step()) { AcDbObjectId idBlock; pIter->getRecordId(idBlock); FindOrAddBlockData(idBlock); } delete pIter; } pRecTable->close(); } } void TArchPerDocData::AttachReactor() { #ifdef TASD AcDbDatabase *pDb = m_pDoc->database(); if (m_pDoc) { if (TArchAppDocGlobals::g_mapGlobalsDb2Reactor.IsEmpty()) { Initialize(pDb); m_pDbReactor = new TArchDbReactor(this); pDb->addReactor(m_pDbReactor); TArchAppDocGlobals::g_mapGlobalsDb2Reactor.SetAt(pDb, m_pDbReactor); } else { if (!TArchAppDocGlobals::g_mapGlobalsDb2Reactor.Lookup(pDb, (void*&)m_pDbReactor)) { Initialize(pDb); m_pDbReactor = new TArchDbReactor(this); pDb->addReactor(m_pDbReactor); TArchAppDocGlobals::g_mapGlobalsDb2Reactor.SetAt(pDb, m_pDbReactor); } } //初始化分区表 TDbExtentsZoneTable* pZoneTbl = NULL; if (!g_mapDb2ZoneTable.Lookup(pDb, (void*&)pZoneTbl)) { pZoneTbl = new TDbExtentsZoneTable; OpenZoneTbl(pDb, pZoneTbl); g_mapDb2ZoneTable.SetAt(pDb, pZoneTbl); } } #else ASSERT(m_pDoc); if (!m_pDbReactor) { AcDbDatabase *pDb = m_pDoc->database(); Initialize(pDb); ASSERT(pDb != NULL); m_pDbReactor = new TArchDbReactor(this); pDb->addReactor(m_pDbReactor); } #endif } void TArchPerDocData::DetachReactor() { #ifdef TASD ASSERT(m_pDoc); AcDbDatabase *pDb = m_pDoc->database(); if (!pDb) { return; } { //移除分区表 TDbExtentsZoneTable* pZoneTbl = NULL; g_mapDb2ZoneTable.Lookup(pDb, (void*&)pZoneTbl); if (pZoneTbl) { SaveZoneTbl(pDb, pZoneTbl); delete pZoneTbl; pZoneTbl = NULL; } g_mapDb2ZoneTable.RemoveKey(pDb); TArchDbReactor* pReactor = NULL; TArchAppDocGlobals::g_mapGlobalsDb2Reactor.Lookup(pDb, (void*&)pReactor); if (pReactor) { pDb->removeReactor(pReactor); delete pReactor; pReactor = NULL; } TArchAppDocGlobals::g_mapGlobalsDb2Reactor.RemoveKey(pDb); } #else ASSERT(m_pDoc); AcDbDatabase *pDb = m_pDoc->database(); if (!pDb) { return; } if (m_pDbReactor) { pDb->removeReactor(m_pDbReactor); delete m_pDbReactor; m_pDbReactor = NULL; } #endif } AcDbObjectId TArchPerDocData::GetTransactionId()const { return acapLongTransactionManagerPtr()->currentLongTransactionFor(m_pDoc); } int TArchPerDocData::CompareForFind(const TArchPerDocData *pDoc1, const void *pDoc2) { ASSERT(pDoc1 && pDoc2); if (pDoc1->m_pDoc == pDoc2) { return 0; } return 1; } bool TArchPerDocData::IsTooManyChanged()const { size_t nScale = m_setClipChanged.size() + m_setClippedChanged.size(); for (long i = 0; i < m_lstBlock.GetLength(); i++) { nScale += m_lstBlock.GetAt(i)->GetUpdateScale(); } return nScale > g_nMaxAutoScale; } BOOL TArchPerDocData::IsDocLocked()const { return !m_bDwgBegin; }