Files
envi-code/SourceCode/Code2026/tg_shs/shs_pipebase/TDbMakeObjAssocReactor.cpp
T
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

612 lines
17 KiB
C++

#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<AcDbDatabase,TDbMakeObjAssocReactor> 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<AcDbDatabase,TDbMakeObjAssocReactor> 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<AcDbDatabase,TDbMakeObjAssocReactor> 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;
}