#include "stdafx.h" #include "TInterfaceReleationManager.h" #include "TToolKitBase.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif extern void MakeSureDbHasAssocReactor(AcDbDatabase* pDb,TToolKitBase *pBase); extern TDbMakeObjAssocReactor* g_pObjAssocReactor; TInterfaceReleationManager::TInterfaceReleationManager() { m_pToolKit = NULL; } TInterfaceReleationManager::~TInterfaceReleationManager() { } void TInterfaceReleationManager::TranslateMoveGripPointMsg(const TInterfaceModifyMsg& msg,AcDbObjectIdArray& idOperOns) { CTempTolPipe tol(1.e-6); AcDbObjectId idOn = msg.GetMsgOperateOn(); AcDbEntity* pEnt = NULL; if ( idOn.isValid() && Acad::eOk == acdbOpenAcDbEntity(pEnt,idOn,AcDb::kForWrite,true)) { TDbInterfacesObj* pIObj = TDbInterfacesObj::cast(pEnt); //判断是否是可衍生对象的管子对象 if (pIObj != NULL) { //2判断夹点 夹点不是起点和终点 //if (msg.GetGripPosition() != TDb::eStart && msg.GetGripPosition() != TDb::eEnd) //{ //执行MOVE移动的操作 TransactMoveOperation(msg,idOperOns,pIObj,FALSE); //} } pEnt->close(); } /* [注: movegrip 操作不处理 ctrl 键按下的情况] if (Acad::eOk == acdbOpenAcDbEntity(pEnt,idOn,AcDb::kForRead)) { TDbInterfacesObj* pIObj = TDbInterfacesObj::cast(pEnt); //1判断是否是可衍生对象的管子对象 if (pIObj != NULL) { //2判断夹点 夹点不是起点和终点 if (msg.GetGripPosition() != TDb::eStart && msg.GetGripPosition() != TDb::eEnd) { //3判断是MOVE对象还是衍生拉出对象 if (GetUserChoose() == TInterfaceReleationManager::eMoveObj) { //执行MOVE移动的操作 TransactMoveOperation(msg,idOperOns,pIObj,bCtrl); } else { //衍生拉出对象 TransactPullOperation(msg,idOperOns,pIObj); } } else { //找到夹点对象 //验证其合法性 //进入循环 TransactOtherGripOperation(msg,idOperOns,pIObj); } } pEnt->close(); }*/ } BOOL TInterfaceReleationManager::Find(const 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(); AcDbObjectId idCon = pipeInterface.GetConnectObject(); AcDbObjectId idOwner = pipeInterface.GetOwnerId(); TInterface pipeInterface2; bSuccess = pIntfRec->Find(ptCon,vtDir,idOwner,pipeInterface2); if (bSuccess && pipeInterface2.GetConnectObject() == idCon && !idCon.isNull()) { } else { bSuccess = FALSE; } pIntfRec->close(); return bSuccess; } // add end AcDbDictionary* pNamedDict = NULL; if (Acad::eOk == acdbCurDwg()->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(); AcDbObjectId idCon = pipeInterface.GetConnectObject(); AcDbObjectId idOwner = pipeInterface.GetOwnerId(); TInterface pipeInterface2; bSuccess = pInterfaceRec->Find(ptCon,vtDir,idOwner,pipeInterface2); if (bSuccess && pipeInterface2.GetConnectObject() == idCon && !idCon.isNull()) { } else { bSuccess = FALSE; } pInterfaceRec->close(); } else { pDict->close(); } } else { pNamedDict->close(); } } return bSuccess; } BOOL TInterfaceReleationManager::Find(const AcGePoint3d& ptCon,const AcGeVector3d& vtDir,AcDbObjectId& idFind,const AcDbObjectId& idOwnerNotMe) { //到命名对象字典中找; BOOL bSuccess = FALSE; // add by hh 2011-08-09 接口记录从字典移动到数据库中 TDbInterfaceRecord* pIntfRec = TAuxTools::GetIntfPtrFromDB(); if(NULL != pIntfRec) { TInterface pipeInterface2; bSuccess = pIntfRec->FindOtherSide(ptCon,vtDir,pipeInterface2,idOwnerNotMe); if (bSuccess) { idFind = pipeInterface2.GetOwnerId(); AcDbObjectId idCon = pipeInterface2.GetConnectObject(); if (!idCon.isNull()) { //反过来以 connect 为 owner 找 bSuccess = pIntfRec->Find(ptCon,vtDir,idCon,pipeInterface2); if (bSuccess && pipeInterface2.GetConnectObject() == idFind && !idFind.isNull()) { bSuccess = FALSE; } idFind = idCon; } } pIntfRec->close(); return bSuccess; } // add end AcDbDictionary* pNamedDict = NULL; if (Acad::eOk == acdbCurDwg()->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(); TInterface pipeInterface2; bSuccess = pInterfaceRec->FindOtherSide(ptCon,vtDir,pipeInterface2,idOwnerNotMe); if (bSuccess) { idFind = pipeInterface2.GetOwnerId(); AcDbObjectId idCon = pipeInterface2.GetConnectObject(); if (!idCon.isNull()) { //反过来以 connect 为 owner 找 bSuccess = pInterfaceRec->Find(ptCon,vtDir,idCon,pipeInterface2); if (bSuccess && pipeInterface2.GetConnectObject() == idFind && !idFind.isNull()) { bSuccess = FALSE; } idFind = idCon; } } pInterfaceRec->close(); } else { pDict->close(); } } else { pNamedDict->close(); } } return bSuccess; } BOOL TInterfaceReleationManager::Find2(const AcGePoint3d& ptCon,const AcGeVector3d& vtDir,AcDbObjectId& idFind,AcDbObjectId& idOwnerThis) { //到命名对象字典中找; BOOL bSuccess = FALSE; // add by hh 2011-08-09 接口记录从字典移动到数据库中 TDbInterfaceRecord* pIntfRec = TAuxTools::GetIntfPtrFromDB(); if(NULL != pIntfRec) { TInterfaces tIfArr; TInterface pipeInterfaceFind; pIntfRec->Find(ptCon, tIfArr); int i(0); for (i = 0; i < tIfArr.length(); i++) { pipeInterfaceFind = tIfArr[i]; idFind = pipeInterfaceFind.GetConnectObject(); // 排除空id及自身接口 if (idFind.isValid() && idFind.asOldId() != idOwnerThis.asOldId()) { bSuccess = TRUE; break; } else { idFind = pipeInterfaceFind.GetOwnerId(); if (idFind.isValid() && idFind.asOldId() != idOwnerThis.asOldId()) { bSuccess = TRUE; break; } } } pIntfRec->close(); return bSuccess; } // add end AcDbDictionary* pNamedDict = NULL; if (Acad::eOk == acdbCurDwg()->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(); /* TInterface pipeInterface2; bSuccess = pInterfaceRec->Find(ptCon,vtDir,pipeInterface2); if (bSuccess) { //1. 排除此地是自身[如管子端点拉到中点后] 2. 找到连接对象有效 idFind = pipeInterface2.GetConnectObject(); if (!idFind.isValid() || idFind.asOldId() == idOwnerThis.asOldId()) bSuccess = FALSE; } */ //BEGIN========================================================= //修改时间:2010-03-09 //修改人 :mcl //修改原因:要通过数组找所有接口,一一查找验证。 if (NULL != pInterfaceRec) { TInterfaces tIfArr; TInterface pipeInterfaceFind; pInterfaceRec->Find(ptCon, tIfArr); int i(0); for (i = 0; i < tIfArr.length(); i++) { pipeInterfaceFind = tIfArr[i]; idFind = pipeInterfaceFind.GetConnectObject(); // 排除空id及自身接口 if (idFind.isValid() && idFind.asOldId() != idOwnerThis.asOldId()) { bSuccess = TRUE; break; } else { idFind = pipeInterfaceFind.GetOwnerId(); if (idFind.isValid() && idFind.asOldId() != idOwnerThis.asOldId()) { bSuccess = TRUE; break; } } } //END=========================================================== pInterfaceRec->close(); } } else { pDict->close(); } } else { pNamedDict->close(); } } return bSuccess; } BOOL TInterfaceReleationManager::SetInterfaceRelation(const AcDbDatabase* pDb,const TInterface& pipeInterface) { AcDbEntity* pEnt = NULL; if ( pipeInterface.GetOwnerId().isValid() && Acad::eOk == acdbOpenAcDbEntity(pEnt,pipeInterface.GetOwnerId(),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->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->close(); } else { pDict->close(); } } else { pNamedDict->close(); } } return TRUE; } BOOL TInterfaceReleationManager::Update(const TInterface& pipeInterface) { // 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->downgradeOpen(); } pIntfRec->close(); return TRUE; } // add end AcDbDictionary* pNamedDict = NULL; if (Acad::eOk == acdbCurDwg()->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->close(); } else { pDict->close(); } } else { pNamedDict->close(); } } return TRUE; } //进入连锁移动的循环并处理移动后是否有新的连接 BOOL TInterfaceReleationManager::TransactCycleMoveGripMsg(TDbInterfacesObj* pIObjOrigFr,const TInterfaceModifyMsg& msg,AcDbObjectIdArray& idOperOns) { int nFoundAt = 0; if (!idOperOns.find(msg.GetMsgOperateOn(),nFoundAt)) { TInterfaceModifyMsgs idModiNewMsgs; TDbInterfacesObj* pIObj2 = NULL; AcDbEntity* pEnt2 = NULL; //如果消息回流到原始实体,则不再打开,而是直接传递 if (msg.GetMsgOperateOn().asOldId() == pIObjOrigFr->objectId().asOldId()) { pIObjOrigFr->NotifyInterfaceToModify(msg,idModiNewMsgs); idOperOns.append(msg.GetMsgOperateOn()); } if (Acad::eOk == acdbOpenAcDbEntity(pEnt2,msg.GetMsgOperateOn(),AcDb::kForWrite,true)) { pIObj2 = TDbInterfacesObj::cast(pEnt2); if (pIObj2 != NULL) { pIObj2->NotifyInterfaceToModify(msg,idModiNewMsgs); idOperOns.append(msg.GetMsgOperateOn()); } pEnt2->close(); } //消息回流处理 AcDbObjectIdArray idOperOnsBk; if (idModiNewMsgs.IsFlowBackFlag()) { idOperOnsBk.append(idOperOns); idOperOns.setLogicalLength(0); } //继续传递更改消息,当新的消息对象已经处理过时(在idOperOns内),不传递 TInterfaceModifyMsg msgT; for (int i = 0;i < idModiNewMsgs.length();i++) { msgT = idModiNewMsgs.at(i); //排除对象已经被处理的消息,防止消息处理死循环 if (!idOperOns.find(msgT.GetMsgOperateOn(),nFoundAt)) { TransactCycleMoveGripMsg(pIObjOrigFr,msgT,idOperOns); idOperOns.append(msgT.GetMsgOperateOn()); } } if (idOperOnsBk.length() > 0) idOperOns.append(idOperOnsBk); } return TRUE; } //与用户交互,得到用户的选择 int TInterfaceReleationManager::GetUserChoose() { int nRes = AfxMessageBox(_T("请选出确定的操作[确定:移动对象|取消:衍生拉出对象]"),MB_OKCANCEL); if (nRes == IDOK) { return TInterfaceReleationManager::eMoveObj; } else { return TInterfaceReleationManager::ePullObj; } return 0; } //选择MOVE BOOL TInterfaceReleationManager::TransactMoveOperation(const TInterfaceModifyMsg& msg,AcDbObjectIdArray& idOperOns,TDbInterfacesObj* pIObj,BOOL bCtrl) { //MOVE对象 TInterface pipeInterface; AcDbObjectId idConnect,idFind; int nCount = pIObj->GetInterfaceCount(); AcDbEntity *pEntConnect = NULL; for (int i = 0; i < nCount; ++i) { pipeInterface.Reset(); //获得接口 if (pIObj->GetInterface(i,pipeInterface)) { idConnect = pipeInterface.GetConnectObject(); // 还需要检查接口的有效性 if (idConnect.isNull() || !Find2(pipeInterface.GetPosition()-msg.GetMoveGripOffset(),pipeInterface.GetOutDir(),idFind,pIObj->objectId())) { NewInterfaceReleation(pIObj,pipeInterface); continue; } if ( idConnect.isValid() && Acad::eOk == acdbOpenAcDbEntity(pEntConnect,idConnect,AcDb::kForRead,true)) { TDbInterfacesObj* pIObjConnect = TDbInterfacesObj::cast(pEntConnect); if (pIObjConnect->GetInterfaceCount() > 2 && bCtrl) { //改变对象的接口方向 ChangeInterface(msg,pIObjConnect); pEntConnect->close(); } else { pEntConnect->close(); int nFind = -1; // if (idOperOns.find(idConnect,nFind)) { //不需要处理 } else { TInterfaceModifyMsg msgT = msg; AcGePoint3d ptT = pipeInterface.GetPosition(); AcGeVector3d vecT = msg.GetMoveGripOffset(); ptT -= vecT; msgT.SetMsgPoint(ptT); msgT.SetMsgOperateOn(idConnect); TransactCycleMoveGripMsg(pIObj,msgT,idOperOns); } } } } } return TRUE; } //按住CRTL并选择衍生拉出 BOOL TInterfaceReleationManager::TransactPullOperation(const TInterfaceModifyMsg& msg,AcDbObjectIdArray& idOperOns,TDbInterfacesObj* pIObj) { return TRUE; } //处理非中间夹点的操作 BOOL TInterfaceReleationManager::TransactOtherGripOperation(const TInterfaceModifyMsg& msg,AcDbObjectIdArray& idOperOns,TDbInterfacesObj* pIObj) { if(pIObj != NULL) { //1找到夹点的接口 TInterface pipeInter; AcDbObjectId idCon,idFind; AcGePoint3d ptT1,ptT2,ptPosition; ptT2 = msg.GetMsgPoint(); ptPosition = ptT2; ptT2 += msg.GetMoveGripOffset(); pIObj->GetInterface(ptT2,pipeInter); if (Find2(ptPosition,pipeInter.GetOutDir(),idFind,pIObj->objectId())) { //3进入消息循环 TransactMoveOperation(msg,idOperOns,pIObj,TRUE); } } return TRUE; } //改变接口方向 BOOL TInterfaceReleationManager::ChangeInterface(const TInterfaceModifyMsg& msg,TDbInterfacesObj* pIObj) { if (pIObj != NULL) { } return TRUE; } //建立新的连接 BOOL TInterfaceReleationManager::NewInterfaceReleation(TDbInterfacesObj* pIObj,TInterface& pipeInterface) { TInterface pipeInterfaceOther; AcDbObjectId idFind; //1判断是否是可衍生对象的管子对象 if (pIObj != NULL) { //判断新位置是否有新的接口吻合连接 if (Find(pipeInterface.GetPosition(),pipeInterface.GetOutDir(),idFind,pIObj->objectId())) { //建立关联关系 if (pIObj->isWriteEnabled()) { pIObj->SetInterfaceRelation(pipeInterface.GetPosition(),idFind); } else if (Acad::eOk == pIObj->upgradeOpen()) { pIObj->SetInterfaceRelation(pipeInterface.GetPosition(),idFind); pIObj->downgradeOpen(); } //更新接口关系 pipeInterface.SetOwnerId(pIObj->objectId()); pipeInterface.SetConnectObject(idFind); Update(pipeInterface); pipeInterfaceOther.SetOwnerId(idFind); pipeInterfaceOther.SetPosition(pipeInterface.GetPosition()); pipeInterfaceOther.SetOutDir(-pipeInterface.GetOutDir()); pipeInterfaceOther.SetConnectObject(pipeInterface.GetOwnerId()); SetInterfaceRelation(acdbCurDwg(),pipeInterfaceOther); } else // 判断是否有 T 型的可能性,断开对方三通连接 { if (m_pToolKit != NULL) { MakeSureDbHasAssocReactor(acdbCurDwg(),m_pToolKit); m_pToolKit->TrytoAddTeeOnInterface(pIObj,pipeInterface); //acdbCurDwg()->removeReactor(g_pObjAssocReactor); } } } return TRUE; } //创建三联通 BOOL TInterfaceReleationManager::CreateNewCabTee(const AcGePoint3d& ptCen) { return TRUE; }