#include "stdafx.h" #include "TDbMakeObjAssocReactor.h" #include "TReactorUnlockSwitch.h" #include "TCoverReleationManager.h" #include "TDbInterfaceMsgWrite.h" #include "TInterfaceModifyMsgContext.h" #include "actrans.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif extern TInterfaceModifyMsgContext g_iMsgContext; extern TDbXDataMap g_mapClass2Cmd; ////////////////////////////////////////////////////////////////////////// // 水管类从TDbCurveEntity继承,该类用于代理TDbPipe类,以便于在pipebase里 // 可以访问水管实体的基础数据。为了支持水管风管遮挡,能想得出来的办法都用上了。。 // 该类中不允许添加任何数据成员,以免出现内存错误。 add by hh 2014.8.8 class TDbPipeAgency : public TDbCurveEntity { public: void GetClipEntityId(AcDbObjectIdArray& arClip, AcDbObjectIdArray& arClipped) const { // 遮挡自己的 for(int i = 0; i < m_lstClipId.Length(); i++) { arClip.append(m_lstClipId[i]); } // 被自己遮挡的 for(int j = 0; j < m_lstClippedId.Length(); j++) { arClipped.append(m_lstClippedId[j]); } } }; ////////////////////////////////////////////////////////////////////////// TDbMakeObjAssocReactor::TDbMakeObjAssocReactor() { } TDbMakeObjAssocReactor::~TDbMakeObjAssocReactor() { } void TDbMakeObjAssocReactor::objectAppended(const AcDbDatabase* dwg,const AcDbObject* dbObj) { if (dwg == NULL || dbObj == NULL) return; if (!dbObj->isKindOf(TDbInterfacesObj::desc())) return; // mcl add 2010.05.24.没有添加到当前数据库时,无须建立关系 AcDbDatabase* pDb = dbObj->database(); if (NULL != pDb) { AcDbObjectId idModel = AcDbObjectId::kNull; AcDbBlockTable* pTable = NULL; pDb->getBlockTable(pTable, AcDb::kForRead); if (pTable != NULL) { pTable->getAt(ACDB_MODEL_SPACE, idModel); pTable->close(); } if (((TDbInterfacesObj*)dbObj)->blockId() != idModel) return; } //1. 大数量的接口时先记录,统一注册 int nMaxSetForOp = 0; g_mapClass2Cmd.GetAt(KEY_MAX_SET_FOROP,nMaxSetForOp); if (nMaxSetForOp == 2) //优化批量处理标识 { AcDbObjectIdArray arSet; acedGetCurrentSelectionSet(arSet); if (arSet.length() > MAX_SET_FOROP) { // CUIntArray* pArray = NULL; mcl changed by below. 64位下,id不能转换为UINT了 AcDbObjectIdArray* pArray = NULL; if (!g_iMsgContext.m_mapDb2InfAppended.Lookup((void*)dwg, (void*&)pArray)) { pArray = new AcDbObjectIdArray; g_iMsgContext.m_mapDb2InfAppended.SetAt((void*)dwg, (void*)pArray); } if (pArray != NULL) { pArray->append(dbObj->objectId()); return; } } } //2. 建立关系 TDbInterfacesObj* pIObj = TDbInterfacesObj::cast(dbObj); if (pIObj != NULL) { //排除重合 int nDepClnFlag = 0; pIObj->GetSpecialtyData()->GetAt(KEY_DEEPCLONEFLAG,nDepClnFlag); if (nDepClnFlag) return; TInterface pipeInterface,pipeInterface2; int nCount = pIObj->GetInterfaceCount(); TReactorUnlockSwitch reactorUnlock((AcDbDatabase*)dwg,this); for (int i = 0;i < nCount;i++) { pipeInterface.SetCompareRule(0); if (pIObj->GetInterface(i,pipeInterface)) { if ( Find(dwg,pipeInterface)) { //建立关联关系 if (Acad::eOk == pIObj->upgradeOpen()) { pIObj->SetInterfaceRelation(pipeInterface.GetPosition(),pipeInterface.GetConnectObject()); pIObj->downgradeOpen(); } pipeInterface2.SetOwnerId(pipeInterface.GetConnectObject()); pipeInterface2.SetPosition(pipeInterface.GetPosition()); pipeInterface2.SetOutDir(-pipeInterface.GetOutDir()); pipeInterface2.SetConnectObject(pIObj->objectId()); SetInterfaceRelation(dwg,pipeInterface2); } else { pipeInterface.SetConnectObject(AcDbObjectId::kNull); } //1.1 注册接口信息 pipeInterface.SetOwnerId(pIObj->objectId()); RegisterInterface(dwg,pipeInterface); } } //5.写入遮挡关系更新 pIObj->UpdateCoverDisplay(); } } BOOL TDbMakeObjAssocReactor::SetInterfaceRelation(const AcDbDatabase* pDb,const TInterface& pipeInterface) { if (pDb == NULL) return FALSE; // 该id是否有效 AcDbObjectId idOwner = pipeInterface.GetOwnerId(); if (!idOwner.isValid()) return FALSE; AcDbEntity* pEnt = NULL; if (Acad::eOk == acdbOpenAcDbEntity(pEnt,idOwner,AcDb::kForWrite,true)) { TDbInterfacesObj* pIObj = TDbInterfacesObj::cast(pEnt); if (pIObj != NULL) { pIObj->SetInterfaceRelation(pipeInterface.GetPosition(),pipeInterface.GetConnectObject()); } pEnt->close(); } // add by hh 2011-08-09 接口记录从字典移动到数据库中 TDbInterfaceRecord* pIntfRec = TAuxTools::GetIntfPtrFromDB(); if(NULL != pIntfRec) { if(Acad::eOk == pIntfRec->upgradeOpen()) { pIntfRec->Update(pipeInterface.GetOwnerId(),pipeInterface.GetPosition(),pipeInterface.GetConnectObject()); pIntfRec->Update(pipeInterface.GetConnectObject(),pipeInterface.GetPosition(),pipeInterface.GetOwnerId()); pIntfRec->downgradeOpen(); } pIntfRec->close(); return TRUE; } // add end AcDbDictionary* pNamedDict = NULL; if (Acad::eOk == ((AcDbDatabase*)pDb)->getNamedObjectsDictionary(pNamedDict,AcDb::kForRead)) { AcDbDictionary* pDict = NULL; if (Acad::eOk == pNamedDict->getAt(KEY_IRECORD,(AcDbObject*&)pDict,AcDb::kForRead)) { pNamedDict->close(); TDbInterfaceRecord* pInterfaceRec = NULL; if (Acad::eOk == pDict->getAt(KEY_IRECORD,(AcDbObject*&)pInterfaceRec,AcDb::kForWrite)) { pDict->close(); pInterfaceRec->Update(pipeInterface.GetOwnerId(),pipeInterface.GetPosition(),pipeInterface.GetConnectObject()); pInterfaceRec->Update(pipeInterface.GetConnectObject(),pipeInterface.GetPosition(),pipeInterface.GetOwnerId()); pInterfaceRec->close(); } else { pDict->close(); } } else { pNamedDict->close(); } } return TRUE; } void TDbMakeObjAssocReactor::objectReAppended(const AcDbDatabase* dwg,const AcDbObject* dbObj) { if (dwg == NULL || dbObj == NULL) return; // mcl add 2010.05.24.没有添加到当前数据库时,无须建立关系 if (dbObj->isKindOf(TDbInterfacesObj::desc())) { AcDbDatabase* pDb = dbObj->database(); if (NULL != pDb) { AcDbObjectId idModel = AcDbObjectId::kNull; AcDbBlockTable* pTable = NULL; pDb->getBlockTable(pTable, AcDb::kForRead); if (pTable != NULL) { pTable->getAt(ACDB_MODEL_SPACE, idModel); pTable->close(); } if (((TDbInterfacesObj*)dbObj)->blockId() != idModel) return; } } //恢复删除,重新建立接口关系 AcDbObjectId idOwner = AcDbObjectId::kNull; TDbInterfacesObj* pIObj = TDbInterfacesObj::cast(dbObj); if (pIObj != NULL) { idOwner = pIObj->objectId(); // add by hh 2011-08-09 接口记录从字典移动到数据库中 TDbInterfaceRecord* pIntfRec = TAuxTools::GetIntfPtrFromDB(); if(NULL != pIntfRec) { if(Acad::eOk == pIntfRec->upgradeOpen()) { TInterface pipeInterface,pipeInterface2; int nCount = pIObj->GetInterfaceCount(); TReactorUnlockSwitch reactorUnlock((AcDbDatabase*)dwg,this); for (int i = 0;i < nCount;i++) { pipeInterface.Reset(); if (pIObj->GetInterface(i,pipeInterface)) { pipeInterface2.Reset(); if ( pIntfRec->Find(pipeInterface.GetPosition(),pipeInterface.GetOutDir(),pipeInterface2)) { //建立关联关系 if (Acad::eOk == pIObj->upgradeOpen()) { pIObj->SetInterfaceRelation(pipeInterface.GetPosition(),pipeInterface.GetConnectObject()); pIObj->downgradeOpen(); } pipeInterface2.SetOwnerId(pipeInterface.GetConnectObject()); pipeInterface2.SetPosition(pipeInterface.GetPosition()); pipeInterface2.SetOutDir(-pipeInterface.GetOutDir()); pipeInterface2.SetConnectObject(pIObj->objectId()); SetInterfaceRelation(pIntfRec,pipeInterface2); } else { pIntfRec->Add(pipeInterface); } } } pIntfRec->downgradeOpen(); } pIntfRec->close(); //5.写入遮挡关系更新 if (acdbCurDwg() == dwg) pIObj->UpdateCoverDisplay(); return; } // add end AcDbDictionary* pNamedDict = NULL; if (Acad::eOk == ((AcDbDatabase*)dwg)->getNamedObjectsDictionary(pNamedDict,AcDb::kForRead)) { AcDbDictionary* pDict = NULL; if (Acad::eOk == pNamedDict->getAt(KEY_IRECORD,(AcDbObject*&)pDict,AcDb::kForRead)) { pNamedDict->close(); TDbInterfaceRecord* pInterfaceRec = NULL; if (Acad::eOk == pDict->getAt(KEY_IRECORD,(AcDbObject*&)pInterfaceRec,AcDb::kForWrite)) { pDict->close(); TInterface pipeInterface,pipeInterface2; int nCount = pIObj->GetInterfaceCount(); TReactorUnlockSwitch reactorUnlock((AcDbDatabase*)dwg,this); for (int i = 0;i < nCount;i++) { pipeInterface.Reset(); if (pIObj->GetInterface(i,pipeInterface)) { pipeInterface2.Reset(); if ( pInterfaceRec->Find(pipeInterface.GetPosition(),pipeInterface.GetOutDir(),pipeInterface2)) { //建立关联关系 if (Acad::eOk == pIObj->upgradeOpen()) { pIObj->SetInterfaceRelation(pipeInterface.GetPosition(),pipeInterface.GetConnectObject()); pIObj->downgradeOpen(); } pipeInterface2.SetOwnerId(pipeInterface.GetConnectObject()); pipeInterface2.SetPosition(pipeInterface.GetPosition()); pipeInterface2.SetOutDir(-pipeInterface.GetOutDir()); pipeInterface2.SetConnectObject(pIObj->objectId()); SetInterfaceRelation(pInterfaceRec,pipeInterface2); } else { pInterfaceRec->Add(pipeInterface); } } } pInterfaceRec->close(); } else { pDict->close(); } } else { pNamedDict->close(); } } //5.写入遮挡关系更新 if (acdbCurDwg() == dwg) pIObj->UpdateCoverDisplay(); } } BOOL TDbMakeObjAssocReactor::SetInterfaceRelation(TDbInterfaceRecord* pInterfaceRec,const TInterface& pipeInterface) { AcDbObjectId idOwner = pipeInterface.GetOwnerId(); AcDbEntity* pEnt = NULL; if (idOwner.isValid() && Acad::eOk == acdbOpenAcDbEntity(pEnt,idOwner,AcDb::kForWrite,true)) { TDbInterfacesObj* pIObj = TDbInterfacesObj::cast(pEnt); if (pIObj != NULL) { pIObj->SetInterfaceRelation(pipeInterface.GetPosition(),pipeInterface.GetConnectObject()); } pEnt->close(); } pInterfaceRec->Update(pipeInterface.GetOwnerId(),pipeInterface.GetPosition(),pipeInterface.GetConnectObject()); pInterfaceRec->Update(pipeInterface.GetConnectObject(),pipeInterface.GetPosition(),pipeInterface.GetOwnerId()); return TRUE; } void TDbMakeObjAssocReactor::objectErased(const AcDbDatabase* dwg, const AcDbObject* dbObj,Adesk::Boolean pErased) { if (dwg == NULL || dbObj == NULL) return; if (pErased) //正删除 { // 参见实体的方法 suberase /*TDbInterfacesObj* pIObj = TDbInterfacesObj::cast(dbObj); if (pIObj != NULL) { AcDbObjectId idOwner = pIObj->objectId(); BOOL bResetConet = FALSE; AcDbDictionary* pNamedDict = NULL; if (Acad::eOk == ((AcDbDatabase*)dwg)->getNamedObjectsDictionary(pNamedDict,AcDb::kForRead)) { AcDbDictionary* pDict = NULL; if (Acad::eOk == pNamedDict->getAt(KEY_IRECORD,(AcDbObject*&)pDict,AcDb::kForRead)) { pNamedDict->close(); TDbInterfaceRecord* pInterfaceRec = NULL; if (Acad::eOk == pDict->getAt(KEY_IRECORD,(AcDbObject*&)pInterfaceRec,AcDb::kForWrite)) { pDict->close(); pInterfaceRec->Remove(idOwner); bResetConet = pInterfaceRec->ResetConnect(idOwner); pInterfaceRec->close(); if (bResetConet) { TInterfaceModifyMsg iMsg; iMsg.SetInterfaceOper(TDb::eUpdateDisp); TDbInterfaceMsgWrite msgWrite; msgWrite.WriteInterfaceMsg(iMsg); } } else { pDict->close(); } } else { pNamedDict->close(); } } //5.写入遮挡关系更新 pIObj->UpdateCoverDisplay(); }*/ // add by hh 2014.8.8 删除水管时,更新被其遮挡的风管 CString sName = dbObj->isA()->name(); if(0 == sName.Compare(_T("TDbPipe"))) { TDbPipeAgency* pPipe = (TDbPipeAgency*)dbObj; AcDbObjectIdArray arClip, arClipped; pPipe->GetClipEntityId(arClip, arClipped); for(int i = 0; i < arClipped.length(); i++) { OPENOBJ_BEGIN(arClipped[i], AcDb::kForRead, TDbInterfacesObj, pObj); if(NULL != pObj) { if(AcDb::kVisible == pObj->visibility()) { pObj->UpdateCoverDisplay(); } } OPENOBJ_END(); } } } else //反删除,关系的建立在objectReAppended { TDbInterfacesObj* pIObj = TDbInterfacesObj::cast(dbObj); if (pIObj != NULL) { //5.写入遮挡关系更新 // mcl changed by below.2010.05.21 仅仅更新关系即可 // if (acdbCurDwg() == dwg) // pIObj->UpdateCoverDisplay(); TDbInterfaceMsgWrite msgWrite; TInterfaceModifyMsg iMsg; iMsg.SetMsgOperateOn(pIObj->objectId()); iMsg.SetInterfaceOper(TDb::eUpdateRel); msgWrite.WriteInterfaceMsg(iMsg); } } } void TDbMakeObjAssocReactor::objectModified(const AcDbDatabase* dwg, const AcDbObject* dbObj) { TDbInterfacesObj* pIntf = TDbInterfacesObj::cast(dbObj); if (pIntf != NULL) { //并且当前命令是 undo lfy 2011-9-2 struct resbuf rb; acedGetVar(_T("CMDNAMES"),&rb); if (rb.restype == RTSTR && rb.resval.rstring != NULL) { // change by hh 2011-10-27 判断条件错误 导致无法连续联动 // if (_tcsicmp(rb.resval.rstring,_T("undo"))) if (0 == _tcsicmp(rb.resval.rstring,_T("undo")) || 0 == _tcsicmp(rb.resval.rstring,_T("u"))) { TInterfaceModifyMsg msg; msg.SetInterfaceOper(TDb::eUpdateRel); msg.SetMsgOperateOn(dbObj->objectId()); TDbInterfaceMsgWrite msgWrite; msgWrite.WriteInterfaceMsg(msg); } acutDelString(rb.resval.rstring); } } } void TDbMakeObjAssocReactor::goodbye(const AcDbDatabase* pDb) { pDb->removeReactor(this); CPtrArray* pArray = NULL; if (g_iMsgContext.m_mapDb2TIMsgs.Lookup((AcDbDatabase*)pDb,(void*&)pArray)) { TDbInterfaceMsgObj* pMsgObj = NULL; TInterfaceModifyMsg msg; for (int i = 0;i < pArray->GetSize();i++) { pMsgObj = (TDbInterfaceMsgObj*)pArray->GetAt(i); delete pMsgObj; } pArray->RemoveAll(); delete pArray; g_iMsgContext.m_mapDb2TIMsgs.RemoveKey((AcDbDatabase*)pDb); } } BOOL TDbMakeObjAssocReactor::Find(const AcDbDatabase* pDb,TInterface& pipeInterface) { //到命名对象字典中找; BOOL bSuccess = FALSE; // add by hh 2011-08-09 接口记录从字典移动到数据库中 TDbInterfaceRecord* pIntfRec = TAuxTools::GetIntfPtrFromDB(); if(NULL != pIntfRec) { AcGePoint3d ptCon = pipeInterface.GetPosition(); AcGeVector3d vtDir = pipeInterface.GetOutDir(); bSuccess = pIntfRec->FindOtherSide(ptCon,vtDir,pipeInterface,pipeInterface.GetOwnerId()); pIntfRec->close(); return bSuccess; } // add end AcDbDictionary* pNamedDict = NULL; if (Acad::eOk == ((AcDbDatabase*)pDb)->getNamedObjectsDictionary(pNamedDict,AcDb::kForRead)) { AcDbDictionary* pDict = NULL; if (Acad::eOk == pNamedDict->getAt(KEY_IRECORD,(AcDbObject*&)pDict,AcDb::kForRead)) { pNamedDict->close(); TDbInterfaceRecord* pInterfaceRec = NULL; if (Acad::eOk == pDict->getAt(KEY_IRECORD,(AcDbObject*&)pInterfaceRec,AcDb::kForRead)) { pDict->close(); AcGePoint3d ptCon = pipeInterface.GetPosition(); AcGeVector3d vtDir = pipeInterface.GetOutDir(); bSuccess = pInterfaceRec->FindOtherSide(ptCon,vtDir,pipeInterface,pipeInterface.GetOwnerId()); pInterfaceRec->close(); } else { pDict->close(); } } else { pNamedDict->close(); } } return bSuccess; } BOOL TDbMakeObjAssocReactor::RegisterInterface(const AcDbDatabase* pDb,TInterface& pipeInterface) { if (pDb == NULL) return FALSE; //到命名对象字典中找; BOOL bSuccess = FALSE; // add by hh 2011-08-09 接口记录从字典移动到数据库中 TDbInterfaceRecord* pIntfRec = TAuxTools::GetIntfPtrFromDB(); if(NULL != pIntfRec) { if(Acad::eOk == pIntfRec->upgradeOpen()) { pIntfRec->Add(pipeInterface); pIntfRec->downgradeOpen(); } pIntfRec->close(); return TRUE; } // add end AcDbDictionary* pNamedDict = NULL; if (Acad::eOk == ((AcDbDatabase*)pDb)->getNamedObjectsDictionary(pNamedDict,AcDb::kForRead)) { AcDbDictionary* pDict = NULL; if (Acad::eOk == pNamedDict->getAt(KEY_IRECORD,(AcDbObject*&)pDict,AcDb::kForRead)) { pNamedDict->close(); TDbInterfaceRecord* pInterfaceRec = NULL; if (Acad::eOk == pDict->getAt(KEY_IRECORD,(AcDbObject*&)pInterfaceRec,AcDb::kForWrite)) { pDict->close(); pInterfaceRec->Add(pipeInterface); pInterfaceRec->close(); } else { pDict->close(); } } else { pNamedDict->close(); } } return bSuccess; }